Go 里的端口复用从原理到生产可用代码(SO_REUSEPORT / SO_REUSEADDR)

1. 先把概念掰直:你说的“端口复用”可能是四种事

1)多进程共享同一端口(真正意义上的端口复用)

多个进程同时listen :8080,由内核把新连接分发到不同进程。
关键开关:SO_REUSEPORT(Linux 3.9+ 常见)。

这是本文重点。

2)快速重启不被 TIME_WAIT 卡住

很多人以为这叫“端口复用”,其实是想解决重启时报错占用。
关键开关:SO_REUSEADDR(更多是“允许更快重新绑定”,不是负载均衡共享)。

3)同端口跑多协议(443 上 HTTP/2、gRPC、HTTP/1.1)

一般靠 TLS ALPN 或反向代理分流,不属于多进程共同 bind。

4)一个入口端口,转发到多个后端(Nginx/Envoy/Traefik)

这叫端口“统一入口”,不是 socket 级复用。

你要的是哪一种?如果你想“多实例同端口一起扛连接”,那就是SO_REUSEPORT

2. SO_REUSEPORT 到底做了什么

没有SO_REUSEPORT
一个端口只能被一个监听 socket 持有,其他进程 bind 会失败。

开启SO_REUSEPORT
多个监听 socket 可以绑定同一个(IP, Port)。内核在 accept 阶段把“新连接”分配给其中一个监听 socket(通常基于 hash 或轮询的策略实现,不同内核版本略有差异)。

它的价值很直接:

  • 多进程架构,不需要在应用层做 accept 分发
  • 能让每个进程独占自己的 goroutine、GC、堆、锁
  • 避免单进程在高连接量下出现“某个环节抖动拖全局”的情况

3. Go 标准库的现状:没有直接开关,但可以用 ListenConfig.Control

Go 的net.Listen()没有参数给你开SO_REUSEPORT,但net.ListenConfig提供了一个Control回调,你可以在 socket 创建后、bind 前设置 sockopt。

生产建议:用golang.org/x/sys/unix,比syscall更可靠、常量更齐全。

3.1 TCP 端口复用(多进程共享 :8080)

下面是一个“可落地”的ListenReusePort,支持:

  • SO_REUSEADDR(方便重启)
  • SO_REUSEPORT(多进程共享同一端口)
  • TCP keepalive 参数(可选)
  • 明确错误返回,方便排查
