news 2026/9/28 2:23:53

goim v2.0:基于 Golang 的高性能 IM 与实时推送服务集群实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
goim v2.0:基于 Golang 的高性能 IM 与实时推送服务集群实战指南
  • 后端
  • 即时通讯
  • 微服务

【免费下载链接】goim

goim

项目地址:https://gitcode.com/gh_mirrors/go/goim
点击查看免费下载

goim 是一个用纯 Golang 编写的即时通讯(IM)服务端及实时推送集群,支持单推、多推、房间推送与全量广播,并内置心跳、鉴权、多协议接入与基于 Kafka 的异步推送链路。本文以项目根目录 README.md 为主线,结合仓库内源码与配置,完整讲解 goim 的特性、架构、构建启动、配置项、依赖环境、客户端协议、推送 API 与官方基准测试数据,帮助读者在真实业务中快速部署并深入理解其工作原理。

核心特性:一次看懂 goim 能做什么

README.md 将 goim v2.0 的特性归纳为以下几点,这些特性全部可以在仓库源码中找到对应实现:

  • 轻量级、高性能、纯 Golang:服务端全部由 Go 实现(internal/comet、internal/logic、internal/job三个模块),不依赖任何重量级框架;
  • 灵活的推送粒度:支持单个推送(PushKeys)、多个推送(PushMids)、房间推送(PushRoom)以及全量广播(PushAll),对应实现见 internal/logic/push.go;
  • 一键多订阅者:单个 Key(用户)可以挂载多个订阅连接,可通过配置限制最大订阅者数量,对应接入层 internal/comet/channel.go;
  • 完整的心跳机制:支持应用层心跳、TCP KeepAlive 与长连接心跳,对应协议指令OpHeartbeat(见 api/protocol/operation.go);
  • 安全鉴权:未授权的用户无法订阅消息,认证指令OpAuth/OpAuthReply负责连接鉴权;
  • 多协议接入:支持 WebSocket、TCP(README 同时提及 HTTP 长轮询场景);
  • 可水平扩展的架构:comet(接入层)与 logic(逻辑层)均为无状态/可动态扩容模块,job 可随 Kafka partition 扩展;
  • 基于 Kafka 的异步推送:logic 将推送消息写入 Kafka,job 消费后路由到对应 comet,实现推送与业务解耦。

系统架构:comet、logic、job 三模块如何协同

goim v2.0 采用三层架构,三个可执行程序各自独立部署、通过 Discovery 服务发现相互协作:

  1. comet(接入层):负责维持客户端长连接。它启动 TCP(默认:3101)与 WebSocket(默认:3102,可开 TLS:3103)监听端口,通过Bucket数据结构管理海量 Channel。从 internal/comet/server.go 可以看到,NewServer会按配置创建Bucket.Size个 Bucket,并通过 cityhash 将订阅 Key 均匀哈希到不同 Bucket 中,实现连接的水平切分。每个 Bucket 内部又维护多个 Room 与多路广播协程(见 internal/comet/bucket.go),配合 internal/comet/ring.go 的环形缓冲区实现高吞吐收发;
  2. logic(逻辑层):无状态业务层,对外提供 HTTP 推送/查询接口(默认:3111)与 gRPC 服务(默认:3119),负责鉴权、在线状态维护、Redis 存储与消息路由决策;
  3. job(推送任务层):作为 Kafka 消费者,监听推送 topic(默认goim-push-topic),通过 Discovery 实时感知 comet 节点列表,把消息投递到目标 comet。消费与重新平衡逻辑见 internal/job/job.go。

三个模块启动时都会将自己注册到 bilibili Discovery(注册逻辑见 cmd/comet/main.go 等入口文件),comet 还会周期性上报连接数(conn_count)与 IP 数(ip_count)等元数据,供 logic 完成负载均衡与节点发现。

快速上手:从构建到启动

构建

goim 提供了完整的 Makefile(见 Makefile),一条命令即可完成构建:

make build

build目标会执行以下动作:清空并创建target/目录、将三个示例配置复制为target/comet.toml、target/logic.toml、target/job.toml,然后分别编译出target/comet、target/logic、target/job三个二进制。也可以通过make test运行全量单元测试(go test -v ./...)。

启动

提供了两种启动方式。方式一是使用 Makefile 的run/stop目标(后台运行并分别输出到target/comet.log等日志文件):

make run make stop

