这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记
预主秘钥
TLS 握手期间会发生什么?| SSL 握手 | Cloudflare
Amazon API Gateway 是一种完全托管的服务,可以帮助开发人员轻松创建、发布、维护、监控和保护任意规模的API。 API 充当应用程序的前门,可从您的后端服务访问数据、业务逻辑或功能。
nginx网络模型,为什么能支持高并发
搭建博客参考:strikefreedom.top
域名管理
hosts文件
hosts(域名)到IP的映射
随着example公司业务规模和员工数量的增长,使用该方式面临诸多问题:
- 流量和负载:用户规模指数级增长,文件大小越来越大,统一分发引起较大的网络流量和cpu负载
- 名称冲突:无法保证主机名称的唯性,同名主机添 加导致服务故障
- 时效性:分发靠人工上传,时效性太差
域名系统
改为使用域名系统。具体实现如下
修改配置(云厂商):
清空/etc/hosts
配置/etc/resolv.conf中nameservers为公共DNS
迁移原配置,通过控制台添加解析记录
购买的域名是二级域名
关于域名空间:
- 域名空间被组织成树形结构
- 域名空间通过划分zone的方式进行分层授权管理
- 全球公共域名空间仅对应一棵树
- 根域名服务器:查询起点
- 域名组成格式: [a-zA-Z0-9_-], 以点划分label
如何建设外部网站,提高公司外部影响力?
- 云厂商的DNS
上面的域名配置只对内部的服务器生效,所以如果想建设对外也开放的网站,需要租赁一个外网ip,专用于外部用户访问户网站,将www.example.com解析到外网ip 100.1.2.3,将该ip绑定到一台物理机上,并发布公网route,用于外部用户访问。
自建DNS服务器
背景
- 内网域名的解析也得出公网去获取,效率低下
- 外部用户看到内网ip地址,容易被hacker攻击
- 云厂商权威DNS容易出故障,影响用户体验
- 持续扩大公司品牌技术影响力,使用自己的DNS系统
从公有云托管- >构建自己的DNS系统
权威DNS系统架构
这个背景下,搭建权威DNS就够用了。对所有访问负责的二级域名的请求加以回应
常见的开源DNS: bind, nsd, knot, coredns
Query, Response, Update, Notify, XFR
HTTPS
购买证书后就可以使用了,避免明文传输的问题
接入全站加速
背景
外网访问的问题
- 源站容量低,可承载的并发请求数低,容易被打垮
- 报文经过的网络设备越多,出问题的概率越大,丢包、劫持、mtu问题
- 自主选路网络链路长,时延高
相应解决方案
-
源站容量问题
- 增加后端机器扩容
- 对于静态内容可以使用 CDN来加速缓存
-
网络传输问题
- 动态加速 DCDN,可以动态选择链路
-
全站加速
- 静态+动态加速
静态加速
针对视频、图片等不变的内容,将其缓存在靠近用户的边缘节点,缓存预热后用户直接从边缘获取,从而加速访问速度;
访问源站之后,把获取的内容缓存在CDN节点
解决的问题
- 解决服务器端的“第一公里”问题
- 缓解甚至消除了不同运营商之间互联的瓶颈造成的影响
- 减轻了各省的出口带宽压力
- 优化了网上热点内容的分布
动态加速DCDN
针对POST等非静态请求不能在用户边缘缓存的业务(API类返回值不同),基于智能选路技术,通过特殊的网络优化方式(路由优化、传输优化),从众多回源线路中择优选择一条线路,加速其达到源站的速度。
只有核心机房能响应非静态请求(比如写入),所以就不走中间节点了
请求耗时的计算方法
首先图里的20ms等等是RTT,走一个来回的时间
-
Direct连接的时候为什么只有用户到边缘需要建立连接(20ms),而没有边缘到汇聚,汇聚到核心呢(10ms+10ms)?
在一开始就被预热了,因为不只一个用户在走这些线路
全站加速
四层负载均衡
提问:在运营商处租用的100.1.2.3的公网IP,如何在企业内部使用最合理?
现状:直接找一个物理机,ifconfig将网卡配上这个IP,起server监听即可。应用多时,起多个server监听不同的端口即可。
当多个服务冲突或机器宕机则出现问题。而ip地址数量有限,难以大规模租用。
- 所以关键是,所以该如何尽可能的充分利用和管理有限的公网ip资源?
定义
- 根据IP+端口进行转发。有点像NAT
功能
三个主要功能:
- 解耦vip和rs:用户服务不再局限与某一台物理机,而是灵活的指向后端,后端的容量也可以灵活的扩缩容。
- NAT
- 防攻击:避免将后端的物理机直接暴露在公网,能够防攻击(syn porxy),在负载均衡处进行流量拦截。
调度算法
常见调度算法原理:
-
RR轮询:Round Robin,将所有的请求平均分配给各个真实的服务器RS。
-
加权RR轮询:给每个后端服务器一个权值比例,将请求按照比例分配。
-
最小连接:把新的连接请求分配到当前连接数量最小的服务器。
-
五元组hash:根据sip、sport、proto、dip、dport对静态分配的服务器做散列取摸。(缺点:某台后端服务器故障后,所有连接都重新计算,影响整个hash环)
- 五元组hash的实现比较复杂,要参考论文
-
一致性hash:只影响故障服务器上的连接session,其余服务器上的连接不受影响。
-
在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系
-
把服务器布置在环上,让每台服务器负责一个范围
-
业界实现
- VIP:虚拟IP,一般作为四层反向代理的入口,client看起来一直在与VIP交互
- RS:Real Server,VIP后实际承受client请求的服务,可能是物理机/虚拟机/容器POD
- GW:gateway?
RS怎么知道真实的CIP?通过TCP option字段传递。然后通过特殊的内核模块反解。
因为是四层,所以可以修改TCP的option。flow是个互逆的过程
特点
-
大部分都是通过dpdk技术实现,技术成熟,大厂都在用。
- DPDK:Data Plane Development Kit,一种从数据平面去加速网络报文处理的工具,主要用于4层负载均衡,用于转发的网络加速领域比较多;
-
纯用户态协议栈,kernel bypass,消除协议栈瓶颈。
-
无缓存、零拷贝、大页内存(减少cache miss)。
-
仅针对4层数据包转发,小包转发可达到限速,可承受高cps。
七层负载均衡(Nginx 应用层网关)
提问:四层负载对100.1.2.3只能bind一个80端口,而有多个外部站点需要使用,该如何解决?有应用层(七层)配置需求?(根据HTTP等进行转发,或修改七层协议)
- SSL卸载:业务侧是http服务,用户需要用https访问。
- 请求重定向:浏览器访问未加
www.或http://的前缀,需要自动跳转。 - 路由添加匹配策略:完全、前缀、正则。
- Header编辑(增加、删除、修改)
- 跨域支持:请求网站时需要请求第三方的页面提供支持。
- 协议支持:websocket、grpc、quic。
特点和功能
最灵活的高性能WEB SERVER,应用最广的七层反向代理。比Apache性能好很多。
- 模块化设计,有较好的扩展性和可靠性。
- 基于master/worker架构设计。
- 支持热部署;可在线升级。
- 不停机更新配置文件、更换日志文件、更新服务器二进制。
- 较低的内存消耗:一万个keep-alive连接模式下的非活动连接仅消耗2.5M内存。
- 事件驱动:异步非阻塞模型,支持aio,mmap(内存映射)
功能
- keepalive(心跳?)
- 访问日志
- url rewrite重写
- 路径别名
- 基于ip的用户的访问控制
- 限速及并发连接数控制
结构
master和worker是进程
模块
不是有应用层需求吗,在这里用各种模块来解决,使用profix把不同模块编译进去。不同模块和后端不同功能通信。
ht_core:http功能,与web通信
ht_upstream:与server通信
ht_proxy:反向代理
实现
- 可以把后端服务器的内容缓存到本地。等缓存加载完毕后,再返回给客户端。
- 内存和本地磁盘的通信是高级的IO
- 多路复用
- 事件驱动模型
事件驱动模型
事件驱动模型与观察者模型 | IT宅-arthinking's blog
是操作系统提供的支持
事件放到队列里,多个进程或线程处理对应的回调函数就行,不是同步的,也不会阻塞。
简单调优
优化内核网络参数:
fs.filemax=999999 //一个worker进程能够打开的文件句柄数,调大可以限制并发连接数
net.ipv4.tcp_tw_reuser=1 //允许timewait socket建立新的tcp连接,避免timewait的连接数过多
net.ipv4.tcp_keepalive_time=600 //keepalive频度,默认2小时,调小用于清理无效的tcp连接
net.ipv4.tcp_fin_timeout=30 //tcp主动断连时socket需要保证的最大连接时间
net.ipv4.tcp_max_tw_buckets=5000 //允许的timewait socket的最大数量
net.ipv4.ip_local_port_range=1024 61000 //client端口的取值范围,默认较小,调大区间增加连接
net.ipv4.tcp_max_syn.backlog=1024 //半连接队列长度,调大以防止半连接数量大时请求丢失
net.ipv4.tcp_syncookies=1 //解决连接攻击问题
复制代码
提升CPU使用效率:
- 合适的worker进程数,worker进程数==CPU核数
- CPU亲和:每个worker进程绑定一个CPU核,提升缓存命中率
- 减小cpu开销:multi_accept允许worker批量接受连接;accept_mutex解决惊群问题(来一个任务所有worker都被唤醒,造成额外开销);reuseport监听同端口,内核负载均衡
提升网络效率
- 连接复用:长连接,减少upstream建连
- 使用cache:将请求缓存在本地,减少超时时间对业务的影响
- gzip压缩:减少网络传递的数据包的大小,但会增加cpu开销,需平衡使用
- 开启proxy_buffering:谨慎设置proxy_buffer大小,过大的缓存buffer会增加磁盘io读写
example公司的权威DNS使用UDP,只能放于四层负载均衡后面,不能放在七层负载均衡后
动手实践
如何将本地服务开放外网访问
DNSPod 现在全用的 CNAME 记录
刘作鱼: NS 可以设置域名托管,比如用 DNSPod 注册域名使用华为 DNS,就是改的 NS 记录
\