0x00 前言
zinx的开发文档基本上描述的很详细了,对初学者比较友好。笔者先前基于reactor模型实现过一个TCP网络框架tcpframe,要点是:
- 多进程模型
- Reactor反应堆模式,基于事件驱动的循环
- 基于TLV的协议通信,避免粘包
本文就以上面3个维度分析下zinx网络框架的实现的核心思路。
0x01 zinx的架构
0x02 代码分析
先看下Zinx的网络抽象通用定义,包含如下几个方面:
- 连接管理
- 连接定时器管理
- 收/发送Tcp报文处理
- 业务处理包(业务包)逻辑
- golang的通用网络模型
1、IServer
:服务接口
//定义服务接口
type IServer interface {
Start() //启动服务器方法
Stop() //停止服务器方法
Serve() //开启业务服务方法
AddRouter(msgID uint32, router IRouter) //路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用
GetConnMgr() IConnManager //得到链接管理
SetOnConnStart(func(IConnection)) //设置该Server的连接创建时Hook函数
SetOnConnStop(func(IConnection)) //设置该Server的连接断开时的Hook函数
CallOnConnStart(conn IConnection) //调用连接OnConnStart Hook函数
CallOnConnStop(conn IConnection) //调用连接OnConnStop Hook函数
Packet() Packet
}
2、IConnection
连接mod层接口
//定义连接接口
type IConnection interface {
Start() //启动连接,让当前连接开始工作
Stop() //停止连接,结束当前连接状态M
Context() context.Context //返回ctx,用于用户自定义的go程获取连接退出状态
GetTCPConnection() *net.TCPConn //从当前连接获取原始的socket TCPConn
GetConnID() uint32 //获取当前连接ID
RemoteAddr() net.Addr //获取远程客户端地址信息
SendMsg(msgID uint32, data []byte) error //直接将Message数据发送数据给远程的TCP客户端(无缓冲)
SendBuffMsg(msgID uint32, data []byte) error //直接将Message数据发送给远程的TCP客户端(有缓冲)
SetProperty(key string, value interface{}) //设置链接属性
GetProperty(key string) (interface{}, error) //获取链接属性
RemoveProperty(key string) //移除链接属性
}
3、IConnManager
:连接管理抽象层
type IConnManager interface {
Add(conn IConnection) //添加链接
Remove(conn IConnection) //删除连接
Get(connID uint32) (IConnection, error) //利用ConnID获取链接
Len() int //获取当前连接
ClearConn() //删除并停止所有链接
}
4、IRouter
:路由接口
//路由接口, 这里面路由是 使用框架者给该链接自定的 处理业务方法
//路由里的IRequest 则包含用该链接的链接信息和该链接的请求数据信息
type IRouter interface {
PreHandle(request IRequest) //在处理conn业务之前的钩子方法
Handle(request IRequest) //处理conn业务的方法
PostHandle(request IRequest) //处理conn业务之后的钩子方法
}
5、IRequest
//实际上是把客户端请求的连接信息 和 请求的数据 包装到了 Request里
type IRequest interface {
GetConnection() IConnection //获取请求连接信息
GetData() []byte //获取请求消息的数据
GetMsgID() uint32 //获取请求的消息ID
}
6、Packet
接口:
type Packet interface {
Unpack(binaryData []byte) (IMessage, error)
Pack(msg IMessage) ([]byte, error)
GetHeadLen() uint32
}
7、IMsgHandle
:消息的管理封装,包含了业务处理worker协程池的管理
//消息管理抽象层
type IMsgHandle interface {
DoMsgHandler(request IRequest) //马上以非阻塞方式处理消息
AddRouter(msgID uint32, router IRouter) //为消息添加具体的处理逻辑
StartWorkerPool() //启动worker工作池
SendMsgToTaskQueue(request IRequest) //将消息交给TaskQueue,由worker进行处理
}
8、IMessage
:设置传输消息的通用字段
//将请求的一个消息封装到message中,定义抽象层接口
type IMessage interface {
GetDataLen() uint32 //获取消息数据段长度
GetMsgID() uint32 //获取消息ID
GetData() []byte //获取消息内容
SetMsgID(uint32) //设置消息ID
SetData([]byte) //设置消息内容
SetDataLen(uint32) //设置消息数据段长度
}
9、IDataPack
:封包数据和拆包数据
//封包数据和拆包数据
//直接面向TCP连接中的数据流,为传输数据添加头部信息,用于处理TCP粘包问题
type IDataPack interface {
GetHeadLen() uint32 //获取包头长度方法
Pack(msg IMessage) ([]byte, error) //封包方法
Unpack([]byte) (IMessage, error) //拆包方法
}
0x03 数据流程
Zinx的主要运行流程如下图所示:
封包/拆包
0x04 细节&&总结
0x05 参考
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