< Back

nginx

常用命令

停止:nginx -s stop

启动:nginx

配置重加载(不会关闭nginx):nginx -s reload

查看当前配置文件位置:nginx -t

配置文件

分为三部分:全局块,events,http

  • 全局块:影响nginx服务器整体运行的配置命令

    worker_processes:值越大,并发处理量越多,当然也是会收到软硬件这些限制的

  • events:主要影响nginx与用户的网络连接

    worker_connections:表示支持的最大连接数

  • http:里面也分全局块和server块

反向代理

server { listen 80; # server_name 192.168.56.108; server_name www.yuijam.com; location / { proxy_pass http://127.0.0.1:3000; } }

这样就能将80端口映射到本地的3000端口上了。

负载均衡

起两个服务,一个监听3000,一个3001

const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { res.send('Hello World! 3000') }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
app.get('/', (req, res) => { res.send('Hello World! 3001') })

nginx.conf这样配置:

upstream myserver { server 127.0.0.1:3000; server 127.0.0.1:3001; } server { listen 80; server_name 192.168.56.108; location / { proxy_pass http://myserver; } }

测试的话可以直接去浏览器刷这个地址,正常来说,会是3000和3001交替显示,那就表示达到了负载均衡的作用了。

nginx分配服务器的策略有以下几种:

轮询(默认):每个请求按时间顺序逐一分配到不同的服务器,如果某个服务挂掉了,就自动剔除掉。

weight:权重默认为1,越高会分配的客户端也会越多。

upstream myserver { server 127.0.0.1:3000 weight=2; server 127.0.0.1:3001 weight=1; }

这样设置后,就会先丢两个请求给3000,然后再丢一个给3001。

ip_hash: 每个请求按ip的hash结果来分配,让每个访客固定访问一个服务器,这样有个好处是可以解决session共享的问题。(如果session是存在数据库中的,应该是不用ip_hash也是没有问题的)

upstream myserver { ip_hash; server 127.0.0.1:3000; server 127.0.0.1:3001; }

这样设置后再怎么刷新浏览器都只会显示一个数了。

fair:按服务器的响应时间来分配请求,响应时间短的优先分配。

upstream myserver { fair; server 127.0.0.1:3000; server 127.0.0.1:3001; }

按理说这样配置就可以了,但是我这里会报错说

nginx: [emerg] unknown directive "fair" in /etc/nginx/nginx.conf:

查了下貌似要从https://github.com/gnosek/nginx-upstream-fair?spm=a2c4e.11153940.blogcont73621.10.752155b9TL5eQp 这里用通过源码编译进去?这有点麻烦了就没搞了。

动静分离

从实现来说大概分两种,一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,这也是目前主流的一种做法。另一种是动态资源和静态资源放一起,通过nginx来分开。

高可用

毕竟不能保证nginx自己不挂,所以如果nginx挂了怎么办呢?做法是准备一台备份服务器,再利用一个叫keepalived工具,两台服务器用同样的配置,一个设置会master一个设置为backup,master的服务挂了,会自动切换到backup。

keepalived 要配置一个脚本,他会通过这个脚本去检测主服务器有没有挂掉。

原理

有一个master,有多个worker,worker采用的是争抢的机制,而不是轮询的机制。

多个worker有几个好处。

首先,在用nginx -s reload重启的时候,如果worker1现在有在处理请求,那就继续处理,等到处理完再重新加载配置,然后没有在处理请求的worker来重新加载nginx配置。

其次,每个worker都是一个独立的进程,这样互相之间不会进行影响,一个进程退出后,其他进程还可以继续工作,服务不会中断,master会马上启动新的worker进程。

那么需要启动多少个worker?

nginx和redis类似,都采用了io多路复用机制,每个worker都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是上千万个请求也不在话下,每个worker的线程可以把一个cpu的性能发挥到极致,所以一般来说worker数和cpu数相等即可。设少了会浪费cpu,设多了会造成cpu频繁切换上下文带来开销。比如一个4核cpu就设置4个worker。

如果nginx有一个master,4个worker,每个worker支持的最大连接数是1024,那么支持的最大并发数是多少?

首先要知道什么叫连接数,比方说一个请求,一来一回,就算两个连接数,所以如果做了动静分离之类的,只访问静态资源的话,那请求就到worker这里为止了,一来一回,一共两个。而如果要访问动态资源的话,那就得加上worker到真实服务器上的一来一回两个连接。所以一个worker支持的最大并发其实就是 1024/2或者1024/4,而这里有四个worker,因此总的并发数是:4*1024 / 2或者4*1024 / 4