本节主要对网关主要的一些参数做一些解释说明,并用压测工具测试一下网关的接口,通过压测来验证参数配置是否合理
参数示例
spring: application: name: gateway cloud: gateway: # http连接设置 httpclient: # 全局的响应超时时间,网络链接后,后端服务多久不返回网关就报错 The response timeout. PT10S代表10秒的意思 response-timeout: PT30S # 全局的TCP连接超时时间默认时间是45秒,修改为5秒 connect-timeout: 5000 # 链接池配置 pool: # 最大连接数 max-connections: 10000 # 获取连接的超时时间,单位毫秒 acquire-timeout: 1000 # channel空闲时,最大的存活时间,如果为空,没有最大空闲时间 max-idle-time: 120000 # channel存在的最长时间,如果为null,则没有最大生命时间限制 # max-life-time: 10 # 在后台进行清除channel的时间间隔,默认情况下为0,即不进行定期清除 eviction-interval: 180000 # 设置固定链接池 type: fixed
全局超时配置
spring: cloud: gateway: # http连接设置 httpclient: # 全局的响应超时时间,网络链接后,后端服务多久不返回网关就报错 The response timeout. PT10S代表10秒的意思 response-timeout: PT10S # 全局的TCP连接超时时间默认时间是45秒,修改为5秒 connect-timeout: 5000
如果是想针对单个路由配置超时,可以配置在路由上
spring: cloud: gateway: routes: - id: requestratelimiter_route uri: http://localhost:3000/ predicates: - Path=/normal/** metadata: response-timeout: 7000 connect-timeout: 2000
spring.cloud.gateway.httpclient.pool.type,该参数一共有三种类型
其余参数见注释说明
Gateway底层是使用的netty来处理网络请求。如果你了解过netty,那你应该知道netty的线程模型是使用了两个线程池,bossGroup和workGroup。分别用于处理IO的连接请求,以及业务。
查看一下Gateway源码,可以看到
public interface LoopResources extends Disposable { int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioWorkerCount", "" + Math.max(Runtime.getRuntime().availableProcessors(), 4))); int DEFAULT_IO_SELECT_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioSelectCount", "-1")); //省略大量代码 }
如果想手动修改线程参数值,可以这么做
@SpringBootApplication public class GatewayDemoApplication { public static void main(String[] args) { System.setProperty(ReactorNetty.IO_SELECT_COUNT,"8"); System.setProperty(ReactorNetty.IO_WORKER_COUNT,"8"); SpringApplication.run(GatewayDemoApplication.class, args); } }
本机环境 4核CPU,16G内存,三个服务,eureka-server,euerka-client,gateway
hello-service定义一个接口,模拟耗时200ms
@Controller @Slf4j public class BusinessController { @RequestMapping(value = "/mock/business", method = RequestMethod.POST) @ResponseBody public MapmodifyRequest(@RequestBody Map map) { try { Thread.sleep(200L); } catch (InterruptedException e) { throw new RuntimeException(e); } return map; } }
然后就可以启好网关,并且通过JProfile看到线和、CPU、内存的运行状态了
等会我们通过JMeter再实时观察一下各参数的情况,方便验证我们的网关参数
JMeter配置
定义一个线程组:
1000个线程,10秒内启动,循环100次
定义一个http取样器,同时设置好请求,如下
由于是post请求,请求数据为json,所以添加一个头信息管理器
定义请求结果的报告
JMeter结果:
JMeter中的聚合报告中,主要有十几项的参数,参数如下:
可以看到,请求结果中,是有些报错的,
通过JMeter查看一下线程情况
可以看到,gateway的线程数,并没有因为请求数增加而增加,线程一般启起来都是固定的。基于reactor响应式编程模型和netty框架的支持,一个线程是可以同时处理多个连接(channel)的。
上图中,可以看到,此时运行的线程数为4,IO处理线程为4
内存占用情况,可以在这里看到
————————————————
用JMeter时遇到了如下问题:
JMeter压测时Address Already in use:connect错误解决
在windows 环境下使用jmeter 进行压测的过程中,通常会遇到这样的错误“JMeter Address Already in use:connect”, 查阅了不少资料,发现这是windows本身提供的端口访问机制的问题。
Windows提供给TCP/IP连接的端口为1024-5000,并且要4分钟来循环回收它们,这就导致了我们在短时间内发起大量请求的时候将端口占满了。
解决方案一:
Jmeter里的http sample勾选了keep alive,导致会话一直保持,而windows本身的端口有限,导致端口被占用完后,无法分配新的端口,因此会产生java.net.BindException: Address already in use: connect 报错。
解决方法:HTTP SAMPLE 不勾选"KeepAlive"即可,如下图所示:
解决方案二:
step1:win+r 在cmd中,用regedit命令打开注册表
step2:在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 目录下,
(1)右键Parameters 新建DWORD,名字为MaxUserPort,输入数值65534(十进制)
(2)再次右键 Parameters 新建DWORD,名字为TCPTimedWaitDelay,输入数值30(十进制)表示30秒回收端口
step3:重启计算机。
问题解决