Nginx¶
约 1305 个字 4 张图片 预计阅读时间 4 分钟
nginx是个高可用,高性能的网络服务。
其中,高可用主要由多进程模型保障,高性能主要由异步非阻塞IO模型,以及CPU绑核、内存池、负载均衡、多级缓存等特性保障。
todo:
- 共享内存:原理,示例,nginx怎么用的?
- 信号通信:信号、管道channel
- 惊群问题
- 负载均衡
- 信号量,自旋锁,有哪些机制保证多进程的数据一致性
- nginx的并发能力和规格
- CPU绑核原理
- 常见限流算法有哪些?
一、如何保证高可用的?
多进程模型,master进程负责管理各个worker进程,通过信号或管道方式控制worker;当worker进程退出后,master能捕获信号并重新拉起。
引入多进程后,需要解决:
- 如何负载均衡?
- 如何解决惊群问题?
- 如何进程通信?--- 共享内存原理?
- socket全连接是什么?
哪些设计保证高可用?
- 多进程模型,master简单逻辑,仅负责感知和拉起worker进程
- 多级缓存机制,保护下游规格,以及业务异常兜底
- 限流能力:tps/bps/conn,正交节点级、用户级,资源级
- 健康探测机制,用于集群内的节点平滑升级和上线
- 运维手段
二、如何实现高性能的?
哪些设计保证高性能:
- 异步非阻塞的事件模型 --- 解决IO吞吐率
- 多级缓存 --- 解决性能 + 保护下游 + 服务异常兜底
- 内存池设计 --- 提升性能,减少内存泄漏,减少系统调用
- CPU绑核 --- 优化性能,提升缓存命中率
- 重IO通过异步非阻塞,重计算通过切轻量级多线程,避免队头阻塞
1、异步非阻塞,基于epoll事件机制,从tcp建链、数据读取和发送都是异步的。

2、CPU绑核,将worker数量跟CPU核心数量绑定,让每个worker进程独享一个CPU核心,避免频繁的CPU上下文切换 + 提升CPU缓存命中率(L3 Cache是核间共享)。
绑核是什么系统调用???
3、负载均衡,
nginx多进程模型如何解决“惊群问题”,如何实现多进程间的负载均衡?

Nginx惊群主要发生在epoll_wait和accept这两个函数的调用上。listen_fd由master进程创建,在fork多个work子进程后,各个worker都会将listen_fd加入自己的epoll管理中。
惊群场景1:发生在epoll_wait阶段,通过reuseport关键字,即让多个进程共同监听一个端口,在建立连接请求时,linux内核只会唤醒其中一个worker进程处理。
惊群场景2:发生在accept阶段
作为反向代理,nginx的负载均衡算法有:
- 轮询,round-robin
- 加权轮询,在rr算法基础上通过给不同server配置权重来改变对不同server的访问概率;
- IP散列,基于客户端IP进行hash散列,保证同一个客户端的请求达到同一个后端server;
- 最少连接数:尽量将请求发送给连接数少的服务器,解决部分服务器因长连接占用导致负载不均问题;
- 最短响应时间:响应时间短的后端server优先分配。
4、内存池技术
网络清求tps高,频繁申请和释放内存涉及系统调用频繁且内存碎片也多。
nginx设计了内存池,每个新建清求都会创建一块内存池。内存池分小块内存和大块内存,小块内存一次性预申请一段连续空间,大块内存则直接malloc并用链表管理。

5、共享内存
共享内存是让多个进程将自己的虚拟内存映射到同一块物理内存上,不同进程读写会操作同一块内存,进而实现进程间的通信。
共享内存由master负责创建(mmap创建、munmap释放),fork子进程后共享内存地址直接被继承。更新共享内存需要原子操作或是通过加锁保障。nginx是通过原子变量来实现互斥锁

6、限流能力
常见限流算法:
- 计数器算法
- 漏桶算法
- 令牌桶算法
限流原理:
- tps、bps、conn
7、缓存模块
- 为什么要设计缓存?保护下游服务防止打爆 + 提升业务性能
- 有哪些设计?由于nginx多进程模型,做了3级缓存,进程级和节点级和集群级,进程级进程独立,节点级通过共享内存被所有进程共享。为什么要涉及多级缓存,做进程级是因为节点级数据由红黑树维护需要读写锁,进程级希望能兜住80%的业务场景,为什么要做节点级,因为多进程间数据相似度很多,且避免缓存冗余,所以通过节点级缓存出口避免对下游服务访问暴涨。
- 有什么难点?缓存淘汰,负向缓存避免被持续击穿,缓存过期,缓存复用。
8、asan原理