方式二是手动nohup启动,分别指定各自配置文件与运行参数(注意:三个进程必须带一致的region/zone/deploy.env参数,comet 与 logic 还需携带weight负载权重,comet 额外需要-addrs声明对外地址):

nohup target/logic -conf=target/logic.toml -region=sh -zone=sh001 -deploy.env=dev -weight=10 2>&1 > target/logic.log & nohup target/comet -conf=target/comet.toml -region=sh -zone=sh001 -deploy.env=dev -weight=10 -addrs=127.0.0.1 2>&1 > target/comet.log & nohup target/job -conf=target/job.toml -region=sh -zone=sh001 -deploy.env=dev 2>&1 > target/job.log &

提示:README 示例中三个进程的日志都写到了target/logic.log,这是文档中的笔误;实际运行时建议参照 Makefile 的run目标,为每个进程使用独立的日志文件,便于排查问题。

运行环境与命令行参数

goim 的所有运行参数都可以通过命令行 flag 或环境变量两种方式注入(两者优先级以 flag 为准,实现见 internal/comet/conf/conf.go 与 internal/logic/conf/conf.go):

env: export REGION=sh export ZONE=sh001 export DEPLOY_ENV=dev supervisor: environment=REGION=sh,ZONE=sh001,DEPLOY_ENV=dev go flag: -region=sh -zone=sh001 -deploy.env=dev

常用 flag 及其含义如下(环境变量形式:REGION/ZONE/DEPLOY_ENV/WEIGHT/ADDRS/OFFLINE/DEBUG):

Flag默认值说明
-conf各模块的*-example.toml配置文件路径
-region环境变量REGION区域标识,如sh
-zone环境变量ZONE可用区标识,如sh001
-deploy.env环境变量DEPLOY_ENV部署环境,如dev/prod
-host机器 hostname节点 hostname,作为 comet 的 serverID
-weight环境变量WEIGHT负载均衡权重(comet/logic)
-addrs环境变量ADDRS对外公网地址列表(comet)
-offline环境变量OFFLINE是否标记节点下线(comet)
-debug环境变量DEBUG开启调试日志(comet)

启动后,comet、logic、job 都会监听系统信号,收到SIGQUIT/SIGTERM/SIGINT时依次完成注销服务、gRPC GracefulStop、资源关闭与日志 Flush 后优雅退出(见 cmd/comet/main.go)。

配置详解:三份示例配置逐项解读

README 明确指出“可以通过查看target/comet.toml、logic.toml、job.toml中的注释来理解配置含义”,仓库根目录下即提供了三份可直接使用的示例配置。下面结合配置结构体定义逐项说明。

comet 配置:cmd/comet/comet-example.toml

[discovery] nodes = ["127.0.0.1:7171"] [rpcServer] addr = ":3109" timeout = "1s" [rpcClient] dial = "1s" timeout = "1s" [tcp] bind = [":3101"] sndbuf = 4096 rcvbuf = 4096 keepalive = false reader = 32 readBuf = 1024 readBufSize = 8192 writer = 32 writeBuf = 1024 writeBufSize = 8192 [websocket] bind = [":3102"] tlsOpen = false tlsBind = [":3103"] certFile = "../../cert.pem" privateFile = "../../private.pem" [protocol] timer = 32 timerSize = 2048 svrProto = 10 cliProto = 5 handshakeTimeout = "8s" [whitelist] Whitelist = [123] WhiteLog = "/tmp/white_list.log" [bucket] size = 32 channel = 1024 room = 1024 routineAmount = 32 routineSize = 1024

配置项说明(字段定义见 internal/comet/conf/conf.go):

配置节关键参数作用
discoverynodesDiscovery 服务地址列表,用于服务注册与发现
rpcServeraddr/timeout对外 gRPC 服务监听地址(默认:3109)与超时
rpcClientdial/timeoutcomet 调用 logic 的 gRPC 拨号与请求超时
tcpbindTCP 监听端口列表,支持绑定多个端口;sndbuf/rcvbuf为读写缓冲字节数,reader/writer为收发协程数,readBuf/writeBuf为缓冲通道容量,readBufSize/writeBufSize为单缓冲大小
websocketbind/tlsOpen/tlsBindWebSocket 监听端口;tlsOpen=true时启用 TLS,证书文件取自certFile与privateFile
protocoltimer/timerSize定时器数量与大小;svrProto/cliProto为服务端/客户端协议缓冲池容量;handshakeTimeout为握手超时
whitelistWhitelist/WhiteLog推送白名单(按 mid 配置)与白名单日志路径,由comet.InitWhitelist加载
bucketsizeBucket 数量,影响连接哈希分片粒度与并发度;channel/room为 Channel、Room 初始 map 容量;routineAmount/routineSize为每个 Bucket 内的广播协程数量与消息通道容量

