nginx
nginx
安装Nginx
docker安装
docker run -d --restart=always \--net host \--name nginx \-v ./nginx.conf:/etc/nginx/nginx.conf \-v ./log:/var/log/nginx \ # log-v ./cert:/etc/nginx/cert \ # SSL证书文件, 没有可以去掉-v ./html:/usr/share/nginx/html \nginx:1.24.0 net=host是因为懒得配端口了, 这样好一些
shell启动不够优雅, 建议使用docker compose
version: '3.8'services: nginx: image: nginx:1.24.0 container_name: nginx restart: always network_mode: host volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./logs:/var/log/nginx:rw - ./cert:/etc/nginx/cert:ro - ./html:/usr/share/nginx/html:ro # 一些html或者error.json 注意:
- network_mode是linux专用, docker desktop没用
- host网络模式不是最佳实践, 如果有确定的后端编排还是一起编排比较合适
apt下载安装启动(不建议)
为了不找不自在, 还是用docker部署吧!
不建议使用apt安装, 因为会缺少很多模块, 而且版本较老
sudo apt install nginxservice nginx start # 启动nginx 然后打开80端口查看情况, 如果出现nginx主页说明成功
从源码编译安装并配置SSL模块
参考: https://developer.aliyun.com/article/766958
先安装好nginx
- 去官网下载源码: https://nginx.org/en/download.html
建议下载Stable version
- 解压安装包
tar -zxvf <包的名字>- 安装SSL模块
到nginx目录下, 输入
./configure --prefix=/etc/nginx --with-http_ssl_module/ect/nginx是你的nginx安装位置, 也可以是/usr/local/nginx
如果用apt安装的话, 为/etc/nginx
如果出现 the HTTP rewrite module requires the PCRE library, 则安装:
apt-get install libpcre3 libpcre3-dev 上面的命令是配置ssl模块
- 用make命令编译, 注意不要使用make install, 会重新安装nginx, 当然, 想重新安装也可以输入
make这里面可能会出现errors, 不用管
如果出现了缺少包依赖的错误, 直接安装即可, 这里提供一些可能出现的:
sudo apt-get install libpcre3 libpcre3-dev # 缺少pcresudo apt-get install openssl libssl-dev # 缺少opensslsudo apt-get install zlib1g-dev # 缺少zlib-
将obj的文件复制到nginx上覆盖原来的文件
-
查看是否安装成功
nginx -V如果出现**—with-http_ssl_module**则成功
nginx文件树
nginx配置文件在/etc/nginx中
nginx启动时加载nginx.conf
其中有两行:
include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;意思是引用了这两个目录下的所有文件
其中, sites-enabled 是 sites-available的链接, 把想启动的配置放在这里即可, 同理当想临时关闭某个站点时, 把sites-enabled对应的链接删去即可
当然,也可以在conf.d中放配置文件, 不过不建议
注意: 由于 sites-enabled 有默认的nginx界面,所有访问均会导向默认界面 所以要使我们的配置生效, 需要把sites-enabled的链接删去
nginx架构
配置模板开箱即用
注意, 需要使用上面的docker-compose.yaml启动, 目录下放这个配置文件(nginx.conf)
user nginx;worker_processes auto;
error_log /var/log/nginx/error.log notice; # notice级别pid /var/run/nginx.pid; # nginx进程id
events { worker_connections 1024;}
http { include /etc/nginx/mime.types; default_type application/octet-stream;
# --------------------日志 配置--------------------- # 格式: # remote_addr - remote_user [time_local] "request" status body_bytes_sent "http_referer" "http_user_agent" "http_x_forwarded_for" # 远程地址 用户名 时间 请求 状态 响应大小 来源网址 用户UA 代理地址
# log_format debug '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; log_format debug ' $remote_user [$time_local] $http_x_Forwarded_for $remote_addr $request ' '$http_x_forwarded_for ' '$upstream_addr ' 'ups_resp_time: $upstream_response_time ' 'request_time: $request_time'; access_log /var/log/nginx/access.log debug; # debug级别
# --------------------网络 配置--------------------- sendfile on; # 零拷贝传输(内核和用户) #tcp_nopush on; # 优化网络传输,减少网络报文, 把多个小包合并成一个大包发送 keepalive_timeout 65; # 保持长连接的时间, 如果有客户端在65s内没有任何请求, 则关闭连接
# --------------------压缩 配置--------------------- # 开启/关闭 压缩机制 gzip on; # 根据文件类型选择 是否开启压缩机制 gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/jpg image/gif image/png application/json; # 设置压缩级别,越高资源消耗越大越耗时,但压缩效果越好 gzip_comp_level 5; # 设置是否携带Vary:Accept-Encoding 的响应头 gzip_vary on; # 处理压缩请求的 缓冲区数量和大小 gzip_buffers 32 64k; # 对于不支持压缩功能的客户端请求 不开启压缩机制 gzip_disable "MSIE [1-6]\."; # 比如低版本的IE浏览器不支持压缩 # 设置压缩功能所支持的HTTP最低版本 gzip_http_version 1.1; # 设置触发压缩的最小阈值 gzip_min_length 2k; # off/any/expired/no-cache/no-store/private/no_last_modified/no_etag/auth 根据不同配置对后端服务器的响应结果进行压缩 gzip_proxied any;
# --------------------缓存 配置--------------------- # 指定缓存存放目录为/usr/local/nginx/test/nginx_cache_storage,并设置缓存名称为mycache,大小为64m, 1天未被访问过的缓存将自动清除,磁盘中缓存的最大容量为1gb proxy_cache_path /usr/local/nginx/test/nginx_cache_storage levels=1:2 keys_zone=mycache:64m inactive=1d max_size=1g;
# --------------------限流 配置--------------------- # 对请求速率限流 #limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=5r/s; # 对请求连接数限流 limit_conn_zone $binary_remote_addr zone=myConnLimit:10m;
# --------------------重定向 配置--------------------- server { listen 80; charset utf-8; server_name www.example.com example.com; return 301 https://$server_name$request_uri; # 301永久重定向到https }
# --------------------负载均衡 配置--------------------- # upstream backendserver { # server 172.30.128.64:8081 fail_timeout=60s max_fails=3; # 60秒内 如果请求某一个应用失败3次,则认为该应用宕机 时间到后再有请求进来继续尝试连接宕机应用且仅尝试 1 次,如果还是失败,则继续等待 60 秒...以此循环,直到恢复 # server 172.30.128.64:8082; # server 172.30.128.64:8083 backup; # 设置8083位备机 # } upstream backendserver { server 127.0.0.1:9000; }
# --------------------HTTPS 配置--------------------- server { #SSL 默认访问端口号为 443 listen 443 ssl; #填写绑定证书的域名 server_name www.example.com example.com; #请填写证书文件的相对路径或绝对路径 ssl_certificate /etc/nginx/cert/xxx.pem; #请填写私钥文件的相对路径或绝对路径 ssl_certificate_key /etc/nginx/cert/xxx.key; #停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥 ssl_session_timeout 5m; #服务器支持的TLS版本 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; #开启由服务器决定采用的密码套件 ssl_prefer_server_ciphers on;
# # 指定 username 参数中只要有字母 就不走nginx缓存 # if ($arg_username ~ [a-z]) { # set $cache_name "no cache"; # } # # 前端页面资源 # location /page { # alias '/usr/local/nginx/test/static/'; # index index_page.html;
# allow all; # } # # 后端服务 # location /interface { # proxy_pass http://backendserver/;
# # 指定哪些错误状态才执行 重试 # proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_404;
# # 使用名为 mycache 的缓存空间 # proxy_cache mycache; # # 对于200 206 状态码的数据缓存2分钟 # proxy_cache_valid 200 206 1m; # # 定义生成缓存键的规则(请求的url+参数作为缓存key) # proxy_cache_key $host$uri$is_args$args; # # 资源至少被重复访问2次后再加入缓存 # proxy_cache_min_uses 3; # # 出现重复请求时,只让其中一个去后端读数据,其他的从缓存中读取 # proxy_cache_lock on; # # 上面的锁 超时时间为4s,超过4s未获取数据,其他请求直接去后端 # proxy_cache_lock_timeout 4s; # # 对于请求参数中有字母的 不走nginx缓存 # proxy_no_cache $cache_name; # 判断该变量是否有值,如果有值则不进行缓存,没有值则进行缓存 # # 在响应头中添加一个缓存是否命中的状态(便于调试) # add_header Cache-status $upstream_cache_status;
# limit_conn myConnLimit 12;
# # limit_req zone=myRateLimit burst=5 nodelay; # # limit_req_status 520; # # limit_req_log_level info; # }
# # 后端服务 # location /interface2 { # proxy_pass http://backendserver; # # 使用名为 mycache 的缓存空间 # proxy_cache mycache; # # 对于200 206 状态码的数据缓存2分钟 # proxy_cache_valid 200 206 1m; # # 定义生成缓存键的规则(请求的url+参数作为缓存key) # proxy_cache_key $host$uri$is_args$args; # # 资源至少被重复访问2次后再加入缓存 # proxy_cache_min_uses 3; # # 出现重复请求时,只让其中一个去后端读数据,其他的从缓存中读取 # proxy_cache_lock on; # # 上面的锁 超时时间为4s,超过4s未获取数据,其他请求直接去后端 # proxy_cache_lock_timeout 4s; # # 对于请求参数中有字母的 不走nginx缓存 # proxy_no_cache $cache_name; # 判断该变量是否有值,如果有值则不进行缓存,没有值则进行缓存 # # 在响应头中添加一个缓存是否命中的状态(便于调试) # add_header Cache-status $upstream_cache_status;
# limit_conn myConnLimit 12;
# # limit_req zone=myRateLimit burst=5 nodelay; # # limit_req_status 520; # # limit_req_log_level info; # }
}
# include /etc/nginx/conf.d/*.conf;}配置示例
修改错误返回值
有些时候希望返回的不是service unavailable, 希望返回某段json, 可以这样设置
/50x.json是返回的json内容, 也可以返回其他网页
server {...error_page 5xx /5xx.json;location = /5xx.json {root /usr/share/nginx/html;internal; # 保证这个路径只能内部请求}...}websocket配置
websocket比较特殊, 需要加入upgrade和connection
location /api/ws/ {proxy_redirect off;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_pass http://127.0.0.1:9000/api/ws/;}SSE配置
SSE配置需要去掉缓存, 不然SSE失效
location /api/sse {proxy_redirect off;proxy_pass http://127.0.0.1:9000/api/sse;proxy_buffering off; # 去掉缓存}请求速率限流
http{...# 对请求速率限流limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=5r/s;
server{ location /api { ... limit_req zone=myRateLimit burst=5 nodelay; limit_req_status 520; # 返回码 limit_req_log_level info; } }}-
$binary_remote_addr: 基于客户端IP做限流
zone=myRateLimit:10m 指myRateLimit作为内存区域, 大小10M(16万)IP地址
rate=5r/s 指相同IP每秒最多请求5次(200ms一个请求)
-
burst=5: 削峰, 如果峰值超过rate(比如说200ms来了两个), 则会用一个大小为burst的队列削峰, 然后慢慢根据rate速率处理, 多余的直接503
-
nodelay: 如果是nodelay, 则burst削峰会立即处理, 而不是每200ms取一个
nodelay立即处理, 那么nginx怎么控制并发? 是通过处理但不释放的方式控制. 后面的请求会阻塞
一般建议burst和nodelay一起用, 可以处理突发流量
请求连接数限流
http{# 针对ip 对请求连接数限流...limit_conn_zone $binary_remote_addr zone=myConnLimit:10m;...
server{ ... limit_conn myConnLimit 12; }}https/SSL
注意需要http_ssl_module
server {#SSL 默认访问端口号为 443listen 443 ssl;#填写绑定证书的域名server_name www.hzznb-xzll.xyz hzznb-xzll.xyz;#请填写证书文件的相对路径或绝对路径ssl_certificate 证书路径;#请填写私钥文件的相对路径或绝对路径ssl_certificate_key 私钥路径;#停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥ssl_session_timeout 5m;#服务器支持的TLS版本ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#开启由服务器决定采用的密码套件ssl_prefer_server_ciphers on;}ssl_certificate: .pem或者/csr文件
ssl_certificate_key: 一般是.key文件
80重定向到443
server_name www.hzznb-xzll.xyz hzznb-xzll.xyz;# 重定向到目标地址return 301 https://$server_name$request_uri;压缩
http {# 开启/关闭 压缩机制gzip on;# 根据文件类型选择 是否开启压缩机制gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/jpg image/gif image/png application/json;# 设置压缩级别,一共9个级别 1-9 ,越高资源消耗越大 越耗时,但压缩效果越好,gzip_comp_level 5;# 设置是否携带Vary:Accept-Encoding 的响应头gzip_vary on;# 处理压缩请求的 缓冲区数量和大小gzip_buffers 32 64k;# 对于不支持压缩功能的客户端请求 不开启压缩机制gzip_disable "MSIE [1-6]\."; # 比如低版本的IE浏览器不支持压缩# 设置压缩功能所支持的HTTP最低版本gzip_http_version 1.1;# 设置触发压缩的最小阈值gzip_min_length 2k;# off/any/expired/no-cache/no-store/private/no_last_modified/no_etag/auth 根据不同配置对后端服务器的响应结果进行压缩gzip_proxied any;}负载均衡
配置热备
upstream mysvr {server 192.168.10.121:3333 max_fails=2 fail_timeout=2;server 192.168.10.122:3333 backup;}- max_fails: 允许请求失败的最大次数, 超过时返回proxy_next_upstream模块定义的错误
- fail_timeout: 经历了max_fails失败后暂停服务的时间
轮询(round-robin)
upstream mysvr {server 127.0.0.1:7878;server 192.168.10.121:3333;}- 请求会分别发送到两个服务器, A-B-A-B…
upstream mysvr {server 127.0.0.1:7878 weight=1;server 192.168.10.121:3333 weight=2;}- 给不同服务器设置权重, 上面会变成A-B-B-A-B-B…
ip_hash
upstream mysvr {server 127.0.0.1:7878;server 192.168.10.121:3333;ip_hash;}- 会让相同客户端请求相同的服务器, 实现session等的共享