Nginx 学习

Nginx安装

  • 下载
wget http://nginx.org/download/nginx-1.16.1.tar.gz
  • 解压:
tar -zxvf nginx-1.16.1.tar.gz
  • 进入解压目录:
cd nginx-1.16.1
  • 安装
./configure --prefix=/opt/nginx --with-http_gzip_static_module --with-http_v2_module --with-openssl=/opt/openssl-1.1.1d --with-http_ssl_module --with-ipv6

# 可以提前输入 ./configure --help 来查看所有选项;
# 带 PATH 的代表安装路径,sbin路径、modules路径、conf路径、prefix安装路径、pid路径
# --with开头 表示安装第三方动态模块,--without开头 表示取消已安装模块;--user 和 --group 代表分配的用户和用户组
  • 编译、安装:
# 编译
make
# 安装
sudo make install
  • 启动
sudo /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
# -c 初次启动指定配置文件的路径。不加 nginx会自动加载默认路径的配置文件。
  • 运行
/opt/nginx/sbin/nginx -h # 显示帮助信息 -v 版本 -V 展示运行参数 (测试:-t -T会列出源文件)-q 安静 -s:signal -p:prefix -c:filename -g:directives
/opt/nginx/sbin/nginx -s reload # 重新加载配置; 
/opt/nginx/sbin/nginx -s reopen # 重新打开日志;等同于 kill -USR1 PID
/opt/nginx/sbin/nginx -s stop # 快速停止;等同于 kill -TERM/INT PID
/opt/nginx/sbin/nginx -s quit # 停止接受请求+处理完后关闭;等同于 kill -QUIT PID
/opt/nginx/sbin/nginx -g "pid logs/nginx.pid" # 添加配置
  • nginx 安装后,可选择添加[nginx.service]:vim /usr/lib/systemd/system/nginx.service
[Unit]
Descripitoin=nginx web service
Doucumentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t -c /opt/nginx/conf/nginx.conf
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/opt/nginx/sbin/nginx -s reload
ExecStop=/opt/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=default.target
# 授权 authorize
chmod 755 /usr/lib/systemd/system/nginx.service
# operator
systemctl start/stop/restart/reload/status/enable nginx
# 其中重载reload,体现在 master 进程号不变,worker进程号修改了
  • 将nginx命令配置到环境变量
export PATH=$PATH:/opt/nginx/sbin
  • kill 命令信号:TERM/INT、 QUIT、 HUP、 USR1、 USR2、 WINCH
  • nginx 卸载
./nginx -s stop && rm -rf /opt/nginx && make clean
# make clean 其实就是清理生成的 Makefile 和 objs/ 文件

Nginx 目录

  • conf:里面包含一些cgi(Common Gateway Interface)通用网关「接口|程序」相关的配置,还有编码转换相关的文件(koi-utf、koi-win、win-utf)还最后的 nginx 配置文件。
  • html:网页
  • logs:访问日志、错误日志、nginx进程的PID
  • sbin:执行文件

Nginx 多进程运行

  • nginx 是通过多进程的方式运行的:ps -ef |grep nginx

  • nginx 主要有两类进程

    • master(主进程、不处理业务、协调worker进程、校验配置文件)
    • worker(读取conf配置、加载对于资源、解析并响应)
  • 管理员向 master 发送信号,master 向 worker 传递信号;worker 进程和用户进行连接;

  • 重新打开日志文件:kill -USR1 PID;重新读取配置文件并生效 -HUP

  • 优雅关闭整个服务:kill -TERM/INT PID;所有子进程不在接收处理新连接:-WINCH(只关闭worker进程)

  • 平滑升级:kill -USR2 PID # 这样会复制一份,并得到 nginx.pid.oldbin 文件,再继续运行kill -QUIT OLDPID 这样平滑更新就完成了。

  • nginx 使用服务信号升级