logic 配置:cmd/logic/logic-example.toml

[discovery] nodes = ["127.0.0.1:7171"] [regions] "bj" = ["北京","天津","河北","山东","山西","内蒙古","辽宁","吉林","黑龙江","甘肃","宁夏","新疆"] "sh" = ["上海","江苏","浙江","安徽","江西","湖北","重庆","陕西","青海","河南","台湾"] "gz" = ["广东","福建","广西","海南","湖南","四川","贵州","云南","西藏","香港","澳门"] [node] defaultDomain = "conn.goim.io" hostDomain = ".goim.io" heartbeat = "4m" heartbeatMax = 2 tcpPort = 3101 wsPort = 3102 wssPort = 3103 regionWeight = 1.6 [backoff] maxDelay = 300 baseDelay = 3 factor = 1.8 jitter = 0.3 [rpcServer] network = "tcp" addr = ":3119" timeout = "1s" [rpcClient] dial = "1s" timeout = "1s" [httpServer] network = "tcp" addr = ":3111" readTimeout = "1s" writeTimeout = "1s" [kafka] topic = "goim-push-topic" brokers = ["127.0.0.1:9092"] [redis] network = "tcp" addr = "127.0.0.1:6379" active = 60000 idle = 1024 dialTimeout = "200ms" readTimeout = "500ms" writeTimeout = "500ms" idleTimeout = "120s" expire = "30m"

配置项说明(字段定义见 internal/logic/conf/conf.go):

  • regions:区域-省份映射表,用于按用户地域路由/加权分配 comet 节点;
  • node:节点信息模板,defaultDomain/hostDomain为域名配置,tcpPort/wsPort/wssPort与 comet 各协议端口对应,heartbeat/heartbeatMax为下发给客户端的心跳周期与最大尝试次数,regionWeight为跨区域权重系数;
  • backoff:客户端连接失败时的指数退避参数(maxDelay最大延迟秒、baseDelay初始延迟、factor增长因子、jitter抖动系数);
  • rpcServer/rpcClient/httpServer:gRPC 服务(:3119)、gRPC 客户端与 HTTP 服务(:3111)的监听与超时配置;
  • kafka:推送 topic 与 broker 地址列表;
  • redis:在线状态与 Key 映射存储,expire = "30m"表示在线记录的过期时间,active/idle为连接池最大活跃/空闲连接数。

job 配置:cmd/job/job-example.toml

[discovery] nodes = ["127.0.0.1:7171"] [kafka] topic = "goim-push-topic" group = "goim-push-group-job" brokers = ["127.0.0.1:9092"]

job 的配置最为精简:discovery.nodes用于发现 comet 节点,kafka节指定消费的 topic、消费者组(group)与 broker 列表。job 通过sarama-cluster以消费者组方式消费(见 internal/job/job.go),topic 的 partition 数量即决定了 job 的可扩展上限。

外部依赖:Discovery 与 Kafka

goim v2.0 有两个强依赖,README 专门列出:

  1. Discovery(bilibili discovery,默认地址127.0.0.1:7171):承担服务注册与发现职责。comet 与 logic 启动时通过naming.New+resolver.Register注册 gRPC 服务(见 cmd/logic/main.go),job 则通过dis.Build("goim.comet")监听 comet 节点变更(见 internal/job/job.go);
  2. Kafka:异步推送的消息队列。logic 收到推送请求后写入 Kafka topic,job 作为消费者取出PushMsg(protobuf 序列化)并路由到对应 comet。这条链路保证了推送高峰期的削峰与解耦。

客户端通讯协议与推送 API

comet 客户端协议

comet 支持 WebSocket 与 TCP 两种客户端协议,完整定义见 docs/proto.md。

WebSocket:请求地址为ws://DOMAIN/sub,采用 JSON Frame,请求与返回结构一致:

{ "ver": 102, "op": 10, "seq": 10, "body": {"data": "xxx"} }

其中ver为协议版本号,op为指令,seq为序列号(与响应一一对应),body为授权令牌。

TCP:请求地址为tcp://DOMAIN,采用二进制协议,包结构为:包长度(int32 大端)+ 包头长度(int16 大端)+ 版本号(int16 大端)+ 操作指令(int32 大端)+ 序列号(int32 大端)+ body(长度 = 包长度 - 包头长度)。

