Nginx是一款高性能的HTTP和反向代理服务器,欧博abg以其稳定性、丰富的功能集、简单的配置文件以及低资源占用而闻名。 Nginx的主要应用场景包括: 静态资源服务器:Nginx可以高效地提供静态文件,如HTML、CSS和JavaScript文件。 反向代理:Nginx可以作为前端代理,将客户端的请求转发到后端的服务器,并将后端服务器的响应返回给客户端。 在Nginx的反向代理配置中,一个看似不起眼的字符可能会对请求的转发路径产生重大影响。本文将探讨代理地址设置中的几种情况及其对应的行为。 Nginx中如何配置反向代理Nginx能够作为一个反向代理来终结来自于客户端的请求,并且向上游服务器打开一个新的请求。 在nginx中这个功能需要使用location指令来实现。 location指令可以用在虚拟服务器server部分,欧博官网并且意味着提供来自客户端的URI或者内部重定向访问。除少数情况外,location也可以被嵌套使用,它们被作为特定的配置尽可能地处理请求。 location定义如下: 代码语言:javascript 复制 location [modifier] uri {...} modifier会影响location的处理及优先级。 或者是命名location: 代码语言:javascript 复制 location @name {...} 命名location仅对内部访问重定向,在进入一个location之前它会保留被请求的URI部分。命名location只能够在server级别定义。 location修饰符及处理方式: = 使用精确匹配并且终止搜索。即一旦匹配上使用=修饰的location,下面的其它location配置就无效了。 ~ 区分大小写的正则表达式匹配。 ~*不区分大小写的正则表达式匹配。 ^~ 如果该location是最佳的匹配,那么对于匹配这个location的字符串不再进行正则表达式检测。注意,欧博这不是一个正则表达式匹配----它的目的是优先于正则表达式匹配。 当使用^~修饰符时,即使有其他更精确的匹配,也会选择这个location块。在这种情况下,即使有其他匹配规则,URI也不会被替换。 易错点澄清:何时替换uri?为了更好地响应客户端请求,可以根据请求的URI、http客户端参数或者一些约定的逻辑进行拆分。通过代理服务器,欧博娱乐请求的原始URL中的任何部分都能够以这种方式进行转换。 其中,把请求代理到上游服务器配置中,最重要的是proxy_pass指令。该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式。 其语法结构为: 代码语言:javascript 复制 proxy_pass URL; 其中,URL为要设置的被代理服务器的地址,包含传输协议、主机名称或IP地址+端口、URI等要素。传输协议通常是http或https。指令同时还接受以unix开始的UNIX-domain套接字路径。例如: 代码语言:javascript 复制 proxy_pass :8080; proxy_pass https://www.ai-as.net/newUri; proxy_pass :/tmp/aias.socket:/uri/; 明白了proxy_pass指令的使用,我们来解释大家经常讨论的一个问题,就是proxy_pass指令的URL变量末尾是否加斜杠“/”的问题。 先说结论: 代码语言:javascript 复制 如果proxy_pass后面的URL包含URI, 带有URI部分的proxy_pass指令 将会使用该URI替代request_uri中与location 指令uri相同的部分。 后面示例有详细说明。 URL中没有包含URI的指定示例: location /uri { proxy_pass ; } 其它情况在nginx看来, proxy_pass后面的URL都包含了URI,即使只加了一个斜杠“/”, 即斜杠“/”也是URI。 例如,下面例子中的/uri,在请求传递到上游服务器时将会被替换为newUri。 代码语言:javascript 复制 location /uri { proxy_pass ; } 以nginx/1.26.0为例,proxy_pass中URL有四种情况,nginx收到请求后,重新发起请求的URL如下图所示: 场景1:proxy_pass ; 1.1浏览器请求的URL: 1.2Nginx中的conf/nginx.conf中的配置: 代码语言:javascript 复制 location /proxy_pass_no_dir_without_slash/ { proxy_pass ; } 1.3Nginx重新发起请求的URL: /proxy_pass_no_dir_without_slash 原因:proxy_pass的URL 上没有包含资源路径URI。 1.4示例: 代码语言:javascript 复制 % curl nginx debug日志: 场景2:proxy_pass ; 2.1浏览器请求的URL: 2.2Nginx中的conf/nginx.conf中的配置: 代码语言:javascript 复制 location /proxy_pass_no_dir_with_slash/ { proxy_pass ; } 2.3Nginx重新发起请求的URL: 原因:proxy_pass的URL 上包含资源路径“/”。 2.4示例: 代码语言:javascript 复制 curl nginx debug日志: 场景3:proxy_pass ; 3.1浏览器请求的URL: 3.2Nginx中的conf/nginx.conf中的配置: 代码语言:javascript 复制 location /proxy_pass_dir_without_slash/ { proxy_pass ; } 3.3Nginx重新发起请求的URL: 原因:proxy_pass的URL 上包含资源路径“/dir”。 3.4示例: 代码语言:javascript 复制 curl nginx debug日志: 场景4:proxy_pass ; 4.1浏览器请求的URL: 4.2Nginx中的conf/nginx.conf中的配置: 代码语言:javascript 复制 location /proxy_pass_dir_with_slash/ { proxy_pass ; } 4.3Nginx重新发起请求的URL: 原因:proxy_pass的URL 上包含资源路径“/dir/ ”。 4.4示例: 代码语言:javascript 复制 % curl nginx debug日志: 5、使用到的nginx/nginx.conf 代码语言:javascript 复制 % cat conf/nginx.conf #user nobody; worker_processes 1; error_log logs/error.log debug; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } location /proxy_pass_no_dir_without_slash/ { proxy_pass ; } location /proxy_pass_no_dir_with_slash/ { proxy_pass ; } location /proxy_pass_dir_without_slash/ { proxy_pass ; } location /proxy_pass_dir_with_slash/ { proxy_pass ; } # error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass ; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } } 查看的日志文件:logs/error.log 代码语言:javascript 复制 % tail -f logs/error.log 2024/05/19 23:23:59 [debug] 66640#0: *38 http keepalive handler 2024/05/19 23:23:59 [info] 66640#0: *38 kevent() reported that client 127.0.0.1 closed keepalive connection 2024/05/19 23:23:59 [debug] 66640#0: *38 close http connection: 4 2024/05/19 23:23:59 [debug] 66640#0: *38 event timer del: 4: 13660789921 2024/05/19 23:23:59 [debug] 66640#0: *38 reusable connection: 0 2024/05/19 23:23:59 [debug] 66640#0: *38 free: 0000000000000000 2024/05/19 23:23:59 [debug] 66640#0: *38 free: 00007FD0E8105850, unused: 152 2024/05/19 23:23:59 [debug] 66640#0: timer delta: 1 2024/05/19 23:23:59 [debug] 66640#0: worker cycle 2024/05/19 23:23:59 [debug] 66640#0: kevent timer: -1, changes: 0 留个小问题: 你的nginx error.log日志中示例中的debug日志吗? 小结Nginx作为一款功能强大的反向代理服务器,其location和proxy_pass指令提供了灵活的配置选项。然而,在使用过程中,需要注意一些易错点,如proxy_pass中的斜杠问题、多次重写以及特殊场景下的URI不替换。通过仔细检查和理解这些细节,可以避免常见的配置错误,确保Nginx正确地转发请求。 巩固小作业下面的这个location配置效果是一致的吗? 配置1: 代码语言:javascript 复制 location / { proxy_pass ; } 配置2: 代码语言:javascript 复制 location / { proxy_pass ; } REFERENCEhttps://www.bilibili.com/video/BV1GJ4m187Em/?vd_source=028ee6e6a7217b4a4237d439b7fd348d 通过debug日志定位问题 https://time.geekbang.org/course/detail/100020301-79641 (责任编辑:) |