将我的服务开放给用户 | 青训营笔记

136 阅读12分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记

接入问题引入

经典问题:浏览器输入网站域名到网页加载出来都经历了那些过程?

DNS域名解析->TCP建连->TSL握手->HTTP请求

  1. URL解析:地址栏输入地址,浏览器对输入内容进行解析,判断URL的合法性,和是否有可用缓存
  2. DNS解析:域名解析系统(DNS)查找对应的IP地址
  3. 建立TCP连接(三次握手):浏览器向服务器发起TCP连接,与浏览器建立TCP三次握手
  4. TSL握手:保证 HTTP 通信是安全的
  5. HTTP请求:浏览器将http请求数据发给服务器(客户端–>服务器)
  6. HTTP响应:服务器处理收到的请求,返回响应结果至浏览器(服务器–>客户端)
  7. 页面渲染:浏览器解析响应结果,进行页面渲染

以上步骤中,1为缓存相关,2、3、4、5、6为网络相关,7为浏览器相关

企业接入

域名系统

域名空间:

  • 域名空间是一个树形结构
  • 通过划分zone的方式进行分层授权管理
  • 全球公共域名空间仅对应一棵树
  • 根域名服务器:查询起点
  • 域名组成格式:[a-zA-Z0-9_-],以点划分label image.png 顶级域:.gov政府,.edu教育,.com商业,.mil军事,.org非盈利组织

企业需要通过域名购买和配置迁移才能拥有自己的域名,购买二级域名:example.com,还需要进行域名备案,一般在云厂商处即可进行实名认证并备案 image.png

开放外部用户访问

租赁一个外网IP,专用于外部用户访问门户网站,将所购买的域名“www.example.com” 解析到所租赁的外网IP,将该IP绑定到一台物理机上(公司的门户网站也要部署到这台物理机上),并发布公网路由,用于外部用户访问。至此,外部用户的访问过程如下:

  1. 用户通过云厂商DNS解析服务获取“www.example.com” 的解析地址
  2. 得到其相应的IP地址
  3. 访问得到的IP地址与实现访问

自建DNS服务器

从公有云托管->构建自己的DNS系统 自建DNS服务器原因:

  • 内网域名的解析也要去公网获取,效率低下
  • 外部用户看得到内网IP地址,容易被hacker攻击
  • 云厂商权威DNS容易出故障,影响用户体验
  • 持续扩大公司品牌技术影响力,使用自己的DNS系统

DNS解析过程

image.png

权威DNS系统架构

用户访问过程:

  1. 向Local DNS获取“www.example.com” 的解析地址
  2. Local DNS有缓存,则返回给用户域名对应的IP地址
  3. 没有缓存,则Local DNS向公司自建的权威DNS服务器发起解析请求
  4. 得到IP地址,返回给用户
  5. 用户访问IP地址,发送请求和接收响应

接入HTTPS协议

HTTP明文传输,有安全风险,包括窃听风险,篡改风险,冒充风险,所以使用HTTPS加密

对称加密和非对称加密

  • 对称加密:一份密钥,客户端和服务器双方持有相同的密钥,双方通信时使用密钥对称加密数据,并且使用密钥对称解密数据image.png存在缺陷:传输开始之前要先传输密钥,有可能被截获,进而导致加密的数据会被解密。
  • 非对称加密:公钥和私钥,如果使用公钥对数据加密,则只能使用相应的私钥才能解密,同样,如果使用私钥对数据加密,只能使用相应的公钥才能解密。image.png

SSL的通信过程(RAS密钥交换算法)

  1. 客户端先发一个Client Hello 消息,里面有客户端使用的TLS版本号,支持的密码套件列表(cipher suites supported)和生成的随机数(Client Random),该随机数会被服务端保留,它是生成对称加密密钥的材料之一。
  2. 服务端收到客户端的Client Hello 之后,会确认TSL版本号是否支持,并且从密码套件列表中选择一个密码套件,以及生成随机数(Server Random),接着返回Server Hello 消息,消息里面有服务器确认的TLS版本号,也给出了随机数(Server Random),和服务端所选择的密码套件。然后服务端为了证明自己的身份会发送Server Certificate 给客户端,这个消息里面含有数字证书。随后,服务端发送Server Hello Done 消息,告诉客户端已经把该给你的都给你了。
  3. 客户端收到数字证书后会验证证书,认为证书可信则继续向下走,客户端生成一个新的随机数(pre-master),用服务器的公钥(从数字证书中取出)加密该随机数,通过Change Key Exchange 消息传给服务端,服务端收到后,用私钥解密得到客户端新发来的随机数(pre-master)。至此,客户端和服务端都共享了三个随机数,分别是Client RandomServer Randompre-master。于是,双方根据这三个随机数生成会话秘钥(Session key)。生成后,客户端发送一个Change Cipher Spec 消息,告诉服务端开始使用加密方式发送消息。然后客户端再发送一个Encrypted Handshake Message(Finished) 消息,把之前所有发送的数据做个摘要,再用会话秘钥加密,让服务端验证下加密通信是否可用,并且之前握手信息是或否有被中途篡改过。
  4. 服务端同样发送Change Cipher SpecEncrypted Handshake Message,如果双方验证加密解密都没问题,那么就可以使用会话秘钥来加密HTTP的请求和响应了。 image.png

客户端验证数字证书

客户端收到数字证书后会验证:

  • 是否是可信机构颁布
  • 域名是否与实际访问一致
  • 检查数字签名是否合法(数字签名是算出来的,即算出来的结果是否一致)
  • 检查证书有效期
  • 检查证书的撤回状态

