这是我参与「第三届青训营-后端场」笔记创作活动的第9篇笔记。
1. 域名系统
example公司建立了多个内部站点,包括办公、文档、员工认证、人事等。网络运维人员使用Host主机表的方式(主机表中存储Host -> ip映射),管理员维护一份主配置,员工通过ftp协议拉取host的主配置,从而达到访问的目的。
随着example公司业务规模和员工数量的增长,使用该方式面临诸多问题:
流量和负载:用户规模指数级增长,文件越来越大,统一分发引起较大的网络流量和cpu负载。
名称冲突:无法保证主机名称的唯一性,同名主机添加导致服务故障。
时效性:分发靠人工上传,时效性太差。
工业界常用办法:使用域名系统替换hosts文件
关于域名空间:
- 域名空间被组织成树形结构
- 域名空间通过划分zone的方式进行分层授权管理
- 全球公共域名空间仅对应一棵树
- 根域名服务器:查询起点
- 域名组成格式:
[a-zA-Z0-9_-],以点.划分label
根节点下有多个顶级域(general Top-level Domains,gTLD。gov政府、edu教育网、com商业、mil军事、org非盈利组织)。
域名购买与配置迁移
- 购买域名:从共有云厂商处购买二级域名(顶级域下)example.com。此时域名树下又多了一个二级域节点。
- 域名备案:向工信部备案,防止域名在网上从事非法的网站经营活动,打击不良互联网信息的传播。一般在云厂商处即可进行实名认证并备案。
- 修改配置:清空/etc/hosts文件,配置/etc/resolv.conf中nameservers为公共DNS。迁移原配置,通过控制台添加解析记录即可。
如何建设外部网站,提升公司外部影响力?
方案:租赁一个外网ip,专用于外部用户访问门户网站,将www.example.com解析到外网ip100.1.2.3,将该ip绑定到一台物理机上,并发布公网route,用于外部用户访问。
对于想访问www.example.com公司门户网站的用户而言,他会从云厂商的DNS服务器中获得ip地址100.1.2.3,从而能够访问站点。
2.自建DNS服务器
为什么要用自建的DNS代替云厂商的DNS?
- 内网域名的解析也得出公网去获取,效率低下。
- 外部用户看到内网ip地址,容易被hacker攻击。
- 云厂商权威DNS容易出故障,影响用户体验。
- 持续扩大公司品牌技术影响力,使用自己的DNS。
站在企业角度思考,我们需要的是哪种DNS服务器? 权威DNS。LocalDNS(可选)。
常见开源DNS软件:bind、nsd、knot、coredns。
bind的DNS架构:
- DNS系统包含Master和slave两种。
- 如果用户发起一个DNS请求,DNS系统会返回用户一个Response。
- 如果App的域名与ip变更,会通知DNS系统更新数据,Master更新数据并返回一条更新响应。
- Master更新数据后,会通知slave拉取其数据。
对于想访问www.example.com公司门户网站的用户而言,他会向LocalDNS服务器询问地址,LocalDNS通过迭代询问从example公司的权威DNS服务器上获得了ip地址100.1.2.3,从而能够访问站点。
3.接入HTTPS协议
用户反映访问www.example.com经常出现问题,如:
- 页面出现白页/出现某些奇怪的东西
- 返回了403的页面
- 搜索不了东西
- 搜索问题带了小尾巴,页面总要闪几次
- 页面弹窗广告
- 信息泄漏,进行搜索会有推销电话打来
- ........
公司发现这是有人抓取了用户的信息并进行篡改。HTTP明文传输,弊端越来越明显。
解决方法:使用HTTPS解决云传输带来的不安全的问题。
证书链
如何保证公钥是可信的,且不会被劫持。
- server端发送带签名的证书链
- client收到证书链后需要验证:
- 是否是可信机构颁布
- 域名是否与实际访问一致
- 数字签名是否一致
- 证书有效期是否过期
- 检查证书的撤回状态
根证书存在于本地,只给信任的下级授权,逐级形成证书链。
4.接入全站加速
外部用户访问站点一定是一番通顺的吗?可能出现的问题有哪些?
- 源站容量低,可承载的并发请求低,容易被打垮
- 报文经过的网络设备越多,出问题的概率就越大。(丢包、劫持、mtu匹配不一致)
- 自主选路网络链路长,时延高
体现为相应慢、卡顿。极大的流失了用户群体,NPS留存率数据不乐观。
解决方案:
- 源站容量问题:增加后端机器进行扩容;如果是静态内容可以使用静态加速缓存。
- 网络传输问题:动态加速DCDN。
全站加速=静态加速+动态加速
- 静态加速CDN
当前的访问过程:client获取DNS解析,然后向站点服务器发起请求,得到相应。
针对静态文件传输,网络优化方式?缓存。通过将静态内容缓存在CDN节点上,用户无需访问源站,而是就近访问CDN节点,加速响应同时减轻源站压力。
改进后的过程:对公司的权威DNS进行配置。系统返回智能调度DNS的相应结果,用户去访问CDN节点。CDN节点拉取源站信息同时缓存,之后再有访问就直接给出缓存的结果。
加速后的优势:
- 解决服务器的“第一公里”问题,减少了链路的距离。
- 缓解甚至消除了不同运营商之间互联的瓶颈造成的影响。
- 减轻了各省的出口宽带压力。
- 优化网络热点内容分布。
- 动态加速DCDN
针对POST等非静态请求等不能在用户边缘缓存的业务,基于智能选路技术,从众多回源线路中择优选取一条路线进行传输。
5.四层负载均衡
提问:在运营商处租用的100.1.2.3的公网IP,如何在企业内部使用最合理?
现状:直接找一个物理机,ifconfig将网卡配上这个IP,起server监听即可。应用多时,起多个server监听不同的端口即可。
当多个服务冲突或机器宕机则出现问题。而ip地址数量有限,难以大规模租用。所以该如何尽可能的充分利用和管理有限的公网ip资源?
什么是四层负载均衡:四层是基于OSI的七层模型进行划分的,第四层主要针对tcp、udp的转发。基于IP+端口,利用某种算法将报文转发给某个后端服务器,实现负载均衡地落到后端服务上。
三个主要功能:
- 解耦vip和rs,用户服务不再局限与某一台物理机,而是灵活的指向后端,后端的容量也可以灵活的扩缩容。
- NAT
- 避免将后端的物理机直接暴露在公网,能够防攻击(syn porxy),在负载均衡处进行流量拦截。
常见调度算法原理:
- RR轮询:Round Robin,将所有的请求平均分配给各个真实的服务器RS。
- 加权RR轮询:给每个后端服务器一个权值比例,将请求按照比例分配。
- 最小连接:把新的连接请求分配到当前连接数量最小的服务器。
- 五元组hash:根据sip、sport、proto、dip、dport对静态分配的服务器做散列取摸。(缺点:某台后端服务器故障后,所有连接都重新计算,影响整个hash环)
- 一致性hash:只影响故障服务器上的连接session,其余服务器上的连接不受影响。
常见的实现方式FULLNAT:
RS怎么知道真实的CIP?
通过TCP option字段传递。然后通过特殊的内核模块反解。
特点:
- 大部分都是通过dpdk技术实现,技术成熟,大厂都在用。
- 纯用户态协议栈,kernel bypass,消除协议栈瓶颈。
- 无缓存、零拷贝、大页内存(减少cache miss)。
- 仅针对4层数据包转发,小包转发可达到限速,可承受高cps。
6.七层负载均衡
提问:四层负载对100.1.2.3只能bind一个80端口,而有多个外部站点需要使用,该如何解决?(有一些7层相关的配置需求,该怎么做?)
- SSL卸载:业务侧是http服务,用户需要用https访问。
- 请求重定向:浏览器访问未加
www.或http://的前缀,需要自动跳转。 - 路由添加匹配策略:完全、前缀、正则。
- Header编辑(增加、删除、修改)
- 跨域支持:请求网站时需要请求第三方的页面提供支持。
- 协议支持:websocket、grpc、quic。
Nginx
简介:最灵活的高性能WEB SERVER,应用最广的七层反向代理。
特点:
- 模块化设计,有较好的扩展性和可靠性。
- 基于master/worker架构设计。
- 支持热部署;可在线升级。
- 不停机更新配置文件、更换日志文件、更新服务器二进制。
- 较低的内存:一万个keep-alive连接模式下的非活动连接仅消耗2.5M内存。
- 事件驱动:异步非阻塞模型,支持aip,mmap(内存映射)。
代理服务器功能:
- keepalive
- 访问日志
- url rewrite重写
- 路径别名
- 基于ip的用户的访问控制
- 限速及并发连接数控制
- ........
内部有一个Master进程和多个Worker进程,每个Worker进程可以响应多个用户请求。每个Worker有核心模块(core)和诸多外围模块(upstream、proxy、fastcgi)。使用模块时将相应的模块编入即可。基于不同模块可以和不同后端进行通信。
事件驱动模型通过异步io提高cpu利用率。
Nginx调优
优化内核网络参数:
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,只能放于四层负载均衡后面,不能放在七层负载均衡后。