一、简介
Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,目前使用最多的就是负载均衡。Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 perl、php等。但是不支持 java。Java 程序只能通过与 tomcat 配合完成。Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 ,能经受高负载的考验。
二、Nginx 安装
2.1. 下载 Nginx
官网下载地址:https://nginx.org/en/download.html
注意:同时还需安装 openssl 和 zlib 组件。
2.2. 启动 Nginx
cd /usr/local/nginx/sbin/ # 根据实际安装目录
./nginx
三、基本使用
3.1. 常用命令
cd /usr/local/nginx/sbin/ # 根据实际安装目录
nginx -t # 检查语法
nginx # 启动
nginx -s reload # 重启
nginx -s stop # 关闭进程
nginx -s quit # 平滑关闭nginx
nginx -V # 查看nginx的安装状态
3.2. 简单代理
location / {
proxy_pass http://127.0.0.1:3000;
proxy_redirect off;
proxy_set_header Host $host;
}
3.3. 全局变量
变量 | 描述 |
$args | 这个变量等于请求行中的参数,同 $query_string |
$remote_port | 客户端的端口 |
$content_length | 请求头中的 Content-length 字段 |
$remote_user | 已经经过 Auth Basic Module 验证的用户名 |
$content_type | 请求头中的 Content-Type 字段 |
$request_filename | 当前请求的文件路径,由 root 或alias指令与URI请求生成 |
$document_root | 当前请求在 root 指令中指定的值 |
$scheme | HTTP方法(如http,https) |
$host | 请求主机头字段,否则为服务器名称 |
$hostname | 主机名 |
$http_user_agent | 客户端agent信息 |
$http_cookie | 客户端cookie信息 |
$server_protocol | 请求使用的协议,通常是HTTP/1.0或HTTP/1.1 |
$server_addr | 服务器地址,在完成一次系统调用后可以确定这个值 |
$server_name | 服务器名称 |
$server_port | 请求到达服务器的端口号 |
$limit_rate | 这个变量可以限制连接速率 |
$request_method | 客户端请求的动作,如 GET/POST |
$request_uri | 包含请求参数的原始URI,不包含主机名,如:/foo/bar.php?arg=baz |
$remote_addr | 客户端的IP地址 |
$uri | 不带请求参数的当前URI,$uri不包含主机名,如 /foo/bar.html |
$document_uri | 与 $uri 相同 |
$nginx_version | nginx 版本 |
详见:https://nginx.org/en/docs/varindex.html
3.4. 监听端口
server {
listen 80; # 标准 HTTP 协议
listen 443 ssl; # 标准 HTTPS 协议
listen 443 ssl http2; # 对于 http2
listen [::]:80; # 使用 IPv6 在 80 上收听
# 仅监听使用 IPv6
listen [::]:80 ipv6only=on;
}
3.5. 监听域名
server {
# 监听 example.com
server_name example.com;
# 监听多个域
server_name example.com www.example.com;
# 监听所有子域
server_name *.example.com;
# 监听所有顶级域
server_name example.*;
# 监听未指定的主机名(监听 IP 地址本身)
server_name "";
}
3.6. 负载均衡
upstream test {
server 127.0.0.1:83 weight=9; # 权重
server 127.0.0.1:83 weight=1; # 权重
# 失败超时时间
server 127.0.0.1:83 max_fails=3;
server 127.0.0.1:83 weight=3 down;
}
server 可选参数:
- weight:访问权重数值越高,收到请求越多
- fail_timeout:指定的时间内必须提供响应
- max_fails:尝试失败服务器连接的最大次数
- down:标记一个服务器不再接受任何请求
- backup:有服务器宕机,标记的机器接收请求
按访问url的hash结果来分配请求:
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
响应时间短的优先分配:
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
按访问IP的hash结果来分配请求:
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
3.7. 子文件夹中的代理
location /folder/ { # / 很重要!
proxy_pass http://127.0.0.1:3000/; # / 很重要!
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;
}
3.8. 静态资源
server {
listen 80;
server_name example.com;
root /path/to/website;
# root /www/data/ 示例,如果里面没有'root',它将寻找 /www/data/index.html
location / {
}
location /images/ { # 如果里面没有“root”,它将寻找 /www/data/images/index.html
}
location /videos/ { # 由于里面有“root”,它会寻找 /www/media/videos/index.html
root /www/media;
}
}
3.9. HTTPS 协议
server {
listen 443 ssl http2;
server_name example.com;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/fullchain.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
add_header Strict-Transport-Security max-age=15768000;
}
3.10. 反向代理
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://0.0.0.0:3000;
# 其中 0.0.0.0:3000 是绑定在
# 0.0.0.0端口3000 列表上的 Node.js 服务器
}
}
upstream:
upstream node_js {
server 0.0.0.0:3000;
# 其中 0.0.0.0:3000 是绑定在
# 0.0.0.0端口3000 列表上的 Node.js 服务器
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_js;
}
}
支持 WebSockets 的应用程序:
upstream node_js {
server 0.0.0.0:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_js;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
3.11. 重定向(301永久)
将 www.example.com 重定向到 example.com:
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
3.12. 重定向(302临时)
server {
listen 80;
server_name mydomain.com;
return 302 http://otherdomain.com;
}
3.13. 将 http 重定向到 https
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
3.14. HTTP 请求端真实的IP
location / {
proxy_set_header X-Forwarded-For $remote_addr;
}
3.15. 重定向参数
- permanent:永久性重定向。日志中的状态码为 301。
- redirect:临时重定向。日志中的状态码为 302。
四、示例
4.1. websocket 的代理 keepalive
upstream backend {
server 127.0.0.1:3000;
keepalive 5;
}
# HTTP Server
server {
server_name my_hostname.com;
error_log /var/log/nginx/mynginx.access.log;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
4.2. Apache 的反向代理
server {
server_name domain.tld;
access_log /log/domain.tld.access.log;
error_log /log/domain.tld.error.log;
root /var/www/domain.tld/htdocs;
# 将请求传递给 Apache 后端
location / {
proxy_pass http://backend;
}
# 使用后备处理静态文件
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|zip|webm|mp3|aac|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp)$ {
add_header "Access-Control-Allow-Origin" "*";
access_log off;
log_not_found off;
expires max;
try_files $uri @fallback;
}
# 如果找不到文件,则回退以将请求传递给 Apache
location @fallback {
proxy_pass http://backend;
}
}
4.3. Gitlab 的反向代理
server {
#侦听的80端口
listen 80;
server_name git.example.cn;
location / {
proxy_pass http://localhost:3000;
# 以下是一些反向代理的配置可删除
proxy_redirect off;
# 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header Host $host;
client_max_body_size 10m; # 允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; # 缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 300; # nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 300; # 后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 300; # 连接成功后,后端服务器响应时间(代理接收超时)
# 设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
# proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_buffers 4 32k;
# 高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
}
}
4.4. 重定向整个网站
server {
server_name old-site.com;
return 301 $scheme://new-site.com$request_uri;
}
4.5. 重定向单页
server {
location = /oldpage.html {
return 301 http://example.org/newpage.html;
}
}
4.6. 重定向整个子路径
location /old-site {
rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;
}
4.7. 负载均衡
upstream example {
ip_hash;
# upstream的负载均衡,weight是权重,可以根据机器配置定义权重。
# weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.10.11:8081 ;
server 127.0.0.1:82 weight=3;
server 127.0.0.1:83 weight=3 down;
server 127.0.0.1:84 weight=3; max_fails=3 fail_timeout=20s;
server 127.0.0.1:85 weight=4;;
keepalive 32;
}
server {
#侦听的80端口
listen 80;
server_name git.example.cn;
location / {
# 在这里设置一个代理,和 upstream 的名字一样
proxy_pass http://example;
}
}
4.8. 内容缓存
允许浏览器基本上永久地缓存静态内容:
location /static {
root /data;
expires max;
}
如果要求浏览器永远不会缓存响应,请使用 -1:
location = /mynginx.png {
mynginx_png;
expires -1;
}
4.9. 跨域问题
server {
listen 80;
server_name api.xxx.com;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,HEAD';
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
4.10. 代理转发
upstream server-api {
# api 代理服务地址
server 127.0.0.1:3110;
}
upstream server-resource {
# 静态资源 代理服务地址
server 127.0.0.1:3120;
}
server {
listen 3111;
server_name localhost; # 这里指定域名
root /home/www/server-statics;
# 匹配 api 路由的反向代理到API服务
location ^~/api/ {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-api;
}
# 假设这里验证码也在API服务中
location ^~/captcha {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-api;
}
# 假设你的图片资源全部在另外一个服务上面
location ^~/img/ {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://server-resource;
}
# 路由在前端,后端没有真实路由,
# 路由不存在的 404 状态的页面返回 /index.html
# 使用场景,用在 React/Vue项目没有真实路由
location / {
try_files $uri $uri/ /index.html =404;
# 空格很重要 ^
}
}
4.11. 屏蔽 IP
include blockip.conf;
# 在 blockip.conf 里面输入内容,如:
deny 192.168.10.12;
deny IP; # 屏蔽单个 ip 访问
allow IP; # 允许单个 ip 访问
deny all; # 屏蔽所有 ip 访问
allow all; # 允许所有 ip 访问
deny 123.0.0.0/8; # 屏蔽整个段即从 123.0.0.1 到 123.255.255.254 访问的命令
deny 124.45.0.0/16; # 屏蔽IP段即从 123.45.0.1 到 123.45.255.254 访问的命令
deny 123.45.6.0/24; # 屏蔽IP段即从 123.45.6.1 到 123.45.6.254 访问的命令
# 如果你想实现这样的应用,除了几个IP外,其他全部拒绝
allow 1.1.1.1;
allow 1.1.1.2;
deny all;
4.12. 强制将 http 重定向到 https
server {
listen 80;
server_name example.com;
rewrite ^ https://$http_host$request_uri? permanent; # 强制将 http 重定向到 https
# 在错误页面和“服务器”响应头字段中启用或禁用发射nginx版本。 防止黑客利用版本漏洞攻击
server_tokens off;
}
4.13. 爬虫 User-Agent 过滤
location / {
if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {
return 503;
}
# 正常处理
# ...
}
4.14. 图片防盗链
location ~* \.(gif|jpg|png|swf|flv)$ {
root html;
valid_referers none blocked *.nginx.com;
if ($invalid_referer) {
rewrite ^/ www.nginx.cn;
# return 404;
}
}
4.15. 虚拟目录配置
location /img/ {
alias /var/www/image/;
}
# 访问 /img/ 目录里面的文件时,
# 会自动去 /var/www/image/ 目录找文件
location /img/ {
root /var/www/image;
}
# 访问 /img/ 目录下的文件时,
# 会去 /var/www/image/img/ 目录下找文件
4.16. 屏蔽文件目录
# 通用备份和归档文件
location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" {
deny all;
}
# 拒绝访问 .git 和 .svn 目录
location ~ (.git|.svn) {
deny all;
}
# 拒绝访问隐藏文件和目录
location ~ /\.(?!well-known\/) {
deny all;
}
4.17. 使网站不可索引
add_header X-Robots-Tag "noindex";
location = /robots.txt {
return 200 "User-agent: *\nDisallow: /\n";
}
4.18. Gzip 配置
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "msie6";
注意:使用 SSL/TLS 协议时,压缩响应可能会受到 BREACH 攻击。最合适压缩的,还是普通的文本类型的响应,比如纯文本文件、html/css/js响应、xml、JSON数据等等。这个是比较消耗CPU资源的哦。
参考资料:https://nginx.org/en/docs/