Nginx¶
Nginx工作模式?¶
Nginx采用master-worker模式,nginx启动成功后,会有一个master进程和至少一个worker进程;master进程负责处理系统信号、加载配置、管理worker进程;worker进程负责处理具体的业务逻辑。
nginx采用了异步非阻塞的工作方式,epoll模型:当有i/o事件产生时,epoll就会告诉进程哪个连接由i/o事件产生,然后进程就会处理这个事件。nginx配置use epoll后,以异步非阻塞的方式工作,能够处理百万计的并发连接。
master-worker模式的优缺点:
-
稳定性高
一个worker进程挂掉后master进程会立即启动一个新的worker进程,保证worker进程数量不变,降低服务中断的概率
-
高性能
Nginx 启动 N 个 worker, 并将 worker 和 cpu 进行绑定,每个 worker 有自己的 epoll 和 定时器,由于没有进程、线程切换开销,性能非常好。配合Linux的cpu亲和性的匹配中,可以充分利用多核cpu的优势,提升性能
-
支持平滑重启
处理信号、配置重新加载等可以做到尽可能不中断服务
Nginx Location 路径匹配规则是怎么样的?¶
对于请求: http://example.com/static/img/logo.jpg
- 如果命中精确匹配,例如:
则优先精确匹配,并终止匹配。
- 如果命中多个前缀匹配,例如:
则记住最长的前缀匹配,即上例中的 /static/img/,并继续匹配
- 如果最长的前缀匹配是优先前缀匹配,即:
- 否则,如果命中多个正则匹配,即:
location /static/ {
}
location /static/img/ {
}
location ~* /static/ {
}
location ~* /static/img/ {
}
则忘记上述 2 中的最长前缀匹配,使用第一个命中的正则匹配,即上例中的 location ~* /static/ ,并终止匹配(命中多个正则匹配,优先使用配置文件中出现次序的第一个)
- 否则,命中上述 2 中记住的最长前缀匹配
Nginx的负载均衡策略有哪些?¶
负载均衡策略 | 说明 |
---|---|
轮询(rr) | 负载均衡默认策略 |
weight | 权重方式,权重越高分配到需要处理的请求越多,此策略比较适合服务器的硬件配置差别比较大的情况。此策略可以与least_conn和ip_hash结合使用。 |
ip_hash | 依据ip分配方式,基于客户端IP的分配方式,确保了相同的客户端的请求一直发送到相同的服务器,实现会话粘滞目的 |
least_conn | 最少连接方式,把请求转发给连接数较少的后端服务器,可以达到更好的负载均衡效果 |
fair(第三方) | 响应时间方式 |
url_hash(第三方) | 依据URL分配方式 |
nginx基于权重轮询平滑算法是怎么实现的?¶
常规的基于权重的轮询调度算,假定a, b, c三台机器的负载能力分别是4:2:1,则可以给它们分配的权限为4, 2, 1。 这样轮询完一次后,a被调用4次,b被调用2次,c被调用1次。
对于普通的基于权重的轮询算法,可能会产生以下的调度顺序{a, a, a, a, b, b, c}。这样的调度顺序其实并不友好,它会一下子把大压力压到同一台机器上,这样会产生一个机器一下子很忙的情况。 于是乎,就有了平滑的基于权重的轮询算法。
所谓平滑就是调度不会集中压在同一台权重比较高的机器上。这样对所有机器都更加公平。 比如,对于{a:5, b:1, c:1},产生{a, a, b, a, c, a, a}的调度序列就比{c, b, a, a, a, a, a} 更加平滑。
算法逻辑:
算法执行2步,选择出1个当前节点。
- 用上次选择后的权重加上每个节点配置的权重,作为节点当前权重值,第一选择的时候,上次选择后的权重都是0
- 选择当前权重值最大的节点为选中节点,并把它的当前值减去所有节点的权重总和,作为选择后的权重值
例如{a:5, b:1, c:1}三个节点。一开始我们初始化三个节点的当前值为{0, 0, 0}。 选择过程如下表:
轮数 | 当前权重 | 选择节点 | 选择后的权重 |
---|---|---|---|
0 | - | - | {0, 0, 0} |
1 | {5, 1, 1} | a | {-2, 1, 1} |
2 | {3, 2, 2} | a | {-4, 2, 2} |
3 | {1, 3, 3} | b | {1, -4, 3} |
4 | {6, -3, 4} | a | {-1, -3, 4} |
5 | {4, -2, 5} | c | {4, -2, -2} |
6 | {9, -1, -1} | a | {2, -1, -1} |
7 | {7, 0, 0} | a | {0, 0, 0} |
我们可以发现,a, b, c选择的次数符合5:1:1,而且权重大的不会被连接选择。7轮选择后, 当前值又回到{0, 0, 0},以上操作可以一直循环,一样符合平滑和基于权重。
nginx四层、七层负载均衡的有什么区别?¶
四层就是基于IP+端口的负载均衡,通过虚拟IP+端口接收请求,然后再分配到真实的服务器;nginx修改数据包里面的目标和源IP和端口,然后把数据包发向目标服务器,服务器处理完成后,nginx再做一次修改,返回给请求的客户端。
七层通过虚拟的URL或主机名接收请求,然后再分配到真实的服务器。七层就是基于URL等应用层信息的负载均衡。Nginx需要读取并解析http请求内容,然后根据具体内容(url,参数,cookie,请求头)然后转发到相应的服务器,转发的过程是:建立和目标机器的连接,然后转发请求,收到响应数据在转发给请求客户端。
七层负载均衡是:
# cat /etc/nginx/conf.d/test.conf
upstream phpserver {
server192.168.2.3;
server192.168.2.4;
}
upstream htmlserver {
server192.168.2.1;
server192.168.2.2;
}
# /etc/nginx/nginx.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ($request_uri ~*\.html$){
proxy_pass http://htmlserver;
}
if ($request_uri~* \.php$){
proxy_pass http://phpserver;
}
}
四层负载均衡: