HTTP协议 | 青训营

114 阅读3分钟

HTTP协议

image.png

HTTP协议

HTTP协议是什么

HTTP:超文本传输协议(Hypertext Transfer Protocol)

image.png

为什么需要协议

需要明确的边界

开始

结束

能够携带信息

什么消息

消息类型

...

image.png

协议里面有什么(POST为例)

请求包

POST /sis HTTP/1.1
who: Atex
Content-Type: text/plain
Host: 127.0.0.1:8888
Content-Length: 28Let's watch a movie tofether

应答包

HTTP/1.1 200 OK
Server: hertz
Date: Thu, 21 Apr 2022 11:46:32 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Upstream-Caught: 1650541592984580

OK

image.png

请求流程

image.png

不足与展望

image.png

HTTP框架的设计与实现

分层设计

专注性、扩展性、复用性

image.png

高内聚 低耦合、易复用、高扩展性

image.png

应用层设计

提供合理的API

可理解性:如ctx.Body(), ctx.GetBody()

不要用 ctx.BodyA()

简单性:如ctx.Request.Header.Peek(key)

/ctx.GetHeader(key)

冗余性、兼容性、可测性、可见性

中间件设计

中间件需求

配合Handler实现一个完整的请求处理生命周期

拥有预处理逻辑与后处理逻辑

可以注册多中间件

对上层模块用户逻辑模块易用

洋葱模型

将核心逻辑与通用逻辑分离, 实现命令一级一级的处理

使用场景

日志记录

性能统计

安全控制

事务处理

异常处理

image.png

举例

打印每个请求的request和response

image.png

1.既然要实现预处理和后处理,那这个就很像调用了一个函数

image.png

2.路由上可以注册多Middleware,同时也可以满足请求级别有效,只需要将Middleware设计为和业务和Handler相同即可

3.用户如果不主动调用下一个处理函数怎么办?

image.png

核心:在任何场景下index保证递增

4.出现异常想停止怎么办?

image.png

调用链

image.png

适用场景

不调用Next:初始化逻辑且不需要在同一调用栈

调用Next:后处理逻辑或需要在同一调用栈上

路由设计

框架路由实际上就是为URL匹配对应的处理函数(Handlers)

静态路由:/a/b/c、/a/b/d

参数路由:/a/:id/c (/a/b/c,/a/d/c)、/*all

路由修复:/a/b <--> /a/b/

冲突路由以及优先级:/a/b、/:id/c

匹配HTTP方法

多处理函数:方便添加中间件

青铜:map[string]handlers

/a/b/c、/a/b/d /a/:id/c、/*all

黄金:前缀匹配树

/a/b/c、/a/b/d

如何处理带参数的路由注册?

(处理形如:/a/:id/b类型的路由)

image.png

image.png

如何匹配HTTP方法?

路由映射表image.png

外层Map:根据method进行初步筛选

如何实现添加多处理函数?

在每个节点上使用一个list存储handler

image.png

协议层设计

抽象出合适的接口

image.png

1.Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter

2.需要在连接上读写数据

网络层设计

image.png

go net "BIO" 用户管理buffer

image.png

netpoll NIO 网络库管理buffer

image.png

性能修炼之道

针对网络库的优化

go net

存下全部Header

减少系统调用次数

能够复用内存

能够多次读

go net "BIO"

image.png

go net with bufio绑定一块缓冲区

image.png

netpoll

存下全部Header

拷贝出完整的Body

image.png

netpoll with nocopy peek

分配足够大的buffer

限制最大buffer size

image.png

不同网络库优势

image.png

针对协议的优化 --Headers解析

找到Header Line边界:\r\n

先找到\n再看他前一个是不是\r

image.png

那能不能查找更快呢?答:可以运用SIMD

使用和不使用SIMD性能对比image.png

image.png

针对协议相关的Headers快速解析:

1.通过Header Key首字母快速筛选除掉完全不可能的key

2.解析对应value到独立字段

3.使用byte slice管理对应header存储,方便复用

image.png

热点资源池化

原始方法,就是消息队列来一个处理一个,这样的速度比较慢

image.png

池化

image.png

image.png