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

222 阅读18分钟

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

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

接入问题引入

浏览器输入网站域名www.toutiao.com到网页加载出来,都经历了哪些过程?

  1. DNS解析
  2. TCP建连
  3. SSL/TLS握手
  4. HTTP请求发送

如何开放外部用户访问

方案:租赁一个外网IP,专用于外部用户访问门户网站,将www.example.com解析到外网IP 100.1.2.3,将该IP 绑定到一台物理机上,并发布公网route,用于外部用户访问。

image-20220521163146317.png

自建DNS服务器

原因:

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

从公有云托管->构建自己的DNS系统

DNS解析过过程

DNS(Domain Name System)域名系统,是互联网上作为域名和IP地址相互映射的一个分布式数据库。DNS能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过域名,最终得到该域名对应的IP地址的过程叫做域名解析(或主机名解析)。

img

下面来详细解释DNS域名解析的过程:

1、网络客户端就是我们平常使用的电脑,打开浏览器,输入一个域名。比如输入www.163.com,这时,你使用的电脑会发出一个DNS请求到本地DNS服务器。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。

2、查询www.163.com的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果。如果没有,本地DNS服务器还要向DNS根服务器进行查询。

3、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到(.com顶级)域服务器上去继续查询,并给出(.com顶级)域服务器的地址。

4、本地DNS服务器继续向(.com顶级)域服务器发出请求,(.com顶级)域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器(163.com权威)域服务器的地址。

5、最后,本地DNS服务器向(163.com权威)域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

  • 权威DNS:保存了相应域名的权威信息。权威DNS即通俗上“这个域名我说了算”的服务器
  • LocalDNS:缓存+递归查询,运营商(集团网)部署的本地DNS服务器,直接接受网内客户端请求
  • 根DNS服务器:全球有13台,LocalDNS未命中缓存查询的起点服务器。

权威DNS 系统架构

常见的开源DNS: bind、nsd、 knot、coredns

  • DNS Query
  • DNS Response
  • DNS Update
  • DNS Notify
  • DNS XFR

image-20220521164459590.png

  • DNS Update:DNS主服务器master接受外部的变更指令
  • DNS Notify:DNS主服务器master接受变更命令后,会自增自身的serial号,同时将变更的serial号告知从服务器slave
  • DNS IXFR:DNS从服务器slave以增量的形式向master要求获取本次变更的内容
  • DNS AXFR:DNS从服务器slave以全量的形式向master要求获取当前的全量数据

当有了自己的权威DNS系统,不用担心DNS服务器经常宕机了。

image-20220521164533521.png

接入HTTPS协议

主要解决明文传输的数据安全问题

