1 针对网络库的优化
1.1 go net
需求:
- 存下全部的header(长度不定)
- 减少系统调用次数
- 复用内存
- 多次读
解决:
- go net with bufio 绑定一块缓冲区
// go net
type Conn interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
...
}
// go net with bufio
type Reader interface {
Peek(n int) ([]byte, error) // keep the pointer fixed
Discard(n int) (discarded int, err error) // let the pointer move forward
Release() error // deallocate the memory
Size() int
Read(b []byte) (l int, err error)
}
type Writer interface {
Write(p []byte)
Size() int
Flush() error
...
}
1.2 netpoll
需求:
- 存下全部header
- 拷贝出完整的body
解决:
- netpoll with nocopy peek
- 匹配足够大的buffer
- 限制最大buffer size
1.3 优势
go net:
- 流式友好
- 小包性能好
net poll:
- 中大包性能好
- 时延低
2 针对协议的优化
2.1 header解析
- 找到header line
边界:\r\n
法一:遍历,找\n,再看前一个是否为\r
法二:SIMD,更快
Single Instruction Multiple Data 单指令多数据 - 针对协议相关的headers快速解析
1.通过header key首字母快速筛除不可能的key
2.解析对应value到独立字段
3.使用byte slice管理对应header存储,方便复用
// Headers resolution
switch s.Key[0] | 0x20 {
case 'h':
if utils.CaseInsensiitiveCompare(s.Key, bytestr.StrHost) {
h.SetHostBytes(s.Value)
continue
}
...
}
2.2 header key规范化
aaa-bbb -> Aaa-Bbb
两次表映射:str -> ascii -> str
取:
- 超高转换效率
舍:
- 额外内存开销
- 变更困难
2.3 热点资源池化
建立RequestContext池
取:
- 减少内存分配
- 提高内存复用
- 降低GC压力
- 性能提升
舍:
- 额外Reset逻辑
- 请求内有效
- 问题定位困难