http修炼之道|青训营

75 阅读9分钟

背景

​编辑

 

一、HTTP协议

1.什么是http协议

HTTP协议,即超文本传输协议(Hypertext Transfer Protocol),是一种用于在Web服务器和客户端浏览器之间传输数据的通信协议。它是一个应用层协议,承载于TCP协议之上。

2.特点

HTTP协议的主要特点包括:
传输效率高:HTTP协议是无连接和无状态的,这意味着在传输HTTP报文之前,不需要建立HTTP连接,并且在数据传输过程中不保存任何历史和状态信息。此外,请求时只需要传输请求方法和路径,传输格式简单。
传输可靠性高:HTTP协议采用TCP作为传输层协议,以确保数据的可靠传输。
兼容性好:HTTP协议支持B/S和C/S模式,可以传输任意类型的数据对象。
灵活性高:HTTP协议允许传输任意类型的数据对象,并且作为Web文档传输协议,其版本更新较为缓慢,目前只更新了三个版本。

总之,HTTP协议是互联网上最常用的通信协议之一,它为Web服务器和客户端浏览器之间的数据传输提供了标准化的协议。

3.为什么需要协议

协议是通信中的一种约定或规范,它定义了通信双方之间数据传输的格式、加密方式、校验方式等规则。通信协议的存在是为了确保通信的可靠性和高效性,它能够使设备之间进行相互通信,并确保数据在传输过程中不被损坏、篡改或丢失。
在互联网通信中,HTTP协议是一种应用层协议,它定义了客户端与服务器之间请求和响应的格式、头部信息、请求方法等规则。HTTP协议的存在使得Web服务器和客户端浏览器之间能够进行有效的数据传输,从而实现Web应用程序的功能。
此外,协议还可以提供一种标准化的通信方式,使得不同设备之间可以相互通信,从而实现更广泛的应用场景。由于协议定义了数据传输的格式和规则,因此可以根据协议开发各种不同的应用程序,从而实现更丰富的功能。

4.协议里有什么?

HTTP协议的内容包括请求和响应。请求包括请求行、请求头、请求正文三个部分,其中请求行包括请求方式、URL、HTTP版本。常见的请求方式有POST、GET、PUT、DELETE、TRACE、CONNECT、OPTIONS等。请求头用于传递一些请求时的辅助信息,例如User-Agent、Accept、Content-Type等。请求正文通常用于传递POST请求中的数据。
响应包括响应行、响应头、响应正文三个部分,其中响应行包括响应信息、响应状态码、HTTP版本。响应信息通常是一些描述性信息,例如“OK”、“Found”等。响应状态码表示响应的状态,例如200表示成功,404表示未找到资源,500表示服务器内部错误等。响应头用于传递一些响应时的辅助信息,例如Content-Type、Content-Length等。响应正文是服务器返回给客户端的数据。
此外,HTTP协议还定义了一些通用的头域,例如Cache-Control、Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via等。这些头域可以用于传递一些通用的信息,例如缓存控制、连接状态、请求或响应的日期等。

​编辑

 ​编辑

5.请求流程

​编辑

 在HTTP请求流程中,首先浏览器会向服务器发送请求行。请求行包括了请求方法、请求 URI(Uniform Resource Identifier)和 HTTP 版本协议。最常见的请求方法是GET,用于请求服务器上的资源。另外一种常用的请求方法是POST,用于向服务器发送一些数据。
在发送请求行之后,浏览器还会以请求头形式发送其他一些信息,包括浏览器的一些基础信息,比如所使用的操作系统、浏览器内核等信息,以及当前请求的域名信息、浏览器端的 Cookie 信息等。
之后,如果使用POST方法,浏览器还要准备数据发送给服务器,这些数据通过请求体来发送。
总的来说,HTTP请求流程包括发送请求行、发送请求头和发送请求体等步骤。这些信息有助于服务器更好地理解和处理客户端的请求。

6.不足与展望

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

二、HTTP框架的设计与实现

1.分层设计

​编辑

 

分层设计是软件架构设计的一种常见模式,它将应用程序分为多个层次,每个层次都有特定的功能和职责。以下是一个常见的三层分层设计:
表示层:表示层负责向用户显示信息和接收用户输入。这包括用户界面、表单验证和用户反馈等。
业务逻辑层:业务逻辑层处理应用程序的核心功能和业务逻辑。它包含所有的业务规则、流程和算法等。
数据访问层:数据访问层负责与数据存储(如数据库、文件系统等)进行交互,并将数据提供给上层使用。

特点:

  1. 高内聚低耦合
  2. 易复用
  3. 高扩展性

2.应用层设计

应用层是信息系统体系结构中的一部分,它负责展示层与领域层之间的协调,并与其他系统的应用层进行交互。应用层的设计应该尽量简单,其服务及方法一般以用例为对应关系,一个用例对应到一个应用层服务方法。方法中不包含业务规则或者知识,不保留业务对象的状态,只保留应用任务的进度状态,更注重业务能力或者业务流程的相关展示。

应用层通过调用领域层和基础设施层来完成协调,它包含一些核心概念,如领域实体、值对象、领域服务、聚合,以及它们之间的关系。领域层是DDD的核心,负责表达业务概念、业务状态信息及业务规则,具体表现形式是领域模型。 DDD提倡充血模型,即尽量将业务逻辑归属到领域对象上。

提供合理的API

可解释性:使用主流的概念方便理解,如ctx.GetBody()或ctx.Body()而不是ctx.BodyA()
简单性:常用API放到上层,易误用/低频AP放下层
可见性:最小暴露原则,不需暴露API就不暴露,可抽象为接口
冗余性:不需要冗余或能通过其他API组合得到的API
兼容性:尽量避免break change做好版本管理

