11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

用双十一的故事串起碎片的网络协议(中)

  • 2019-04-19
  • 本文字数:3357 字

    阅读完需:约 11 分钟

用双十一的故事串起碎片的网络协议(中)

上一节我们讲到,手机 App 经过了一个复杂的过程,终于拿到了电商网站的 SLB 的 IP 地址,是不是该下单了?


别忙,俗话说的好,买东西要货比三家。大部分客户在购物之前要看很多商品图片,比来比去,最后好不容易才下决心,点了下单按钮。下单按钮一按,就要开始建立连接。建立连接这个过程也挺复杂的,最终还要经过层层封装,才构建出一个完整的网络包。今天我们就来看这个过程。


4.购物之前看图片,静态资源 CDN

客户想要在购物网站买一件东西的时候,一般是先去详情页看看图片,是不是想买的那一款。



我们部署电商应用的时候,一般会把静态资源保存在两个地方,一个是接入层 nginx 后面的 varnish 缓存里面,一般是静态页面;对于比较大的、不经常更新的静态图片,会保存在对象存储里面。这两个地方的静态资源都会配置 CDN,将资源下发到边缘节点。


配置了 CDN 之后,权威 DNS 服务器上,会为静态资源设置一个 CNAME 别名,指向另外一个域名cdn.com,返回给本地 DNS 服务器。


当本地 DNS 服务器拿到这个新的域名时,需要继续解析这个新的域名。这个时候,再访问的时候就不是原来的权威 DNS 服务器了,而是 cdn.com 的权威 DNS 服务器。这是 CDN 自己的权威 DNS 服务器。


在这个服务器上,还是会设置一个 CNAME,指向另外一个域名,也即 CDN 网络的全局负载均衡器。


本地 DNS 服务器去请求 CDN 的全局负载均衡器解析域名,全局负载均衡器会为用户选择一台合适的缓存服务器提供服务,将 IP 返回给客户端,客户端去访问这个边缘节点,下载资源。缓存服务器响应用户请求,将用户所需内容传送到用户终端。


如果这台缓存服务器上并没有用户想要的内容,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器,将内容拉到本地。


5.看上宝贝点下单,双方开始建连接

当你浏览了很多图片,发现实在喜欢某个商品,于是决定下单购买。


电商网站会对下单的情况提供 RESTful 的下单接口,而对于下单这种需要保密的操作,需要通过 HTTPS协议进行请求。


在所有这些操作之前,首先要做的事情是建立连接



HTTPS协议是基于 TCP协议的,因而要先建立 TCP 的连接。在这个例子中,TCP 的连接是从手机上的 App 和负载均衡器 SLB 之间的。


尽管中间要经过很多的路由器和交换机,但是 TCP 的连接是端到端的。TCP 这一层和更上层的 HTTPS 无法看到中间的包的过程。尽管建立连接的时候,所有的包都逃不过在这些路由器和交换机之间的转发,转发的细节我们放到那个下单请求的发送过程中详细解读,这里只看端到端的行为。


对于 TCP 连接来讲,需要通过三次握手建立连接,为了维护这个连接,双方都需要在 TCP 层维护一个连接的状态机。


一开始,客户端和服务端都处于 CLOSED 状态。服务端先是主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态。


客户端收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后处于 ESTABLISHED 状态。这是因为,它一发一收成功了。服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它的一发一收也成功了。


当 TCP 层的连接建立完毕之后,接下来轮到 HTTPS 层建立连接了,在 HTTPS 的交换过程中,TCP 层始终处于 ESTABLISHED。


对于 HTTPS,客户端会发送 Client Hello 消息到服务器,用明文传输 TLS 版本信息、加密套件候选列表、压缩算法候选列表等信息。另外,还会有一个随机数,在协商对称密钥的时候使用。


然后,服务器会返回 Server Hello 消息,告诉客户端,服务器选择使用的协议版本、加密套件、压缩算法等。这也有一个随机数,用于后续的密钥协商。


