转发一份比较详细的nginx配置说明。
via:https://deepzz.com/post/how-to-write-nginx-server.html
安装完 nginx ,我们先来看一看 nginx 的默认配置 /etc/nginx/nginx.conf
,当然可能与你的默认配置不同,不过大同小异:
# worker以什么身份运行user nginx; // default nobody# worker进程个数,一般为 CPU 个数,也可选 autoworker_processes 1; # default 1# 每个worker可打开的描述符限制worker_rlimit_nofile 8192;# 错误日志保存路径和级别error_log /var/log/nginx/error.log warn;# 进程pid保存路径pid /var/run/nginx.pid;# 指定dns服务器resolver 10.0.0.1; events { # 每个worker最大连接数 worker_connections 1024; # default 1024}# http 服务定义http { # 加载 mime 类型 include /etc/nginx/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 /var/log/nginx/access.log main; # 是否调用sendfile函数(zero copy 方式)来输出文件,如果磁盘IO重负载应用,可设置为off sendfile on; # 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用 #tcp_nopush on; keepalive_timeout 65; # 代理相关设置 # proxy_connect_timeout 90; # proxy_read_timeout 180; # proxy_send_timeout 180; # proxy_buffer_size 256k; # proxy_buffers 4 256k; # proxy_busy_buffers_size 256k; # proxy_temp_file_write_size 256k; # tcp_nodelay on; # gzip 压缩 #gzip on; # 加载其它配置,这样我们在 conf.d 下写的文件才会生效 include /etc/nginx/conf.d/*.conf; }
加载配置 /etc/nginx/conf.d
,才能让我们的配置生效:
# 加载其它配置include /etc/nginx/conf.d/*.conf;
一般的,如果是小站点不用去修改默认配置。当流量到达一定程度,需要进行适当优化。
内置变量
内置变量,nginx 各个模块都将请求的一些参数进行变量化,通过 $ + 变量名
即可使用。每个模块或多或少都有自己的变量。着重介绍下核心模块的 内置变量:
# 通过arg_<name>的方式可取出相关参数,若请求 /foo?name=Tony&age=2,则 arg_name=tony arg_age=2$arg_name$args# 客户端IP地址二进制$binary_remote_addr# 发送到客户端的字节数,不包括响应头$body_bytes_sent# 发送给客户端字节数$bytes_sent# 连接序列号$connection# 当前已经连接的请求书$connection_requests# Content-Length 请求头$content_length# Content-Type 请求头$content_type# cookie 名称$cookie_name# 当前请求的 root 或 alias 的值$document_root# 与 $uri 相同$document_uri# 优先级:请求行中的 host name,请求头中的 Host,请求匹配的 server name$host# host name$hostname# 任意请求头字段。变量名的最后一部分是转换为小写的字段名,用下划线替换破折号$http_name# 如果连接在 SSL 模式下运行,则为 on,否则为空字符串$https# ? 后如果请求行有参数,或者空字符串$is_args# 设置此变量可以限制响应速度$limit_rate# 当前时间(秒),分辨率为毫秒$msec# nginx 版本号$nginx_version# 当前 worker 进程号$pid# 如果是 pipelined 则为 p,否则为 . $pipe# 代理协议头中的客户端地址,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用$proxy_protocol_addr# 来自代理协议头的客户端端口,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用$proxy_protocol_port# 与 $args 相同$query_string# 与当前请求的 root 或 alias 指令值对应的绝对路径名,所有符号链接都解析为实际路径$realpath_root# 客户端地址$remote_addr# 客户端端口$remote_port# 使用 Basic auth 的用户名$remote_user# 完整的请求行$request# 请求体,当将请求体读入内存缓冲区时,proxy_pass、fastcgi_pass、uwsgi_pass和scgi_pass指令处理的位置可以使用变量的值$request_body# 具有请求主体的临时文件的名称$request_body_file# 如果请求完成则为 OK,否则为空$request_completion# 当前请求的文件路径,基于 root 或 alias 和请求 URI$request_filename# 由16个随机字节生成的惟一请求标识符,以十六进制表示$request_id# 请求长度(包括请求行、头和请求体)$request_length# 请求方法,如 GET 或 POST$request_method# 请求处理时间,从客户端读取第一个字节以来的时间$request_time# 若请求 /foo?a=1&b=2,则 request_uri=/foo?a=1&b=2$request_uri# 如 http 或 https$scheme# 任意响应报头字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号$sent_http_name# 响应结束时发送的任意字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号$sent_trailer_name# 接受请求的服务器的地址$server_addr# 接受请求的 server 名称$server_name# 接受请求的 server 端口$server_port# 请求协议,如 HTTP/1.0 或 HTTP/1.1 或 HTTP/2.0$server_protocol# 响应状态$status$tcpinfo_rtt,$tcpinfo_rttvar,$tcpinfo_snd_cwnd,$tcpinfo_rcv_space# 本地时间ISO 8601标准格式$time_iso8601# 通用日志格式的本地时间$time_local# 若请求 /foo?a=1&b=2,则 uri=/foo$uri# 用户代理$http_user_agent# cookie$http_cookie
你还可以通过自定义变量指令 set
进行变量的定义。
server定义
server 即虚拟服务,它用来描述我们站点一些访问规则。需要填写在 http
标签中,可定义多个,如:
http { server { ... } server { ... } ... }
一个常见的 server 的定义:
resolver 10.0.0.1;# 负载均衡upstream dynamic { zone upstream_dynamic 64k; server backend1.example.com weight=5; server backend2.example.com:8080 fail_timeout=5s slow_start=30s; server 192.0.2.1 max_fails=3; server backend3.example.com resolve; server backend4.example.com service=http resolve; server backup1.example.com:8080 backup; server backup2.example.com:8080 backup; }# http服务server { listen 80; server_name example.com www.example.com; location / { rewrite https://$host; # 重定向到https } }# https 服务server { listen 443 ssl; # 监听端口 server_name example.com www.example.com; # 匹配域名 # ssl证书 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5; ssl_certificate /usr/local/nginx/conf/cert.pem; ssl_certificate_key /usr/local/nginx/conf/cert.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 静态服务 location / { root /usr/share/nginx/html; index index.html index.htm; } # 反向代理 location /api { proxy_pass http://dynamic; health_check; } }
下面就让我们来详细解释下。
http_upstream_module
http_upstream_module,upstream
说白了就是做负载均衡,它可以帮助我们定义一组相同服务的别名,如backend
,当请求到来的时候可以通过相关策略帮我们选一组服务提供响应。
目前只能被 proxy_pass
,fastcgi_pass
,uwsgi_pass
,scgi_pass
,memcached_pass
,grpc_pass
使用。
形式如下:
upstream <name> { # 命名 server <address> [parameters]; # 服务 server <address> [parameters]; ... }
[parameters] 参数可选以下值:
- weight=number,default 1,设置 server 的权重
- max_conns=number,default 0,限制 server 的活跃连接数,0 代表不限制
- max_fails=number,default 1,设置在 fail_timeout 时间内失败的最大次数,可由
proxy_next_upstream
,fastcgi_next_upstream
,uwsgi_next_upstream
,scgi_next_upstream
,memcached_next_upstream
,grpc_next_upstream
指定下组 upstream,0 值代表不启用 - fail_timeout=time,default 10s,设置多长时间判定无连接服务器失败
- backup,标记 server 为备用 server,当 primary server 不可用时启用
- down,标记 server 下线不可用
- resolve,用来监视与服务器域名对应IP地址的更改,它会自动更改上游配置,
upstream
必须驻留在共享内存中,必须写在http
标签中。
http { resolver 10.0.0.1; upstream u { zone ...; ... server example.com resolve; } }
- route=string,设置 server 路由名称
- server=name,
- slow_start=time,慢启动,server 非正常状态恢复到正常需要的时间
- drain,设置为 drain 模式
其它负载均衡设置:
zone name [size]
,设置共享内存的名称和大小state file
,hash key [consistent]
,负载均衡方式,key 可以为文本,变量,或其组合ip_hash
,负载均衡方式,根据IP地址范围分布 server,用 IPv4 前三个8位或整个IPv6keepalive connections
,设置到上游 server 保持最大空闲连接
upstream memcached_backend { server 127.0.0.1:11211; server 10.0.0.2:11211; keepalive 32; } server { ... location /memcached/ { set $memcached_key $uri; memcached_pass memcached_backend; } }
keepalive_requests number
,设置最大请求连接数keepalive_timeout timeout
,连接超时时间ntlm
,允许使用NTLM身份验证代理请求
upstream http_backend { server 127.0.0.1:8080; ntlm; } server { ... location /http/ { proxy_pass http://http_backend; proxy_http_version 1.1; proxy_set_header Connection ""; ... } }
least_conn
,负载均衡方式,将请求传给活跃连接数最少的 serverleast_time header | last_byte [inflight]
,负载均衡方式,将请求传给平均响应时间和活跃连接数最少的 serverqueue number [timeout=time]
,队列缓存,当选择不到 server 处理请求时放入队列,如果队列满,返回502random [two [method]]
,负载均衡方式,sticky
,会话关联,同一客户端请求将会被传给同一 upstream 的同一 server
# cookie upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; sticky cookie srv_id expires=1h domain=.example.com path=/; } # route map $cookie_jsessionid $route_cookie { ~.+\.(?P<route>\w+)$ $route; } map $request_uri $route_uri { ~jsessionid=.+\.(?P<route>\w+)$ $route; } upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; sticky route $route_cookie $route_uri; } # learn upstream backend { server backend1.example.com:8080; server backend2.example.com:8081; sticky learn create=$upstream_cookie_examplecookie lookup=$cookie_examplecookie zone=client_sessions:1m; }
listen
listen 监听设置,来看一看可选参数:
默认 listen *:80 | *:8000; listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]]; listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]]; listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
真的多,可平时也没用几个,举例:
listen 127.0.0.1:8000;listen 127.0.0.1; # 如果只指定地址,默认监听 80listen 8000;listen *:8000;listen localhost:8000;listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;# IPv6listen [::]:8000;listen [::1];# unix socketlisten unix:/var/run/nginx.sock;
其它参数说明:
default_server
,如果指定,server 将会成为默认 serverssl
,开启 ssl 模式,即 httpshttp2
,正常情况开启 http2 都应该开始 ssl,但 nginx 也支持不开启 ssl 下的 http2 协议spdy
,和 http2 一样,建议开启 sslsetfib=number
,监听套接字设置关联的路由表FIB (SO_SETFIB选项)。这目前只适用于FreeBSDfastopen=number
,为监听套接字启用“TCP Fast Open”(1.5.8),并限制尚未完成三方握手的连接队列的最大长度backlog=number
rcvbuf=size
,接受 buffer 的大小(SO_CRCVBUF)sndbuf=size
,发送 buffer 的大小(SO_SNDBUF)accept_filter=filter
,可选 dataready 和 httpready,在 accept() 前过滤deferred
,指示在Linux上使用deferred accept() (TCP_DEFER_ACCEPT套接字选项)bind
,标记指定 address:port 单独的绑定ipv6only on|off
,只接受 IPv6 连接reuseport
so_keepaliv on|off|[keepidle]:[keepintv1]:[keepcnt]
,”TCP keepalive” 开关
server_name
server_name,设置虚拟主机的名称。
形式如下:
默认值 server_name ""; server_name name ...;
例1,穷举域名
server { server_name example.com www.example.com; }
例2,通配符写法
server { server_name example.com *.example.com www.example.*; }
例3,这种写法满足例1
server { server_name .example.com; }
例4,正则表达式,以 ~ 开头
server { server_name www.example.com ~^www\d+\.example\.com$; }
例5,正则表达式捕获
server { server_name ~^(www\.)?(.+)$; location / { root /sites/$2; } }server { server_name _; location / { root /sites/default; } }
例6,正则表达式变量
server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } }server { server_name _; location / { root /sites/default; } }
例7,与空名称使用
server { server_name www.example.com ""; }
如果当一个名称匹配多个 server 的是时候,匹配优先级如下:
- 确切的名称
- 以 * 开头的最长的通配符名称
- 以 * 结尾的最长通配符名称
- 第一个匹配的正则表达式
更多匹配规则请查阅:http://nginx.org/en/docs/http/server_names.html
location
location 是用来干嘛的,它是用来根据 URI 进行配置设置的,如:
server { listen 80; server_name example.com; location / { # 普通请求网页 root /usr/share/nginx/html; index index.html index.htm; } location /api { # API请求代理 proxy_pass http://dynamic; health_check; } }
形式如下:
location [ = | ~ | ~* | ^~ ] uri { ... }
- none,如果没有修饰符,则将该位置解释为前缀匹配。这意味着给定的位置将根据请求URI的开头进行匹配,以确定匹配
=
,代表精确匹配,完全相等即匹配~
,区分大小写的正则表达式匹配~*
,不区分大小写的正则表达式匹配^~
,普通字符匹配,如果该选项匹配,只匹配该选项
nginx 的匹配过程如下:
- 精确匹配
=
,如果匹配成功,搜索停止 - 前缀匹配,最长位置匹配,如果该匹配具有
^~
,搜索停止 - 正则匹配,按配置文件中定义的顺序进行匹配。
- 如果第3条规则产生匹配的话,结果被使用。否则,使用第2条规则的结果。
让我们通过一个例子来了解下匹配规则:
location = / { [ configuration A ] } location / { [ configuration B ] } location /documents/ { [ configuration C ] } location ^~ /images/ { [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { [ configuration E ] }
请求 /
将会匹配 A,请求 /index.html
将会匹配 B,请求 /documents/document.html
将会匹配 C,请求 /images/1.gif
将会匹配 D,请求 /documents/1.jpg
将会匹配 E。
ssl mode
ssl 模式可以让我们站点启用 HTTPS,具体详细请参考 http_ssl_module。
想要开启 ssl 模式,需要在 listen
关键字处添加上 ssl
,如:
server { listen 443 ssl; server_name example.com; ssl_certificate example.com.rsa.crt; ssl_certificate_key example.com.rsa.key; ssl_certificate example.com.ecdsa.crt; ssl_certificate_key example.com.ecdsa.key; ... }
上面的例子是部署双证书,当某一证书因某种原因失效不至于导致站点不能访问。下面来看看参数解释:
ssl_buffer_size size
,default 16k,发送数据的缓冲区的大小ssl_certificate file
,PEM 格式证书文件ssl_certificate_key file
,PEM 格式私钥文件ssl_ciphers ciphers
,default HIGH:!aNULL:!MD5,ssl套件 openssl ciphersssl_client_certificate file
,用于验证客户端证书的 CA 文件ssl_crl file
,用于验证客户端证书的吊销文件ssl_dhparam file
,为DHE密码指定具有DH参数的文件ssl_early_data on|off
,default onssl_ecdh_curve curve
,default auto,为ECDHE密码指定一条曲线ssl_password_file file
,私钥密码文件ssl_prefer_server_ciphers on|off
,是否启用服务器套件偏好ssl_protocols [SSLv2] [SSLv3] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3]
,default TLSv1 TLSv1.1 TLSv1.2,可选的ssl协议ssl_session_cache off|none|[builtin[:size]] [shared:name:size]
,default none,设置 session cache 的类型和大小
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_ticket_key file
,设置一个文件,其中包含用于加密和解密TLS会话票据的密钥
ssl_session_ticket_key current.key;ssl_session_ticket_key previous.key; 随机一个 AES256(80),AES128(40)openssl rand 80 > ticket.key
ssl_session_tickets on|off
,default on,是否启用 session ticketssl_session_timeout time
,default 5m,超时时间ssl_stapling on|off
,default off,ocsp 装订ssl_stapling on; resolver 192.0.2.1;
ssl_stapling_file file
ssl_stapling_responder url
ssl_stapling_verify on|off
,default offssl_trusted_certificate file
,指定验证客户端证书的 CA 文件ssl_verify_client on|off|optional|optional_no_ca
,default off,是否验证客户端证书ssl_verify_depth number
,default 1,设置客户端证书链的验证深度
相关变量
$ssl_cipher,已建立连接使用的 ciphers$ssl_ciphers,客户端支持的 ciphers$ssl_client_escaped_cert,urlencoded 客户端证书$ssl_client_fingerprint,SHA1指纹$ssl_client_i_dn,issuer DN$ssl_client_i_dn_legacy,同上,1.11.6之后使用$ssl_client_raw_cert,PEM格式客户端证书$ssl_client_s_dn,subject DN$ssl_client_s_dn_legacy,同上,1.11.6之后使用$ssl_client_serial,客户端证书序列号$ssl_client_v_end,客户端证书结束时间$ssl_client_v_remain,剩余多少天$ssl_client_v_start,证书开始时间$ssl_client_verify,客户端证书是否验证成功,"SUCCESS" 或 "FAILED:reason" 或 "NONE"$ssl_curves,客户端支持的曲线$ssl_early_data$ssl_protocol,连接使用的协议$ssl_server_name,从 SNI 获取的 server name$ssl_session_id,连接的 session id$ssl_session_reused,session是否重用,"r" 重用,"." 没有
其它模块
其它模块你需要根据文档及编译信息判断该模块是否默认编译在 nginx 中,并且版本是否匹配:
ngx_http_access_modulengx_http_addition_module ngx_http_api_module ngx_http_auth_basic_module ngx_http_auth_jwt_module ngx_http_auth_request_module ngx_http_autoindex_module ngx_http_browser_module ngx_http_charset_module ngx_http_dav_module ngx_http_empty_gif_module ngx_http_f4f_module ngx_http_fastcgi_module ngx_http_flv_module ngx_http_geo_module ngx_http_geoip_module ngx_http_grpc_module ngx_http_gunzip_module ngx_http_gzip_module ngx_http_gzip_static_module ngx_http_headers_module ngx_http_hls_module ngx_http_image_filter_module ngx_http_index_module ngx_http_js_module ngx_http_keyval_module ngx_http_limit_conn_module ngx_http_limit_req_module ngx_http_log_module ngx_http_map_module ngx_http_memcached_module ngx_http_mirror_module ngx_http_mp4_module ngx_http_perl_module ngx_http_proxy_module ngx_http_random_index_module ngx_http_realip_module ngx_http_referer_module ngx_http_rewrite_module ngx_http_scgi_module ngx_http_secure_link_module ngx_http_session_log_module ngx_http_slice_module ngx_http_spdy_module ngx_http_split_clients_module ngx_http_ssi_module ngx_http_ssl_module ngx_http_status_module ngx_http_stub_status_module ngx_http_sub_module ngx_http_upstream_module ngx_http_upstream_conf_module ngx_http_upstream_hc_module ngx_http_userid_module ngx_http_uwsgi_module ngx_http_v2_module ngx_http_xslt_module
上一篇:via浏览器嗅探网页视频链接
下一篇:使用nginx反代谷歌