image.png 左边是签发证书,右边是客户端校验服务端的数字证书 签发证书:

  • 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
  • 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在文件证书上,形成数字证书; 校验数字证书:
  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

接入全站加速

  • 源站容量问题:增加后端机器扩容,静态内容使用静态加速缓存
  • 网络传输问题:动态加速DCDN 全站加速=静态加速+动态加速

静态加速CND

缓存静态文件,将服务器上的静态内容(视频,图片)缓存到CND节点上,当访问这些静态内容时,无需访问服务器源站,通过就近原则访问CDN结点就可以,从而达到加速的效果,同时减轻源站的压力。

通过静态加速,从DNS获取的就不是源站的解析结果,而是CDN结点的解析结果,CDN结点使用自动调度DNS,根据一定的算法和策略(静态拓扑、容量等),将一些合适的CDN结点的IP地址返回给Local DNS,然后返回Client。当Client请求时,如果CDN结点没有客户端想要的,则会向源站发起请求,并将源站的相应缓存到CDN结点,同时也返回给客户端。

静态加速带来的好处:

  1. 解决服务端的“第一公里”问题
  2. 缓解甚至消除了不同运营商之间互联的瓶颈造成的影响
  3. 减轻了各省的出口带宽压力
  4. 优化了网上热点内容的分布

动态加速DCND

针对POST等非静态请求等不能在用户边缘缓存的业务,基于智能选路技术,从众多回源线路中择优选择一条线路进行传输。

场景与加速类型: 用户首次登录抖音,注册用户名手机号等用户信息---动态加速CDCN
抖音用户点开某个特定的短视频加载后观看---静态加速DCN
用户打开头条官网进行网页浏览---静态加速CDN+动态加速DCDN

4层负载均衡

基于IP+端口,利用某种算法将报文转发给某个后端服务器,实现负载均衡地落到后端服务器上。主要是对于TCP和UDP流量的转发。

主要功能:

  1. 解耦VIP和RS,(VIP:虚拟IP,一般作为四层反向代理的入口,client看起来一直在与VIP交互。RS:Real Server,VIP后实际承受client请求的服务,可能是物理机/虚拟机/容器POD)
  2. NAT
  3. 防攻击:syn proxy

常见的调度算法

  • RR轮询:将所有的请求平均分配给每个真实服务器RS
  • 加权RR轮询:给每个后端服务器一个权值比例,将请求按照比例分配
  • 最小链接:把新的连接请求分配到当前连接数最小的服务器
  • 五元组hash:根据源IP(sip),源端口(sport),协议(proto),目的IP(dip),目的端口(dport)对静态分配的服务器做散列取模,该方法有缺点:当某个后端服务器故障后,所有连接都重新计算,影响整个hash环
  • 一致性hash:出故障时直营校故障服务器上的连接session,其余服务器的连接不受影响

常见的实现方式FULLNAT

image.png 4层负载均衡通过VIP来接受外部请求,但是在内部不能拿VIP作为Client,所以用另一个网卡绑定一个LIP,LIP是一个内部IP,通过这个LIP与RS进行通信,从而将请求转发给RS。物理机再将相应发给4层负载均衡,4层负载均衡再回传给客户端。

注:RS通过TCP的option字段来传递真实的CIP,然后通过特殊的内核模块反解。

4层负载均衡特点

  • 大部分是通过dpdk技术实现,技术成熟,大厂都在用。(DPDK:Data Plane Development Kit,一种从数据面去加速网络报文处理的工具,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。主要用户4层负载均衡,用于转发的网络加速领域比较多;以极大提高网卡报文的处理性能和吞吐量,提高数据平面应用程序的工作效率)
  • 纯用户态协议栈,kernel bypass,消除协议栈瓶颈
  • 无缓存,零拷贝,大页内存(减少cache miss)
  • 仅针对4层数据包转发,小包转发可达到限速,可承受高cps

7层负载均衡

7层负载均衡主要是为了解决4层负载均衡无法解决的http报文流量的处理

Nginx

最灵活的高性能web server,应用最广的7层反向代理

  • 模块化设计,较好的扩展性和可靠性
  • 基于master/worker架构设计
  • 支持热部署,可在线圣经
  • 不停机更新配置文件、更新日志文件、更新服务器二进制
  • 较低的内存消耗:一万个keep-alive连接模式下的非活动连接仅消耗2.5M内存
  • 事件驱动:异步非阻塞模型、支持aio,mmap(内存映射)

Nginx内部架构

image.png 有一个master进程和多个worker进程。每个worker进程可以相应多个用户请求,每个work进程有核心模块和外围的诸多模块组成(比如实现http功能的ht_core模块,实现负载均衡的upstream模块,反代理模块proxy等),基于不同的模块可以和不同的后端通信,worker进程还可以管理cache,可以把后端服务器的内容缓存到本地,缓存在内存与本地磁盘之间通信时提供AIO,mmap等机制加速硬盘的访问。相应用户的请求支持select/epoll等多路复用请求的机制。

事件驱动模型--异步非阻塞

每个进程使用异步非阻塞方式可以处理多个客户端请求,减少OS进程切换。当某个worker进程接收到客户端请求以后,调用IO进行处理,如果不能立即得到结果,就去处理其他请求(即为 非阻塞),而客户端在此期间也无需等待相应,可以去处理其他使其(即为 异步)。当IO请求返回时,会通知此worker进程,该进程得到通知,咱叔挂起当前处理的事务去相应客户端请求。