nginx 教程

安装nginx

// 一键安装脚本
wget http://nginx.org/download/nginx-1.12.2.tar.gz && tar zxvf nginx-1.12.2.tar.gz && cd nginx-1.12.2 && ./configure && make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

常用命令

启动:
nginx
重载加载配置:
nginx -s reload
//查看nginx监听的端口是否存在
netstat -tlnup|grep nginx
关闭nginx服务器
pkill -9 nginx

配置文件

vim /usr/local/nginx/conf/nginx.conf
vim /usr/local/nginx/conf/vhost/www.movingbox.cn.conf
location / {
proxy_pass http://127.0.0.1:3100;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_connect_timeout 300; //注意这里几个配置决定了API的timeout时间
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
}
location /demo/ {
proxy_pass http://127.0.0.1:3101;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}

hide etag

server {
listen 80;
listen 443 ssl http2;
proxy_hide_header etag;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

mac linux

// 使用brew下载nginx
brew install nginx
// nginx地址
/usr/local/etc/nginx
// 查看nginx配置有木有生效
//Locate the nginx.conf file my nginx is actually using
nginx -t
// 查看nginx所有的配置
nginx -T

Ngnix Location的匹配顺序

对于每个请求来说,nginx 会选择最匹配的一个 location 来处理这个请求,nginx 其实就是通过对比这些 location 规则来选择一个 location,对比的顺序可以总结为:
1.首先匹配前缀匹配(没有 RE 表达式),针对当前这个请求,每个前缀匹配都匹配一遍.
2.搜索=匹配,如果当前请求匹配上了,搜索将会停止,直接使用这个这个 location.
3.如果第二步没有匹配上,nginx 会按照如下步骤继续搜索最长前缀匹配:
3.1 如果最长前缀匹配有^~这个modifier,nginx 会停止搜索并直接使用这个 location.
3.2 如果没有使用 ^~,暂存这个 location并且继续搜索.
4.只要最长前缀匹配被暂存和选中,nginx 就会看当前的 location 是否有大小写敏感的 RE(~~*),第一个匹配上这种会被当做有效的 location来处理这个请求.
5.如果没有 RElocation 匹配上,前面暂存的 location 就会被选中来处理这个请求.

举例

修饰符
= :精确匹配(必须全部相等)
~ :大小写敏感(正则表达式)
~* :忽略大小写(正则表达式),这里要注意忽略大小写的意思是请求的字符大小写都可以,
但是不会进行大小转换,请求的大小写对应的文件必须存在。
^~ :只需匹配uri部分
@ :内部服务跳转
location = / {
# 只处理请求 /.
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
location /data/ {
# 所有以 /data/ 匹配,但是还会继续搜索.
# 如果没有其他 location 匹配上,就用这个处理请求.
}
location ^~ /img/ {
# 所有以 /img/ 开头的请求并且会停止搜索.
}
location ~* .(png|gif|ico|jpg|jpeg)$ {
# 以png, gif, ico, jpg ,jpeg结尾的请求.
# 如果请求是到 /img/ 路径的话 还是会被上面👆的 location 处理
}
如何防止图片盗链:
location ~ .(png|gif|jpe?g)$ {
valid_referers none blocked yourwebsite.io *.yourwebsite.io;
if ($invalid_referer) {
return 403;
}
}
在可写权限的目录禁止脚本:
location ~* /(media|images|cache|tmp|logs)/.*.(php|jsp|pl|py|asp|cgi|sh)$ {
return 403;
}

Redirecting from a Former Name to the Current Name

server {
listen 80;
listen 443 ssl;
server_name www.old-name.com old-name.com;
return 301 $scheme://www.new-name.com$request_uri;
}

Forcing all Requests to Use SSL/TLS

server {
listen 80;
server_name www.domain.com;
return 301 https://www.domain.com$request_uri;
}

一个简单的 302 案例

rewrite ^/oldlocation$ http://www.newdomain.com/newlocation redirect;

一个简单的 301 案例

rewrite ^/oldlocation$ http://www.newdomain.com/newlocation permanent;
eg: joinplastic.com 跳转配置
rewrite ^/products/palletBox/palletBox.php$ https://www.joinplastic.com/product-category/pallet-box/ permanent;
rewrite ^/products/foldableBox/foldablePlasticCrates.php$ https://www.joinplastic.com/product-category/folding-crate/ permanent;
rewrite ^/products/pallets/pallet.php$ https://www.pallet-wholesale.com/plastic-pallets/ permanent;
rewrite ^/products/attached-lid-containers/attached-lid-containers.php$ https://www.plastic-crates.com/product-category/totes-with-lids/ permanent;
rewrite ^/products/stackableBox/stackableBox.php$ https://www.joinplastic.com/product-category/plastic-stacking-crates/ permanent;

如果有花括号(量词),需要用双引号或者单引号将表达式包起来

Curly braces are used both in regex and for block control, you must enclose your regex with quotes (single or double)

location ~* "^/.{16,22}[^/]$" {
return 301 https://www.ausplastic.com;
}

部署react 项目,直接访问二级路由回报 404 错误, 需要加上配置

location / {
try_files $uri /index.html;
}

nginx 配置 react 前端项目

server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /usr/local/nginx/conf/ssl/www.movingbox.cn.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/www.movingbox.cn.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server_name www.movingbox.cn movingbox.cn;
access_log /data/wwwlogs/www.movingbox.cn_nginx.log combined;
index index.html index.htm index.php;
# 注意这里,react 生成的前端根目录在public
# 但由于要 lets encrypt 自动申请证书成功,不能直接在这里指向/public
root /data/wwwroot/www.movingbox.cn;
if ($ssl_protocol = "") { return 301 https://$host$request_uri; }
if ($host != www.movingbox.cn) { return 301 $scheme://www.movingbox.cn$request_uri; }
include /usr/local/nginx/conf/rewrite/none.conf;
#error_page 404 /404.html;
#error_page 502 /502.html;
location ~ [^/]\.php(/|$) {
#fastcgi_pass remote_php_ip:9000;
fastcgi_pass unix:/dev/shm/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) {
deny all;
}
# 注意这里,配置lets encrypt 自动申请证书
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /data/wwwroot/www.movingbox.cn/;
}
location /{
root /data/wwwroot/www.movingbox.cn/public/;
try_files $uri $uri/index.html =404;
# 注意这里,路由没有找到 返回404 code;
# 交给前端 404.html 页面;
error_page 404 /404.html;
}
# 注意这里,配置图片的参数如 expires, 同时要指定 root 目录,
# 因为匹配到此条规则,就不会用上条规则的 root,
# 而是会用默认的 server 下的 root,即 root /data/wwwroot/www.movingbox.cn;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
root /data/wwwroot/www.movingbox.cn/public/;
expires 30d;
access_log off;
}
# 注意这里,配置js\css 文件同上面一样, 同时要指定 root 目录,
location ~ .*\.(js|css)?$ {
root /data/wwwroot/www.movingbox.cn/public/;
expires 7d;
access_log off;
}
}

利用nginx 做负载均衡 load balancer

参考 https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#overview

upstream my_http_servers {
server 127.0.0.1:444; # httpServer1 listens to port 444
server 127.0.0.1:445; # httpServer2 listens to port 445
server 127.0.0.1:446; # httpServer3 listens to port 446
server 127.0.0.1:447; # httpServer4 listens to port 447
}
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://my_http_servers;
}
}
// my_http_servers 为自定义的名称
// proxy_pass http://my_http_servers; 注意 my_http_servers 前要有 http://
// server 可以为本地ip,也可以为 其他ip 如: server 54.218.*8.*4:28000;

Choosing a Load-Balancing Method

//Round Robin
upstream backend {
# no load balancing method is specified for Round Robin
server backend1.example.com;
server backend2.example.com;
}
//Least Connections – A request is sent to the server with the least number of active connections, again with server weights taken into consideration
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}

多个位置用到 反向代理的 地址,可以将其放到 upstream 里面

upstream my-backend {
localhost:9000;
}
server {
listen 80;
server_name my-awesome-php.site;
root /path/to/root;
# The protected location
location /protected {
auth_basic "Give me codes.";
auth_basic_user_file /path/to/.htpasswd;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass my-backend;
}
}
# Normal files (blank location is OK, just means serve from root)
location / {
}
# PHP for normal stuff
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass my-backend;
}
}