之前在做RTA项目的时候感觉接口性能到了瓶颈,QPS一直上不去,网上看了很多文章,经过多次修改和压测接口性能终于有一定的提升,这里记录一下优化点。
-
servlet 容器优化
默认情况下,Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器,可以将 Web 服务器切换到 Undertow 来提高应用性能。
第一步,pom文件添加一下内容:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!--移除 tomcat 依赖 --> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <!--添加 undertow 依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>
第二步,添加undertow配置
server: undertow: threads: io: 8 worker: 64 buffer-size: 1024 direct-buffers: true
server.undertow.threads.io:设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程,不要设置过大,建议多次压测后选最优值。
server.undertow.threads.worker:阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程,它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数 * 8。
server.undertow.buffer-size: 这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理,每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可。
server.undertow.direct-buffers: 是否分配的直接内存(NIO直接分配的堆外内存)。 -
Feign 配置优化
feign默认使用的是基于JDK提供的URLConnection调用HTTP接口,不具备连接池,所以资源开销上有点影响,经测试JDK的URLConnection比Apache HttpClient快很多倍。Apache HttpClient和okhttp都支持配置连接池功能,也可以使用okhttp请求方式。当使用HttpClient时,可如下设置:
feign: httpclient: enabled: true max-connections:1000 max-connections-per-route: 200
当使用OKHttp时,可如下设置:
feign: okhttp: enabled: true httpclient: max-connections: 1000 max-connections-per-route: 200
max-connections 设置整个连接池最大连接数(该值默认为200)
max-connections-per-route 设置路由的默认最大连接(该值默认为50)
根据自己的场景决定,限制实际的数量。 -
Hystrix 配置优化
首先需要设置参数hystrix.threadpool.default.coreSize 来指定熔断隔离的线程数,这个数需要调优,经测试线程数我们设置为和提供方的容器线程差不多,吞吐量高许多。其次,启用Hystrix后,很多服务当第一次访问的时候都会失败 是因为初始化负载均衡一系列操作已经超出了超时时间了,因为默认的超时时间为1S,需要修改超时时间参数,方可解决这个问题。
参考的hystrix配置如下:
hystrix: threadpool: default: coreSize: 500 command: default: circuitBreaker: requestVolumeThreshold: 1000 fallback: enabled: true execution: isolation: thread: timeoutInMilliseconds: 100000
- hystrix.command.default: 全局的作用域,作用的所有的hystrix的客户端,如果需要对某个微服务,可以写serviceId
- hystrix.command.default.fallback.enabled 是否开启回退方法
- hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 请求处理的超时时间,缺省为1000,表示默认的超时时间为1S
- hystrix.threadpool.default.coreSize 核心线程池数量
- hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 回退最大线程数
- hystrix.command.default.circuitBreaker.requestVolumeThreshold 熔断器失败的个数,进入熔断器的请求达到1000时服务降级(之后的请求直接进入熔断器)
-
Ribbon 优化
Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易就会出现上面所描述的显现。因此我们可以通过设置:
ribbon: eager-load: enabled:true clients:service-1,service-2,service-n
参数说明:
- ribbon.eager-load.enabled : 开启Ribbon的饥饿加载模式
- ribbon.eager-load.clients:指定需要饥饿加载的服务名,如果不指定服务名称,饥饿加载模式无效