【深入解析spring cloud gateway】12 gateway参数调优与分析

本节主要对网关主要的一些参数做一些解释说明,并用压测工具测试一下网关的接口,通过压测来验证参数配置是否合理

一、连接池参数

参数示例

yaml 复制代码
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

Http超时配置

全局超时配置

yaml 复制代码
spring:
  cloud:
    gateway:
      # http连接设置
      httpclient:
        # 全局的响应超时时间,网络链接后,后端服务多久不返回网关就报错 The response timeout. PT10S代表10秒的意思
        response-timeout: PT10S
        # 全局的TCP连接超时时间默认时间是45秒,修改为5秒
        connect-timeout: 5000

如果是想针对单个路由配置超时,可以配置在路由上

yaml 复制代码
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,该参数一共有三种类型

  • ELASTIC:弹性链接池,连接数上限为Integer.MAX,默认值就是这个类型
  • FIXED: 固定连接池,最大连接数采用spring.cloud.gateway.httpclient.pool.max-connections的配置
  • DISABLED:不使用任何连接池

其余参数见注释说明

二、线程池参数

Gateway底层是使用的netty来处理网络请求。如果你了解过netty,那你应该知道netty的线程模型是使用了两个线程池,bossGroup和workGroup。分别用于处理IO的连接请求,以及业务。

查看一下Gateway源码,可以看到

java 复制代码
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"));
    //省略大量代码
  }
  • DEFAULT_IO_WORKER_COUNT,工作线程数,默认值是CPU核心数,如果核心数少于4,那么就是最小为4
  • DEFAULT_IO_SELECT_COUNT ,IO线程数,默认为-1,当它为-1时,其实就等于IO线程数

如果想手动修改线程参数值,可以这么做

  • 添加环境变量,reactor.netty.ioWorkerCount=xx,reactor.netty.ioSelectCount=xx
  • 或者动设置属性值,如下代码
java 复制代码
@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

环境准备:JeMeter+JProfile

  • 下载JProfile,安装好
  • 下载JMeter,安装好
  • idea安装jprofile插件

测试代码编写

hello-service定义一个接口,模拟耗时200ms

java 复制代码
@Controller
@Slf4j
public class BusinessController {

    @RequestMapping(value = "/mock/business", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> modifyRequest(@RequestBody Map<String, String> map) {
        try {
            Thread.sleep(200L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return map;
    }
}
  • 启动微服务和eureka注册中心
  • 启动gateway网关,点击那个蓝色的小图标

然后就可以启好网关,并且通过JProfile看到线和、CPU、内存的运行状态了

等会我们通过JMeter再实时观察一下各参数的情况,方便验证我们的网关参数

JMeter配置

定义一个线程组:

1000个线程,10秒内启动,循环100次

定义一个http取样器,同时设置好请求,如下

由于是post请求,请求数据为json,所以添加一个头信息管理器

定义请求结果的报告

JMeter结果:

JMeter中的聚合报告中,主要有十几项的参数,参数如下:

  • 1、Label:每个请求的名称,比如HTTP请求等
  • 2、#Samples:表示这次测试中一共发出了多少个请求,如果模拟10个用户,每个用户迭代10次,那么这里显示100;【我的是用户有100,只迭代一次,因此也是100】
  • 3、Average:平均响应时间------默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以Transaction 为单位显示平均响应时间;
  • 4、Median:中位数,也就是 50% 用户的响应时间;
  • 5、90% Line ~ 99% Line:90% ~99%用户的响应时间;
  • 6、Min:最小响应时间;
  • 7、Maximum:最大响应时间;
  • 8、Error%:本次测试中出现的错误率,即 错误的请求的数量/请求的总数;
  • 9、Throughput:吞吐量------默认情况下表示每秒完成的请求数(Request per Second),当使用了 Transaction ;
  • 10、Received KB/src:每秒从服务器端接收到的数据量;
  • 11、Sent KB/src:每秒从客户端发送的请求的数量。

    可以看到,请求结果中,是有些报错的,
    通过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:重启计算机。

问题解决

相关推荐
BingoGo1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
DianSan_ERP5 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
呉師傅5 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