然后,服务器会给你一个服务器端的证书,然后说:“Server Hello Done,我这里就这些信息了。”


客户端当然不相信这个证书,于是你从自己信任的 CA 仓库中,拿 CA 的证书里面的公钥去解密电商网站的证书。如果能够成功,则说明电商网站是可信的。这个过程中,你可能会不断往上追溯 CA、CA 的 CA、CA 的 CA 的 CA,反正直到一个授信的 CA,就可以了。


证书验证完毕之后,觉得这个服务端是可信的,于是客户端计算产生随机数字 Pre-master,发送 Client Key Exchange,用证书中的公钥加密,再发送给服务器,服务器可以通过私钥解密出来。


接下来,无论是客户端还是服务器,都有了三个随机数,分别是:自己的、对端的,以及刚生成的 Pre-Master 随机数。通过这三个随机数,可以在客户端和服务器产生相同的对称密钥。


有了对称密钥,客户端就可以说:“Change Cipher Spec,咱们以后都采用协商的通信密钥和加密算法进行加密通信了。”


然后客户端发送一个 Encrypted Handshake Message,将已经商定好的参数等,采用协商密钥进行加密,发送给服务器用于数据与握手验证。


同样,服务器也可以发送 Change Cipher Spec,说:“没问题,咱们以后都采用协商的通信密钥和加密算法进行加密通信了”,并且也发送 Encrypted Handshake Message 的消息试试。


当双方握手结束之后,就可以通过对称密钥进行加密传输了。


真正的下单请求封装成网络包的发送过程,我们先放一放,我们来接着讲这个网络包的故事。


6.发送下单请求网络包,西行需要出网关

当客户端和服务端之间建立了连接后,接下来就要发送下单请求的网络包了。


在用户层发送的是 HTTP 的网络包,因为服务端提供的是 RESTful API,因而 HTTP 层发送的就是一个请求。


POST /purchaseOrder HTTP/1.1Host: www.geektime.comContent-Type: application/json; charset=utf-8Content-Length: nnn { "order": {  "date": "2018-07-01",  "className": "趣谈网络协议",  "Author": "刘超",  "price": "68" }}
复制代码


HTTP 的报文大概分为三大部分。第一部分是请求行,第二部分是请求的首部,第三部分才是请求的正文实体


在请求行中,URL 就是 www.geektime.com/purchaseOrder ,版本为 HTTP 1.1。


请求的类型叫作 POST,它需要主动告诉服务端一些信息,而非获取。需要告诉服务端什么呢?一般会放在正文里面。正文可以有各种各样的格式,常见的格式是 JSON。


请求行下面就是我们的首部字段。首部是 key value,通过冒号分隔。


Content-Type 是指正文的格式。例如,我们进行 POST 的请求,如果正文是 JSON,那么我们就应该将这个值设置为 JSON。


接下来是正文,这里是一个 JSON 字符串,里面通过文本的形式描述了,要买一个课程,作者是谁,多少钱。


这样,HTTP 请求的报文格式就拼凑好了。接下来浏览器或者移动 App 会把它交给下一层传输层。


怎么交给传输层呢?也是用 Socket 进行程序设计。如果用的是浏览器,这些程序不需要你自己写,有人已经帮你写好了;如果在移动 APP 里面,一般会用一个 HTTP 的客户端工具来发送,并且帮你封装好。


HTTP协议是基于 TCP协议的,所以它使用面向连接的方式发送请求,通过 Stream 二进制流的方式传给对方。当然,到了 TCP 层,它会把二进制流变成一个的报文段发送给服务器。


在 TCP 头里面,会有源端口号和目标端口号,目标端口号一般是服务端监听的端口号,源端口号在手机端,往往是随机分配一个端口号。这个端口号在客户端和服务端用于区分请求和返回,发给那个应用。


