Nginx 快速上手
apt install nginx / yum install nginx
nginx -v
nginx version: nginx/1.21.0
Nginx 操作常用命令
Nginx 的命令在控制台中输入
nginx -h就可以看到完整的命令
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/local/nginx/)
-e filename : set error log file (default: logs/error.log)
-c filename : set configuration file (default: conf/nginx.conf)
-g directives : set global directives out of configuration file
常用指令
nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启\
nginx -s reopen # 重启 Nginx\
nginx -s stop # 快速关闭\
nginx -s quit # 等待工作进程处理完成后关闭\
nginx -T # 查看当前 Nginx 最终的配置\
nginx -t -c <配置路径> # 检查配置是否有问题,如果已经在配置目录,则不需要-c
Nginx 配置
Nginx 的主配置文件是
/etc/nginx/nginx.conf,你可以使用cat -n nginx.conf来查看配置
nginx.conf 结构图
main # 全局配置,对全局生效\
├── events # 配置影响 Nginx 服务器或与用户的网络连接\
├── http # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置\
│ ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分\
│ ├── server # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块\
│ ├── server
│ │ ├── location # server 块可以包含多个 location 块,location 指令用于匹配 uri\
│ │ ├── location
│ │ └── ...
│ └── ...
└── ...
Nginx 语法规则
- 每条指令以
;分号结尾,指令与参数间以空格符号分隔; - 指令块以
{}大括号将多条指令组织在一起; include语句允许组合多个配置文件以提升可维护性;- 使用
#符号添加注释,提高可读性; - 使用
$符号使用变量;
Nginx初始配置
# Nginx 进程数,一般设置为和 CPU 核数一样
worker_processes 1;
# Nginx 的错误日志存放目录
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
# Nginx 服务启动时的 pid 存放位置
#pid logs/nginx.pid;
events {
# 每个进程允许最大并发数
worker_connections 1024;
}
http {
# 文件扩展名与类型映射表
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"';
# Nginx访问日志存放位置
#access_log logs/access.log main;
# 开启高效传输模式
sendfile on;
# 减少网络报文段的数量
#tcp_nopush on;
# 保持连接的时间,也叫超时时间,单位秒
#keepalive_timeout 0;
keepalive_timeout 65;
# gzip压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 3;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;
gzip_static on;
gzip_vary on;
gzip_buffers 2 4k;
gzip_http_version 1.1;
# 加载子配置项
include /usr/local/nginx/conf/conf.d/*.conf;
server {
# 配置监听的端口
listen 80;
# 配置的域名
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# 网站根目录
root html;
# 默认首页文件
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# 默认50x对应的访问页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# 禁止访问的ip地址,可以为all
# deny all;
# 允许访问的ip地址,可以为all
# allow all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
=精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;^~用于不含正则表达式的 uri 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;~表示用该符号后面的正则去匹配路径,区分大小写;~*表示用该符号后面的正则去匹配路径,不区分大小写。跟~优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;
全局变量
配置一个web服务器你需要了解的全局变量
| 变量名称 | 含义 |
|---|---|
| $host | 请求信息中的 Host,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口 |
| $request_method | 请求类型,如 GET、POST |
| $remote_addr | 客户端的 IP 地址 |
| $remote_port | 客户端的端口 |
| $args | 请求参数 |
| $arg_PARAMETER | GET 请求中变量名 PARAMETER 参数的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer... |
| $content_length | 请求头中的 Content-length 字段 |
| $http_user_agent | agent信息 |
| $http_cookie | cookie信息 |
| $server_protocol | 请求使用的协议,如 HTTP/1.0、HTTP/2.0 |
| $server_addr | 服务器地址 |
| $server_name | 服务器名称 |
| $server_port | 服务器端口 |
| $request_filename | 当前连接请求的文件路径,由root或alias指令与URI请求生成。 |
配置反向代理
vim /etc/nginx/nginx.conf
server {
listen 80;
server_name arc.com;
location / {
proxy_pass https://www.baidu.com;
}
}
改完保存退出,
nginx -s reload重新加载,进入默认网址,那么现在就直接跳转到 baidu 站了
反向代理一些常用的指令
proxy_set_header:在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息;proxy_connect_timeout:配置 Nginx 与后端代理服务器尝试建立连接的超时时间;proxy_read_timeout:配置 Nginx 向后端服务器组发出 read 请求后,等待相应的超时时间;proxy_send_timeout:配置 Nginx 向后端服务器组发出 write 请求后,等待相应的超时时间;proxy_redirect:用于修改后端服务器返回的响应头中的 Location 和 Refresh。
反向代理解决跨域
server {
listen 80;
server_name arc.com;
location / {
proxy_pass https://www.baidu.com;
}
}
这样就将对前一个域名
arc.com的请求全都代理到了https://www.baidu.com;,前端的请求都被我们用服务器代理到了后端地址下,绕过了跨域。
配置 header 解决跨域
server
{
listen 80;
server_name arc.com;
location /hello {
proxy_pass http://localhost:3000;
# 指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;
# 预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
# 带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
# 表示允许这个域跨域调用(客户端发送请求的域名和端口)
# $http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;
# 表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;
# OPTIONS预检命令,预检命令通过时才发送请求
# 检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}
}
}
gzip 压缩
gzip 是一种常用的网页压缩技术,传输的网页经过 gzip 压缩之后大小通常可以变为原来的一半甚至更小(官网原话),更小的网页体积也就意味着带宽的节约和传输速度的提升,特别是对于访问量巨大大型网站来说,每一个静态资源体积的减小,都会带来可观的流量与带宽的节省。
gzip on;
gzip_min_length 1k;
gzip_comp_level 3;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;
gzip_static on;
gzip_vary on;
gzip_buffers 2 4k;
gzip_http_version 1.1;
gzip_proxied on;
- gzip: 开启或关闭gzip压缩
- gzip_min_length:允许压缩的页面最小字节数,页面字节数从header头中的
Content-Length中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大; - gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
- gzip_types:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
- gzip_static:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该
.gz文件内容; - gzip_vary:用于在响应消息头中添加
Vary:Accept-Encoding,使代理服务器根据请求头中的Accept-Encoding识别是否启用 gzip 压缩; - gzip_buffers:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
- gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本;
- gzip_proxied:默认 off,nginx做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;
服务器文件2306491B,gzip压缩后浏览器得到599617B
Webpack 的 gzip 配置
webpack提供了compression-webpack-plugin插件来打包gzip
打包后
看到这里,大家可能会有个疑问,nginx提供了gzip压缩,webpack又提供了gzip压缩,是不是重复劳动了呢?实际上,如果全都是使用 Nginx 来压缩文件,会耗费服务器的计算资源,如果服务器的
gzip_comp_level配置的比较高,就更增加服务器的开销,相应增加客户端的请求时间,得不偿失。因此你可以开始gzip_static on;
配置负载均衡
http {
upstream myserver {
# ip_hash; # ip_hash 方式
# fair; # fair 方式
server 127.0.0.1:8081; # 负载均衡目的服务地址
server 127.0.0.1:8080;
server 127.0.0.1:8082 weight=10; # weight 方式,不写默认为 1
}
server {
location / {
proxy_pass http://myserver;
proxy_connect_timeout 10;
}
}
}
Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:
- 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
- weight,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;
- ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;
- fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;
一些常用技巧
图片防盗
server {
listen 80;
server_name arc.com;
# 图片防盗链
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked 192.168.0.2; # 只允许本机 IP 外链引用
if ($invalid_referer) {
return 403;
}
}
}
请求过滤
# 非指定请求全返回 403
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 403;
}
location / {
# IP访问限制(只允许IP是 192.168.0.2 机器访问)
allow 192.168.0.2;
deny all;
root html;
index index.html index.htm;
}
配置静态文件缓存
# 图片缓存时间设置
location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ {
expires 10d;
}
# 如果不希望缓存
expires -1;
单页面项目 history 路由配置
server {
listen 80;
server_name arc.com;
location / {
root /usr/share/nginx/html/dist; # vue 打包后的文件夹
index index.html index.htm;
try_files $uri $uri/ /index.html @rewrites;
expires -1; # 首页一般没有强制缓存
add_header Cache-Control no-cache;
}
# 接口转发,如果需要的话
#location ~ ^/api {
# proxy_pass http://www.baidu.com;
#}
location @rewrites {
rewrite ^(.+)$ /index.html break;
}
}