HTTP框架性能优化 | 青训营

79 阅读1分钟

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逻辑
- 请求内有效
- 问题定位困难