大家好,又见面了,我是你们的朋友全栈君。
网关的大部分工作是请求转发,属于IO密集型的应用,我们要在有限的资源的情况下结合公司实际请求场景做调优。
一,容器选择
在容器方面,undertow的呼声很高,一个是他很轻量级的,其次他属于java开发,性能也很好,笔者根据实际情况对tomcat和undertow做了一个对比
默认配置下,8核cpu,tomcat启动后会初始化10个io线程,而undertow会初始化72个线程,8个IO线程,64个work线程(8*8)
性能对比:写一个接口,接口中什么也不做,就睡眠2s
请求个数 | tomcat | tomcat(max-threads:100) | undertow | |||
---|---|---|---|---|---|---|
50 | 平均耗时(ms): | 2241 | 2241 | 2321 | ||
线程个数: | 93 | 93 | 105 | |||
内存 | 94 | 133 | ||||
100 | 平均耗时(ms): | 2231 | 2021 | 2517 | ||
线程个数: | 143 | 138 | 105 | |||
内存 | ||||||
200 | 平均耗时(ms): | 2424 | 2788 | 3884 | ||
线程个数: | 238 | 138 | 105 | |||
内存 | ||||||
300 | 平均耗时(ms): | 3596 | 3753 | 5454 | ||
线程个数: | 238 | 138 | 105 | |||
内存 | ||||||
400 | 平均耗时(ms): | 3427 | 4623 | 6865 | ||
线程个数: | 238 | 138 | 105 | |||
内存 |
从对比来看,就初始化来看,tomcat最初只初始化10个线程,而undertow则会初始化所有的线程
性能来看,tomcat也是要占优势的
tomcat 比undertow要灵活,适应高峰和低谷也比较强
二,hystrix隔离方式
zuul默认的是信号量方式,也就是控制进来的请求总量,可以全局配置,也可以配置单个服务的最大信号量,还有一种方式是线程隔离,每种路由方式会创建单独的线程池,这样的好处是一个服务的影响不会扩散到其他的服务,但是在资源有限,且服务有限的情况下,还是信号量合适,这样我们可以充分利用tomcat创建的线程池,而不用创建过多的hystrix线程池
三:ribbon相应时间:
在默认的情况下,ribbon很容易就会报错,比如read timeout等,可以通过
代码语言:javascript复制ribbon:
ReadTimeout: 60000
ConnectTimeout: 10000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 1
来控制,但是如果设置过长也会导致长时间的等待,建议60比较合适
四:httpclient选择
zuul默认是Appache Httpclient,呼声比较高的是okhttp
但是经过测试,okhttp的性能更好,所以可以通过
代码语言:javascript复制<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
引入okhttp并在ribbon中配置:
代码语言:javascript复制ribbon:
httpclient:
enabled: false
okhttp:
enabled: true
五:超时配置
使用zuul时,一共有三个超时参数
1.zuul.host.socket-timeout-millis和zuul.host.connect-timeout-millis这个超时是指在使用url路由时,则使用这里的超时,ribbon配置的超时将不会生效
2.ribbon.ReadTimeout 和ribbon.ConnectTimeout这个就是服务名路由时的超时
3.hystrix.command.execution.isolation.thread.timeoutMilliseconds这个超时在线程隔离的模式下是hystrix的熔断超时,应该大于ribbon和zuul的超时,还需加上重试的时间,在信号量隔离模式下是信号量的释放时间,也就是说如果你这里配置2 ,但是接口执行时间是5s,那么到了2秒后依然会释放信号量
还有一点需要注意的是hystrix.command.default.circuitBreaker.requestVolumeThreshold默认是20,也就是说如果熔断器失败了20个后就会开启CIRCUIT_OPEN模式这个也需结合实际情况来进行配置
六:jvm参数
根据目前dev环境情况(没有数据),以及本地测试(使用jmeter提交400个请求),网关一般情况下对内存使用为80M左右,老年代为36M左右,元数据空间为63M左右,可以保守设置为堆内存代销为300M,年轻代150M, 老年代150M,
而默认情况下,NewRatio=2 , 而在JVM的默认参数中MetaspaceSize=21M , 这样会导致前期jvm调整metaspacesize大小并发生fullgc所以咱们可以设置一下jvm参数
-Xms300m -Xmx300m -XX:NewRatio=1 -XX:MetaspaceSize=100m
该配置下程序启动发生YGC :4 FGC : 0 堆中 E:80M , T : 0 M , F : 19M , O:9M ,Me:56M
连续发起1600次请求后:YGC:10 FGC: 0 堆中:E:71M , T:0M , F : 10M, O:34M , Me: 62M
后期可根据生产实际情况调整大小
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170623.html原文链接:https://javaforall.cn