💠
💠 2024-09-20 17:30:23
Nginx
Official Site | Official Doc
Tengine
nginx-tutorial
Nginx的安装
命令安装
- 安装
sudo apt install nginx
- 启动服务
sudo nginx
- 或者
sudo /etc/init.d/nginx start
- 或者 systemd 方式
systemctl start nginx
- 关闭
sudo nginx -s quit
- 或者
sudo /etc/init.d/nginx stop
- 或者 systemd 方式
systemctl stop nginx
编译安装
不建议使用这种方式进行安装,很容易出现兼容问题
- 下载 nginx,pcre,zlib,openssl 的压缩包
- 进入解压根目录(按实际情况配置)
配置各个包
1
2
3
4
5
6
7
8
|
./configure --sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-pcre=/home/kuang/pcre-8.20 \
--with-openssl=/home/kuang/openssl \
--with-zlib=/home/kuang/zlib-1.2.11
|
Docker安装
nginx hub 官方镜像
命令参数
-s signal
- stop 停止
- quit 退出
- reopen 重新打开
- reload 重载配置(修改配置文件常使用)
-t
测试配置文件
可视化管理工具
nginxWebUI
nginx-proxy-manager
0xJacky/nginx-ui: Yet another WebUI for Nginxgo+js
内置变量
Official Doc | Nginx 内置变量
$remote_addr
客户端地址
$remote_port
客户端端口
配置使用
Official Doc
知乎专栏
nginx基本配置 | ngrok nginx docker本地搭建服务器
nginx 配置文件的语法是自己独有的语法, 比较像 shell, 里面有用到正则, 变量等概念
- 读取自定义目录配置:
- nginx.conf 中 http 块内添加
include /etc/nginx/conf.d/*.conf;
- 错误页面重定向
error_page 404 /404.html;
也可以填完整URL
Nginx反向代理,当后端为Https时的一些细节和原理
nginx提供Http服务,但是反向代理了HTTPS地址时 需要注意证书的一致性问题
静态资源Web服务器
参考 nginx配置静态文件服务器
1
2
3
4
5
6
7
8
9
10
11
|
server {
client_max_body_size 4G;
listen 80;
# server_name static.me; # 如果需要使用域名 则需要在hosts文件配置
root /home/mini/Sync;
location / {
autoindex on; # 显示索引
autoindex_exact_size on; # 显示大小
autoindex_localtime on; # 显示时间
}
}
|
- 若出现403错误, 将 /etc/nginx/nginx.conf 中第一行的
user nginx;
改成可访问静态文件目录的用户即可
配置为文本文件类型
即 text/plain; 类型。例: 浏览器直接查看 code 目录下所有源代码
1
2
3
4
5
6
|
location /code/ {
# All files in it
location ~* {
add_header Content-Type text/plain;
}
}
|
如果有编码问题可配置成 add_header Content-Type 'text/plain;charset=UTF-8';
location ~* /.*\.(py|md|sql)${}
反向代理多个服务
配置反向代理
- nginx 的 80 端口下:
/
路径的请求转发到9991端口 /myth
转发到7898端口
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
|
upstream one {
server 127.0.0.1:9991;
}
upstream two {
server 127.0.0.1:7898;
}
server {
listen 80;
server_name 1.1.1.1;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxt true;
proxy_pass http://one;
proxy_redirect off;
}
location /myth{
proxy_pass http://two;
proxy_redirect off;
}
}
|
静态资源+反代理后端
Nginx反向代理解决跨域问题 | nginx简易使用教程,使用nginx解决跨域问题
配置统一出口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
server {
client_max_body_size 4G;
listen 80; # listen for ipv4; this line is default and implied
server_name static.me;
location / {
root /data/static;
# proxy_pass http://127.0.0.1:8889/; 如果静态资源在别的端口上,这样配置也可以
}
location /api/ {
# add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://127.0.0.1:8889/; # 去除请求的 api 路径,并访问后端
# proxy_pass http://127.0.0.1:8889; 这种方式不会去除 /api/
}
location /api/a-service {
proxy_pass http://127.0.0.1:8889/a-service; # 移除 /api/ 路径,保留a-service (api路径下多个服务时使用此类型配置)
}
}
|
- 将静态文件交由Nginx进行处理, 后台的服务统一用一个前缀和前台进行区分, 然后将服务端的真实host和ip或者域名配置进来
- 这样在于前端看来就是访问 static.me/api 而已, 实际上访问的是 127.0.0.1:8889/api
注意,原先使用nginx反向代理tomcat,尝试配置后端为一个本地dns解析的域名。然后发现这是无法生效的,所以应该使用真实IP或公网域名
前后端分离时避免跨域
在需要被跨域访问的服务端,添加如下配置
1
2
3
|
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
|
配置https
nginx搭建https服务 | nginx http/2
自签发证书
配置HTTPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
upstream one {
server 127.0.0.1:8888;
}
server {
listen 443;
server_name web.me;
# 主要就是添加了这一块
ssl on;
ssl_certificate /data/https/server.crt;
ssl_certificate_key /data/https/server.key;
# http 转向 https
return 302 https://$host$request_uri;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxt true;
proxy_pass https://one;
proxy_redirect off;
}
}
|
通过 certbot 配置 HTTPS
免费的网站, 并且现在支持泛域名了参考博客 | 参考博客
Nginx反向代理https
1
2
3
4
|
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto #进行安装 但是过程中会有一些设置,
./certbot-auto certonly --email xxx@xxx --nginx -d xxx.domain # 生成 xxx.domain 证书
|
SSL 接收到一个超出最大准许长度的记录 要在端口后加上SSL nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
upstream one {
server 127.0.0.1:8080;
}
server{
listen 443 ssl;
server_name xxx.domain
access_log /data/log/https.log;
# ssl配置
ssl on;
ssl_certificate /etc/letsencrypt/live/xxx.domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.domain/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/xxx.domain/chain.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
location / {
proxy_pass https://one;
}
}
|
配置Websocket反向代理
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
|
# 配置连接的配置信息
map $http_upgrade $connection_upgrade{
default upgrade;
'' close;
}
upstream back_end {
server 127.0.0.1:8888;
}
server {
listen 80;
server_name 127.0.0.1;
location / {
# 设置转发真实ip
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Nginx-Proxt true;
# 设置接收到的请求类型
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://back_end;
# 默认是 1.0 不支持 keepAlive
proxy_http_version 1.1;
proxy_redirect off;
proxy_read_timeout 300s;
}
}
|
绕过Grafana,免密登录,需要预先生成key
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
|
map $http_upgrade $connection_upgrade{
default upgrade;
'' close;
}
# http://grafana-user.test/d/spring_boot_21/shang-shu-tai-jian-kong-mian-ban?orgId=1
server {
listen 80;
server_name grafana-user.test;
location / {
proxy_pass http://192.168.1.1:9091/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
proxy_set_header Authorization "Bearer xxxxx";
# add_header X-Frame-Options SAMEORIGIN;
proxy_hide_header X-Frame-Options;
}
location /api/live/ws {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Nginx-Proxt true;
proxy_set_header Authorization "Bearer cccc";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_redirect off;
proxy_read_timeout 300s;
proxy_pass http://192.168.1.1:9091;
}
}
|
转发代理
例如 aaa.com 需要VPN等方式才能访问,Nginx所在的主机能访问,就可以这么配置,然后配置DNS将 aaa.com 解析到Nginx的主机上,就可以实现其他客户机不安装VPN 直接访问 aaa.com
1
2
3
4
5
6
7
8
9
10
11
|
server {
server_name aaa.com;
listen 80;
location / {
proxy_pass http://aaa.com;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
|
防盗链
gzip
nginx 启用 gzip压缩
1
2
3
4
5
|
gzip on;
gzip_comp_level 4; # 缺省值
gzip_buffers 4 16k;
gzip_http_version 1.1; # 缺省值
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
负载均衡
Nginx 反向代理 负载均衡 虚拟主机配置
分为四层和七层:
- 在四层只依据ip的报文转发(修改进入时目的ip
从nginx改成upstream的IP
,修改返回时发送ip)
- 在七层依据数据内容做转发,例如按http请求后缀做转发 *.jpg 到A服务器 *.jsp到B服务器
负载均衡策略
Doc: Http Load Balancer
- Round Robin:
- 默认方式,对所有backend无差别按序轮询, 如果backend宕机会自动移除掉
- Weight:
- 对所有backend按权重进行轮询,权重越高分发到的请求就越多,默认值为1。适合硬件差别比较大的多个节点
1
2
3
4
5
6
7
|
#动态服务器组
upstream dynamic_server {
server localhost:8080 weight=2;
server localhost:8081;
server localhost:8082 backup;
server localhost:8083 max_fails=3 fail_timeout=20s;
}
|
- Least Connections(least_conn):
- 依据每个backend当前活跃连接数,将请求分发到连接数最少的backend上,此时会考虑backend的weight权重比例
- upstream配置块中在首行添加
least_conn;
即可
- IP Hash(ip_hash): 对请求来源IP地址计算hash值,通过某种映射(例如取余,详细可查看ip_hash相关源码)分发至对应backend
- upstream配置块中在首行添加
ip_hash;
即可
- Generic Hash(hash): 用户自定义资源(例如URL)计算hash完成分发,可选consistent关键字支持
一致性hash
特性
Q & A
- 如果负载均衡了A B两个节点,请求进入了A节点后,立马移除了对A节点的负载均衡,该请求是否能正常执行
- 能正常执行,假如此时请求A失败,例如A节点宕机, 请求还会转移至B节点(failover)
- 如果负载均衡了A B两个节点, A节点宕机了,后续请求是否还会分发到A节点
Nginx Plus
对标 F5 BIG-IP
5-reasons-switch-f5-big-ip-to-nginx-plus
Keepalived
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
参考: keepalived实现服务高可用
同类应用
Caddy
official website
具有丰富的插件支持, 配置简洁, 自动配置 HTTPS证书,相较于nginx资源消耗更多 吞吐量低一些
参考: 使用 Caddy 替代 Nginx,全站升级 https,配置更加简单
Squid
Official
Varnish
HAProxy
Official 企业级工具
nuster
Github基于 HAProxy
Tips
- 文件上传报错 413
- http{} 中添加
client_max_body_size 80M;
- request_time 比实际时间长 Nginx的延迟关闭
lingering_timeout
access 日志中 upstream 408状态码 本身返回的502 实际上upstream没收到请求
Random HTTP 408 on POST requests and no body is transferred