# 准备工作
./configure && make && make install # 旧版
./configure && make # 新版
# 备份原有的二进制 nginx 
mv nginx oldnginx
# 更新 nginx 二进制文件
cp ~/nginx-1.17.1/objs/nginx /usr/local/nginx/sbin/
# 复制得到新的进程(根据新的二进制文件运行的进程)
kill -USR2 'more /usr/local/nginx/logs/nginx.pid'
# 退出旧版本
kill -QUIT 'more /usr/local/nginx/logs/nginx.pid.oldbin'
  • nginx 使用 make 命令升级
# 准备工作
./configure && make && make install # 旧版
./configure && make # 新版
# 备份原有的二进制 nginx 
mv nginx oldnginx
# 更新 nginx 二进制文件
cp ~/nginx-1.17.1/objs/nginx /usr/local/nginx/sbin/
# 在新版本的根目录下执行
make upgrade
  • nginx 更新模块
# 查看之前安装的模块有哪些(需要添加到后面)
nginx -V
# 清理
make clean
# 模块更新
./configure --without.... --with...
# 编译
make
# 更新
mv objs/nginx /opt/nginx/sbin/ && make upgrade

Nginx 核心配置

  • 配置文件 /usr/local/nginx/conf/nginx.conf 由三大块组成;
    • 全局块:http 和 events 之外的配置都是全局(指令名:指令值;既 -g 可以加的配置)
    • events 块:与用户网络连接相关的内容,性能相关。如 use epoll;
    • http 块:可以配置多个 server 块(端口+主机名+location块+error_page)
# worker 进程的用户,可以 useradd www,然后设置为www(会添加一个/home/www/目录方便配置)
user www;
# 是否开启工作进程,主要用于测试,需要重启,只留一个nginx进程(不区分master worker)
master_process off; # default on;
# 开启多少个worker进程,实现并发。适合为cpu物理内核数,超了会分时(也可以叫业务进程)
worker_processes auto;
# 是否以守护进程启动
daemon off; # default on;
# pid 文件路径
pid file;
# 错误日志存放路径(不记录访问请求),还包括日志级别:debug info notice warn error crit alert emerg
error_log file error; # 不建议 info 以下级别,会有大量 I/O

# 事件驱动模块
events {
  # 单个worker进程最大连接数;不能大于系统支持的最大文件句柄数
  worker_connections  1024;
  # 网络连接序列化,解决 “惊群” 问题(一根🦴打扰到所有🐶)但 3🐶3🦴时效率较慢不如竞争。需根据请求频率进行设置
  accept_mutex on; # default on, could set off
  # 单个worker是否能接收多个请求(设为on能提高效率)
  multi_accept on; # default off;
  # 设置 nginx 服务器使用哪种事件驱动来处理多路复用(方式)
  use epoll; # select/poll/epoll/kqueue 也可以在编译时 --with-select_module --with-poll_module 来选择(最终以配置文件为主)
}

