0x00 前言
0x01 数据结构:Ring
Ring的使用场景
Ring本质上是一个环形缓冲区,其中保存的是空闲的protocol.Proto
对象,主要用于长连接下TCP数据的拆包封包(每个连接都会初始化自己的Ring
结构)
为什么要设计如此的结构呢?这里有个issue,思考下,长连接的场景,连接上不断有报文收发,使用一个可复用协议包体的数据结构是一个不错的优化手段(避免频繁内存申请释放,此外还可以控制总大小)。
如下面的结构,一个Channel
代表一个TCP连接:
// Channel used by message pusher send msg to write goroutine.
type Channel struct {
Room *Room
CliProto Ring
signal chan *protocol.Proto //
Writer bufio.Writer
Reader bufio.Reader
Next *Channel
Prev *Channel
mutex sync.RWMutex
//...
}
Ring的结构
// Ring ring proto buffer.
type Ring struct {
// read
rp uint64 // read位置
num uint64 // 总长度
mask uint64 // 掩码:用于%num的效果
// TODO split cacheline, many cpu cache line size is 64
// pad [40]byte
// write
wp uint64 // write位置
data []protocol.Proto // 对象数组
}
Ring
的操作:
//初始化对象数组长度为2的n次方
func (r *Ring) init(num uint64) {
// 2^N
if num&(num-1) != 0 {
for num&(num-1) != 0 {
num &= num - 1
}
num <<= 1
}
r.data = make([]protocol.Proto, num)
r.num = num
r.mask = r.num - 1
}
// 读写入的对象内容
func (r *Ring) Get() (proto *protocol.Proto, err error) {
if r.rp == r.wp {
return nil, errors.ErrRingEmpty
}
proto = &r.data[r.rp&r.mask]
return
}
// 读游标+1
func (r *Ring) GetAdv() {
r.rp++
if conf.Conf.Debug {
log.Infof("ring rp: %d, idx: %d", r.rp, r.rp&r.mask)
}
}
// 获取待写入对象
func (r *Ring) Set() (proto *protocol.Proto, err error) {
if r.wp-r.rp >= r.num {
return nil, errors.ErrRingFull
}
proto = &r.data[r.wp&r.mask]
return
}
//写入游标+1
func (r *Ring) SetAdv() {
r.wp++
if conf.Conf.Debug {
log.Infof("ring wp: %d, idx: %d", r.wp, r.wp&r.mask)
}
}
// 重置
func (r *Ring) Reset() {
r.rp = 0
r.wp = 0
// prevent pad compiler optimization
// r.pad = [40]byte{}
}
Ring在项目中的应用
0x03 参考
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