熟悉Nginx的基础配置和Nginx能达到的功能。
基本命令
# 快速关闭 nginx,可能不保存相关信息,并迅速终止 web 服务
nginx -s stop
# 平稳关闭 nginx,保存相关信息,有安排的结束 web 服务
nginx -s quit
# 因改变了 nginx 相关配置,需要重新加载配置而重载
nginx -s reload
# 重新打开日志文件
nginx -s reopen
# 为 nginx 指定一个配置文件,来代替缺省的
nginx -c filename
# 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件
nginx -t
# 显示 nginx 的版本
nginx -v
# 显示 nginx 的版本,编译器版本和配置参数
nginx -V
基础配置
# 运行用户
# user somebody;
# 启动进程,通常设置成和 cpu 的数量相等
worker_processes 1;
# PID文件,记录当前启动的 nginx 的进程 ID
pid D:/Tools/nginx-1.10.1/logs/nginx.pid;
# 工作模式及连接数上限
events {
use epoll;
# 单个后台 worker process 进程的最大并发链接数
worker_connections 1024;
}
# 设定 http 服务器,利用它的反向代理功能提供负载均衡支持
http {
# 设定 mime 类型(邮件支持类型),类型由 mime.types 文件定义
include D:/Tools/nginx-1.10.1/conf/mime.types;
default_type application/octet-stream;
# 设定日志
log_format
# sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
# 必须设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的 uptime
sendfile on;
# tcp_nopush on;
# 连接超时时间
keepalive_timeout 120;
tcp_nodelay on;
# gzip 压缩开关
# gzip on;
# 设置允许跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Authorization,Content-Type,Accept,Origin,User- Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since;
add_header Access-Control-Allow-Methods GET,POST,PUT,PATCH,DELETE,OPTIONS;
# 设定实际的服务器列表
upstream zp_server1{
server 127.0.0.1:8089;
}
}
反向代理
上面讲解了 nginx 的基础配置,更多的功能主要通过 http 节点下的 server 节点实现,比如反向代理。
反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
server {
# 监听 80 端口,80 端口是知名端口号,用于 HTTP 协议
listen 80;
# 定义使用 www.xx.com 访问
server_name www.helloworld.com;
# 首页
index index.html
# 指向 webapp 的目录
root home/default
# 编码格式
harset utf-8;
# 代理配置参数:在默认情况下经过 proxy 转发的请求,在后端看来远程地址都是 proxy 端的 ip
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_set_header Host $host;
# 后端的 Web 服务器可以通过 X-Forwarded-For 获取用户真实 IP
proxy_set_header X-Forwarder-For $remote_addr;
# 允许 web 服务器端获得用户的真实 ip
proxy_set_header X-Real-IP $remote_addr;
# 反向代理的路径(和 upstream 绑定),location 后面设置映射的路径
location / {
proxy_pass http://zp_server1;
}
# 静态文件,nginx 自己处理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root \webapp\views;
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
expires 30d;
}
# 设定查看 nginx 状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
}
# 禁止访问 .htxxx 文件
location ~ /\.ht {
deny all;
}
# 错误处理页面(可选择性配置)
# error_page 404 /404.html;
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root html;
# }
}
负载均衡
我们在 server 外添加了一个 upstream,而直接在 proxy_pass 里面直接用 http://+upstream 的名称来使用。
upstream 中的 server 元素必须要注意,不能加 http://,但 proxy_pass 中必须加。
# 设定负载均衡的服务器列表
upstream load_balance_server {
#weigth参数表示权值,权值越高被分配到的几率越大
server 192.168.1.11:80 weight=5;
server 192.168.1.12:80 weight=1;
server 192.168.1.13:80 weight=6;
}
多 webapp 配置
很多时候一个服务器会运行多个不同的系统,我们知道,http 的默认端口号是 80,如果在一台服务器上同时启动这 3 个 webapp 应用,都用 80 端口,肯定是不成的。所以,这三个应用需要分别绑定不同的端口号。那么问题来了,用户在实际访问 www.helloworld.com
站点时,访问不同 webapp,总不会还带着对应的端口号去访问吧。所以,你再次需要用到反向代理来做处理。
一个一级域名实现
upstream product_server{ server www.helloworld.com:8081; } upstream admin_server{ server www.helloworld.com:8082; } upstream finance_server{ server www.helloworld.com:8083; } 配合 server 下 location 进行实现: # 默认指向 product 的 server location / { proxy_pass http://product_server; } location /product/ { proxy_pass http://product_server; } location /admin/ { proxy_pass http://admin_server; } location /finance/ { proxy_pass http://finance_server; } 通过以上方式访问时候通过添加路径参数的方式实现访问多站点。
多个域名二级实现
首先需要在服务器配置 DNS 解析。通过多 server,同 80 端口的方式实现访问多站点。
具体配置如下:server { listen 80; server_name blog.pig1024.me; location / { proxy_pass http://120.76.244.22:8899; proxy_set_header X-Real-IP $remote_addr; } } server { listen 80; server_name pig1024.me; index index.jsp index.html; root /home/default; location / { proxy_pass http://127.0.0.1:9000; proxy_set_header X-Real-IP $remote_addr; } }
Https 反向代理
配置基本相同,注意如下几点即可:
# 监听 443 端口。443 为知名端口号,主要用于 HTTPS 协议
listen 443 ssl;
# 定义使用 www.xx.com 访问
server_name www.helloworld.com;
# ssl 证书文件位置(常见证书文件格式为:crt/pem)
ssl_certificate cert.pem;
# ssl 证书 key 位置
ssl_certificate_key cert.key;
# 阿里云 DEMO
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header X-Real-IP $remote_addr;
root html;
index index.html index.htm;
}
很明显站点开启 HTTPS 之后,需要保证 HTTP 也能正常访问,有两种处理处理方式:
- http 强制跳转 https(推荐)
server { listen 80; server_name blog.pig1024.me; rewrite ^ https://$http_host$request_uri? permanent; #return 301 https://$http_host$request_uri; }
- 同时支持 http 和 https(不推荐)
server { listen 80; listen 443 ssl; server_name www.example.com; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key; ... }
静态站点
有时候,我们需要配置静态站点(即 html 文件和一堆静态资源)。
server {
listen 80;
server_name static.zp.cn;
location / {
root /app/dist;
index index.html;
# 转发任何请求到 index.html
}
}
项目路径自定义
server {
listen 80 default_server;
server_name localhost;
index index.jsp index.html;
root /home/default;
location ~ .* {
proxy_pass http://127.0.0.1:9000;
proxy_set_header X-Real-IP $remote_addr;
}
}
<Engine name="Catalina" defaultHost="localhost">
# 标签下增加 host 标签
<Host name="localhost" appBase="/home/default"
unpackWARs="true" autoDeploy="true">
Location 匹配规则
指令语法
location [=|~|~*|^~|@] /uri/ { … } 或 location @name { … }
匹配模式
- 普通字符串匹配:以=开头或开头无引导字符(~)的规则
- 正则匹配:以~或~开头表示正则匹配,~表示正则不区分大小写
匹配规则
总体的匹配原则是:先匹配普通字符串模式,再匹配正则模式
。
- 先查找是否有=开头的精准匹配
- 在查找普通匹配,以
最大前缀
为原则 - 需要注意的是通常匹配到一个普通格式后,搜索并未结束,而是暂存当前匹配的结果,并继续搜索正则匹配模式。
- 所有正则匹配模式 location 中找到第一个匹配项后,就以此项为最终匹配结果,所以正则匹配项匹配规则,受定义的前后顺序影响,但普通匹配模式不会
- 如果未找到正则匹配项,则以 3 中缓存的结果为最终结果
- 如果一个都没有找到,返回 404
正则匹配与非正则匹配
- location ~ /test/.+.jsp$ { … }:正则匹配,支持标准的正则表达式语法。
- location ^~ / { … }:
^~意思是关闭正则匹配
,当搜索到这个普通匹配模式后,将不再继续搜索正则匹配模式。
常见问题
权限问题
Nginx 代理静态资源后,错误提示 ERR_CONTENT_LENGTH_MISMATCH
- 原因:nginx 会缓存大文件到 proxy_temp 目录中,主进程在读取缓存的时候由于权限问题而无法访问
- 解决:通过 sudo chmod -R 777 /usr/local/var/run/nginx/* 打开权限即可
666