关于spring-cloud:SpringCloud升级之路20200x版13UnderTow-核心配置

5次阅读

共计 5079 个字符,预计需要花费 13 分钟才能阅读完成。

本系列代码地址:https://github.com/HashZhang/…

Undertow 的配置能够参考 Undertow 的 Builder,并且其中也有一些默认的配置参数:

Undertow

private Builder() {ioThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2);
    workerThreads = ioThreads * 8;
    long maxMemory = Runtime.getRuntime().maxMemory();
    //smaller than 64mb of ram we use 512b buffers
    if (maxMemory < 64 * 1024 * 1024) {
        //use 512b buffers
        directBuffers = false;
        bufferSize = 512;
    } else if (maxMemory < 128 * 1024 * 1024) {
        //use 1k buffers
        directBuffers = true;
        bufferSize = 1024;
    } else {
        //use 16k buffers for best performance
        //as 16k is generally the max amount of data that can be sent in a single write() call
        directBuffers = true;
        bufferSize = 1024 * 16 - 20; //the 20 is to allow some space for protocol headers, see UNDERTOW-1209
    }

}
  • ioThreads 大小为可用 CPU 数量 * 2,即 Undertow 的 XNIO 的读线程个数为可用 CPU 数量,写线程个数也为可用 CPU 数量。
  • workerThreads 大小为 ioThreads 数量 * 8.
  • 如果内存大小小于 64 MB,则不应用间接内存,bufferSize 为 512 字节
  • 如果内存大小大于 64 MB 小于 128 MB,则应用间接内存,bufferSize 为 1024 字节
  • 如果内存大小大于 128 MB,则应用间接内存,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协定头。

DefaultByteBufferPool 结构器:

public DefaultByteBufferPool(boolean direct, int bufferSize, int maximumPoolSize, int threadLocalCacheSize, int leakDecetionPercent) {
    this.direct = direct;
    this.bufferSize = bufferSize;
    this.maximumPoolSize = maximumPoolSize;
    this.threadLocalCacheSize = threadLocalCacheSize;
    this.leakDectionPercent = leakDecetionPercent;
    if(direct) {arrayBackedPool = new DefaultByteBufferPool(false, bufferSize, maximumPoolSize, 0, leakDecetionPercent);
    } else {arrayBackedPool = this;}
}

其中:

  • direct:是否应用间接内存,咱们须要设置为 true,来应用间接内存。
  • bufferSize:每次申请的 buffer 大小,咱们次要要思考这个大小
  • maximumPoolSize:buffer 池最大大小,个别不必批改
  • threadLocalCacheSize:线程本地 buffer 池大小,个别不必批改
  • leakDecetionPercent:内存透露查看百分比,目前没啥卵用

对于 bufferSize,最好和你零碎的 TCP Socket Buffer 配置一样。在咱们的容器中,咱们将微服务实例的容器内的 TCP Socket Buffer 的读写 buffer 大小成截然不同的配置(因为微服务之间调用,发送的申请也是另一个微服务承受,所以调整所有微服务容器的读写 buffer 大小统一,来优化性能,默认是依据零碎内存来主动计算出来的)。

查看 Linux 零碎 TCP Socket Buffer 的大小:

  • /proc/sys/net/ipv4/tcp_rmem (对于读取)
  • /proc/sys/net/ipv4/tcp_wmem (对于写入)

在咱们的容器中,别离是:

bash-4.2# cat /proc/sys/net/ipv4/tcp_rmem
4096    16384   4194304 
bash-4.2# cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   4194304 

从左到右三个值别离为:每个 TCP Socket 的读 Buffer 与写 Buffer 的大小的 最小值,默认值和最大值,单位是字节。

咱们设置咱们 Undertow 的 buffer size 为 TCP Socket Buffer 的默认值, 即 16 KB。Undertow 的 Builder 外面,如果内存大于 128 MB,buffer size 为 16 KB 减去 20 字节(为协定头预留)。所以, 咱们应用默认的即可

application.yml 配置:

server.undertow:
    # 是否调配的间接内存 (NIO 间接调配的堆外内存),这里开启,所以 java 启动参数须要配置下间接内存大小,缩小不必要的 GC
    # 在内存大于 128 MB 时,默认就是应用间接内存的
    directBuffers: true
    # 以下的配置会影响 buffer, 这些 buffer 会用于服务器连贯的 IO 操作
    # 如果每次须要 ByteBuffer 的时候都去申请,对于堆内存的 ByteBuffer 须要走 JVM 内存调配流程(TLAB -> 堆),对于间接内存则须要走零碎调用,这样效率是很低下的。# 所以,个别都会引入内存池。在这里就是 `BufferPool`。# 目前,UnderTow 中只有一种 `DefaultByteBufferPool`,其余的实现目前没有用。# 这个 DefaultByteBufferPool 绝对于 netty 的 ByteBufArena 来说,非常简单,相似于 JVM TLAB 的机制
    # 对于 bufferSize,最好和你零碎的 TCP Socket Buffer 配置一样
    # `/proc/sys/net/ipv4/tcp_rmem` (对于读取)
    # `/proc/sys/net/ipv4/tcp_wmem` (对于写入)
    # 在内存大于 128 MB 时,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协定头
    buffer-size: 16384 - 20