指令对照表(详见 api/protocol/operation.go):

指令说明
0/1握手 / 握手回复
2/3客户端心跳 / 服务端心跳回复
4/5发送消息 / 发送消息回复(下行消息)
7/8认证 / 认证回复
14/15订阅 / 订阅回复
16/17退订 / 退订回复

HTTP 推送 API

logic 对外暴露完整的 HTTP 推送与在线查询接口,详见 docs/push.md。统一返回格式为 JSON,错误码约定:OK = 0、RequestErr = -400、ServerErr = -500。主要接口如下:

接口方法说明
/goim/push/keysPOST按 Key 列表推送,参数operation、keys,body 为消息内容
/goim/push/midsPOST按用户 mid 列表推送,参数operation、mids
/goim/push/roomPOST按房间推送,参数operation、type(房间类型)、room(房间 ID)
/goim/push/allPOST全量广播,参数operation、speed(推送速率限制)
/goim/online/topGET查询在线人数 Top 房间,参数type、limit
/goim/online/roomGET查询指定房间在线人数,参数type、rooms
/goim/online/totalGET查询总连接数与 IP 数(返回conn_count、ip_count)
/goim/nodes/weightedGET获取加权后的节点信息(域名、端口、心跳参数、退避策略),供客户端选择接入节点
/goim/nodes/instancesGET获取全部 comet 实例信息(region、zone、地址、连接数、权重等元数据)

推送请求示例(/goim/push/keys):

POST /goim/push/keys?operation=5&keys=key1,key2 Body: {"test":1} response: { "code": 0 }

这些接口分别映射到 internal/logic/push.go 中的PushKeys、PushMids、PushRoom、PushAll实现,最终经 Kafka 交给 job 异步分发。

示例客户端

仓库提供了可直接运行的示例:

  • WebSocket 客户端:examples/javascript/client.js(含 examples/javascript/index.html 网页演示),展示如何连接 comet、完成握手/认证并收发消息;
  • 服务端示例:examples/javascript/main.go 演示服务端调用 logic 推送接口;
  • 第三方 SDK:README 同时收录了 Android 与 iOS 的社区 SDK 入口,可作客户端参考。

官方基准测试

README 记录了官方在单台服务器上完成的压测数据(详细中文报告见 docs/benchmark_cn.md,英文版见 docs/benchmark_en.md):

压测环境(1 台实例)

CPU内存OS
Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHzDDR3 32GBDebian GNU/Linux 8

压测场景

项目数值
在线连接数1,000,000
压测时长15 分钟
广播推送速率40 条/秒(房间广播)
推送消息{"test":1}
接收统计方式每秒采样 1 次,共 30 次

资源占用

项目数值
CPU2000% ~ 2300%
内存14GB
GC 暂停504ms
网络入向 450MBit/s,出向 4.39GBit/s

压测结果:消息接收速率达到35,900,000 条/秒。

以上数据为项目官方 README 记录的基准测试结果,实际性能取决于机器规格、网络环境与配置调优,请以自建压测为准。

许可协议

goim 基于MIT License开源(见根目录 LICENSE),可自由用于商业与非商业项目。需要说明的是,v2.0 版本同时依赖 bilibili Discovery 与 Kafka 两个外部服务,部署前请先准备这两套环境(Kafka 快速安装可参考 scripts/kafka.sh 与 scripts/zk.sh)。


从特性梳理、架构拆解,到 Makefile 构建、三份 TOML 配置逐项解读、协议指令与 HTTP 推送接口,再到官方压测数据,本文已完整覆盖 README.md 的全部核心内容,并辅以仓库源码级佐证。按照本文步骤搭建 Discovery 与 Kafka 后,依次启动 logic、comet、job 三个进程,即可跑通一套可水平扩展的 goim 实时推送集群。

  • 后端
  • 即时通讯
  • 微服务

【免费下载链接】goim

goim

项目地址:https://gitcode.com/gh_mirrors/go/goim
点击查看免费下载

相关推荐

上一篇:boofuzz部署与运维完整指南:从开发到生产环境的最佳实践
下一篇:GitHub Issue Templates Pull Request模板:代码贡献管理最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 2:23:05

大麦抢票脚本快速上手:3步配置参数,开售即自动下单

大麦抢票脚本快速上手:3步配置参数,开售即自动下单 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 热门演出中午开售,页面瞬间挤满&#x…

作者头像 李华