nginx常用配置

nginx

基本配置

nginx简单来说可以由三部分组成:全局块、events块和http块,并且nginx中存在作用域,每个大括号代表一个作用域。
#全局块 user www; worker_processes 1; pid logs/nginx.pid; #events块 events { worker_connections 1024; } # http块 http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #server块 server { #指定域名和端口号 listen 80; server_name localhost; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; location / { root html; index index.html index.htm; } } }
nginx主要功能在http块中,http块又有server块,server块又有location。
server块是虚拟主机部分,需要指定域名(或ip地址)以及端口号,每个server块中可以有多个location块,location块的作用是根据客户端的请求URL去定位不同的应用。
如上面的配置,当访问http:localhost时就会匹配到location /,并将html/index.html返回。
location的匹配规则

内置变量

nginx变量理解成某种在请求之间全局共享的东西,或者说“全局变量”。所有的内置变量都可以通过$变量名来引用。
常用的内置变量
  • $args //请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
  • $content_length //HTTP请求信息里的“Content-Length”
  • $conten_type //HTTP请求信息里的“Content-Type”
  • $document_root //nginx虚拟主机配置文件中的root参数对应的值
  • $document_uri //当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的参数
  • $host //主机头,也就是域名,请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称
  • $http_user_agent //客户端的详细信息,也就是浏览器的标识,用curl -A可以指定
  • $http_cookie //客户端的cookie信息
  • $limit_rate //如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
  • $remote_addr //客户端的公网ip
  • $remote_port //客户端的端口
  • $remote_user //如果nginx有配置认证,该变量代表客户端认证的用户名
  • $request_body_file //做反向代理时发给后端服务器的本地资源的名称
  • $request_method //请求资源的方式,GET/PUT/DELETE等
  • requestilename//document_root/$document_uri的组合
    • f
  • requestri//document_uri和$args
    • u
  • $scheme //请求的协议,如ftp,http,https
  • $server_protocol //客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
  • $server_addr //服务器IP地址
  • $server_name //服务器的主机名
  • $server_port //服务器的端口号
  • uri//document_uri相同
  • $http_referer //客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定

静态资源

使用静态资源

当指定某个目录作为locationroot时,可以通过URL的方式访问到静态资源。
\html\static中存放一张图片R-C.jpg,访问localhost/static/R-C.jpg
location / { root html; index index.html index.htm; }
notion image

缓存

可以设置expires来控制资源的缓存时间。
使用置expires可以控制HTTP应答中的“Expires”和“Cache-Control”的头标,从而起到控制页面缓存的作用。
可以在time值中使用正数或负数。“Expires”头标的值将通过当前系统时间加上您设定的 time 值来获得。
  • epoch指定“Expires”的值为 1 January, 1970, 00:00:01 GMT。
  • max指定“Expires”的值为 31 December 2037 23:59:59 GMT,“Cache-Control”的值为10年。
  • 1指定“Expires”的值为 服务器当前时间 -1s,即永远过期
“Cache-Control”头标的值由您指定的时间来决定:
  • 负数:Cache-Control: no-cache正数或零:Cache-Control: max-age = #, # 为您指定时间的秒数。
  • “off” 表示不修改“Expires”和“Cache-Control”的值