SSL/TLS:(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议

1、对称加密:使用相同的秘钥来加密传输内容,一端加密后,对端收到数据会用相同的秘钥来解密(缺点是密钥KEY在传输过程中可能被获取)

image-20220521164911576.png

2、非对称加密:如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。

image-20220521164930941.png

接入全站加速

外网用户访问站点,可能出现的问题有哪些?

image-20220521165759466.png

  • 源站容量低,可承载的并发请求数低,容易被打垮
  • 报文经过的网络设备越多,出问题的概率越大,丢包、劫持、mtu问题
  • 自主选路网络链路长,时延高

极大的流失了大部分的用户群体,NPS留存率数据不乐观。

解决方案:

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

静态加速:针对视频、图片等不变的内容,将其缓存在靠近用户的边缘节点,缓存预热后用户直接从边缘获取,从而加速访问速度;

动态加速DCDN:针对API类返回值不同的请求,通过特殊的网络优化方式(路由优化、传输优化)等技术加速其达到源站的速度。

image-20220521170139245.png

用户请求域名时,Local DNS会优先将请求打到全站加速的权威DNS上,拿到权威DNS的IP地址,再去访问全站加速的节点,但其没有请求的response,要解析源站的IP地址,从而从内部拿到权威DNS的解析结果返回给用户。

image-20220521170449741.png

负载均衡

什么是负载均衡?

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

负载均衡分类

负载均衡根据所采用的设备对象(软/硬件负载均衡),应用的 OSI 网络层次(网络层次上的负载均衡),及应用的地理结构(本地/全局负载均衡)等来分类。以下着重介绍的是根据应用的 OSI 网络层次来分类的两个负载均衡类型。

image-20220523095304020.png

根据负载均衡所作用在 OSI 模型的位置不同,负载均衡可以大概分为以下几类:

二层负载均衡(mac)

根据 OSI 模型分的二层负载,一般是用虚拟 MAC 地址方式,外部对虚拟 MAC 地址请求,负载均衡接收后分配后端实际的 MAC 地址响应。

三层负载均衡(ip)

一般采用虚拟 IP 地址方式,外部对虚拟的 IP 地址请求,负载均衡接收后分配后端实际的 IP 地址响应。

四层负载均衡(tcp)

在三层负载均衡的基础上,用 ip+port 接收请求,再转发到对应的机器。

七层负载均衡(http)

根据虚拟的 url 或 IP,主机名接收请求,再转向相应的处理服务器。

在实际应用中,比较常见的就是四层负载及七层负载

四层负载均衡

什么是四层负载均衡?(基于IP+端口的负载均衡)

主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。换种说法就是,基于IP+端口,利用某种算法将报文转发给某个后端服务器,实现负载均衡地落到后端服务器上。

在三层负载均衡的基础上,通过发布三层的 IP 地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行 NAT (网络地址转换)处理,转发至后台服务器,并记录下这个 TCP 或者 UDP 的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。

以常见的 TCP 为例,负载均衡设备在接收到第一个来自客户端的 SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标 IP 地址进行修改(改为后端服务器 IP),直接转发给该服务器。TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。 在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

对应的负载均衡器称为四层交换机(L4 switch),主要分析 IP 层及 TCP/UDP 层,实现四层负载均衡。此种负载均衡器不理解应用协议(如 HTTP/FTP/MySQL 等等)。要处理的流量进行 NAT 处理,转发至后台服务器,并记录下这个 TCP 或者 UDP 的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。

四层负载均衡主要功能:

  • 解耦VIP和RS:应用服务不再局限于某一台物理机,可以灵活的指向后端,从而使后端的容量灵活进行扩缩容
  • NAT:不做请求的任何处理,只把请求转发给后端,作为一层流量代理
  • 防攻击:避免将后端物理机的IP直接暴露在公网,可以在四层负载均衡进行一个syn proxy攻击拦截

VIP:虚拟IP,一般作为四层反向代理的入口,client看起来一直在与VIP交互

RS:Real Server,VIP后实际承受client请求的服务,可能是物理机/虚拟机/容器POD

实现四层负载均衡的软件有:

  • F5:硬件负载均衡器,功能很好,但是成本很高
  • lvs:重量级的四层负载软件
  • nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活
  • haproxy:模拟四层转发,较灵活

四层负载均衡常见的调度算法原理:

四层负载均衡是通过什么算法或什么规则将流量转发给后端的服务器?

  1. RR轮询:Round Robin,将所有的请求平均给每个真实服务器RS

  2. 加权RR轮询:给每个后端服务器一个权值比例,将请求按照比例分配

  3. 最小连接:把新的连接请求分配给当前连接数量最小的服务器

  4. 五元组hash:根据sip、sport、proto、dip、dport对静态分配的服务器做散列取模

    (缺点:当后端的某个服务器故障,所有连接都要重新计算,影响整个hash环)

  5. 一致性hash:只影响故障服务器上的连接session,其余服务器上的连接不受影响

四层负载均衡内部实现原理(FULLNAT模式):

image-20220523104339577.png

  • CIP、CPort:客户端IP、Port
  • VIP、VPort:公网IP、Port
  • LIP、LPort:四层负载均衡内部请求转发的IP、Port
  • RSIP、RSPort:目标IP、Port

RS如何知道真实的CIP? --> 通过TCP option字段传递,然后通过特殊的内核模块反解

四层负载均衡的特点:

  • 大部分都是通过dpdk技术实现,技术成熟,大厂都在用
  • 纯用户态协议栈,kernel bypass,消除协议栈瓶颈
  • 无缓存,零拷贝,大页内存(减少cache miss)
  • 仅针对4层数据包转发,小包转发可达到限速,可承受高cps(每秒新建连接数)

DPDK:Data Plane Development Kit,一种从数据面去加速网络报文处理的工具,主要用于4层负载均衡,用于转发的网络加速领域比较多,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率

Kernel Bypass(内核旁路)是绕过Linux内核(TCPIP协议栈)的技术,不使用Linux内核子系统的功能,采用自己实现的相同功能的代码来处理,从用户空间直接访问和控制设备内存,避免数据从设备拷贝到内核,再从内核拷贝到用户空间。Kernel Bypass目前主流实现方案如DPDK、SolarFlare。

使用四层负载均衡

使用了四层负载均衡后,请求会优先转发给四层负载均衡,然后再转发给后端服务器。

image-20220523105924565.png

七层负载均衡

什么是七层负载均衡?(基于虚拟的 URL 或主机 IP 的负载均衡)

所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。七层负载均衡主要用来处理四层负载均衡报文无法处理的HTTP流量的一些治理。

在四层负载均衡的基础上(没有四层是绝对不可能有七层的) ,再考虑应用层的特征,比如同一个 Web 服务器的负载均衡,除了根据 VIP 加 80 端口辨别是否需要处理的流量,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。举个例子,如果你的 Web 服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。

以常见的 TCP 为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立 TCP 连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。

对应的负载均衡器称为七层交换机(L7 switch),除了支持四层负载均衡以外,还有分析应用层的信息,如 HTTP 协议 URI 或 Cookie 信息,实现七层负载均衡。此种负载均衡器能理解应用协议。

实现七层负载均衡的软件有:

  • haproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移
  • nginx:只在 http 协议和 mail 协议上功能比较好,性能与 haproxy 差不多
  • apache:功能较差
  • Mysql proxy:功能尚可

Nginx

最灵活的高性能WEB SERVER,应用最广的7层反向代理。

基本特性

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

正向代理和反向代理

由于防火墙的原因,我们并不能直接访问谷歌,那么我们可以借助VPN来实现,这就是一个简单的正向代理的例子。这里你能够发现,正向代理“代理”的是客户端,而且客户端是知道目标的,而目标是不知道客户端是通过VPN访问的。

正向代理最大的特点是客户端非常明确要访问的服务器地址;而服务器只清楚请求来自哪个代理服务器,不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。

img

当我们在外网访问百度的时候,其实会进行一个转发,代理到内网去,这就是所谓的反向代理,即反向代理“代理”的是服务器端,而且这一个过程对于客户端而言是透明的。

反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息!

img

Nginx反向代理示意图

image-20220523212535851.png

代理服务器功能

  • Keepalive
  • 访问日志
  • url rewrite重写
  • 路径别名
  • 基于ip 的用户的访问控制
  • 限速及并发连接数控制
  • ....

Nginx内部架构

image-20220523215945728.png

Nginx的响应速度快的原因之一是引入了事件驱动模型

事件驱动模型

事件驱动模型是实现异步非阻塞的一个手段。 事件驱动模型中,一个进程(线程)就可以了。

对于web服务器来说,客户端A的请求连接到服务端时,服务端的某个进程(Nginx worker process)会处理该请求,此进程在没有返回给客户端A结果时,它又去处理了客户端B的请求。服务端把客户端A以及客户端B发来的请求作为事件交给了“事件收集器”,而“事件收集器”再把收集到的事件交由“事件发送器”发送给“事件处理器”进行处理。最后“事件处理器”处理完该事件后,通知服务端进程,服务端进程再把结果返回给客户端A、客户端B。在这个过程中,服务端进程做的事情属于用户级别的,而事件处理这部分工作属于内核级别的。也就是说这个事件驱动模型是需要操作系统内核来作为支撑的。

img

异步非阻塞

  1. 传统服务器:一个进程/线程处理一个连接/请求阻塞模型、依赖OS 实现并发
  2. Nginx:一个进程/线程处理多个连接/请求异步非阻塞模型、减少OS 进程切换

image-20220523220728117.png

Nginx简单优化

image-20220523220958901.png

  1. 优化内核网络参数 fs.filemax= 999999 (一个worker进程可以同时打开的最大句柄数,这个参数直线限制最大并发连接数) net.ipv4.tcp_tw_reuse= 1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_max_tw_buckets = 5000 net.ipv4.ip_local_port_range = 1024 61000 net.ipv4.tcp_max_syn.backlog=1024 net.ipv4.tcp_syncookies = 1 ...

  2. 提升CPU使用效率

    • 合适的worker进程数 Worker进程数= CPU 核数
    • CPU亲和 每个worker 程绑定一个CPU核,提升缓存命中率
    • 减少CPU开销 multi_accept允许worker同时接受新连接 accept_mutex解决惊群问题 reuseport 监听同端口,内核负载均衡
  3. 提升网络效率

    • 连接复用 减少upstream建连
    • 使用Cache 减少超时时间对业务的影响
    • gzip压缩 减小数据包在网络传输中的大小,但会增加cpu开销,需平衡使用
    • 开启proxy_buffering 谨慎设置proxy_buffer 大小,过大会促使磁盘io读写

使用七层负载均衡

image-20220523131118428.png

为什么权威DNS服务器不会挂在七层负载均衡后面?

权威DNS服务主要基于TCP、UDP的转发,而七层负载均衡基于HTTP转发,所以权威DNS服务器工作在四层负载均衡后面

两者之间的区别

四层负载均衡就像银行的自助排号机,每一个达到银行的客户根据排号机的顺序,选择对应的窗口接受服务;而七层负载均衡像银行大堂经理,先确认客户需要办理的业务,再安排排号。这样办理理财、存取款等业务的客户,会根据银行内部资源得到统一协调处理,加快客户业务办理流程。

image-20220523111406458.png

总结:从上面的对比看来,四层负载与七层负载最大的区别就是效率与功能的区别。四层负载架构设计比较简单,无需解析具体的消息内容,在网络吞吐量及处理能力上会相对比较高,而七层负载均衡的优势则体现在功能多,控制灵活强大。在具体业务架构设计时,使用七层负载或者四层负载还得根据具体的情况综合考虑。