This is my 17th day of the August Challenge

This series of code address: github.com/HashZhang/s…

The Undertow configuration can be seen in the Undertow Builder, and there are some default configuration parameters:

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
    }

}
Copy the code
  • The size of ioThreads is the number of available cpus * 2, that is, the number of XNIO read threads in Undertow is the number of available cpus, and the number of write threads is also the number of available cpus.
  • The workerThreads size is the number of ioThreads * 8.
  • If the memory size is less than 64 MB, direct memory is not used and bufferSize is 512 bytes
  • If the memory size is greater than 64 MB and less than 128 MB, use direct memory with a bufferSize of 1024 bytes
  • If the memory size is greater than 128 MB, direct memory is used, and the bufferSize is 16 KB minus 20 bytes, which is used for the protocol header.

DefaultByteBufferPool constructor:

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; }}Copy the code

Among them:

  • Direct: Whether to use direct memory, we need to set this to true to use direct memory.
  • BufferSize: The size of the buffer requested each time. This size is the main consideration
  • MaximumPoolSize: Indicates the maximum size of the buffer pool
  • ThreadLocalCacheSize: Specifies the size of the thread-local buffer pool. You do not need to change it
  • LeakDecetionPercent: Percentage of memory leak checks. Currently not useful

For bufferSize, it is best to have the same configuration as your system’s TCP Socket Buffer. In our container, we set the size of the TCP Socket Buffer within the microservice instance’s container to the same size. (Since microservices call each other and send requests that are also received by another microservice, adjust the size of the read/write Buffer for all microservice containers to the same size.) To optimize performance, which is automatically calculated based on system memory by default).

Check the size of the TCP Socket Buffer in Linux:

  • /proc/sys/net/ipv4/tcp_rmem(For reading)
  • /proc/sys/net/ipv4/tcp_wmem(For writing)

In our container, they are:

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 4194304Copy the code

The three values from left to right are the minimum, default, and maximum sizes of the read Buffer and write Buffer of each TCP Socket, in bytes.

We set our Undertow buffer size to the default TCP Socket buffer, which is 16 KB. In Undertow Builder, if the memory is larger than 128 MB, the buffer size is 16 KB minus 20 bytes (reserved for protocol headers). So, we’ll just use the default.

Application. Yml configuration:

server.undertow: # If NIO is directly allocated out of the heap, this parameter needs to be configured to reduce unnecessary GC. # If NIO is directly allocated out of the heap, this parameter will default to directBuffers using direct memory: If you need a ByteBuffer every time you need a ByteBuffer, you need to go through the JVM memory allocation process (TLAB -> heap). For direct memory, system calls are required, which is very inefficient. Therefore, memory pools are usually introduced. In this case, it's 'BufferPool'. # Currently, there is only one 'DefaultByteBufferPool' in UnderTow, the other implementations are currently useless. DefaultByteBufferPool is very simple compared to Netty's ByteBufArena, similar to JVM TLAB's mechanism. It is better to have the same configuration as your system's TCP Socket Buffer # '/proc/sys/net/ipv4/tcp_rmem' (for reads) # '/proc/sys/net/ipv4/tcp_wmem' (for writes) # in memory greater than 128 For MB, the bufferSize is 16 KB minus 20 bytes, which is used for the protocol header buffer-size: 16384-20Copy the code

Worker configuration is actually the core configuration of XNIO. The main configuration needs to be IO thread pool and Worker thread pool size.

By default, the SIZE of I/O threads is the number of available cpus x 2, that is, the number of read threads is the number of available cpus, and the number of write threads is the number of available cpus. The size of the worker thread pool is the size of an IO thread x 8.

Microservice applications involve more blocking operations, so the worker thread pool can be made larger or smaller. Our application is set to the IO thread size * 32.

Application. Yml configuration:

Server.undertow. threads: # Set the number of I/O threads, which are mainly used for non-blocking tasks that are responsible for multiple connections. The default is one read thread and one write thread per CPU core: This value is set depending on the blocking factor of the system thread executing the task. The default value is number of I/O threads *8 worker: 128Copy the code

The abstract for Undertow related configuration in Spring Boot is the ServerProperties class. All of the configurations currently covered by Undertow are described below (excluding those related to accessLog, which are discussed in detail in the next section) :

server: undertow: If you need a ByteBuffer every time you need a ByteBuffer, you need to go through the JVM memory allocation process (TLAB -> heap). For direct memory, system calls are required, which is very inefficient. Therefore, memory pools are usually introduced. In this case, it's 'BufferPool'. # Currently, there is only one 'DefaultByteBufferPool' in UnderTow, the other implementations are currently useless. DefaultByteBufferPool is very simple compared to Netty's ByteBufArena, similar to JVM TLAB's mechanism. It is better to have the same configuration as your system's TCP Socket Buffer # '/proc/sys/net/ipv4/tcp_rmem' (for reads) # '/proc/sys/net/ipv4/tcp_wmem' (for writes) # in memory greater than 128 For MB, the bufferSize is 16 KB minus 20 bytes, which is used for the protocol header buffer-size: 16364 # Specifies whether to allocate direct memory (NIO directly allocates memory out of the heap), which is enabled here, so the Java startup parameter needs to be configured for direct memory size to reduce unnecessary GC # # Set the number of I/O threads that are used for non-blocking tasks that are responsible for multiple connections. The default is one read thread and one write thread per CPU core. The value is set depending on the blocking factor of the system thread executing the task. The default value is the number of I/O threads *8 worker: Max -http-post-size: -1b # Specifies whether to create a filter at startup. The default value is true. Do not change the eager filter-init: # Limit the number of HTTP headers, default is 200 max-headers: 200 # Limits the number of key-value pairs of cookies in HTTP headers. Default is 200 max-cookies: 200 # Whether/is allowed to escape with %2F. / is a reserved URL word. Do not enable this escape unless your application explicitly requires it. The default is false allow-encoded-slash: False # Whether to allow URL decoding, default is true, all but %2F will be handled by decode- URL: true # URL character encoding set, default is UTF-8 url-charset: Utf-8 # specifies whether the HTTP header in the response will include 'Connection: keep-alive'. Default is true: The default value is no timeout. Our microservice does not use client timeout because it may have a long scheduled task, so we will keep the default value no-request-timeout: -1: whether to preserve preserve-path-on-forward: false options: 1: whether to preserve preserve-path-on-forward: false options: Xnio. Options class socket: SSL_ENABLED: False # spring boot no undertow related configuration configuration here, in the abstract. The corresponding IO undertow. UndertowOptions class server: ALLOW_UNKNOWN_PROTOCOLS: falseCopy the code

Spring Boot does not abstract all of the Undertow and XNIO configurations. If you want to customize some of these configurations, you can do so using the server.undertow. Server. The undertow. Options. The socket corresponding XNIO related configuration, configuration class is org. XNIO. The options; Server. The undertow. Options. The corresponding undertow of related configuration, server configuration class is IO undertow. UndertowOptions.

This section describes the core configuration of Undertow in detail, including thread pool and buffer configuration, as well as some configuration related to the HTTP protocol. We also showed how these configurations can be configured under Spring Boot. In the next section, we’ll go into more detail on how to configure the Accesslog for Undertow.

Wechat search “my programming cat” to follow the public account, every day, easy to improve technology, win a variety of offers: