1, CONNECT_TIMEOUT_MILLIS
- Parameters belonging to socketchannel
- When the client establishes a connection, if the connection cannot be made within the specified milliseconds, a timeout exception will be thrown
- Note: don't use so in Netty_ Timeout is mainly used for blocking IO, while Netty is non blocking io
Examples
public class TimeOutTest { public static void main(String[] args) { NioEventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap() .group(group) .channel(NioSocketChannel.class) // Throw an exception if no connection is established within one second .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000) .handler(new LoggingHandler()); ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress("localhost", 8080)).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } }
- Client through bootstrap The option function is used to configure parameters. The configuration parameters act on SocketChannel
- The server configures parameters through ServerBootstrap, but different methods need to be selected for different channels
- Configure parameters on ServerSocketChannel through option
- Configure the parameters on SocketChannel through childOption
Source code analysis
The thread connecting to the server in the client is the NIO thread, and the main thread throws an exception. How does this achieve timeout judgment and thread communication?
Exception set in connect method of AbstractNioChannel:
@Override public final void connect( final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) { . . . // Get timeout from parameter int connectTimeoutMillis = config().getConnectTimeoutMillis(); if (connectTimeoutMillis > 0) { // Execute a scheduled task through schedule connectTimeoutFuture = eventLoop().schedule(new Runnable() { @Override public void run() { ChannelPromise connectPromise = AbstractNioChannel.this.connectPromise; ConnectTimeoutException cause = new ConnectTimeoutException("connection timed out: " + remoteAddress); //If no connection is obtained after the timeout, tryFailure puts the exception into promise for the main thread to get if (connectPromise != null && connectPromise.tryFailure(cause)) { close(voidPromise()); } } }, connectTimeoutMillis, TimeUnit.MILLISECONDS); } . . . } } catch (Throwable t) { promise.tryFailure(annotateConnectException(t, remoteAddress)); closeIfClosed(); } }
The timeout judgment is mainly realized through the schedule method of Eventloop and Promise
- schedule sets a scheduled task, and executes this method after delaying connectTimeoutMillis seconds
- If no connection is established within the specified time, the task will be executed, the ConnectTimeoutException exception will be created, and the exception will be passed to the main thread through poise and thrown
2, SO_BACKLOG
This parameter is a parameter of ServerSocketChannel
Triple handshake and connection queue
- At the first handshake, because the connection between the client and the server has not been fully established, the connection will be put into the semi connection queue
- After three handshakes, the connection will be put into the full connection queue
- The server handles the Accept event after three TCP handshakes, that is, after the connection is established. The server gets the connection from the full connection queue and processes it
Before linux 2.2, the backlog size includes the size of two queues. After linux 2.2, the following two parameters are used to control the backlog size
- Semi connected queue - sync queue
- Size via / proc / sys / net / IPv4 / TCP_ max_ syn_ The backlog specifies that when syncookies are enabled, there is no logical maximum limit, and this setting will be ignored
- Full connection queue - accept queue
- Its size is specified by / proc/sys/net/core/somaxconn. When using the listen function, the kernel will take the smaller value of the two according to the passed backlog parameters and system parameters
- If the accpet queue is full, the server will send a connection rejection error message to the client
Examples
In Netty, SO_BACKLOG is mainly used to set the size of the full connection queue. When the rate of processing Accept is less than the rate of connection establishment, the number of connections stacked in the full connection queue is greater than so_ If the value set by backlog is, an exception will be thrown
public class BackLogTest { public static void main(String[] args) { NioEventLoopGroup bossGroup = new NioEventLoopGroup(1); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap server = new ServerBootstrap() .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) //Set the full connection queue size to 2 .option(ChannelOption.SO_BACKLOG, 2) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { } }); ChannelFuture channelFuture = server.bind(8080).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
3, TCP_NODELAY
- Belongs to socketchannel parameter
- Because of Nagle algorithm, data packets will be piled up to a certain number and sent together, which may lead to a certain delay in data transmission
- This parameter defaults to false. If the undesired sending is delayed, you need to set this value to true
4, So_ SNDBUF & SO_ RCVBUF
- SO_SNDBUF belongs to socketchannel parameter (send buffer size)
- SO_RCVBUF can be used for both socketchannel parameter and serversocketchannel parameter (it is recommended to set it on serversocketchannel) (accept buffer size)
- This parameter is used to specify the sliding window size of receiver and sender
5, ALLOCATOR
- Belongs to socketchannel parameter
- Used to configure whether ByteBuf is pooled or non pooled, direct memory or heap memory
use
ServerBootstrap server = new ServerBootstrap() .childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator())
- Pool and use direct memory
// true indicates that direct memory is used new PooledByteBufAllocator(true);
- Pool and use heap memory
// false indicates that heap memory is used new PooledByteBufAllocator(false);
- Non pooling and using direct memory
// ture means using direct memory new UnpooledByteBufAllocator(true);
- Non pooling and using heap memory
// false indicates that heap memory is used new UnpooledByteBufAllocator(false);
6, RCVBUF_ALLOCATOR
- Belongs to socketchannel parameter
- Control the size of Netty receive buffer
- It is responsible for the allocation of inbound data, determines the size of inbound buffer (and can be dynamically adjusted), and uniformly adopts direct direct memory. The specific pooling or non pooling is determined by the allocator