Worker 配置其实就是 XNIO 的外围配置,次要须要配置的即 io 线程池以及 worker 线程池大小。

默认状况下,io 线程大小为可用 CPU 数量 2,即读线程个数为可用 CPU 数量,写线程个数也为可用 CPU 数量。worker 线程池大小为 io 线程大小 8.

微服务利用因为波及的阻塞操作比拟多,所以能够将 worker 线程池大小调大一些。咱们的利用设置为 io 线程大小 * 32.

application.yml 配置:

server.undertow.threads:
    # 设置 IO 线程数, 它次要执行非阻塞的工作, 它们会负责多个连贯, 默认设置每个 CPU 外围一个读线程和一个写线程
    io: 16
    # 阻塞工作线程池, 当执行相似 servlet 申请阻塞 IO 操作, undertow 会从这个线程池中获得线程
    # 它的值设置取决于零碎线程执行工作的阻塞系数,默认值是 IO 线程数 *8
    worker: 128

Spring Boot 中对于 Undertow 相干配置的形象是 ServerProperties 这个类。目前 Undertow 波及的所有配置以及阐明如下(不包含 accesslog 相干的,accesslog 会在下一节详细分析):

server:
  undertow:
    # 以下的配置会影响 buffer, 这些 buffer 会用于服务器连贯的 IO 操作
    # 如果每次须要 ByteBuffer 的时候都去申请,对于堆内存的 ByteBuffer 须要走 JVM 内存调配流程(TLAB -> 堆),对于间接内存则须要走零碎调用,这样效率是很低下的。# 所以,个别都会引入内存池。在这里就是 `BufferPool`。# 目前,UnderTow 中只有一种 `DefaultByteBufferPool`,其余的实现目前没有用。# 这个 DefaultByteBufferPool 绝对于 netty 的 ByteBufArena 来说,非常简单,相似于 JVM TLAB 的机制
    # 对于 bufferSize,最好和你零碎的 TCP Socket Buffer 配置一样
    # `/proc/sys/net/ipv4/tcp_rmem` (对于读取)
    # `/proc/sys/net/ipv4/tcp_wmem` (对于写入)
    # 在内存大于 128 MB 时,bufferSize 为 16 KB 减去 20 字节,这 20 字节用于协定头
    buffer-size: 16364
    # 是否调配的间接内存 (NIO 间接调配的堆外内存),这里开启,所以 java 启动参数须要配置下间接内存大小,缩小不必要的 GC
    # 在内存大于 128 MB 时,默认就是应用间接内存的
    directBuffers: true
    threads:
      # 设置 IO 线程数, 它次要执行非阻塞的工作, 它们会负责多个连贯, 默认设置每个 CPU 外围一个读线程和一个写线程
      io: 4
      # 阻塞工作线程池, 当执行相似 servlet 申请阻塞 IO 操作, undertow 会从这个线程池中获得线程
      # 它的值设置取决于零碎线程执行工作的阻塞系数,默认值是 IO 线程数 *8
      worker: 128
    # http post body 大小,默认为 -1B,即不限度
    max-http-post-size: -1B
    # 是否在启动时创立 filter,默认为 true,不必批改
    eager-filter-init: true
    # 限度门路参数数量,默认为 1000
    max-parameters: 1000
    # 限度 http header 数量,默认为 200
    max-headers: 200
    # 限度 http header 中 cookies 的键值对数量,默认为 200
    max-cookies: 200
    # 是否容许 / 与 %2F 本义。/ 是 URL 保留字, 除非你的利用明确须要,否则不要开启这个本义,默认为 false
    allow-encoded-slash: false
    # 是否容许 URL 解码,默认为 true,除了 %2F 其余的都会解决
    decode-url: true
    # url 字符编码集,默认是 utf-8
    url-charset: utf-8
    # 响应的 http header 是否会加上 'Connection: keep-alive',默认为 true
    always-set-keep-alive: true
    # 申请超时,默认是不超时,咱们的微服务因为可能有长时间的定时工作,所以不做服务端超时,都用客户端超时,所以咱们放弃这个默认配置
    no-request-timeout: -1
    # 是否在跳转的时候放弃 path,默认是敞开的,个别不必配置
    preserve-path-on-forward: false
    options:
      # spring boot 没有形象的 xnio 相干配置在这里配置,对应 org.xnio.Options 类
      socket:
        SSL_ENABLED: false
      # spring boot 没有形象的 undertow 相干配置在这里配置,对应 io.undertow.UndertowOptions 类
      server:
        ALLOW_UNKNOWN_PROTOCOLS: false

Spring Boot 并没有将所有的 Undertow 与 XNIO 配置进行形象,如果你想自定义一些相干配置,能够通过下面配置最初的 server.undertow.options 进行配置。server.undertow.options.socket 对应 XNIO 的相干配置,配置类是 org.xnio.Options;server.undertow.options.server 对应 Undertow 的相干配置,配置类是 io.undertow.UndertowOptions

咱们这一节具体介绍了 Undertow 的外围配置,次要包含线程池以及 buffer 配置,以及对于 http 协定的一些配置。并且咱们还介绍了这些配置在 spring boot 下该如何配置。下一节,咱们将具体介绍如何配置 Undertow 的 accesslog。

微信搜寻“我的编程喵”关注公众号,每日一刷,轻松晋升技术,斩获各种 offer

正文完
 0