該參數是 ServerSocketChannel 的參數
三次握手與連接隊列
第一次握手時,因為客戶端與服務器之間的連接還未完全建立,連接會被放入半連接隊列中
當完成三次握手以后,連接會被放入全連接隊列中
服務器處理Accept事件是在TCP三次握手,也就是建立連接之后。服務器會從全連接隊列中獲取連接並進行處理
在 linux 2.2 之后,分別用下面兩個參數來控制
- 半連接隊列 - sync queue
- 大小通過 /proc/sys/net/ipv4/tcp_max_syn_backlog 指定,在
syncookies
啟用的情況下,邏輯上沒有最大值限制,這個設置便被忽略
- 大小通過 /proc/sys/net/ipv4/tcp_max_syn_backlog 指定,在
- 全連接隊列 - accept queue
- 其大小通過 /proc/sys/net/core/somaxconn 指定,在使用 listen 函數時,內核會根據傳入的 backlog 參數與系統參數,取二者的較小值
- 如果 accpet queue 隊列滿了,server 將發送一個拒絕連接的錯誤信息到 client
作用
在Netty中,SO_BACKLOG
主要用於設置全連接隊列的大小。當處理Accept的速率小於連接建立的速率時,全連接隊列中堆積的連接數大於SO_BACKLOG
設置的值是,便會拋出異常
設置方式如下
// 設置全連接隊列,大小為2 new ServerBootstrap().option(ChannelOption.SO_BACKLOG, 2);
backlog被保存在了DefaultServerSocketChannelConfig
配置類中
private volatile int backlog = NetUtil.SOMAXCONN;
- backlog的值會根據操作系統的不同,來選擇不同的默認值
- Windows 200
- Linux/Mac OS 128
- 如果配置文件
/proc/sys/net/core/somaxconn
存在,會讀取配置文件中的值,並將backlog的值設置為配置文件中指定的
TCP_NODELAY
- 屬於 SocketChannal 參數
- 因為 Nagle 算法,數據包會堆積到一定的數量后一起發送,這就可能導致數據的發送存在一定的延時
- 該參數默認為false,如果不希望的發送被延時,則需要將該值設置為true
SO_SNDBUF & SO_RCVBUF
- SO_SNDBUF 屬於 SocketChannal 參數
- SO_RCVBUF 既可用於 SocketChannal 參數,也可以用於 ServerSocketChannal 參數(建議設置到 ServerSocketChannal 上)
- 該參數用於指定接收方與發送方的滑動窗口大小
ALLOCATOR
- 屬於 SocketChannal 參數
- 用來配置 ByteBuf 是池化還是非池化,是直接內存還是堆內存
使用
// 選擇ALLOCATOR參數,設置SocketChannel中分配的ByteBuf類型 // 第二個參數需要傳入一個ByteBufAllocator,用於指定生成的 ByteBuf 的類型 new ServerBootstrap().childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator());
池化並使用直接內存
// true表示使用直接內存 new PooledByteBufAllocator(true);
池化並使用堆內存
// false表示使用堆內存 new PooledByteBufAllocator(false);
非池化並使用直接內存
// ture表示使用直接內存 new UnpooledByteBufAllocator(true);
非池化並使用堆內存
// false表示使用堆內存 new UnpooledByteBufAllocator(false);
RCVBUF_ALLOCATOR
- 屬於 SocketChannal 參數
- 控制 Netty 接收緩沖區大小
- 負責入站數據的分配,決定入站緩沖區的大小(並可動態調整),統一采用 direct 直接內存,具體池化還是非池化由 allocator 決定