# 实现 Http服务,走 http 协议
http {
  # 引用文件
  include       mime.types; # 服务器返回文件类型 内容为:types { text/css css; application/json json;} 这里 /etc/nginx/mime.types 和 mime.types 
  # 不包含在 types里面的,默认为什么类型(type):流的方式
  default_type  application/octet-stream;
  # 数据零拷贝;是否使用Linux 提供的 sendfile()这个函数来进行传输
  sendfile        on;
  # 长连接的超时时间,单位默认是 s秒
  keepalive_timeout  65;
  # keep-alive 连接最多使用的次数 
  keepalive_requests 100;

  include /etc/nginx/conf/\*.conf;

  # 一个 server 代表一个虚拟主机 vhost(通过端口区分)
  server {
    # 监听端口号:127.0.0.1:80指定ip+指定端口;127.0.0.1指定ip;*:8080 或 8080指定端口;
    # 没有匹配到 server_name 会默认去找第一个server ,要指定默认server,添加 default_server 属性;
    listen       80;
    # 主机名 或 域名:www.baidu.com *.baidu.com 多个用空格隔开;wildcard *只能出现在首段/尾段;波浪形正则:~^正则表达式$;
    server_name  localhost;
    # 子目录/路径
    location / {
      # 资源所匹配的目录(不配置,默认为当前目录的 html 文件夹)
      # root是网站根目录的逻辑概念,物理上表示为文件夹。
      root   html;
      # /斜杠时走的默认页(不配置,默认为 index.html 文件)
      index  index.html index.htm;
    }
    # 错误码跳转
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      # /usr/share/nginx/html 和 html都行(相对路径 和 绝对路径 都行)
      # root 会将 location 地址附加到末尾
      root   /usr/share/nginx/html;
      # 默认页;没有这步设置,也会将location附加到root末尾,起到同样效果,主要是给/用的;
      index 50x.html;
    }
  } 
  server {
    listen 80;
    server_name ~^www\.(\w+)\.com$;
    default_type text/plain;
    return 200 '--> access $1';
  }
  # 防止恶意域名解析
  server {
    # 匹配顺序:精确->前通配符->后通配符->正则->default_server->第一个server
    listen 80 default_server;
    server_name _;
    return 444;
  }
}

vim 可视化操作:ctrl-v + I/d + input + ESC

:set nu 开启行号;

:24,28d 删除对应行

  • 虚拟主机(一台主机一个站点太浪费了)

目录:baidu.com -> /www/baidu.com

