Linux中的SO_REUSEPORT 使用场景
目录
SO_REUSEPORT 是 Linux 3.9+ 引入的一个 socket 选项,允许多个进程或线程绑定到同一个 IP 和端口,内核会自动进行负载均衡。它的主要目的是提高网络应用的并发性能和可靠性。
1. SO_REUSEPORT 的主要用途
(1) 提高 TCP/UDP 服务的并发性能
- 传统方式(单进程监听):
- 单个进程监听一个端口,所有连接都由该进程处理,容易成为性能瓶颈。
- 使用
SO_REUSEPORT:- 多个进程/线程可以同时监听同一个端口,内核自动分配新连接(TCP)或数据包(UDP)给不同的进程。
- 适用于 Nginx、Redis、HAProxy、游戏服务器 等高并发场景。
(2) 实现无缝重启(Zero-Downtime Restart)
- 传统方式:
- 重启服务时,需要先关闭旧进程,再启动新进程,导致短暂服务不可用。
- 使用
SO_REUSEPORT:- 新进程可以绑定同一个端口,旧进程继续处理已有连接,新连接由新进程处理。
- 适用于 Web 服务器、微服务 等需要平滑升级的场景。
(3) 防止惊群效应(Thundering Herd Problem)
- 传统方式(
SO_REUSEADDR+ 多进程):- 多个进程监听同一个 socket,新连接到来时,所有进程都会被唤醒(惊群效应),但只有一个能处理连接,浪费 CPU。
- 使用
SO_REUSEPORT:- 内核保证每个新连接只会唤醒一个进程,避免惊群效应。
(4) UDP 多进程负载均衡
- 传统方式:
- UDP 通常由单进程处理,难以利用多核 CPU。
- 使用
SO_REUSEPORT:- 多个进程可以同时监听同一个 UDP 端口,内核自动分配数据包,提高吞吐量。
- 适用于 DNS 服务器、QUIC/HTTP3 服务。
2. SO_REUSEPORT vs SO_REUSEADDR
| 特性 | SO_REUSEADDR |
SO_REUSEPORT |
|---|---|---|
| 允许多个进程绑定相同端口 | ❌(仅允许 TIME_WAIT 状态端口复用) | ✅ |
| 内核负载均衡 | ❌ | ✅ |
| 防止惊群效应 | ❌ | ✅ |
| 适用场景 | 快速重启、避免端口占用 | 高并发、无缝重启 |
3. 代码示例
(1) C 语言设置 SO_REUSEPORT
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, SOMAXCONN);
(2) Go 语言设置 SO_REUSEPORT
package main
import (
"net"
"syscall"
)
func main() {
lc := net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
})
},
}
ln, _ := lc.Listen(context.Background(), "tcp", ":8080")
defer ln.Close()
}
4. 适用场景总结
| 场景 | 是否推荐 SO_REUSEPORT |
说明 |
|---|---|---|
| 高并发 TCP 服务(Nginx、Redis) | ✅ | 多进程负载均衡 |
| UDP 高并发(DNS、QUIC) | ✅ | 提高 UDP 吞吐量 |
| 无缝重启(Zero-Downtime) | ✅ | 新旧进程共存 |
| 单进程服务 | ❌ | 无并发需求 |
| Windows 或旧版 Linux | ❌ | 仅 Linux 3.9+ 支持 |
5. 注意事项
- 仅 Linux 3.9+ 支持,Windows 和 macOS 不支持。
- UDP 需保证数据包有序性,可能需额外处理(如 QUIC 协议)。
- TCP 连接不能跨进程迁移,旧进程退出后,其连接会断开。
总结
SO_REUSEPORT适用于高并发、无缝重启、UDP 多进程负载均衡。- 相比
SO_REUSEADDR,它能避免惊群效应,提升性能。 - 代码实现简单,但需注意平台兼容性。
如果你的服务需要高并发或平滑升级,强烈建议使用 SO_REUSEPORT! 🚀
Do not communicate by sharing memory; instead, share memory by communicating.

浙公网安备 33010602011771号