在 IP 头里面,都需要加上自己的地址(即源地址)和它想要去的地方(即目标地址)。当一个手机上线的时候,PGW 会给这个手机分配一个 IP 地址,这就是源地址,而目标地址则是云平台的负载均衡器的外网 IP 地址。


在 IP 层,客户端需要查看目标地址和自己是否是在同一个局域网,计算是否是同一个网段,往往需要通过 CIDR 子网掩码来计算。


对于这个下单场景,目标 IP 和源 IP 不会在同一个网段,因而需要发送到默认的网关。一般通过 DHCP 分配 IP 地址的时候,也会同时配置默认网关的 IP 地址。


但是客户端不会直接使用默认网关的 IP 地址,而是发送 ARP 协议,来获取网关的 MAC 地址,然后将网关 MAC 作为目标 MAC,自己的 MAC 作为源 MAC,放入 MAC 头,发送出去。


一个完整的网络包的格式是这样的。



真不容易啊,本来以为上篇就发送下单包了,结果到中篇这个包还没发送出去,只是封装了一个如此长的网络包。别着急,你可以自己先预想一下,接下来的内容将在后面的文章中更新,欢迎你来订阅我的专栏。


戳我试读或订阅《趣谈网络协议》,欢迎你来给我留言和讨论。


文章选自《趣谈网络协议》


2019-04-19 18:118094
用户头像

发布了 23 篇内容, 共 35.8 次阅读, 收获喜欢 159 次。

关注

评论

发布
暂无评论
发现更多内容

【等保小知识】等保一级二级三级哪个要求更高?

行云管家

网络安全 等保 等级保护 等保20

什么是立体车库?立体车库企业如何管理业务流程?

优秀

低代码 业务流程管理 立体车库

叮咚买菜自建MongoDB上云实践

MongoDB中文社区

mongodb

公安大数据合成作战平台建设,合成作战指挥中心平台开发

电微13828808271

Dubbo框架学习笔记九

六维

dubbo 12月日更

【MongoDB学习笔记】-使用 MongoDB 进行 CRUD 操作(下)

恒生LIGHT云社区

数据库 mongodb

可视化开发主流开源流程引擎与设计器研究对比

全象云低代码

低代码 流程 低代码开发 低代码平台 可视化软件

全链路在线生产数据库压测利器:Apache ShardingSphere 影子库特性升级

SphereEx

开源 技术分享 ShardingSphere SphereEx 影子库

为什么孩子会有拖延症?

Tiger

28天写作

当游戏爱上MongoDB–参会赢Kindle!

MongoDB中文社区

mongodb

IAST 在去哪儿 Q-SDL 体系中的应用

火线安全

信息安全 DevSecOps IAST

作业三

施正威

公安重点人员动态预警管控系统建设,警务情指一体可视化决策系统

电微13828808271

行云管家V6.5正式发布:喜大普奔,主机临时授权功能上线啦!

行云管家

云计算 云资源 云管理

Spring核心原理分析之MVC九大组件(1)

Tom弹架构

Java spring 源码

深入解析Apache Pulsar系列: Broker消息确认的管理

博文视点Broadview

遇到或问过的一些Spring面试题(持续更新)

Lazy

Java spring

教你用Camtasia简单几步制作精美片头

淋雨

Camtasia

百度王海峰:深耕自然语言处理近30年,推进AI融合创新

百度大脑

人工智能

重启iptables为啥内核参数不对了?

BUG侦探

Linux iptables

黑客实验环境的搭建与使用

喀拉峻

黑客 网络安全 环境配置 网络攻防 环境搭建

面对复杂微服务系统观测时,如何化繁为简?

尔达Erda

云计算 程序员 云原生 程序员微服务

如何使用pFuzz以多种方法验证Web应用程序防火墙的安全性

H

网络安全 防火墙 信息安全

用双十一的故事串起碎片的网络协议(中)_语言 & 开发_刘超_InfoQ精选文章