Nginx运维
Nginx集群
主从结构:1个主进程,多个worker进程;master进程:读取和验证配置、维持和管理worker 进程; worker进程:请求处理;
nginx采用event-based model和OS-depedent 机制,将requests分发给各个worker进程;worker进程数最好和可用cpu cores数匹配;nginx及其modules工作方式由配置文件中的配置决定(nginx.conf);
集群命令
nginx -s signal
stop — fast shutdown
quit — graceful shutdown
reload — reloading the configuration file
reopen — reopening the log files
ps -ax | grep nginx:list nginx进程
Configuration Structure
nginx包含多个modules,modules由配置文件中的指定的指令控制;
指令分两种:简单指令和block指令;
简单指令:包含名字和paremes,space分隔,分号(;)结尾,例如:worker_connections 1024;
block指令:名字和parames,space分隔,和简单指令类似,但是以{}包围的一组指令结尾,例如:
location / {
root html;
index index.html index.htm;
}
如果,block指令的{}内有其他指令,则block 指令被叫做a context;不再任何context内的指令在 main context中,如http 在main context中,server在http中;
注释说明在#标记后边;
serve out static content
web server会请求一些资源文件,比如images或者html pages文件,资源位置可以通过server下的location block指令中的parames来定位。如:location /images/ {
root /data;
}
如果请求uri匹配指定的前缀“/images/”,则将uri附加到root指定的path后边,构成资源文件的本地path,如http://localhost/images/example.png请求匹配该location,则资源文件path为/data/images/example.png,然后nginx将资源返回,如果资源文件不存在则返回404。
如果server下有多个匹配的location block指令,如:server {
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
nginx选择location 前缀最长的那个,只有当其他location都匹配不上时,才会选择那个匹配上的前缀最短的location,在此例中,nginx选择location /images/。
如果nginx并没有按预想的工作,查看access.log和error.log分析对应的问题。
location指令定义:用前缀string或者正则表达式表示的指定模式与请求uri相匹配,正则表达式以"~*"、“~”修饰符指定,如 location ~ ^/test$(以/开始,test结尾,大小写敏感), “@” prefix定义一个named location,
matching:对标准化后的uri操作,包括解码、解析相对路径组件的引用(".","…")、压缩多个邻近斜线“///”为一个“/”处理后的uri;match流程图如下:
regular location的使用优先级高于frefix location;regular locations内根据配置顺序匹配,在前的优先级高于在后的,优先级高的先匹配,匹配上即终止,使用第一个匹配上location;frefix locations匹配优先级一样,选择mached longgest prefix location。
特殊:1、longest matched prefix location如果有“^~”修饰,则regular不check;2、如果location有”=“修饰符,则表示准确匹配,如果匹配上,则search结束,这种location不能含有嵌套;3、不同的版本也有不同特殊规则,这个最好参考官网版本说明;
重定向location:”@“ frefix定义了一个指定的location,不是用来处理普通的请求,而是用于请求重定向,不能被嵌套,也不能包含嵌套。
Setting Up a Simple Proxy Server
nginx常作为一个代理服务器来使用,把接收的请求转发给被代理的服务,并将接收到的响应返回给client。在配置文件nginx.cong中用server block directive 配置。
request: http://localhost/index.html
server {
listen 80;
server_name localhost;
root test1;
location / {
root test;
}
}
2021/03/18 14:34:08 [error] 17904#27976: *2 CreateFile() "C:\install\nginx\nginx-1.18.0/test/index.html" failed (2: The system cannot find the file specified), client: 127.0.0.1, server: localhost, request: "GET /index.html HTTP/1.1", host: "localhost"
selected location里的root指令优先级高于,location 外部的root指令;如果selected location 没有root指令,则使用外部的root指令。
root指令:为请求设置根目录;
请求:http://localhost/index.html
示例1:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
2021/03/19 14:12:31 [error] 41016#39084: *4 CreateFile() "C:\install\nginx\nginx-1.18.0/test/index.html" failed (2: The system cannot find the file specified), client: 127.0.0.1, server: localhost, request: "GET /index.html HTTP/1.0", host: "localhost:8080"
示例2:http://localhost/index.html
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8080;
server_name localhost;
location /{
root test;
}
}
页面正常,proxy server将请求转发到localhost:8080地址,nginx从本地返回了resource file。
示例3:
server {
location / {
proxy_pass http://localhost:8080/;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
nginx会将以.gif .jpg .png结尾的请求mapped to the regular location的root指令的参数指定的directory;其他请求uri会匹配上the prefix location指令,将请求转发给the specified proxied server。
配置代理conn的指令有很多。下面介绍几种常用指令的用法:
proxy_pass
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
proxy_pass:1、设置被代理服务的协议、a address和a location 映射到的uri(optional);可以指定http或者https作为协议,地址可以指定为domain或ip,port可选择,port不设置则用默认值,http默认是80端口,https默认是443端口。
2、作为unix-domain socket 路径,在单词“unix”后指定,并且用冒号括起来,格式如下:
proxy_pass http://unix:/tmp/backend.socket:/uri/;
规则:
1、如果proxy_pass 地址domain解析对应多个地址,以循环的方式使用这多个地址,也可以通过一个服务器组指定多个地址;
Syntax: upstream name { ... }
Default: —
Context: http
desc: 定义一个服务器组,设置多个server指令:
Syntax: server address [parameters];
Default: —
Context: upstream
desc: 定义一个服务的address和其他parameters
示例:http://localhost/index.html
upstream req_to_server {
server localhost:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://req_to_server;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8080;
server_name localhost;
location /{
root test;
}
}
请求正确处理,拿到了resource file;
配置设置了一个服务器组req_to_server,并在server context里的location context中,将proxy_pass指令的address设为了该服务器组。
2、如果proxy_pass的地址指定为一个domain name,这个name会先在配置的server groups中搜索,如果没有,则由resolver指令指定域名服务器解析或者服务器本身的dns服务器解析。
resolver:配置域名服务器,用来解析域名;
3、 request uri passed to the server按如下规则:
a、 proxy_pass指令有指定uri,则使用此uri替换规范化化后的请求uri匹配location的那部分;
http://localhost/50x.html
server {
listen 80;
server_name localhost;
location /50x.html {
proxy_pass http://localhost:8081/index.html;
}
error_page 500 502 503 504 /50x.html;
}
server {
listen 8081;
server_name 127.0.0.1;
location /{
root test;
}
}
proxy_pass的uri:index.html替换了matching location的request uri:50x.html;如果是 location / {},则传给server的uri就会是/index.html50x.html.
b、 proxy_pass未指定uri,传到the server的uri和客户端请求的uri一样;如果客户端请求uri改写或者changed,则传递完全changed uri;
http://localhost/index.html
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8081;
}
error_page 500 502 503 504 /50x.html;
}
server {
listen 8081;
server_name 127.0.0.1;
location /{
root test;
}
}
proxy_pass没有指定uri,则将原始request uri作为请求的uri传递给server;
request:http://localhost/50x.html
server {
listen 80;
server_name localhost;
location / {
rewrite /* /index.html break;
proxy_pass http://localhost:8081;
}
error_page 500 502 503 504 /50x.html;
}
server {
listen 8081;
server_name 127.0.0.1;
location /{
root test;
}
}
the changed uri(by rewrite),经规范化后作为请求uri传递给server;
c、 有些情况,无法确定请求uri的哪部分被替代
i、location是使用正则表达式指定时,location里的proxy_pass不能有uri
server {
listen 80;
server_name localhost;
location ~ /.(html)$ {
proxy_pass http://localhost:8081/test;
}
error_page 500 502 503 504 /50x.html;
}
server {
listen 8081;
server_name 127.0.0.1;
location /{
root test;
}
}
C:\install\nginx\nginx-1.18.0>nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in C:\install\nginx\nginx-1.18.0/conf/nginx.conf:43
ii、proxy_pass在named location中时,proxy_pass不能有uri部分;
server {
listen 80;
server_name localhost;
location @index.html {
proxy_pass http://localhost:8081/test;
}
error_page 500 502 503 504 /50x.html;
}
报和i一样的启动bug。
iii、 如果在一个proxied locaton内部,使用rewrite指令改变请求的uri,忽略proxy_pass指定的uri,将完全changed uri传给server,示例见b;
iiii、 proxy_pass使用了变量作为uri;
实验:设置变量指定uri,变量uri未生效,传递的是原始uri;
请求:http://localhost/index.html
server {
listen 80;
server_name localhost;
location /index.html {
set $req_uri /index1.html;
proxy_pass http://localhost:8081$req_uri;
}
error_page 500 502 503 504 /50x.html;
}
server {
listen 8081;
server_name localhost;
location / {
root test;
}
}
发现location /index.html未生效;
location /name/ {
proxy_pass http://127.0.0.1$request_uri;
}此实例用的变量是nginx内置变量request_uri,该变量可以获取请求uri,将原始请求的uri传递给了server;
proxy_pass_header 、proxy_hide_header
一对功能相反的指令
Syntax: proxy_pass_header field;
Default: —
Context: http, server, location
desc:允许proxied server将response header的某个field传递给client
Syntax: proxy_hide_header field;
Default: —
Context: http, server, location
desc:设置proxied server response header除“Date”, “Server”, “X-Pad”, and “X-Accel-…”(默认不传给client)外的某个字段不传给client;
Setting Up FastCGI Proxying
nginx能被用于将请求route到FastCGI servers,这些servers上运行着由各种框架和编程语言构建的application。
最基本的nginx配置包括使用fastcgi_pass指令取代proxy_pass指令和使用fastcgi_param设置传递给FastCGI servers的参数。
假设FastCGI server可以通过localhost:9000访问,示例如下:
SCRIPT_FILENAME参数:用来确定脚本name,
QUERY_STRING 参数:传递请求参数;
server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
d
o
c
u
m
e
n
t
r
o
o
t
document_root
documentrootfastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
此示例,除静态图片的请求外,会将其他所有请求route给运行在localhost:9000上通过FastCGI协议访问的被代理服务。