Gateway网关使用不规范,同事加班泪两行~

沙海 2021年7月15日01:03:53Java评论32字数 4279阅读14分15秒阅读模式
摘要

Gateway网关使用不规范,同事加班泪两行~ 芋道源码

Gateway网关使用不规范,同事加班泪两行~

芋道源码 文章源自JAVA秀-https://www.javaxiu.com/37819.html

以下文章来源于Java知音,作者辣椒文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

Java知音文章源自JAVA秀-https://www.javaxiu.com/37819.html

专注于java。分享java基础、原理性知识、JavaWeb实战、spring全家桶、设计模式及面试资料、开源项目,助力开发者成长!文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

点击上方“芋道源码”,选择“设为星标文章源自JAVA秀-https://www.javaxiu.com/37819.html

管她前浪,还是后浪?文章源自JAVA秀-https://www.javaxiu.com/37819.html

能浪的浪,才是好浪!文章源自JAVA秀-https://www.javaxiu.com/37819.html

每天 8:55 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/37819.html

 文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 问题文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 原因文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 解决文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 后续文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

问题

Spring cloud gateway是替代zuul的网关产品,基于Spring 5、Spring boot 2.0以上、Reactor, 提供任意的路由匹配和断言、过滤功能。文章源自JAVA秀-https://www.javaxiu.com/37819.html

笔者公司之前有系统也使用了Spring cloud gateway做为后台应用访问的网关,采用的版本信息为:文章源自JAVA秀-https://www.javaxiu.com/37819.html

组件版本其他
spring boot2.1.7.RELEASE
spring cloudGreenwich.SR2
spring cloud gateway2.1.2.RELEASE

其中的一个路由的代码如下:文章源自JAVA秀-https://www.javaxiu.com/37819.html

@Bean    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {        RouteLocatorBuilder.Builder routes = builder.routes();        RouteLocatorBuilder.Builder serviceProvider = routes          .route("accept",            r -> r            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)            .and()            .method(HttpMethod.POST)            .and()            .readBody(String.class, readBody -> true)            .and()            .path("/gateway-accept/**")            .filters(f -> {              f.rewritePath("/gateway-accept/(?<path>.*)", "/${path}");                  return f;              })            .uri("lb://ACCEPT-MICROSERVICE"));        return serviceProvider.build();    }

后台采用的是版本也是spring boot 2.1.2.RELEASE, 内置Tomcat的一个服务。文章源自JAVA秀-https://www.javaxiu.com/37819.html

一开始系统运行良好,最近业务慢慢繁忙,前端调用说偶尔返回这样的问题:文章源自JAVA秀-https://www.javaxiu.com/37819.html

{"timestamp":"2021-01-06T01:50:00.468+0000","path":"/gateway-accept/policy","status":500,"error":"Internal Server Error","message":"Connection prematurely closed BEFORE response"}

字面意思是“响应前过早关闭连接”, 查看后台服务的日志,根本没有调用的信息,再次调用也没有问题,服务和网关都没有任何问题,到底怎么回事?文章源自JAVA秀-https://www.javaxiu.com/37819.html

原因

由于这是Spring cloud gateway的问题,肯定有人碰上过,先去gateway的github上的issues去碰碰运气。文章源自JAVA秀-https://www.javaxiu.com/37819.html

果然,在issues中查找“Connection prematurely closed BEFORE response”,列出了十几条,相关的有七八条,一个一个翻阅,终于一个issue提到了相同的的问题:文章源自JAVA秀-https://www.javaxiu.com/37819.html

https://github.com/spring-cloud/spring-cloud-gateway/issues/1148文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

总结如下文章源自JAVA秀-https://www.javaxiu.com/37819.html

gateway调用后台服务,会使用httpclient连接池里面的连接文章源自JAVA秀-https://www.javaxiu.com/37819.html

gateway使用的httpclient连接池的连接有个参数:max-idle-time,大意指的是多长时间连接不使用就关闭。如果设置为null, 连接不会关闭。文章源自JAVA秀-https://www.javaxiu.com/37819.html

后台服务也有相应的连接对应连接池的连接,参数keepAliveTimeout,大意指后台服务的连接空闲多长时间就会自动关闭,缺省的值就是connection-timeout参数的值。如果为-1就不会有时间限制,缺省值为60s ,但是一般的再server.xml里面设置为20s.文章源自JAVA秀-https://www.javaxiu.com/37819.html

