分类 nginx 下的文章

  • 转发内容替换(不支持长链接内容替换)
# 关闭gzip
gunzip on;
gzip_disable ".";

# 转发内容全局替换
proxy_redirect off; 
sub_filter_once     off; # off为多次替换,默认值为on仅仅替换一次
sub_filter_types *; # 替换的content-type类型
sub_filter "hometree-ts.oss-cn-shanghai.aliyuncs.com" "hometree-ts.oss-accelerate.aliyuncs.com";
sub_filter "oss-ts.jiayuanshu.net" "hometree-ts.oss-accelerate.aliyuncs.com";

sub_filter "hometree.oss-cn-shanghai.aliyuncs.com" "hometree.oss-accelerate.aliyuncs.com";
sub_filter "oss.jiayuanshu.net" "hometree.oss-accelerate.aliyuncs.com";
sub_filter "hometree.oss.jiayuanshu.net" "hometree.oss-accelerate.aliyuncs.com";


sub_filter 指令
sub_filter string replacement。将string替换成replacement,不区分大小写。
sub_filter_last_modified on | off。默认:off,防止缓存。是否在Response header中写入Last-Modified,控制缓存。
sub_filter_once on | off。默认: on,只执行一次。sub_filter指令是执行一次,还是重复执行。
sub_filter_types mime-type …。默认: text/html。指定类型的MINE TYPE,如果所有类型,则使用:*。
  • 自动转发且自动帮助登录
location /online_api1/ {
    proxy_set_header Authorization 'Bearer eyJ0eXJ9.eyJpc3MiiA';
    proxy_pass https://api.test.cn/; 
}
  • 微服务2种配置方式
 # 访问 /*/aaa 实际请求 http://localhost:9501/aaa
location /abcd/ {
            proxy_pass http://localhost:9501/;
}
location ~ /abcd(/|$)(.*) { 
    proxy_pass http://localhost:9501/$2;
}

# 访问 /*/aaa 实际请求 http://localhost:9501/aaa 
location ~ /[a-z_0-9]+(/|$)(.*) { # 为列出来的都转发到该接口 
    if ($query_string = ''){
        proxy_pass http://t.wuloves.com/$2;
    }
    proxy_pass http://t.wuloves.com/$2?$query_string;
}
  • location 携带参数
location ^~ /abc {
    proxy_set_header    Host $host;
    proxy_set_header    X-Real-IP  $remote_addr;
    proxy_pass http://127.0.0.1:8081/;
}
  • 路径转发
location /callback/ {
    proxy_pass http://www.baidu.com/;
}
# 网上有人说https协议不能访问, 测试实际访问是http, 配置中转发到https转发正常, 同样实际测试转发的域名是无法将域名替代为ip通过https访问的
# 当前被访问的为https未测试
location /https/ {
    proxy_pass https://www.baidu.com/;
}

# 重点,转发websocket需要的设置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection upgrade;

  • 创建文件 auto_start_nginx.bat 并放入启动目录
taskkill /f /im nginx.exe
d:
cd "D:\s\nginx-1.18.0\"
start "" "nginx.exe"
  • 创建文件 hide_php_cgi.bat 并放入启动目录
set ws=WScript.CreateObject("WScript.Shell")
ws.Run "D:\s\php\php-cgi.exe -b 127.0.0.1:9000",0
  • 重启nginx
taskkill /f /im nginx.exe
nginx.exe

  • 配置文件路径
lnmp安装环境的默认路径
/usr/local/nginx/conf/nginx.conf
  • 重写
# 将blog目录下的路由重写到blog/index.php
location /blog {
    index index.php;
    try_files $uri $uri/ /blog/index.php?q=$uri;
}

# 其他demo
文件找不到自动重定向到这个php文件
location /{
    if (!-e $request_filename){
        rewrite ^/detail/(\d+)\.html$ /detail.php?id=$1 last;
    }
}

  • 重写2