甚至可以使用时间单位,比如30m,会被自动换算成1800s
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30m; }
所有时间单位。
notion image
设置的缓存时间
当然你也可以通过add_header来控制缓存时间,效果是一样的,只不过没使用expires方便
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { # expires 30m; add_header cache-control 'max-age=1000'; }

压缩

nginx支持gzip压缩,通过gzip on;来启动gzip压缩。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { gzip on; # 是否开启gzip压缩 gzip_comp_level 6; # 压缩比,1-9,压缩比越高服务器开销越大,一般设置5-7即可 gzip_types image/jpeg ; # 匹配MIME类型进行压缩,(无论是否指定)"text/html"类型总是会被压缩的 }
notion image
gzip开启成功
当nginx开启反向代理时,需要设置gzip_proxied,默认值是off
gzip_proxied在Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含“Via”的 header头。
  • off - 关闭所有的代理结果数据的压缩
  • expired - 启用压缩,如果header头中包含 “Expires” 头信息
  • no-cache - 启用压缩,如果header头中包含 “Cache-Control:no-cache” 头信息
  • no-store - 启用压缩,如果header头中包含 “Cache-Control:no-store” 头信息
  • private - 启用压缩,如果header头中包含 “Cache-Control:private” 头信息
  • no_last_modified - 启用压缩,如果header头中不包含 “Last-Modified” 头信息
  • no_etag - 启用压缩 ,如果header头中不包含 “ETag” 头信息
  • auth - 启用压缩 , 如果header头中包含 “Authorization” 头信息
  • any - 无条件启用压缩

日志

nginx分为两种日志:access_log(访问日志)和error_log(错误日志)。

访问日志

访问日志主要记录客户端的请求。客户端向Nginx服务器发起的每一次请求都记录在这里。客户端IP,浏览器信息,referer,请求处理时间等信息都可以在访问日志里得到。
错误日志在Nginx中是通过error_log指令实现的。该指令记录服务器和请求处理过程中的错误信息。
访问日志通过access_log来设置,格式如下
access_log path [format [buffer=size | off ] 默认值: access_log log/access.log combined
指令 access_log 指派路径、格式和缓存大小。参数 “off” 将清除当前级别的所有 access_log 指令。如果未指定格式,则使用预置的 “combined” 格式。缓存默认是64k。
我们设置好访问日志,文件路径指向logs/localhost.access.log,并使用默认格式。然后硬刷新
server { listen 80; server_name localhost; access_log logs/localhost.access.log combined; }
# logs/localhost.access.log文件 127.0.0.1 - - [23/Jan/2022:11:56:51 +0800] "GET / HTTP/1.1" 200 851 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53" 127.0.0.1 - - [23/Jan/2022:11:56:51 +0800] "GET /static/R-C.jpg HTTP/1.1" 200 9383 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53" 127.0.0.1 - - [23/Jan/2022:11:56:52 +0800] "GET /favicon.ico HTTP/1.1" 404 288 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.53"

错误日志

错误日志通过error_log来设置,格式如下
error_log path(存放路径) level(日志等级) 日志等级分为[ debug | info | notice | warn | error | crit ],越前面的等级越高
示例
server { listen 80; server_name localhost; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; }

配置HTTPS

前面已经了解了如何配置http服务,那么如何配置https呢?
配置https前必须要先准备好SSL证书,在根目录下新建cert目录,将两个文件放到此目录中,然后在nginx配置文件中配置
server { listen 443 ssl; server_name localhost; ssl_certificate ../cert/fullchain.pem; ssl_certificate_key ../cert/privkey.pem; location / { root html; index index.html index.htm; } }
https默认端口号是443,listen 443 ssl表示监听此端口上接受的连接并且应在 SSL 模式下工作。
notion image
因为window不能使用443端口,因此我改为了81端口
因为window不能使用443端口,因此我改为了81端口,实际中在服务器上是开启443端口,因为访问https时默认使用的端口号是443
假如用户仍然是通过http访问而不是https,我们如何让强制用户从http协议跳转到https协议呢?其实也很简单,通过rewrite重写URL即可
server { listen 80; server_name localhost; # 如果端口号不是443则重写URL if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 ; } }

自定义错误页面

默认情况下,nginx会提供默认的404页面,但是我们通常想要使用自己做的错误界面,因此就需要在nginx进行修改。
首先准备好写好的404.html50x.html
server { listen 80; server_name localhost; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; }
当出现404或504等错误时,就会跳转到你设置的界面之中。

访问控制

某些时候,我们可能只希望某些特定ip才能访问,例如后台信息系统等场景,这时候就需要使用nginx的allowdeny,设置白名单和黑名单。
location / { deny 123.9.51.42; # 禁止该ip的访问 allow 45.76.202.231; # 只允许该ip的访问 }
可以传入all来表示禁止所有的访问
#禁止所有ip访问 location / { deny all; } #只允许 45.76.202.231 的访问 location / { allow 45.76.202.231; deny all; } #禁止对敏感文件的访问 location = /user.ini { deny all; }

反向代理

nginx通过proxy_pass来实现反向代理。
location ^~ /api/ { proxy_pass http://localhost:3000/; }
此时访问http://localhost/api/就相当于访问http://localhost:3000/
反向代理还有些常用的指令:
  • proxy_set_header :在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。
  • proxy_connect_timeout:配置Nginx与后端代理服务器尝试建立连接的超时时间。
  • proxy_read_timeout : 配置Nginx向后端服务器组发出read请求后,等待相应的超时时间。
  • proxy_send_timeout:配置Nginx向后端服务器组发出write请求后,等待相应的超时时间。
  • proxy_redirect :用于修改后端服务器返回的响应头中的Location和Refresh。

虚拟主机

虚拟主机是指在一台物理主机服务器上划分出多个磁盘空间,每个磁盘空间都是一个虚拟主机,每台虚拟主机都可以对外提供Web服务,并且互不干扰。虚拟主机可以把多个不同域名的网站部署在同一台服务器上。

基于不同端口号的虚拟主机

通过不同的端口号来配置多个网站。
server { listen 80; server_name yujin123.cn; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; error_page 404 /404.html; location / { root html1; index index.html index.htm; } } server { listen 81; server_name yujin123.cn; location / { root html2; index index.html index.htm; } }

基于不同域名的虚拟主机

通过多个域名来配置虚拟主机
server { listen 80; server_name yujin123.cn; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; error_page 404 /404.html; location / { root html1; index index.html index.htm; } } server { listen 80; server_name yujin321.cn; location / { root html2; index index.html index.htm; } }

基于不同ip地址的虚拟主机

server { listen 80; server_name 112.23.108.95; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; error_page 404 /404.html; location / { root html1; index index.html index.htm; } } server { listen 80; server_name 112.23.108.94; location / { root html2; index index.html index.htm; } }

实现跨域

nginx实现跨域有两种方式。

第一种(同源)

第一种方式是利用反向代理,代理后端接口使其与网站同源。
server { listen 80; server_name localhost; access_log logs/localhost.access.log combined; error_log logs/localhost.error.log debug; location ^~ /api/ { proxy_pass http://localhost:3000/; } location / { root html; index index.html index.htm; } }
因为网站与请求接口同源(协议、域名和端口号都相同),符合浏览器的同源策略,因此不会产生跨域问题。

第二种(CORS)

第二种是利用跨源资源共享(CORS)来实现跨域,在nginx中添加响应头,配置access-control-allow-originaccess-control-allow-headersaccess-control-allow-methods,分别表示允许跨域的源、请求头和方法。
server { listen 8080; server_name localhost; location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; } }