Nginx 是一款轻量级的 Web 服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。
在使用中,经常将其用到以下几个方面:
Ubuntu 配置 Nginx
安装 nginx:
1
| sudo apt-get install nginx
|
重启 nginx 前,需要测试 nginx 配置是否正确:
重新加载 nginx:
不特殊指定,默认加载/etc/conf/nginx.conf
的配置。
Nginx 默认配置解读
对于nginx version: nginx/1.14.0 (Ubuntu)
版本的 nginx,默认配置如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf;
events { worker_connections 768; }
http {
sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048;
include /etc/nginx/mime.types; default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
|
几个重要的点:
- user:代表执行 nginx 的用户,可以换成权限更高的用户
- http/mail:代表 http/邮箱服务的配置
include /etc/nginx/conf.d/*.conf
:加载 conf.d 下的所有以.conf 结尾的配置文件
在配置的时候,一般都将对应的配置文件放在/etc/nginx/conf.d/
。
代理 Http(s)服务
xin-tan.com 是 vuepress 构建的,为了提供给用户更好的浏览体验,用 nginx 做服务器,要求如下:
- 强制 https:监听 80 port,请求转发给 443 port(换协议)
- 配置 SSL 证书:配置私钥文件和证书文件(一般云厂商申请的 ssl 证书,都有对应说明)
- 指定 locaiton:和 SPA 应用一致,路由交给前端 router 管理
代码:https://github.com/dongyuanxin/blog/blob/master/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| server { listen 80; server_name xin-tan.com; return 301 https://$server_name$request_uri;
location / { root /home/ubuntu/data/blog-static; index index.html index.htm index.nginx-debian.html; try_files $uri $uri/ =404; } }
server { listen 443 ssl; server_name xin-tan.com; ssl_certificate /tmp/1_bundle.crt; ssl_certificate_key /tmp/2.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on;
location / { root /home/ubuntu/data/blog-static; index index.html index.htm index.nginx-debian.html; try_files $uri $uri/ =404; } }
|
实现负载均衡
nginx 的优势之一是:可以代理多个服务器。
通俗来说,按照某些规则,将请求分配给对应的服务器。从而实现某些方面(请求量、服务器负载等等)的负载均衡。
基本配置
假设针对 a.com 域名的 http 服务,提供负载均衡。并且有多个后端服务,分别运行在本地服务(也可以是同一 vpc 下、或者远程服务器)的不同端口。
假设这些后端服务都是相同的逻辑,并且是无状态服务。
那么首先需要配置反向代理:
1 2 3 4 5 6 7 8
| server { listen 80; server_name 193.112.241.232;
location / { proxy_pass <http://myservers>; } }
|
这里的 myservers 是 upstream 的 name(往下看就明白了)。
负载均衡的各种策略(upstream)
1、普通轮询
1 2 3 4
| upstream myservers { server 127.0.0.1:4445; server 127.0.0.1:4446; }
|
2、按权重轮询
1 2 3 4
| upstream myservers { server 127.0.0.1:4445 weight=10; server 127.0.0.1:4446 weight=1; }
|
3、ip hash:相同的 ip 负载到同一个 upstream server
1 2 3 4 5
| upstream myservers{ ip_hash; server 127.0.0.1:4445 weight=1; server 127.0.0.1:4446 weight=2; }
|
4、一致性 hash
1 2 3 4 5
| upstream myservers{ hash $custom_key consistent; server 127.0.0.1:4445 weight=2; server 127.0.0.1:4446 weight=1; }
|
5、自定义 hash 规则:可以使用 Nginx 变量
1 2 3 4 5
| upstream myservers{ hash $uri; server 127.0.0.1:4445 server 127.0.0.1:4446; }
|
配置 HTTP 长连接
为什么要用长连接?
- 不需要每次 tcp 请求都经历握手和挥手的过程
- 提高响应请求响应时间,减少 time-wait 状态的 Socket
Nginx 配置思路
先来看请求链路过程是:C 端请求 => Nginx 代理 => 上游的 Server。
所以,Nginx 要做到两头都是长连接:
- C 端请求 => Nginx 代理:nginx 扮演 server
- Nginx 代理 => 上游的 Server:naginx 扮演 client
思路和 nginx 在不同过程中的“角色”清除后,剩下就是配置了。
Nginx 配置
C 端到 Nginx
默认配置文件中已有:keepalive_timeout。为 0,禁用长连接;不为 0,代表长连接超时关闭时间。
除此之外,还有常用的:keepalive_requests。默认为 100,为一个长连接能接受的最大请求数。
Nginx 到上游 Server
反向代理配置中,需要支持 keep-alive:
1 2 3 4 5 6 7 8 9 10 11
| server { listen 80; server_name 193.112.241.232;
location / { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_pass <http://myservers>; } }
|
到上游 Server 的配置:
1 2 3 4 5 6
| upstream myservers { server 127.0.0.1:4445; server 127.0.0.1:4446; keepalive 100; }
|
服务健康检查
为什么要心跳检查?
目的是为了 Server 的健康检查。因为 nginx 支持 4 层和 7 层代理,所以支持 tcp 心跳检查和 http 心跳检查。
nginx 配置
http 心跳检查:
1 2 3 4 5 6 7 8 9
| upstream myservers { server 127.0.0.1:4445; server 127.0.0.1:4446; # 5s检查一次。检查成功1次,标记server存活;失败5次,标记挂掉。 check interval=5000 rise=1 fail=5 timeout=5000 type=http; # http 心跳包 check_http_send "HEAD /status HTTP/1.0\\r\\n\\r\\n"; check_http_expect_alive http_2xx http_3xx; }
|
tcp 检查:
1 2 3 4 5
| upstream myservers { server 127.0.0.1:4445 weight=1; server 127.0.0.1:4446 weight=2; check interval=5000 rise=1 fail=5 timeout=5000 type=tcp; }
|
参考资料