- 文件不存在时重写
location ~* ^.+.(gif|jpg|jpeg|js|css)$ {
    if (!-e $request_filename) {
        rewrite ^(.*)$ /../html2$1 break;
    }
}
# 根目录下找文件, 如果没有找到, 再去相邻的目录做寻找
 
- 将某个目录下的请求重新到该目录下的index.php文件
location /blog/ {
        if (!-e $request_filename) {
                rewrite ^/ /blog/index.php last;
        }
}
  • 热更新配置文件
nginx -s reload
原理, 启动新的worker, 如果启动成功, 接管新的请求, 原有的worker处理完成后再关闭
如果启动新的worker失败, 抛出错误, 原有的worker不会因为配置文件导致请求无法继续
  • 域名转发请求, websocket+http
server {
    listen 443 ssl;   #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。
    server_name api.wuloves.com;  #将localhost修改为您证书绑定的域名,例如:www.example.com。
    ssl_certificate /data/key/api.qj30.cn/api.wuloves.com.pem;   #将domain name.pem替换成您证书的文件名。
    ssl_certificate_key /data/key/api.qj30.cn/api.wuloves.com.key;   #将domain name.key替换成您证书的密钥文件名。
    ssl_client_certificate /data/key/ca.crt;
    ssl_session_timeout 30m;
    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; 
    ssl_verify_client      off;

        location / {
            proxy_pass https://api.wuloves.com/;
            proxy_ssl_certificate /data/key/api.qj30.cn/api.wuloves.com.pem;
            proxy_ssl_certificate_key /data/key/api.qj30.cn/api.wuloves.com.key;

            proxy_ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
            proxy_ssl_ciphers             HIGH:!aNULL:!MD5;
            proxy_ssl_trusted_certificate /data/key/ca.crt;
 
            proxy_ssl_verify        off;
            proxy_ssl_verify_depth  2;
            proxy_ssl_session_reuse on;

    # 重点,转发websocket需要的设置
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
#    proxy_set_header Connection $connection upgrade;

        }
        access_log /data/web/logs/api.wuloves.com.success.ssl.log;
        error_log  /data/web/logs/api.wuloves.com.error.ssl.log;
} 
  • 接口转发跨域全局处理
server {
        listen     8002  ;

proxy_hide_header Access-Control-Allow-Origin; # 避免转发的头部包含这些,提前做好屏蔽
proxy_hide_header Access-Control-Allow-Credentials;
proxy_hide_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
proxy_hide_header Access-Control-Expose-Headers;

# always 官方也给出了解释。只有在 状态码是 200,201,204,302.....的情况下,才有效。除非你使用always关键字。
add_header Access-Control-Allow-Origin * always;// 主动对请求后的数据添加头
add_header Access-Control-Allow-Credentials 'true' always;
add_header Access-Control-Allow-Methods '*' always;
add_header Access-Control-Allow-Headers 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization,Access-Token,X-Requested-With,*' always;
add_header Access-Control-Expose-Headers '*' always;

if ($request_method = 'OPTIONS') { // 如果是预处理请求,直接返回
#    add_header Access-Control-Max-Age '120';
    return 204;
}

location /course/ {
            proxy_pass http://localhost:1801/;
}
location /common/ {
            proxy_pass http://localhost:1802/;
}
location /gem/ {
            proxy_pass http://localhost:1803/;
}
location /wechat/ {
            proxy_pass http://localhost:1804/;
}


location ~ /[a-z_0-9]+(/|$)(.*) { # 访问 /*/aaa 实际请求 http://localhost:9501/aaa
# return 200 'Preferential match';  
    proxy_pass http://localhost:9501/$2; # 为列出来的都转发到该接口
}

}
  • 缓存