目录:blog.baidu.com -> /www/blog.baidu.com

  • root 和 alias
    • root 最上层目录,结果为:root路径 + location路径
    • alias 目录别名,结果为:alias路径 替换 location路径(小心结尾斜杠/,alias直接替换是否会缺失)
  • index 默认首页(可以是图片等)从前往后,找到第一个为止;
  • error_page code... [=[response]] uri; # server可以配置多个error_page
    • 结合 error_page 404 @errorxx; location @errorxx {…}(@表示仅内部请求重定向, 不直接处理用户请求)
    • 修改返回状态码:error_page 404 =200 /50x.html; 浏览器就能显示为 200(=号前有空格,后没有空格

反向代理、负载均衡+urlRewrite -> 网关服务器

location 匹配符
  • location [ = | ~ | ~* | ^~ | @] uri {....}
    • (none) 不带符号必须以指定 uri 的开始字符 (也叫前缀字符) /abc 可以匹配 /abcef
    • ~ 正则表达式, ~* 正则表示 (不区分大小写);(注意缓存)
    • ^~ 不再检查正则表达式,如果匹配则不搜索其他正则(短路)
    • = 精确匹配, 可以定义URI和路径的精确匹配。如果发现匹配,则终止路径查找。 (^~= 都能性能优化)
    • 上面的匹配过程是,顺序匹配,匹配所有成功的,最后执行最后一个匹配的 location;
    • @ 仅用于Nginx服务器内部请求之间的重定向, 仅在内部定向时使用. 例如 error_page. (带有 @ 的location不直接处理用户请求)
  • 动静分离:动态资源使用 proxy_pass,静态资源 nginx 本地转发;
    • urlRewrite:/item/100 -> /itemService?id=100
      • flag标记说明:last(继续向下匹配)break(匹配完直接终止)redirect(302临时重定向,浏览器显示跳转后的URL)permanent(301永久重定向,浏览器显示跳转后的URL)
  • 反向代理 proxy_pass:用来代理服务器地址,可以是主机名称、IP地址加端口号的形式
    • URL:包含传输协议(http,https://)如果 location 结尾加“/”是不包含location的。location /server -> 代理后加;location /server/ -> 代理后不加
    • proxy_set_header:准备工作return 200 $http_username; 代表返回请求头里的username参数;proxy_set_header username TOM; 这个参数等主要作用是为了记录真实的主机地址,毕竟做了一遍代理;
    • proxy_redirect http://192.168.200.146/ http://192.168.200.133/ 后一个是本机地址,作用是替换重定向地址(重定向LocationUrl),可以替换为 default(或off)。被转发的服务器:if(!-f $request_filename) { return 302 http://192.168.200.146/; }然后本机的 location / 可以设置为proxy_pass http://192.168.200.146/ 来起到URL不变的效果。另外因为是整个转发,所以本机并不知道访问得到的是错误地址,所以不会有error日志。
  • 负载均衡 upstream:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
http {
  # 服务器组(The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, and grpc_pass directives.)
	upstream: httpUpstream {
    # 负载均衡策略:ip_hash、least_conn、least_time、url_hash、fair、ntlm、random
  	ip_hash;
  	# 不写上面的话默认为轮询;后面的附加内容「权重:weight;不参与负载均衡:down(对应的是 up 因为默认所以不用写);所有服务器都不能访问时访问的备用机:backup」
  	server 192.168.44.44:80 weight=8;
  	server 192.168.44.43:80 weight=2 backup;
  	server 192.168.44.42:80 weight=2 down;
  }

  server {
    listen       80;
    server_name  localhost;
    location / {
      # urlRewrite
      rewrite ^/([0-9]+).html$	/index.jsp?pageNum=$1 break;
      proxy_pass http://www.google.com;
    }
    location /httpUpstream {
      # 使用upstream就不要写端口了,因为具体到集群里端口号并不相同
      proxy_pass http://httpUpstream;
    }
  	# 波浪线 ~代表正则 *代表大小写不敏感
    location ~*/(js|css|img) {
      proxy_pass http://httpUpstream;
    }
  }

其他负载均衡策略:ip_hash、least_conn、url_hash、fair(响应时间,会受到流量倾斜)、ntlm(The upstream connection is bound to the client connection once the client sends a request with the “Authorization” header field value starting with “Negotiate” or “NTLM”. )

七层负载均衡:主要是基于虚拟 URL 或主机IP 的负载均衡;主要是 nginx

四层负载均衡:主要是 ip+port 的负载均衡;如软件的 LVS 和 nginx(–with-stream),硬件的 F5 机器

  • Rewrite 功能配置
    • urlRewrite:/item/100 -> /itemService?id=100
    • 语法:rewrite regex replacement [flag];
    • flag标记说明:last(能作为新 URL 继续匹配其他 location 块)break(作为新 URL 在本块中继续处理,不会去其他 location 块)redirect(302临时重定向,浏览器显示跳转后的URL)permanent(301永久重定向,浏览器显示跳转后的URL)
    • rewrite_log on|off 重写日志记录功能,开启后将以 notice 级别输出到 error_log 中(error_log file [error | debug | info | notice | warn | error | crit | alert | emerg];
    • server_name_in_redirect off 在0.8.48之前默认为 on 需要设置为 off

动静分离

  • 静态资源优化:
    • sendfile on; 使用sendfile() 函数来代替read和write函数,使得文件读取到内核缓冲区后,直接发送到socket缓冲区发送文件。替换之前的先read()到应用程序缓冲区,再write()到socket缓冲区;(“虚拟文件”:/dev/mem 可以用于读取内存的内容)
    • tcp_nopush on; sendfile开启后才生效,提升效率(别急,存满再发)
    • tcp_nodelay on; keepalive开启后才生效,提高实时性(别耽误,有数据就发)
      • nopush 和 nodelay 看起来是互斥的,但在Linux2.5.9之后可以兼容(判断是否足后一个包。nopush优先数据包装满立即发,末尾最后一个未装满则忽略nopush直接发送),所以上面三个都建议打开;
    • keepalive_timeout 65; 默认秒
{
  upstream webservice {
  	server 192.168.10.100:8080;
	}
  server {
    listen 80;
    server_name localhost;
    location /demo {
      proxy_pass http://webservice;
    }
    location ~/.*\.(png|jpg|gif|js) {
      root html/static;
    }
    location / {
      root html/static;
      index index.html index.htm;
    }
  }
}

Nginx 静态资源压缩实战

nginx可以通过配置gzip来对静态资源进行压缩,相关的指令可以配置在http、server和location块中。

相关模块有:ngx_http_gzip_modulengx_http_gzip_static_modulengx_http_gunzip_module 三个模块

  • 开启:giz on; & gzip_types mime-type ... (默认只对text/html;仅测试可以用:gzip_types *;
  • 级别:gzip_comp_level 6 (low1-9hight)
  • 告知:gzip_vary on default off;告知respond头启用了压缩:Vary: Accept-Encoding
  • 缓冲区数量和大小:gzip_buffers 32 4k | gzip_buffers 16 8k number size;
  • 不支持的浏览器不压缩:gzip_disable "MSIE [1-6]\.";
  • 压缩响应所需的最低 http 请求版本:gzip_http_version 1.1;
  • 太小的就不压缩:gzip_min_length 1k; 不写默认bytes字节,取得是Content-Length的值
  • 代理:gzip_proxied off|expired|no-cache|no-store|private|auth|any

Gzip 和 sendfile 共存问题

  • 引入ngx_http_gzip_static_module 模块,使用gzip_static off|on|always指令

浏览器缓存

expires [modified] time; (单位为秒)

expires epoch|max|off; (max 十年;epoch no-cache;off 默认不缓存)

主要跟 Expires (http1)和 Cache-Control (http1.1) 头有关;Cache-Control: max-age=1000;

添加指定的响应头和响应值:add_header Cache-Control no-cache;

跨域问题解决

同源策略:是一种浏览器最核心也是最基本的安全功能。(同源指:协议、域名/IP、端口 相同)

添加响应头:add_header Access-Control-Allow-Origin *;

添加响应头:add_header Accesss-Control-Allow-Methods GET,POST,PUT,DELETE;

防盗链

valid_referers none|blocked|server_names|string…

如果匹配到了 $valid_referers的值就为 0;没匹配到就是 1;

location / {
  # 可以设置 none、blocked、[server_names]、[ip] 可以写多个以空格分开
  valid_referers none 192.168.0.101;
  if (valid_referers) {
    return 403;
  }
  root html;
  index index.html index.htm;
}
  • if 命令:nginx 上的 if 后面必须跟空格,且判断符号如 = 、 != 、~ 符号等的前后都需要加空格;(其中正则表达式匹配 ~ 可以只匹配一部分内容)
    • break 指令:同一作用域后面的配置无效,且 终止当前匹配把当前 URI 在本 location 块中进行重定向访问处理(取消 return 的作用不会跳转到别的地方,而去找本块的 root 和 index 进行重定向访问)。

防止恶意域名解析

server {
  listen 80 default_server;
  server_name _;
  access_log off;
  return 444;
}

域名转发

server {
  listen 80;
  server_name aa.com bb.com;
  access_log off;
  rewrite ^(.*) http://cc.com$1;
}

https

{
  # 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;
    }
  }
  server {
    listen       80;
    server_name  www.bibi.com bibi.com;
    
    location / {
      return 301 https://$server_name$request_uri;
      root   html;
    }
  }
}

Keepalived 之 VRRP 原理

virtual route redundancy protocol 协议,虚拟路由冗余协议。能将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由IP;存在竞争(选择协议)有 master 和 backup 两种节点;master 需要在指定的时间间隔内,对外汇报自己的健康状态;在 master 出问题后,backup 根据优先级来进行竞争。

vrrp 协议:选择协议 + 路由容错协议(竞争 + 心跳-替换)

下载站点+用户认证

{
  server {
    location /download {
      root /usr/local;  # 访问/usr/local/download目录
      autoindex on; # 开启站点,npx_http_autoindex_module 模块
      autoindex_exact_size off;
      autoindex_format html; # json
      autoindex_localtime on;
      auth_basic "information to display"; # ngx_http_auth_basic_module 模块
      auth_basic_user_file customize_file_name;
    }
  }
}

使用 http password 生成器:httpd-tools

htpasswd -c /xxx/ username
htpasswd -b /xxx/ username password
htpasswd -D /xxx/ username # delete
htpasswd -v /xxx/ username # verify

Vue History 模式访问 404 解决办法

来自官网

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

或者

server {
        listen       8888; # 自定义
        server_name  localhost;
        root        /xxx/dist; # vue 项目的打包后的dist
        location / {
            try_files $uri $uri/ @router; # 需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
            index  index.html index.htm;
        }
        # 对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
        # 因此需要rewrite到index.html中,然后交给路由在处理请求资源
        location @router {
            rewrite ^.*$ /index.html last;    /index.html前面有空格
        }
        # .......略
}

try_files

排序 检查存在 文件处理 ifnx=>内部重定向

Syntax: try_files file … uri;
try_files file … =code;
Default: —
Context: server, location
Description: Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made.

http核心模块的内置变量:

$uri:当前请求的uri,不带参数
$request_uri:请求的uri,带完整参数
$host:http请求报文中host首部;如果请求中没有host首部,则以处理此请求的虚拟主机的主机名代替
$hostname:nginx服务运行所在主机的主机名
$remote_addr:客户端IP
$remote_port::客户端port
$remote_user:使用用户认证时客户端用户输入的用户名
$request_filename:用户请求中的URI经过本地root或alias转换后映射的本地的文件路径
$request_method:请求方法
$server_addr:服务器地址
$server_name: 服务器名称
$server_port:服务器端口
$server_protocol:服务器向客户端发送响应时的协议,如http/1.1,http/1.0
$scheme:在请求中使用的scheme 映射协议本身的协议。 如https://www.tshare365.com中的https;
$http_HEADER:匹配请求报文中指定的HEADER
$http_host 匹配请求报文中的host首部
$sent_http_HEADER:匹配响应报文中指定的HERDER

  • 例如 $http_content_type匹配相应报文中的content-type首部
    $document_root:当前请求映射到的root配置
    $status : 引用状态码

前后端分离项目代理 (真实IP)

location / {
  root   /usr/share/nginx/html;
  index  index.html index.htm;
  try_files $uri $uri/ /index.html;
}

location ^~ /simple/ {
    proxy_pass http://10.8.8.8:8080/;
}

location ^~ /realIp/ {
  proxy_pass  http://10.8.8.8:8080/;
  # proxy_redirect 可选. 与相应头 Location有关(与 302有关)
  proxy_redirect    off;
  proxy_set_header  Host             $host:$server_port;
  # 客户端或上一级代理
  proxy_set_header  X-Real-IP        $remote_addr;
  # 包含了客户端和各级代理ip的完整ip链路
  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
  # 可选
  proxy_set_header  X-Real-Port      $remote_port;
  proxy_set_header  REMOTE-HOST      $remote_addr;
  # proxy_set_header  X-Real-IP        $proxy_protocol_addr;
  # proxy_set_header  X-Forwarded-For  $proxy_protocol_addr;
  # proxy_set_header  X-Forwarded-Host $host:$server_port;
  # proxy_set_header  X-Forwarded-Server $host;
}

nginx 简单三步:

  • location 末尾加 /
  • proxy_pass 末尾加 /
  • proxy_set_header 设置两个参数 X-Real-IPX-Forwarded-For (其余可选)

注意事项

  1. 在后端开发中, 前面设置的真实 IP , 还需要我们手动获取!!!
  • java 代码
public String getRemortIP(HttpServletRequest request) {
  return request.getHeader("x-forwarded-for") == null ? request.getRemoteAddr() : request.getHeader("x-forwarded-for");
}
  1. 做反向代理时出现302错误; 原因大概率是跳转的地址少了端口号
proxy_set_header  Host  $host;   
# 加上即可
proxy_set_header  Host  $host:$server_port;

注意中间的冒号 “:” 别忘了; 如果使用了docker 容器, 并且端口不一致 (如 -p 8082:80). 一定要记得改为正确的
proxy_set_header Host $host:8082;
这里由于 302 返回的是 80 端口, 但实际外部是 8082, 所以我们直接写死为8082

  1. 大小写问题

    域名请求头 大小写不敏感, URIMethod (“GET”, “OPTIONS”…) 区分大小写

Header names are not case sensitive. From RFC 2616

proxy_redirect

Syntax: proxy_redirect default;

  • proxy_redirect off;
  • proxy_redirect redirect replacement;

Default: proxy_redirect default;
Context: http, server, location

该参数与相应头 LocationRefresh有关 ( Location 与 302 有关)

  • 最简单的参数: off 为取消 proxy_redirect 从顶层配置级别继承的效果。
  • 默认值: proxy_redirect default; 不设置默认就是这个参数. 下面两种参数完全等价, 代码来自官网(链接)
location /one/ {
    proxy_pass     http://upstream:port/two/;
    proxy_redirect default;
}
# 上下完全等价
location /one/ {
    proxy_pass     http://upstream:port/two/;
    proxy_redirect http://upstream:port/two/ /one/;
}
  • 普通参数:
    • redirect,匹配Locarion消息头的字符串,支持变量的使用和正则表达式。
    • replacement,用于替换redirect变量内容的字符串,支持变量的使用。
    • 这种方式用的比较少

另外 Refresh 的用法一看便知, 设置的 proxy_redirect 也会进行 Refresh 替换

response.getWriter().write("注册成功!3秒之后会跳转到主页...");
response.setHeader("refresh", "3;../index.html");

proxy_pass

@see http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_proxy_module.html#proxy_pass

first, separates [hostname] and [path] -> localhost + /proxy/abc.html

finally, get match part /proxy/abc.html to process. Will eventually change hostname.

proxy hostname

location /proxy/ {
  proxy_pass http://127.0.0.1:8080/;
} # request -> http://localhost/proxy/abc.html
  • /proxy/ + 8080/ 8080/abc.html 用配置的路径替换掉匹配部分 转发 (proxy_pass使用URI)
  • /proxy/ + 8080 8080/proxy/abc.html 原样转发 ###### (配置的路径没有使用URI, 使用原始的 URI 进行改造, 所以看起来就像原来的一样)

match path

location /proxy {
  proxy_pass http://127.0.0.1:8080/;
} # request -> http://localhost/proxy/abc.html
  • /proxy + 8080/ 8080//abc.html 替换掉匹配部分 转发
  • /proxy + 8080 8080/proxy/abc.html 原样转发 ##### (配置的路径没有使用URI, 所以使用原始的 URI 进行改造, 所以看起来就像原来的一样)

proxy hostname + uri

location /proxy/ {
  proxy_pass http://127.0.0.1:8080/api/;
} # request -> http://localhost/proxy/abc.html
  • /proxy/ + 8080/api/ 8080/api/abc.html 替换掉匹配部分 转发
  • /proxy/ + 8080/api 8080/apiabc.html 替换掉匹配部分 转发
  • /proxy + 8080/api 8080/api/abc.html 替换掉匹配部分 转发

非 URI 其实就是IP或域名

某些情况确实能使用URI:

如:

  • 使用正则表达式定义路径。

    这种情况下,指令不应该使用 URI。

  • 在需要代理的路径中,使用 rewrite 指令改变了 URI,但仍使用相同配置处理请求( break ):

location /name/ {
    rewrite    /name/([^/]+) /users?name=$1 break;
    proxy_pass http://127.0.0.1;
} # 这种情况下,本指令设置的URI会被忽略,改变后的URI将被发送给后端服务器。

后端服务器的地址,端口和 URI 中都可以使用变量:

proxy_pass http://$host$uri;

# 甚至像这样:proxy_pass $request;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值