不要试图在文档说明

3.中间层设计

​编辑

中间件的设计主要包括以下几个方面:
协议:中间件需要定义自己的协议,以确保计算机之间能够相互交流和通信。
持久化机制:中间件需要实现数据的持久化,以确保数据在故障后能够恢复。
消息分发机制:中间件需要实现消息的分发,以便将数据传递给其他系统或应用程序。
高可用设计:中间件需要实现高可用性设计,以确保系统能够持续提供服务。
高可靠设计:中间件需要实现高可靠性设计,以确保数据在传输过程中不会丢失或损坏

中间件需要handler完成,有预处理和后处理逻辑,我们以常用的洋葱模型。

洋葱模型是一种更细化的分层架构,它由一系列的中间件组成,每个中间件都负责处理不同的业务逻辑。洋葱模型的中间件像洋葱一样,一层一层地覆盖,最外层是应用程序逻辑,内部是数据访问逻辑。每次请求都会从外层进入,逐层处理每个中间件,最后到达最内层的数据访问层。然后,数据访问层将处理后的数据返回给应用程序逻辑,完成一次请求-响应周期。 

先经过日志中间件预处理后经过metrics中间件预处理,之后进行真正业务逻辑,最后退出业务逻辑得到后处理,先经过metric中间件后处理,其次经过日志中间件后处理,再将响应返回给用户。适用场景包括:日志记录、性能统计、安全控制、事务处理、异常处理等

func Middleware(param){
    //预处理
    
    Next()
    
    //后处理
}

若用户不主动调用下一个处理函数,核心是保持中间件的handler的索引递增

func (ctx *RequestContext) Next(){
    ctx.index++
    for ctx.index<len(ctx.handlers){
        ctx.handlers[ctx.index]()
        ctx.index++
    }
}

中间件调用链:

​编辑

 

4.路由设计

路由设计是一个复杂而重要的任务,涉及到网络性能、可靠性、安全性等多个方面。以下是一些路由设计的主要考虑因素:
最短路径:使用最短路径的算法,如Dijkstra算法,来计算网络中的最佳路径。
负载平衡:通过将流量分散到多个路径上,以减轻网络中的负载。
容错性:设计路由以允许在某些路径或设备失败时仍能保持数据传输。
网络拓扑:网络拓扑结构对路由设计具有重要影响。设计一个有效的拓扑可以提供更好的性能和可靠性。
安全性:考虑到网络中的安全问题,路由设计需要考虑到防止攻击和非法访问。
路由协议:选择适当的路由协议,如RIP、OSPF、BGP等,以实现网络的最佳路由。
网络管理:路由设计应考虑网络管理的需要,以便能够轻松地配置、监视和故障排除网络设备。

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

  • 静态路由: /a/b/c、 /a/b/d
  • 参数路由:/al:id/c (/a/b/c, /a/d/c)、/*all
  • 路由修复:1a/b <->/a/6/
  • 冲突路由以及优先级:/a/b、/: id/c
  • 匹配 HTTP 方法
  • 多处理函数:方便添加中间件

路由包括静态路由和动态路由,静态路由可使用map,key是URL,value是其handler,动态路由则需前缀树,每个节点用list存储handler

5.如何做设计

明确需求:考虑清楚要解决什么问题,有哪些需求

业界调研:业界有哪些解决方案可供参考

方案权衡:思考不同方案的取舍

方案评审:相关人员对不同方案评审

确定开发:确定最合适的方案进行开发

6.协议层设计

type server interface{
    Serve(c context.Context,conn network.Conn) error
}

抽象出合适的接口

实现Serve的接口,传入标准context(注意不要将context存储在结构体)和读写的连接,返回error

需要在连接上读写数据

协议层设计是网络编程中非常重要的一部分,它决定了网络通信的效率和可靠性。以下是一些协议层设计的主要考虑因素:
应用层协议:应用层协议决定了应用程序如何与网络进行通信。常见的应用层协议有HTTP、FTP、SMTP等。
传输层协议:传输层协议负责提供端到端的数据传输服务,保证数据可靠地到达目的地。常见的传输层协议有TCP和UDP。
网络层协议:网络层协议负责为主机提供数据传输服务,找到目标主机的路径。常见的网络层协议有IP和IPv6。
链路层协议:链路层协议负责在两个直接连接的主机之间传输数据。常见的链路层协议有PPP和以太网协议。
在协议层设计中,需要根据具体应用的需求和网络环境来选择合适的协议。同时,需要考虑协议的可靠性、效率、安全性等方面,以确保网络通信的质量和安全。

7.网络层设计

网络层设计是计算机网络的重要组成部分,负责将数据包从源地址传输到目标地址。以下是一些网络层设计的主要考虑因素:
路由选择:网络层需要能够确定数据包传输的最佳路径,这涉及到路由选择算法的设计和实施。
分组交换:网络层需要将数据包分割成若干个字节,并在到达目标地址后重新组合。
互联网络:网络层需要能够将不同的网络连接起来,使得数据可以在不同的网络之间传输。
协议转换:网络层需要能够将不同协议之间的数据包进行转换,以便在不同的协议之间进行通信。
流量控制:网络层需要能够控制数据的传输速度,以避免过度拥塞或数据丢失。
网络安全性:网络层需要考虑到网络安全性问题,例如防火墙、VPN等安全措施的设计和实施。
在网络层设计中,需要选择合适的协议和算法,以实现高效、可靠、安全的网络通信。同时,需要考虑网络拓扑结构、硬件设备、软件实现等方面,以确保网络层的稳定性和可扩展性。