proxy_cache_path /cache/nginx/ levels=1:2 keys_zone=mycache:64m;
server {
        listen     8002  ;

# 缓存配置部分
proxy_cache mycache; # /s/nginx-1.18.0/cache; #引用mycache缓存空间;
proxy_cache_valid 200 302 1m;
proxy_cache_methods GET HEAD;

}
  • 更多
location /root {
#    root  "/data/www"; // 访问链接为 /root/1.txt 时, 实际访问路径为 /data/www/root/1.txt
#    alias  "/date/www"; // 访问链接为 /root/1.txt 时, 实际访问路径为 /data/www/1.txt
}

  • Nginx https ssl配置
server {
    listen 443 ssl;   #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。
    server_name www.wuloves.com;  #将localhost修改为您证书绑定的域名,例如:www.example.com。
    root /web/www.wuloves.com;
    index index.php index.html index.htm;
    ssl_certificate /key/www.wuloves.com/www.wuloves.com.pem;   #将domain name.pem替换成您证书的文件名。
    ssl_certificate_key /key/www.wuloves.com/www.wuloves.com.key;   #将domain name.key替换成您证书的密钥文件名。
    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 / {
#        try_files $uri $uri/ /index.php?$query_string;
#    }
    # 将blog目录下的路由重写到blog/index.php

    location /blog/ {
        if (!-e $request_filename) {
            rewrite ^/ /blog/index.php last;
        }
    }

    location ~ \.php {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_split_path_info  ^(.+\.php)(/.*)$;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        include        fastcgi.conf;
        if (!-e $request_filename) {
            rewrite ^/ /blog/index.php last;
        }
    }
        access_log /web/logs/www.wuloves.com.success.ssl.log;
        error_log  /web/logs/www.wuloves.com.error.ssl.log;
} 
  • Nginx 强制https访问
server {
    listen       80;
    server_name  www.wuloves.com;
    rewrite ^(.*)$  https://$host$1 permanent;  
    access_log /dev/null;
    error_log  /dev/null;
}

nginx转发请求时出现错误: 6009#0: *1 connect() to 127.0.0.1:9501 failed (13: Permission denied) while connecting to upstream

  • 错误日志
[root@localhost code]# vim + /var/log/nginx/error.log
2020/07/06 21:52:21 [error] 6009#0: *6 no live upstreams while connecting to upstream, client: 192.168.2.80, server: _, request: "GET /https/ HTTP/1.1", upstream: "https://www.baidu.com/", host: "192.168.2.140"
2020/07/06 21:52:29 [crit] 6009#0: *1 connect() to 127.0.0.1:9501 failed (13: Permission denied) while connecting to upstream, client: 192.168.2.80, server: _, request: "GET /report/ HTTP/1.1", upstream: "http://127.0.0.1:9501/report/", host: "192.168.2.140"
  • nginx转发环境
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;

        location /https/ {
            proxy_pass https://www.baidu.com/;
        }

        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /report/ {
            proxy_pass http://127.0.0.1:9501/;
        }

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }
  • 过的第一个坑
查了很多资料说是权限问题, 于是
vim /etc/nginx/nginx.conf
把其中的 user nginx;  改为 user root; 重启nginx不管用, 然后又改回去了
  • 执行了下面一条命令, nginx都不需要重启, 就正常了, 可以正常访问 /https/ 的转发, 但是 /report/ 转发还是报错了
setsebool -P httpd_can_network_connect 1
  • /report/ 报错内容
2020/07/06 21:54:02 [error] 6009#0: *10 open() "/usr/share/nginx/html/home/msg/data/personalcontent" failed (2: No such file or directory), client: 192.168.2.80, server: _, request: "GET /home/msg/data/personalcontent?num=8&indextype=manht&_req_seqid=3114502296&asyn=1&t=1594086842083&sid=31906_1445_31325_32139_31254_32046_32230_31709_32258_26350 HTTP/1.1", host: "192.168.2.140", referrer: "http://192.168.2.140/https/"
  • 解决过程
把report的配置移动到https的转发配置后面重启nginx就好了