对于前端开发人儿,nginx可谓是一件趁手的兵器。不管是本地环境,生产环境,都能用的上。
so,不必多说,说一下最近项目 生产环境的 nginx配置历程。
项目背景: Linux服务器,PC端网站应用一个,移动端 H5 页面若干。
思考:需要进行两部分考虑
- 1. 通用部分: 连接超时时间,gzip 等相关部分 只做简单介绍。
- 2. 虚拟主机配置(server 部分):https相关配置,PC应用 接口相关 配置,文件缓存策略,移动端 H5页面 相关配置
Part 1 通用部分
包括部分:
- 日志、sendfile等通用配置
- gzip 部分详解
在 nginx 基本设置与参数说明 一文中,有详细注释
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#开启gzip压缩
# gzip_static on;
gzip on;
gzip_proxied any;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6].";
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain text/css application/json font/ttf image/svg+xml image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,且6以上,提升很小了
gzip_comp_level 4;
# 设置压缩所需要的缓冲区大小
gzip_buffers 16 8k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.1;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
Part 2 虚拟主机配置(server 部分)
包含内容:
https 配置
默认 https 访问,即访问 http协议下该网址时,转到 https 该网址下
PC网站应用 接口相关,反向代理
h5页面访问配置
不同文件缓存策略
1. https 配置
ssl证书部分 (以阿里云举例)
1.首先在阿里云管理后台 搜索 SSL证书 进入SSL证书部分
2.根据自己需要可购买不同’的SSL证书 需要进行绑定域名操作
3.审核通过 可在 SSL证书 部分 看到购买的证书 点击下载即可
4.将证书放到服务器的某个目录下(建议在nginx文件夹内)
接下来就是 nginx 相关的配置
server {
# 监听443端口 http默认为80端口 https默认为 443端口
listen 443 ssl;
# 定义使用localhost:8080访问,若为线上地址 这里写域名 or 线上服务器 IP
server_name localhost:8080;
# 注意 1. key 与 文件类型对照清楚 2. 文件路径从 根目录 写起
ssl_certificate /usr/local/nginx/cert/toka.pem;
ssl_certificate_key /usr/local/nginx/cert/toka.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_tickets on;
2. 默认 https 访问
访问 http协议下该网址时,转到 https 该网址
有多种方式,这里采用 return 指令
当访问http协议的地址时,转到https协议的地址下
#设定虚拟主机配置
server {
listen 80;
server_name www.xxx.com;
return 301 https://www.xxx.com$request_uri;
}
server {
# 监听443端口 http默认为80端口 https默认为 443端口
listen 443 ssl;
...
3. PC网站应用 接口相关,反向代理
# 当在请求中匹配到 /api/ 时 会将请求转到代理的服务地址 即 proxy_pass 的地址
# 这里的配置规则 同前端项目中的proxyTable
# create-react-app package.json文件 proxy部分
# vue-cli vue.config.js文件 devServer 中的 proxy部分
location /api/ {
# 被代理的服务器的协议和地址(你要代理的服务地址)
proxy_pass http://www.xxx.com/api/;
proxy_redirect off;
# 加入这三个指令 服务端可以获得访客ip(可用于数据分析)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#允许客户端请求的最大单文件字节数
client_max_body_size 10m;
#缓冲区代理缓冲用户端请求的最大字节数,
client_body_buffer_size 128k;
#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 90;
#连接成功后,后端服务器响应时间(代理接收超时)
proxy_read_timeout 90;
#设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_buffers 4 32k;
#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;
#连接超时时间
keepalive_timeout 30;
}
4. h5页面访问配置
这里配置h5页面访问时 路途艰辛
先后体验了 html文件 404、html文件内引用的 css、js文件404 等错误
然后仔细阅读了文档 看到 nginx的location、root、alias指令用法和区别 这一篇时
root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
$server_name 为 你的服务器地址 或者 域名地址
所以下图的配置可以解释为 当访问到 $server_name/h5/xxx 路径时, 匹配到了 location ^~ /h5/ 停止去匹配其他规则
root路径为 usr/local/nginx/ , location路径为 /h5/
所以当访问 二级目录 h5 下面的资源时 实际路径是 usr/local/nginx/h5/xxx(root路径+location路径)
若为 windows 服务器,root路径为 C:\nginx\xx (双反斜杠)
5. 不同文件缓存策略
针对前端项目做的 文件缓存策略 仅供参考
location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
access_log off;
expires 1d; #1d (天) 1h(时) 1m(分) 1s(秒)
}
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
access_log off;
expires 30d;
}
location ~* ^.+\.(eot|ttf|otf|woff|svg)$ {
access_log off;
expires max;
}
location ~* ^.+\.(html|htm)$ {
expires 1h;
}
......
99.其他
涉及到的 微信、line三方登录 的反向代理配置
location /wechat/ {
proxy_pass https://api.weixin.qq.com/;
}
location /line/ {
# proxy_set_header Host api.line.me;
proxy_pass https://api.line.me/;
}
anyway,所有的配置如下
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#开启gzip压缩
# gzip_static on;
gzip on;
gzip_proxied any;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6].";
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain text/css application/json font/ttf image/svg+xml image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,且6以上,提升很小了
gzip_comp_level 4;
# 设置压缩所需要的缓冲区大小
gzip_buffers 16 8k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.1;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#设定虚拟主机配置
server {
listen 80;
server_name www.xxx.com;
return 301 https://www.xxx.com$request_uri;
}
server {
# 监听443端口 http默认为80端口 https默认为 443端口
listen 443 ssl;
# 定义使用localhost:8080访问,若为线上地址 这里写域名 or 线上服务器 IP
server_name localhost:8080;
# 注意 1. key 与 文件类型对照清楚 2. 文件路径从 根目录 写起
ssl_certificate /usr/local/nginx/cert/toka.pem;
ssl_certificate_key /usr/local/nginx/cert/toka.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_tickets on;
# error_page 497 "https://$host$uri?$args";
location / {
#定义服务器的 默认网站根目录位置(即你的项目文件放置目录)
root html;
#定义首页索引文件的名称
index index.html index.htm;
charset utf-8;
}
location ^~ /h5/ {
# alias app;
root /usr/local/nginx/;
index index.html index.htm;
}
# 当在请求中匹配到 /api/ 时 会将请求转到代理的服务地址 即 proxy_pass 的地址
# 这里的配置规则 同前端项目中的proxyTable
# create-react-app package.json文件 proxy部分
# vue-cli vue.config.js文件 devServer 中的 proxy部分
location /api/ {
# 被代理的服务器的协议和地址(你要代理的服务地址)
proxy_pass http://www.xxx.com/api/;
proxy_redirect off;
# 加入这三个指令 服务端可以获得访客ip(可用于数据分析)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#允许客户端请求的最大单文件字节数
client_max_body_size 10m;
#缓冲区代理缓冲用户端请求的最大字节数,
client_body_buffer_size 128k;
#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 90;
#连接成功后,后端服务器响应时间(代理接收超时)
proxy_read_timeout 90;
#设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_buffers 4 32k;
#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;
#连接超时时间
keepalive_timeout 30;
}
location /wechat/ {
proxy_pass https://api.weixin.qq.com/;
}
location /line/ {
# proxy_set_header Host api.line.me;
proxy_pass https://api.line.me/;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
access_log off;
expires 1d; #1d (天) 1h(时) 1m(分) 1s(秒)
}
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
access_log off;
expires 30d;
}
location ~* ^.+\.(eot|ttf|otf|woff|svg)$ {
access_log off;
expires max;
}
location ~* ^.+\.(html|htm)$ {
expires 1h;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}