0x00 前言
本篇文章,分析下 GoIM 的 Comet 模块。
- Comet 主方法
- Comet 主要数据结构
- Comet 管理服务(与 Job 模块通信)
Comet模块的位置:
0x01 Comet 模块
Comet 模块为用户代理 Server(主要提供对外服务),用于客户端的连接,根据情况可部署多个 Comet-Server(扩展)。Comet 模块支持 Tcp, Http, WebSocket, TLS WebSocket 等多种服务。
0x02 主逻辑入口
Comet 的入口 main.go,主要完成初始化及服务器的启动工作及注册: 这里提几点可借鉴的经验:
- 使用随机数必须运行
rand.Seed(time.Now().UTC().UnixNano())
,一般放在初始化时 - 使用
runtime.GOMAXPROCS(runtime.NumCPU())
设置合适的 core 数是个好习惯,K8S 环境常用automaxprocess
设置 - 启动了 N 个监听端口(配置文件)
- 对外端口有:
InitTCP
,InitWebsocket
- 对内端口(管理):
grpc.New(conf.Conf.RPCServer, srv)
- 对外端口有:
- 服务的注册使用
register
完成,用于客户端服务发现 - Server 端优雅退出
- Comet 维护了一个 白名单 机制
func main() {
...
rand.Seed(time.Now().UTC().UnixNano())
runtime.GOMAXPROCS(runtime.NumCPU())
println(conf.Conf.Debug)
log.Infof("goim-comet [version: %s env: %+v] start", ver, conf.Conf.Env)
// register discovery
dis := naming.New(conf.Conf.Discovery)
resolver.Register(dis)
// new comet server
srv := comet.NewServer(conf.Conf)
if err := comet.InitWhitelist(conf.Conf.Whitelist); err != nil {
panic(err)
}
if err := comet.InitTCP(srv, conf.Conf.TCP.Bind, runtime.NumCPU()); err != nil {
panic(err)
}
if err := comet.InitWebsocket(srv, conf.Conf.Websocket.Bind, runtime.NumCPU()); err != nil {
panic(err)
}
if conf.Conf.Websocket.TLSOpen {
if err := comet.InitWebsocketWithTLS(srv, conf.Conf.Websocket.TLSBind, conf.Conf.Websocket.CertFile, conf.Conf.Websocket.PrivateFile, runtime.NumCPU()); err != nil {
panic(err)
}
}
// new grpc server
rpcSrv := grpc.New(conf.Conf.RPCServer, srv)
cancel := register(dis, srv)
// signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Infof("goim-comet get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
if cancel != nil {
cancel()
}
rpcSrv.GracefulStop()
srv.Close()
log.Infof("goim-comet [version: %s] exit", ver)
log.Flush()
return
case syscall.SIGHUP:
default:
return
}
}
}
0x03 Comet 结构
comet 结构定义,Comet 对应的结构是项目中最复杂的,下面先简单列举下:
// Server is comet server.
type Server struct {
c *conf.Config
round *Round // accept round store
buckets []*Bucket // subkey bucket
bucketIdx uint32
serverID string
rpcClient logic.LogicClient
}
// Round userd for connection round-robin get a reader/writer/timer for split big lock.
type Round struct {
readers []bytes.Pool
writers []bytes.Pool
timers []time.Timer
options RoundOptions
}
// Bucket is a channel holder.
type Bucket struct {
c *conf.Bucket
cLock sync.RWMutex // protect the channels for chs
chs map[string]*Channel // map sub key to a channel
// room
rooms map[string]*Room // bucket room channels
routines []chan *grpc.BroadcastRoomReq
routinesNum uint64
ipCnts map[string]int32
}
参考
- 消息推送架构-Based-GOIM
- goim 架构与定制
- goim 及分布式工程解构
- goim via nats
- goim源码剖析
- goim v2.0
- 分享 直播 – 弹幕系统简介
- 对于router服务存在的疑问
- 高并发实时弹幕系统的实战之路
- goim 中的 data flow 数据流转及优化思考
FEATURED TAGS
Latex
gRPC
负载均衡
OpenSSH
Authentication
Consul
Etcd
Kubernetes
性能优化
Python
分布式锁
WebConsole
后台开发
Golang
OpenSource
Nginx
Vault
网络安全
Perl
分布式理论
Raft
正则表达式
Redis
分布式
限流
go-redis
微服务
反向代理
ReverseProxy
Cache
缓存
连接池
OpenTracing
GOMAXPROCS
GoMicro
微服务框架
日志
zap
Pool
Kratos
Hystrix
熔断
并发
Pipeline
证书
Prometheus
Metrics
PromQL
Breaker
定时器
Timer
Timeout
Kafka
Xorm
MySQL
Fasthttp
bytebufferpool
任务队列
队列
异步队列
GOIM
Pprof
errgroup
consistent-hash
Zinx
网络框架
设计模式
HTTP
Gateway
Queue
Docker
网关
Statefulset
NFS
Machinery
Teleport
Zero Trust
Oxy
存储
Confd
热更新
OAuth
SAML
OpenID
Openssl
AES
微服务网关
IM
KMS
安全
数据结构
hashtable
Sort
Asynq
基数树
Radix
Crontab
热重启
系统编程
sarama
Go-Zero
RDP
VNC
协程池
UDP
hashmap
网络编程
自适应技术
环形队列
Ring Buffer
Circular Buffer
InnoDB
timewheel
GroupCache
Jaeger
GOSSIP
CAP
Bash
websocket
事务
GC
TLS
singleflight
闭包
Helm
network
iptables
MITM
HTTPS
Tap
Tun
路由
wireguard
gvisor
Git
NAT
协议栈
Envoy
FRP
DPI
gopacket
Cgroup
Namespace
DNS
eBPF
GoZero
Gost
Clash
gopsutil
HIDS
ELKEID
XDP
TC
Linux
netlink