zuul网关优化

574 阅读6分钟

参数semaphore优化

在spring cloud Zuul中有2种对路由的隔离机制,其默认的是信号量(semaphore)对路由做隔离,默认值是100,当一个路由请求的信号量高于100就返回500。

zuul:
  semaphore:
    max-semaphores: 1000 #设置全部路由最大信号量
  routes:
    orchestration:
      service-id: orchestration
    resource-manager:
      service-id: resource-manager
      semaphore:
        max-semaphores: 1000 #针对单个服务的路由设置最大信号量

设置信号量,可在Zuul节点下对所有路由统一设置信号量(semaphore)大小,在实际项目中推荐为每个服务设置不同的信号量(semaphore)。

参数ribbon优化

SpringCloud中ribbon提供负载均衡能力,实际项目中后端不同服务都是多实例,因此从Zuul路由到某个服务也需要支持负载均衡。

ribbon:
  OkToRetryOnAllOperations:true     #全部请求开启重试机制
  ReadTimeout: 6000                 #请求处理超时时间
  ConnectTimeout: 6000              #请求连接超时时间
  MaxTotalHttpConnections: 1000     #最大http连接数
  MaxConnectionsPerHost: 100        #每个host最大连接数
  MaxAutoRetries: 10                #最大重试次数
  MaxAutoRetriesNextServer: 10      #切换实例的重试次数

在高并发或者后端服务由于网络等原因,导致请求某一瞬间发生故障,也许后端服务只是暂时不可达或者响应比较慢。通过调整响应时间以及重试次数提高请求成功率。

hystrix参数优化

hystrix(熔断),当通过服务网关(基于Zuul实现)调用后端服务时候,难免会出现网络、响应超时等情况。通过hystrix可断掉与后端服务的连接,防止拖垮网关服务器。也可以通过hystrix实现服务降级,当发生异常时候,通过fallback处理熔断(比如:返回一些错误提示等)。

hystrix:
  threadpool:
    default:
      coreSize: 1000   #线程池数量
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000  #发生熔断的超时时间
          strategy: SEMAPHORE   #隔离策略
          semaphore:
            max-semaphores: 2000 #信号量大小

使用Undertow代替Tomcat

默认情况下,Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器,可以将 Web 服务器切换到 Undertow 来提高应用性能,Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器

Untertow 的特点:

轻量级:它是一个 Web 服务器,但不像传统的 Web 服务器有容器概念,它由两个核心 Jar 包组成,加载一个 Web 应用可以小于 10MB 内存
Servlet3.1 支持:它提供了对 Servlet3.1 的支持
WebSocket 支持:对 Web Socket 完全支持,用以满足 Web 应用巨大数量的客户端
嵌套性:它不需要容器,只需通过 API 即可快速搭建 Web 服务


移除Tomcat 依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
     <exclusion>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-tomcat</artifactId>
     </exclusion>
  </exclusions>
</dependency>
 


增加Untertow 依赖


<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-undertow</artifactId>
 </dependency>


配置文件加上Untertow的配置

server:
  undertow:
  io-threads: 16
  worker-threads: 256
  buffer-size: 1024
  direct-buffers: true
  io-threads:设置IO线程数,它主要执行非阻塞的任务,默认会取值cpu核心worker-threads:
阻塞任务线程池,当执行类似servlet请求阻塞IO操作会从这个线程池中取得线程,默认值是IO线程数*8buffer-size:设置buffer大小,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理direct-buffers:是否分配的直接内存(NIO直接分配的堆外内存)

Feign参数调优

  1. 替换OKHttp

在默认情况下 spring cloud feign在进行各个子服务之间的调用时,http组件使用的是jdk的HttpURLConnection,没有使用线程池。

有2种可选的线程池:HttpClient和OKHttp

比较推荐OKHttp,请求封装的非常简单易用,性能也很ok。

添加依赖

<dependency>
 <groupId>com.squareup.okhttp3</groupId>
 <artifactId>okhttp</artifactId>
</dependency>

设置参数

feign:
 okhttp:
 enabled: true
 httpclient:
 enabled: false
 max-connections: 1000
 max-connections-per-route: 100
 max-connections:最大连接数max-connections-per-route:每个url的连接数
  1. 开启Feign请求响应压缩

开启压缩可以有效节约网络资源,但是会增加CPU压力,建议把最小压缩的文档大小适度调大一点

## 开启Feign请求响应压缩
feign.compression.request.enabled=true
feign.compression.response.enabled=true
## 配置压缩文档类型及最小压缩的文档大小
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

高并发下常见Zuul异常

在高并发下,针对不同的系统架构、业务场景。需要自己调整Zuul各组件参数来满足性能需求。我们在使用jemeter进行并发测试,发现Zuul(服务网关)层出现了一些异常信息,解决了这些异常信息,QPS,TPS都提高了不少。

无法获取信号量(semaphore异常)

异常信息-1:

spring cloud zuul : could not acquire a semaphore for execution and no fallback

available.

无法获取信号量,系统默认每个路由的信号量为100,当后端一个实例且并发大于100就会经常出现

这个异常信息

调优配置-1:

zuul:
  semaphore:
    max-semaphores: 5000

可根据系统需要支持的并发数适当增加信号量的大小

超时异常信息:

connect time out...

当并发访问时,有些服务所在主机响应可能会比较慢,或者某些业务本身比较耗时(比如上传一个大文件的接口)。如果在Zuul层设置的超时时间小于足业务的耗时,会导致正常的业务请求失败。

调优配置:

ribbon:
  ReadTimeout: 6000                 #请求处理超时时间
  ConnectTimeout: 6000              #请求连接时间

根据业务可适当调大超时时间

熔断

异常信息-3:

short-circuited and no fallback available

并发访问时,后端某些服务发生熔断

调优配置-3:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000  #发生熔断的超时时间,调整熔断超时时间,熔断时间太短,些耗时的业务部不能work熔断时太长,Zuul服务器可能会被拖垮。所以根据具体业务找到一个合适值。
ribbon:
  OkToRetryOnAllOperations:true     #全部请求开启重试机制
  ReadTimeout: 6000                 #请求处理超时时间
  ConnectTimeout: 6000              #请求连接超时时间
  MaxAutoRetries: 10                #最大重试次数

调整重试次数,实际项目中由于网络或者资源不够,偶尔会出现后端服务不能访问,一次访问失败不能

代表后端服务就挂了。

因此开启重试机制,调整重试次数。在一定时间内,重试几次都失败,我们才认为后端服务挂了。