文章标签 » HTTP

0. 概览和基础原理 – 应用层通信原理与排错指南

微服务(Microservices)的兴起导致了系统的拆解、分离,以往的单个大型系统被拆分成多个单一职责的小型功能模块,模块拥有自己独立的进程和数据库,每个模块都是一个完整的小服务。

模块和模块之间需要相互通信,成熟的系统架构中应用层间通信至少涉及到三大块:服务发现、具体通信协议、负载均衡(容灾)。不仅在复杂的系统中,在你执行一次curl命令的时候你也能感受到他们的存在,通常一次curl请求至少包含了:DNS请求、HTTP协议、Nginx转发。

本文不准备学究式的去讨论技术实现,而是希望从实践的角度去讲解常见的应用层通信方式的原理和排错方法。

适宜读者:

  1. 平常只管开发的程序员
  2. 想要搞清大概原理的产品经理
  3. 还没入门的运维

 

一、互联网通信的基石:TCP/IP模型

四层简化协议的封装顺序

TCP/IP网络模型是一个金字塔结构,层层封装,越往上越应用,越往下越底层。

我们可以将这个模型简化一下,将网络连接层和传输层合起来看,四层模型中你只需要关注这两个:网络连接层+传输层(TCP/UDP + IP)、应用层(HTTP、DNS)。

应用层在传输层之上,应用层负责传输业务数据,传输层负责转发数据包。

(因为几乎不会将TCP/IP分开使用,本文统一将网络连接层和传输层合并成为传输层或者四层

二、传输层 TCP/UDP

当一条数据需要发送出去,数据包一层一层打包封装,封装到传输层的时候,数据包里都有什么信息呢?

以UDP为例,UDP/IP的报文逻辑上可以总结为这样:

UDP/IP报文简化逻辑图

可以看到,传输层UDP/IP只关心来源目的的地址和端口,只负责将数据从来源发送到目的,不会有任何别的逻辑。

另外,比起UDP,TCP保证了数据顺序的一致和报文传输的可靠,简单的说就是UDP只管将报文发出去,而TCP会保证发送的报文的先后顺序、保证每个报文都发送到位,除此之外TCP和UDP没有本质区别。

总的来看,TCP和UDP都是实现了以来源地址、来源端口、目的地址、目的端口构成四元组,将报文从来源发送到目的。

三、应用层 (以HTTP为例)

HTTP和TCP/IP的关系

HTTP协议和TCP/IP协议关系如图,TCP包的内容包着整个HTTP协议包,这里我们先不考虑分段传输等。接下来几篇文章中将着重介绍HTTP协议。

HTTP 协议中自定义返回码描述字段

HTTP 协议中每一个 Response 都有一个 Status Code,协议中预定义了若干状态码例如:

200 OK

301 Moved Permanently

404 Not Found

返回码由服务器控制,有些特殊场景下服务器会定义一些特殊返回码来表示返回状态。例如CDN服务商可能会返回自定义的5xx状态码作为回源失败的错误码。

除了状态码,状态码后面的描述其实也是包含在了 HTTP 协议里面,能够自定义返回,例如这是一个腾讯云的彩蛋页面:

HTTP 返回419状态码

HTTP 返回419状态码

http://cloud.tencent.com/419

 

HTTP 返回419状态码

HTTP 返回419状态码

抓包可以看到服务器返回了

HTTP/1.1 419 For One Night

这个419 For One Night当然是这帮工程师想出来的无聊的彩蛋页面的状态码了。

那么如何实现返回自定义状态码描述呢,在PHP里面可以通过header函数实现:

header(‘HTTP/1.1 419 For One Night’);

当然也不是服务端返回什么客户端就用什么,大部分客户端会优先使用预定义描述,也就是在HTTP标准里定义过的状态码描述客户端都会直接用,服务端返回一个非法描述客户端是不会认可的。

那么自定义状态码描述又有什么用呢,当然并没有什么卵用。