packagereuseportimport("context""errors""net""runtime""time""golang.org/x/sys/unix")typeOptionsstruct{ReuseAddrboolReusePortboolKeepAlive time.Duration// 0 表示不设置}funcListenTCP(addrstring,opt Options)(net.Listener,error){lc:=net.ListenConfig{Control:func(network,addressstring,c syscallRawConn)error{// Windows/macOS 端口复用语义不同,这里只实现 Linux 常见行为ifruntime.GOOS!="linux"{returnnil}varctrlErrerrorerr:=c.Control(func(fduintptr){ifopt.ReuseAddr{ctrlErr=unix.SetsockoptInt(int(fd),unix.SOL_SOCKET,unix.SO_REUSEADDR,1)ifctrlErr!=nil{return}}ifopt.ReusePort{ctrlErr=unix.SetsockoptInt(int(fd),unix.SOL_SOCKET,unix.SO_REUSEPORT,1)ifctrlErr!=nil{return}}})iferr!=nil{returnerr}returnctrlErr},KeepAlive:opt.KeepAlive,}ln,err:=lc.Listen(context.Background(),"tcp",addr)iferr!=nil{returnnil,err}returnln,nil}// 兼容 net.ListenConfig.Control 的 RawConn 接口,避免直接依赖 syscall 包typesyscallRawConninterface{Control(func(fduintptr))errorRead(func(fduintptr)(donebool))errorWrite(func(fduintptr)(donebool))error}

使用示例(一个最小 TCP server):

packagemainimport("bufio""fmt""log""net""os""strconv""time""yourmod/reuseport")funcmain(){workerID:=0iflen(os.Args)>1{workerID,_=strconv.Atoi(os.Args[1])}ln,err:=reuseport.ListenTCP(":8080",reuseport.Options{ReuseAddr:true,ReusePort:true,KeepAlive:30*time.Second,})iferr!=nil{log.Fatalf("listen failed: %v",err)}log.Printf("worker=%d listening on :8080",workerID)for{c,err:=ln.Accept()iferr!=nil{log.Printf("accept err: %v",err)continue}gohandle(workerID,c)}}funchandle(idint,c net.Conn){deferc.Close()_=c.SetDeadline(time.Now().Add(2*time.Minute))w:=bufio.NewWriter(c)fmt.Fprintf(w,"hello from worker %d\n",id)w.Flush()}

启动两个进程同时监听同一端口:

go run main.go1go run main.go2

然后压测或多次 curl:

foriin{1..10};docurl-s localhost:8080;done

你会看到输出会在 worker 1 和 worker 2 之间分散。

重要提醒:必须所有监听者都开启 SO_REUSEPORT

如果一个进程没开 reuseport,另一个开了,bind 行为会变得不可预期甚至失败。生产上要统一策略。

4. UDP 端口复用:更常见,也更“自然”

UDP 服务(例如 QUIC、日志采集、metrics ingestion)经常用 reuseport 来多进程吃包。

基本代码与 TCP 类似,只是network变成"udp",返回net.PacketConn

funcListenUDP(addrstring,opt Options)(net.PacketConn,error){lc:=net.ListenConfig{Control:func(network,addressstring,c syscallRawConn)error{ifruntime.GOOS!="linux"{returnnil}varctrlErrerrorerr:=c.Control(func(fduintptr){ifopt.ReuseAddr{ctrlErr=unix.SetsockoptInt(int(fd),unix.SOL_SOCKET,unix.SO_REUSEADDR,1)ifctrlErr!=nil{return}}ifopt.ReusePort{ctrlErr=unix.SetsockoptInt(int(fd),unix.SOL_SOCKET,unix.SO_REUSEPORT,1)ifctrlErr!=nil{return}}})iferr!=nil{returnerr}returnctrlErr},}returnlc.ListenPacket(context.Background(),"udp",addr)}

5. 什么时候该用多进程 + SO_REUSEPORT,什么时候不该用

适合用的典型场景

  • 长连接很多(IM、推送、网关),单进程 GC 或某个锁抖动容易放大
  • 单机多核明显没吃满(CPU 利用率上不去)
  • 想要“水平扩展”到同机多实例,但不想引入额外入口层

不建议直接用的场景

  • 你需要非常精细的连接路由(例如“同一个用户必须固定落到同一个进程”,且你不依赖四元组 hash)
    这种更适合:入口层(Envoy/Nginx/自研 acceptor)做一致性哈希
  • 需要热升级、连接迁移、平滑 drain 的要求很强
    这时往往要配合 systemd socket activation 或代理层做优雅切换

6. 生产实践与坑位清单(很关键)

6.1 观察是否真的复用成功

ss看监听 socket:

ss -lntp|grep':8080'

你应该能看到同一端口上有多个进程在 LISTEN。

6.2 不要把它当成“绝对均衡”

连接分配策略受内核影响,并不保证完全平均。压测时如果你看到轻微倾斜是正常的。
如果你需要更可控的分配策略:入口层做负载均衡更合适。

6.3 与容器/Pod 的关系

Kubernetes 同一个 Pod 里起多个进程复用端口是可行的;跨 Pod 当然不行(端口在网络命名空间里隔离)。
如果你用 hostNetwork,要特别注意端口冲突范围扩大。

6.4 连接“长时间不释放”的服务要特别关注优雅退出

多进程复用端口后,你 rolling restart 时要做:

  • 先停止接新连接(关闭 listener 或切换 readiness)
  • 给老连接 drain 时间
  • 再退出进程

否则容易出现:重启时连接被打断、客户端风暴重连。

7. 小结

  • 真正的“同机多进程共享同一端口”,核心就是SO_REUSEPORT
  • Go 没有一键开关,但net.ListenConfig.Control足够在生产落地
  • SO_REUSEADDR主要解决快速重启的占用问题,不等价于多进程共享
  • 如果你需要更强的路由控制或热升级体验,考虑入口层代理或 systemd socket activation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1159459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust 交叉编译:MacOS ====> Linux (musl 静态编译)

核心说明 你要实现的是 macOS (x86_64/arm64) → Linux CentOS (x86_64) 的 Rust 交叉编译,且指定 musl 静态编译,使用 cargo-zigbuild 是最优方案,没有之一。 优势1:cargo-zigbuild 基于 zig 编译器的交叉编译能力,无…

JAVA常用源码编辑工具有哪些?_java编辑器,零基础入门到精通,收藏这篇就够了

ava 源代码本质上其实就是普通的文本文件,所以理论上来说任何可以编辑文本文件的编辑器都可以作为我们的 Java 代码编辑工具。比如:Windows 记事本,Mac OS X 下的文本编辑,Linux 下的 vi、emacs、gedit、DOS 下的 edit 等。但是这…

使用Ubuntu搭建Java部署环境_ubuntu安装java环境,零基础入门到精通,收藏这篇就够了

在Ubuntu下搭建Java部署环境需要使用到apt命令 apt命令(用于安装、更新、删除、查询软件包) 语法: apt [命令] [软件包名称]接下来我们来搭建Java部署环境 使用apt安装JDK 更新软件包列表 我们先更新软件包列表 apt-get updateUbuntu仓库的软件不一定和软件包官网的版本一样, …

人工造问卷 VS 宏智树 AI:告别 “无效调研”,学术问卷设计原来可以这么简单

作为深耕论文写作科普的教育博主,后台总能收到这样的求助:“花 3 天设计的问卷,导师说信效度为零”“发出去 200 份问卷,150 份数据无效”“量表题项照搬,结果被批缺乏学术逻辑”。实证类论文的核心是数据,…

永磁同步电机反步控制实战手记

永磁同步电机反步(backstepping)控制 1.采用非线性控制策略反步控制法,实现永磁同步电机系统的完全解耦,相比PI控制减少了系统调节参数,抗负载扰动能力明显提高; 2.提供算法对应的参考文献和仿真模型 购买赠送PMSM控制相关电子资料…

JAVA实战:学生选课管理系统_java学生选课管理系统,零基础入门到精通,收藏这篇就够了

一.学生选课管理系统简介 首先定义了两个类:Student和Course。Student类表示学生,包含学生的姓名、学号和已选修的课程列表。Course类表示课程,包含课程的编号、名称和选修该课程的学生列表。 在Student类中,定义了构造方法用于…

【毕业设计】基于深度学习卷积神经网络训练识别橘子是否新鲜基于python_CNN深度学习卷积神经网络训练识别橘子是否新鲜

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

宏智树 AI 数据分析:文科生也能玩转硬核实证,论文说服力翻倍!

作为专注论文写作科普的教育博主,后台总能收到这样的求助:“论文数据一大堆,却不知道怎么分析”“SPSS 操作太复杂,文科生表示看不懂”“数据结果不会可视化,论文干巴巴没说服力”…… 其实,论文数据分析根…

Hadoop Formats 在 Flink 里复用 Hadoop InputFormat(flink-hadoop-compatibility)

1、项目依赖配置 核心依赖是 Flink 的兼容模块&#xff1a; <dependency><groupId>org.apache.flink</groupId><artifactId>flink-hadoop-compatibility</artifactId><version>2.2.0</version> </dependency>如果你要在本地&a…

宏智树 AI:期刊论文投稿通关密码!从选题到见刊的智能加速器

作为深耕论文写作科普的教育博主&#xff0c;后台每天都被 “期刊论文投稿被拒 N 次”“选题不对口”“格式反复改” 的吐槽刷屏。很多科研人明明手握优质研究成果&#xff0c;却因踩中选题偏差、文献不规范、格式混乱等 “隐形雷区”&#xff0c;陷入投稿屡败的困境。而宏智树…

深度学习毕设项目:基于python_CNN深度学习训练识别橘子是否新鲜基于python_CNN深度学习卷积神经网络训练识别橘子是否新鲜

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

零代码开发平台有哪些?

在数字化转型的浪潮中&#xff0c;业务部门对敏捷、定制化软件工具的需求与日俱增&#xff0c;但传统的开发流程却受限于高昂的成本和漫长的周期。零代码开发平台正是在此背景下应运而生的解决方案。它指的是一种允许用户通过完全可视化的拖拽、配置和规则设定&#xff0c;无需…

宏智树 AI:课程论文写作 “开挂神器”!告别凑字数,轻松搞定高分作业

每到期末季&#xff0c;课程论文就成了大学生的 “甜蜜负担”—— 想认真写却抓不住选题方向&#xff0c;凑够字数又担心逻辑混乱&#xff0c;查重时更是被飘红的段落搞得焦头烂额。作为深耕论文写作科普的教育博主&#xff0c;今天就给大家安利一款课程论文 “救星”—— 宏智…

【课程设计/毕业设计】基于卷积神经网络训练识别橘子是否新鲜基于python_CNN深度学习卷积神经网络训练识别橘子是否新鲜

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【2026必看】AI Agent完全指南:从零掌握大模型核心架构,建议收藏学习

AI Agent是2026年AI生态核心&#xff0c;具备自主决策和执行能力&#xff0c;通过感知、规划、行动、记忆和反思五大组件实现闭环架构。A2A协议使不同Agent能协作分工&#xff0c;MCP标准化工具调用&#xff0c;Agent Skills模块化能力构建。这些技术大幅降低开发门槛&#xff…

家庭食谱管理系统 Recipes 怎么搭?用服务器自建一个“全家共享”的菜谱库

🥬 买菜靠感觉,回家才发现缺关键食材 📱 菜谱收藏在各个平台:小红书一份、B站一份、浏览器书签一堆 🧠 想复刻某次做成功的菜,翻半天找不到当时那份步骤 👨‍👩‍👧‍👦 家里人各自保存各自的,根本没法共享、也没法统一整理 后来我干脆一步到位:在服务器上…

HG_REPMGR autofailvoer自动故障转移

文章目录 文档用途详细信息 文档用途 HG_REPMGR自动故障转移配置参考 详细信息 配置集群自动故障转移&#xff08;failover&#xff09;&#xff0c;需要为集群中的每个节点开启 repmgrd 守护进程。当主节点出现故障后&#xff0c;会自动将合适的备节点提升为新主节点&#…

2026年网络安全学习路线,零基础入门到精通,看这篇就够了!赶紧收藏!

针对2025年网络安全领域的学习路线规划&#xff0c;结合当前技术趋势和未来发展方向&#xff0c;帮助你从入门到进阶&#xff0c;逐步掌握网络安全的核心技能。 一、基础阶段&#xff08;3-6个月&#xff09; 目标&#xff1a;建立计算机基础与安全意识 1. 计算机基础 学习…

【必看收藏】RAG分块策略全解析:从入门到精通,解决大模型企业应用痛点

RAG技术通过结合检索与生成&#xff0c;解决大模型在企业应用中的局限性&#xff0c;分块策略是其核心环节。文章详细分析了五种分块策略&#xff08;固定大小、语义、递归、基于文档结构、基于LLM&#xff09;的原理、优缺点及适用场景&#xff0c;强调需根据文档类型和应用需…

【2026年最新整理】网络安全学习路线,入门到入坟,史上最全网络安全学习路线整理

很多小伙伴在网上搜索网络安全时&#xff0c;会出来网络安全工程师这样一个职位&#xff0c;它的范围很广&#xff0c;只要是与网络安全挂钩的技术人员都算网络安全工程师&#xff0c;一些小伙伴就有疑问了&#xff0c;网络安全现在真的很火吗&#xff1f; 那么寒哥就带大家看…