HTTP协议 | 青训营笔记

84 阅读3分钟

主要处理根据路由选择对应的后端逻辑。

再谈http协议

http协议是什么?

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

为什么需要协议?

按照一定的规则让对方理解我们传输的信息,我们需要明确的边界,能够携带什么样的信息。

协议里有什么

拿常见的post请求举例

image.png

协议中post开头,接上我们的url,在接上我们的http版本,这就是请求行。

接下来的四行都是kv对,这是我们的源数据。其中有Content-Lenght表示额传输的数据的字节数。

最后是我们真正想说的话。

回复部分,有http版本,状态码,对状态码的描述,源数据,传输的内容

请求行,状态行

方法名(get,post,head,put,delete,connect,options,trace,patch),url,协议版本

状态码:1XX(信息类),2XX(成功),3XX(重定向),4XX(客户端错误),5XX(服务端错误)

请求头,响应头

包括协议相关和业务相关

请求体,响应体

一个Demo(postman软件)

image.png

image.png

不要尝试go get这些包,这是自己开发的包,也是我们学习的重点(笔者在这里犯迷糊了)

请求流程

首先在业务层,再进入服务治理逻辑依托于中间件层,路由层,协议编(解)码层,传输层

image.png

不足与展望

  • Http1:队头阻塞,传输效率低,明文传输不安全
  • Http2:多路复用,头部压缩,二进制协议
  • QUIC:基于UDP实现,解决队头阻塞,加密减少握手次数,支持快速启动

HTTP框架的设计与实现

分层设计

image.png

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

应用层:跟用户打交道

中间件层:对用户有一些预处理逻辑

路由层:原生的路由寻址

协议层:支持协议,实现对应的抽象接口

网络层:灵活替换网络库的逻辑

image.png

应用层

提供合理的API

  • 可理解性:如ctx.Body() ctx.GetBody() 不要用ctx.BodyA()
  • 简单性:如ctx.Request.Header.Peek(key) /ctx.GetHeader(key)
  • 冗余性:不要出现几个接口做同样的事情
  • 兼容性
  • 可测性
  • 可见性

中间件层

  • 配合Handler实现一个完整的请求处理生命周期
  • 拥有预处理逻辑与后处理逻辑
  • 可以注册多中间件
  • 对上层模块用于逻辑模块易用

image.png

路由设计

  • 框架路由实际上就是为url匹配对应的处理函数
  • 静态路由/a/b/c,/a/b/d
  • 参数路由/a/:id/c,(/a/b/c,/a/b/c),/*all
  • 路由修复/a/b <-> /a/b/\
  • 冲突路由以及优先级/a/b,/:id/c
  • 匹配http方法
  • 多处理函数:方便添加中间件

如果要设计一个路由:

青铜:map[string]handlers

黄金:前缀匹配树

如何匹配http方法?

image.png

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

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

如何查找路由?

image.png

协议层

抽象出合适的接口

image.png

传输层

BIO(阻塞io)

例如:客服打电话问你要身份证,你找身份证时,他需要一直等待

image.png

NIO

注册一个监听器

image.png

image.png

image.png

修能修炼之道

针对网络库的优化

go net "BIO"

存下全部的header,减少系统调用次数,能够复用内存,能够多次读。

go net with bufio

绑定一块缓冲区

针对协议的优化