重要 :如果网关的连接池的连接max-idle-time不设置(null),后台服务的connection-timeout为20s文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 假设网络连接池有个连接(gateway-connect-1)对应后台服务的连接(server-connect-1)文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 前端请求过来,gateway的分配给这个请求的连接正好是(gateway-connect-1), 向后端发起请求调用文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 同时,服务端连接(server-connect-1)已经等待空闲20秒,自动关闭;文章源自JAVA秀-https://www.javaxiu.com/37819.html

  • 可想而知,服务端没有和(gateway-connect-1)对应的连接,于是发生了异常。文章源自JAVA秀-https://www.javaxiu.com/37819.html

需要在网关层设置spring.cloud.gateway.httpclient.pool.max-idle-time文章源自JAVA秀-https://www.javaxiu.com/37819.html

需要服务端设置server.connection-timeout, 这个值要适当的大于网关层的max-idle-time, 意思就是,网关层对后端连接的空闲时间要小于后端服务的连接空闲时间,这样就不会取到无效的网关层的连接。文章源自JAVA秀-https://www.javaxiu.com/37819.html

解决

根据上面的描述,我在yml里面加入:文章源自JAVA秀-https://www.javaxiu.com/37819.html

spring:  cloud:    gateway:      httpclient:        pool:          max-idle-time: 5000          max-connections: 30

在idea里面发现max-idle-time黄色标底,找不到这个配置,点击没有问题的max-connections, 定位到文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

原来,我用的这个gateway版本2.1.2的连接池根本没有提供max-idle-time这个参数,那个版本可以提供?文章源自JAVA秀-https://www.javaxiu.com/37819.html

我新建了一个gateway服务,用的版本如下:文章源自JAVA秀-https://www.javaxiu.com/37819.html

组件版本其他
spring boot2.3.4.RELEASE
spring cloudHoxton.SR1
spring cloud gateway2.2.1.RELEASE

在网关服务层设置:文章源自JAVA秀-https://www.javaxiu.com/37819.html

spring:  cloud:    gateway:      httpclient:        pool:          max-idle-time: 10000

i点击max-idle-time, 可以看到已经提供这个参数了:文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

后端服务设置(后端用的内嵌tomcat):文章源自JAVA秀-https://www.javaxiu.com/37819.html

server:  tomcat:    connection-timeout: 20000

服务调用接口:文章源自JAVA秀-https://www.javaxiu.com/37819.html

@GetMapping(value = "/test")public String get() throws InterruptedException {    Thread.sleep(10);    return "laza";}

第一种设置

网关不设置max-idle-time文章源自JAVA秀-https://www.javaxiu.com/37819.html

后端服务我设置connection-time: 100文章源自JAVA秀-https://www.javaxiu.com/37819.html

使用jmeter测试,配置如下:文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

点击开始,后台出现错误:文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

第二种设置

网关设置max-idle-time:10000文章源自JAVA秀-https://www.javaxiu.com/37819.html

后端服务我设置connection-time: 20000文章源自JAVA秀-https://www.javaxiu.com/37819.html

jmeter设置和上面一样,测试一切正常。文章源自JAVA秀-https://www.javaxiu.com/37819.html

和版本也有点关系,我生产使用的版本目前不支持max-idle-time这个参数的设置,所以要升级一下gateway使用的版本了。文章源自JAVA秀-https://www.javaxiu.com/37819.html

后续

在issues最后,发现这个:文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

图片文章源自JAVA秀-https://www.javaxiu.com/37819.html

点进去以后,发现是蚂蚁金服的同学Lovnx , 详细的阐述了这个问题,有兴趣可以去看一下。他在文章中提到:文章源自JAVA秀-https://www.javaxiu.com/37819.html

reactor.netty.pool.leasingStrategy=lifo获取连接策略由默认的FIFO变更为LIFO,因为LIFO能够确保获取的连接最大概率是最近刚被用过的,也就是热点连接始终是热点连接,而始终用不到的连接就可以被回收掉,LRU的思想(文中原话)文章源自JAVA秀-https://www.javaxiu.com/37819.html

Reactor-Netty 版本问题 我查了一下,spring cloud gateway 2.2.1.release提供的Reactor-Netty版本是0.9.2.RELEASE文章源自JAVA秀-https://www.javaxiu.com/37819.html

<dependency>    <groupId>io.projectreactor.netty</groupId>    <artifactId>reactor-netty</artifactId>    <version>0.9.2.RELEASE</version>    <scope>compile</scope></dependency>

- END -文章源自JAVA秀-https://www.javaxiu.com/37819.html

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

Gateway网关使用不规范,同事加班泪两行~文章源自JAVA秀-https://www.javaxiu.com/37819.html

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/37819.html

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/37819.html

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章源自JAVA秀-https://www.javaxiu.com/37819.html

文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)
文章源自JAVA秀-https://www.javaxiu.com/37819.html

阅读原文文章源自JAVA秀-https://www.javaxiu.com/37819.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定