更新时间:2023-11-07 GMT+08:00

合理配置线程池参数

线程池是微服务的主要业务处理单元,合理的规划线程池不仅可以最大限度提升系统性能,还能防止异常情况导致系统无法给正常用户提供服务。线程池优化和业务自身的性能有很大关系,不同的场景参数设置不同,需要具体分析。下面分两种场景介绍。开始之前需要对业务的性能做一些基本的摸底,对常见的接口进行测试,查看时延。

  • 业务性能很好的情况。

    即非并发场景,接口的平均时延小于10ms。

    业务性能很好的时候,为了让业务系统具备更好的可预测性,防止JVM垃圾回收、网络波动、突发流量等对系统的稳定性造成冲击,需要能够快速丢弃请求,并配合重试等措施,以保障波动情况下系统性能可预测,同时不会出现偶然的业务失败,影响体验。

    • 连接数和超时设置
      # 服务端verticle实例数,保持默认值即可。建议配置为8~10。
      servicecomb.rest.server.verticle-count: 10
      # 最大连接数限制。默认值为 Integer.MAX_VALUE。可以结合实际情况估算最大值,使系统具备更好的韧性。
      servicecomb.rest.server.connection-limit: 20000
      # 连接闲置时间。默认值60秒,一般不需要修改
      servicecomb.rest.server.connection.idleTimeoutInSeconds: 60
      # 客户端verticle实例数,保持默认值即可。建议配置为8~10。
      servicecomb.rest.client.verticle-count: 0
      # 一个客户端与服务器建立的最大连接数为 verticle-count * maxPoolSize,不要超过线程数。
      #  这里是 10*50=500. 实例非常多的场景,要减小单个实例的连接数。
      servicecomb.rest.client.connection.maxPoolSize: 50
      # 连接闲置时间。默认值30 秒,一般不需要修改,要小于服务端的连接闲置时间。
      servicecomb.rest.client.connection.idleTimeoutInSeconds
      
    • 业务线程池配置
      # 线程池组数,建议 2~4
      servicecomb.executor.default.group: 2
      # 建议 50~200
      servicecomb.executor.default.thread-per-group: 100
      # 线程池排队队列大小,默认值为Integer.MAX_VALUE。高性能场景不要使用默认值,以快速丢弃请求
      servicecomb.executor.default.maxQueueSize-per-group: 10000
      # 队列最大等待时间,如果超过,理解丢弃请求的处理并返回。默认值为0。
      # 高性能场景配置小的排队超时时间,快速丢弃请求
      servicecomb.rest.server.requestWaitInPoolTimeout: 100
      # 设置比较短的超时时间,快速丢弃请求, 但是不建议这个值小于1秒,可能导致很多问题。
      servicecomb.request.timeout=5000
      
  • 业务性能不那么好的情况。

    即非并发场景,接口的平均时延大于100ms。时延高通常是由于业务代码存在IO、资源等等待,CPU利用率上不去导致的。如果是由于计算复杂导致的,调优会变得复杂。

    当业务性能不太好的时候,下面几个参数值需要调大,否则业务会大量阻塞。业务性能不好,通过调大参数能够保证系统的吞吐量,应对突发流量来临时带来的业务失败。不过这个是以牺牲用户体验为代价的。

    # 服务端连接闲置时间。
    servicecomb.rest.server.connection.idleTimeoutInSeconds: 120000
    # 客户端连接闲置时间。
    servicecomb.rest.client.connection.idleTimeoutInSeconds: 90000
    # 线程池组数。
    servicecomb.executor.default.group: 4
    # 线程池大小。
    servicecomb.executor.default.thread-per-group: 200
    # 线程池排队队列大小,性能不好的情况下需要排队
    servicecomb.executor.default.maxQueueSize-per-group: 100000
    # 配置较大的超时时间
    servicecomb.rest.server.requestWaitInPoolTimeout: 10000
    servicecomb.request.timeout=30000