我们从如何获取到商品图片,到发出订单信息的过程进行讲解,构建出一个完整的网络包,这是本章的主要内容
购物之前,看静态资源,使用的CDN流程
客户想要在购物网站买一件东西的时候,肯定会看下详情页,这时候就是图片的需求
我们部署电商应用的时候,会将静态资源保存在两个地方,一个是接入层的nginx里面的varnish缓存里面,一个是静态页面,对于比较大的,不经常更新的,静态资源,保存在对象存储里面,然后加上CDN,将资源进行下发
配置了CDN后,权威DNS服务器上,会为静态资源设置一个CNAME别名,指向另外的域名cdn.com,返回本地DNS服务器
当本地的DNS拿到这个域名的时候,需要继续解析这个新的域名,这时候,再访问就不是原本的权威DNS服务器,而是cdn.com的权威DNS服务器,这是CDN的权威DNS服务器
这个CDN的权威DNS服务器,会配置一个CNAME,指向了CDN的全局负载均衡器
本地DNS服务器去请求CDN的全局负载均衡器解析域名,全局负载均衡器会为用户选择一台合适的缓存服务器提供服务,将IP返回给客户端,客户端去访问这个边缘节点,下载资源
如果这个缓存服务器上没有用户想要的内容,那么这台服务器要向上一级缓存服务器请求内容,直到追溯网站的源服务器,内容拉取到
准备下单,建立连接了
这种建立的连接是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版本信息,加密套件候选列表,压缩算法候选列表,还有随机数,供协商对称密钥的时候使用
服务器会返回sever Hello的消息,告诉客户端,服务端选择使用的协议版本,加密套件候选列表,压缩算法等,并且返回一个随机数,供后面的密钥协商
服务器给予一个服务端的证书,然后说Server Hello Done,说明就这些信息了
客户端会拿着这个证书,从自己信任的CA仓库中,拿CA的证书里面的公钥去解密电商网站的证书,如果能成功,说明CA可信,这个过程类似DNS的过程,会一直向上追溯,追溯CA,CA的CA,直到一个授信的CA
证书验证完成了,就可以生成随机数字PreMaster,发送Clinet Key Exchange,将证书的公钥加密,发送给服务器,服务器可以通过私钥解密出来
接下来,不管是客户端,还是服务端,都有了三个随机数,分别是自己的,对端的,刚刚生成的Pre-Master,可以在客户端和服务端生成相同的对称密钥
有了对称密钥,就可以进行通信了,然后客户端发送了Encrypted Handshke Message,将已经商定好的参数等,采用协商密钥加密,发送给服务器用于数据与握手验证
服务器发送了Change Cipher Spec,说明之后使用协商和通信密钥和加密算法进行加密通信,并且发送Encrypted Handshake Message的消息
双方完成握手,进行加密通信
进行发送下单的请求网络包
用户层发送的是HTTP的网络包,服务端提供的是RESTful API,因而HTTP层发送的一个请求,
POST /purchaseOrder HTTP/1.1
Host: www.geektime.com Content-Type: application/json; charset=utf-8 Content-Length: nnn { “order”: { “date”: “2018-07-01”, “className”: “趣谈网络协议”, “Author”: “刘超”, “price”: “68” } } |
HTTP的报文大概分为三大部分,第一部分是请求行,第二部分是请求的首部,第三部分才是请求的正文实体
URL是www.geektime.com/purchaseOrder 版本为1.1
请求的类型是POST,主动告诉服务端一些信息,不是读取
然后是请求头
key:value的形式,通过冒号分隔
Content-Type是指正文的格式,说明了是JSON格式的
然后HTTP的请求报文格式就拼好了,交给下一层的传输层
怎么交给传输层,用Scoket进行程序设计,这些程序不需要自己写
HTTP协议是基于TCP协议的,使用面向连接的方式发送请求,通过Stream二进制流的方式传给对象,到了TCP层,二进制编程一个个报文段发送给服务器
在TCP头,会有源端口和目标端口,目标端口是服务器监听的端口,源端口在手机端,这个是手机随机分配一个端口号,这个端口号手机上分配的,用于标识是哪个应用发送的
在IP头里面,需要加上自己的地址,目标地址,源地址是PGW分配的,这就是源地址,而目标地址,就是云平台的负载均衡器的外网IP地址
在IP层,查看目标地址和自己是否是一个局域网,然后判断是否是一个网段,这个通过CIDR进行计算
对于这个不是一个网段的,目标IP和源IP不会在同一个网段,需要通过DHCP分配IP地址的时候,配置默认网段的IP地址
客户端不会直接使用默认网关的IP地址,而是通过ARP,获取网关的MAC地址,然后将网关MAC作为目标MAC,自己MAC作为源MAC,放入MAC头,发送出去
这就发送出去了