概述
简介
Nginx(“engine x”)一个具有高性能的【HTTP】和【反向代理】的 【WEB服务器】,同时也是一个【POP3/SMTP/IMAP代理服务器】,是由伊戈尔·赛索耶夫(俄罗斯人) 使用C语言编写的,Nginx的第一个版本是 2004年10月4号发布的0.1.0版本。
正向代理 代理的是 客户端。
反向代理 代理的是 服务端。
Nginx的优点
-
速度更快、并发更高——
单次请求或者高并发请求的环境下,Nginx都会比其他Web服务器响应 的速度更快。一方面在正常情况下,单次请求会得到更快的响应,另一方面,在高峰期 (如有数以万计的并发请求),Nginx能比其他Web服务器更快地响应请求。Nginx之所以有这么高的并发处理能力和这么好的性能,原因在于Nginx采用了多进程和I/O多路复用 (epoll)的底层实现。
-
配置简单,扩展性强 ——
Nginx的设计极具扩展性,它本身就是由很多模块组成,这些模块的使 用可以通过配置文件的配置来添加。这些模块有官方提供的、也有第三方提供的模块,如果需要完全可以开发服务自己业务特性的定制模块。
-
高可靠性——
Nginx采用的是多进程模式运行,其中有一个master主进程和N多个worker进程,master主进程负责管理worker进程,worker进程的数量可以手动设置,每个worker进程之间都是相互独立提供服务,并且master主进程可以在某一个worker进 程出错时,快速去"拉起"新的worker进程提供服务。
-
热部署 ——
现在互联网项目都要求以7*24小时进行服务的提供,针对于这一要求, Nginx也提供了热部署功能,可以在Nginx不停止的情况下,对Nginx 进行文件升级、更新配置和更换日志文件等功能。
-
成本低、BSD许可证
BSD是一个开源的许可证,世界上的开源许可证有很多,现在比较流行 的有六种分别是GPL、BSD、MIT、Mozilla、Apache、LGPL。这六种的区别:
Nginx本身是开源的,我们不仅可以免费的将Nginx应用在商业领域,而 且还可以在项目中直接修改Nginx的源码来定制自己的特殊要求。
功能服务
基本服务
Nginx提供的基本功能服务从大体上归纳为 “基本HTTP服务”、“高级 HTTP服务”和"邮件服务"等三大类。
基本HTTP服务
Nginx可以提供基本HTTP服务,可以作为HTTP代理服务器和反向代理服 务器,支持通过缓存加速访问,可以完成简单的负载均衡和容错,支持 包过滤功能,支持SSL等。
- 处理静态文件、处理索引文件以及支持自动索引;
- 提供反向代理服务器,并可以使用缓存加上反向代理,同时完成负载 均衡和容错;
- 提供对FastCGI、memcached等服务的缓存机制,同时完成负载均 衡和容错;
- 使用Nginx的模块化特性提供过滤器功能。Nginx基本过滤器包括 gzip压缩、ranges支持、chunked响应、XSLT、SSI以及图像缩放 等。其中针对包含多个SSI的页面,经由FastCGI或反向代理,SSI过 滤器可以并行处理。
- 支持HTTP下的安全套接层安全协议SSL.
- 支持基于加权和依赖的优先权的HTTP/2
高级HTTP服务
- 支持基于名字和IP的虚拟主机设置
- 支持HTTP/1.0中的KEEP-Alive模式和管线(PipeLined)模型连接
- 自定义访问日志格式、带缓存的日志写操作以及快速日志轮转。
- 提供3xx~5xx错误代码重定向功能
- 支持重写(Rewrite)模块扩展
- 支持重新加载配置以及在线升级时无需中断正在处理的请求
- 支持网络监控
- 支持FLV和MP4流媒体传输
邮件服务
Nginx提供邮件代理服务也是其基本开发需求之一,主要包含以下特性:
- 支持IMPA/POP3代理服务功能
- 支持内部SMTP代理服务功能
常用的功能模块
- 静态资源部署
- Rewrite地址重写 (正则表达式)
- 反向代理
- 负载均衡 (轮询、加权轮询、ip_hash、url_hash、fair)
- Web缓存
- 环境部署 (高可用的环境 )
- 用户认证模块
- …
核心组成
-
nginx二进制可执行文件
-
nginx.conf (配置文件 )
-
error.log (错误的日志记录 )
-
access.log (访问日志记录)
目录结构
/usr/local/nginx 的目录结构(使用tree /usr/local/nginx查看)
conf目录的…cgi,CGI( Common Gateway Interface) 通用网关【接口】,主要解决的问题 是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用CGI【程序】处理及相应结果给客户端的一种标准规范。
后缀为 .default 的文件为前缀名文件的备份文件,如fastcgi.conf.default 是 fastcgi.conf 的备份文件。
├── client_body_temp
├── conf
│ ├── fastcgi.conf (是fastcgi的配置文件)
│ ├── fastcgi.conf.default
│ ├── fastcgi_params (是fastcgi的参数文件)
│ ├── fastcgi_params.default
│ ├── mime.types (记录的是HTTP协议中的Content-Type的值和文件后缀名的对应关系)
│ ├── mime.types.default
│ ├── nginx.conf (是Nginx的核心配置文件,这个文件非常重要,也是学习的重点)
│ ├── nginx.conf.default
│ ├── scgi_params (是scgi的参数文件)
│ ├── scgi_params.default
│ ├── uwsgi_params (是uwsgi的参数文件)
│ ├── uwsgi_params.default
│ ├── koi-utf (与编码转换映射相关的配置文
件,下面两个也是)
│ ├── koi-win
│ └── win-utf
├── fastcgi_temp
├── html (存放nginx自带的两个静态的html页面)
│ ├── 50x.html (访问失败后的失败页面)
│ └── index.html (访问成功的默认首页)
├── logs
│ ├── access.log (访问日志)
│ ├── error.log (错误日志)
│ └── nginx.pid (记录nginx的pid好)
├── proxy_temp
├── sbin (存放执行程序文件nginx)
│ └── nginx (用于控制Nginx的启动和停止)
├── scgi_temp
└── uwsgi_temp
实时查看访问日志、错误日志:
tail -f /usr/local/nginx/logs/access.log
tail -f /usr/local/nginx/logs/error.log
服务器启停命令
Nginx的启停在linux系统中也有多种方式,如:
- Nginx服务的信号控制
- Nginx的命令行控制
Nginx服务的信号控制
Nginx后台进程中包含一个master进程和多个worker进程,master进程主要用来管理worker进程,包含接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当 worker进程出现异常退出后,会自动重新启动新的worker进程。而 worker进程则是专门用来处理用户请求的,各个worker进程之间是平等的,并且相互独立,处理请求的机会也是一样的。
因为master进程在管理worker进程,所以只需要通过给master进程发送信号就可以来控制 Nginx。这需要 进程号和信号:
-
使用
ps -ef | grep nginx
命令查看nginx的相关进程号。或者查看 /usr/local/nginx/logs/nginx.pid 下的内容,里面记录了 master进程的PID。
-
信号:
信号 作用 TERM/INT 立即关闭整个服务 QUIT 处理完任务后再关闭整个服务 HUP 重读配置文件并使服务对新配置项生效 USR1 重新打开日志文件,可以用来进行日志切割 USR2 平滑升级到最新版的Nginx WINCH 所有子进程不在接收处理新连接,相当于给work进程发 送QUIT指令
调用命令为 : kill -信号 PID号
-
发送TERM/INT信号给master进程,会将Nginx服务立即关闭。
kill -TERM PID 或者 kill -TERM `cat /usr/local/nginx/logs/nginx.pid` kill -INT PID 或者 kill -INT `cat /usr/local/nginx/logs/nginx.pid`
-
发送QUIT信号给master进程,master进程会控制所有的work进程不 再接收新的请求,等所有请求处理完后,在把进程都关闭掉。
kill -QUIT PID 或者 kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
发送HUP信号给master进程,master进程会控制旧的work进程不再接收新的请求,等处理完请求后将旧的work进程关闭掉,然后根据nginx的配置文件重新启动新的work进程。
kill -HUP PID 或者 kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
发送USR1信号给master进程,告诉Nginx重新开启日志文件。
kill -USR1 PID 或者 kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
发送USR2信号给master进程,告诉master进程要平滑升级,这个时 候,会重新开启对应的master进程和work进程,整个系统中将会有 两个master进程,并且新的master进程的PID会被记录在
/usr/local/nginx/logs/nginx.pid
,而之前的旧的master进程 PID会被记录在/usr/local/nginx/logs/nginx.pid.oldbin
文件中,接着再次发送QUIT信号给旧的master进程,让其处理完请求后再进行关闭。kill -USR2 PID 或者 kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` kill -QUIT PID 或者 kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
-
发送WINCH信号给master进程,让master进程控制不让所有的work 进程在接收新的请求了,请求处理完后关闭work进程。注意master进程不会被关闭掉。
kill -WINCH PID 或者 kill -WINCH `cat /usr/local/nginx/logs/nginx.pid`
Nginx的命令行控制
这是通过Nginx安装目录下的sbin下的可执行文件nginx来进行 Nginx状态的控制,我们可以通过 ./nginx -h来查看都有哪些参数可以用:
- -?和-h:显示帮助信息
- -v:打印版本号信息并退出
- -V:打印版本号信息和配置信息并退出
- -t:测试nginx的配置文件语法是否正确并退出
- -T:测试nginx的配置文件语法是否正确并列出用到的配置文件信息然后 退出
- -q:在配置测试期间禁止显示非错误消息
- -s:signal信号,后面可以跟 :
- stop [快速关闭,类似于TERM/INT信号的作用]
- quit [优雅的关闭,类似于QUIT信号的作用]
- reopen [重新打开日志文件类似于USR1信号的作用] reload[类似于HUP信号的作用]
- -p prefix路径:指定Nginx的prefix路径,(默认为: /usr/local/nginx/)
- -c 配置文件路径:指定Nginx的配置文件路径,(默认为: conf/nginx.conf)
- -g:用来补充Nginx配置文件,向Nginx服务指定启动时应用全局的配置
核心配置文件结构
Nginx的核心配置文件默认是放在 /usr/local/nginx/conf/nginx.conf
,下面是默认的文件内容,且去除了注释部分:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
文件内容的格式:
-
全局块:主要设置Nginx服务器整体运行的配置指令。
指令名 指令值
-
events块:主要设置Nginx服务器与用户的网络连接,这一部分对 Nginx服务器的性能影响较大。
events { 指令名 指令值; }
-
http块:是Nginx服务器配置中的重要部分,用于设置 代理、缓存、日志记录、 第三方模块配置。
- server块:是Nginx配置和虚拟主机相关的内容。
- location块:基于Nginx服务器接收请求字符串与 location后面的值进行匹配,对特定请求进行处理。
http { 指令名 指令值 server { 指令名 指令值 location / { 指令名 指令值 } } }
http块中可以配
置多个server块,每个server块又可以配置多个location块。
- server块:是Nginx配置和虚拟主机相关的内容。
全局块
-
user 指令 —— 用于配置运行Nginx服务器的worker进程的用户和用户组。
语法 user 用户名字 [所属组别group] 默认值 nobody 位置 全局块 该属性也可以在编译的时候指定,语法如下 ./configure --user=user --group=group,如果两个地方都进行了设置,最终生效的是配置文件中的配置。
使用例子:
-
在nginx.conf的全局块中 设置一个用户信息 “www”;
user www;
可能需要先创建用户,在终端输入: useradd www
-
修改 location块:
location / { root /home/www/html; index index.html index.htm; }
root的值原来是 /root/html,但用户www没有权限访问,所以路径该改为 /home/www/html(创建用户后都会在/home下新建一个用户名文件夹,可以将用户需要用到的文件放进去)
-
-
master_process 指令 —— 用来指定是否开启工作进程。
语法 master_process on/off; 默认值 master_process on; 位置 全局块 -
worker_process指令 —— 用于配置Nginx生成工作进程的数量。
这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致。
语法 worker_process num/auto; 默认值 1 位置 全局块 -
其他指令:
-
daemon —— 设置是否以守护进程的方式启动,默认为 daemon on;
守护式进程是linux后台执行的一种服务进程,特点是独立于控制终端, 不会随着终端关闭而停止。
-
pid —— 用来配置Nginx当前master进程的进程号ID存储的文件路径。默认为 pid logs/nginx.pid;
该属性可以通过./configure --pid-path=PATH来指定
-
error_log —— 用来配置Nginx的错误日志存放路径
语法 error_log file [日志级别] 默认值 error_log logs/error.log error; 位置 全局块,http,server,location 该属性可以通过./configure --error-log-path=PATH来指定
其中日志级别的值有: debug|info|notice|warn|error|crit|alert|emerg,翻译过来为调试|信息|通知|警告|错误|临界|警报|紧急,建议设置的时候不要设置成info以下的等级,因为会带来大量的磁盘I/O消耗,影响Nginx的性能。
-
include —— 用来引入其他配置文件,使Nginx的配置更加灵活。可以放在任意地方。
语法:include file
-
events块
-
accept_mutex —— 用来设置Nginx网络连接序列化。
语法 accept_mutex on/off; 默认值 accept_mutex on; 位置 events 这个配置主要可以用来解决常说的"惊群"问题。Nginx后台是以多进程的工作模式,客户端发来一个请求连接,会有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx的整体性 能。如果将上述值设置为on(开启状态),将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢。
-
multi_accept —— 用来设置是否允许同时接收多个网络连接。
语法 multi_accept on/off; 默认值 multi_accept off; 位置 events 如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的 连接。否则,一个工作进程可以同时接受所有的新连接。
-
worker_connections —— 用来配置单个worker进程最大的连接数。
语法 worker——connections 数量 默认值 worker——connections 512 位置 events 这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能 的连接数。另外,number值不能大于操作系统支持打开的最大文件句 柄数量。
-
use —— 用来设置Nginx服务器选择哪种事件驱动来处理网络消息。
语法 user 方法 默认值 根据操作系统而定 位置 events 注意:此处所选择事件处理模型是Nginx优化部分的一个重要内容, method的可选值有 select / poll / epoll / kqueue等,只有linux内核在2.6以上时,才能使用 epoll 函数来优化Nginx。
events指令配置例子:
events{
accept_mutex on;
multi_accept on;
worker_commections 1024;
use epoll;
}
启动测试:
./nginx -t
./nginx -s reload
http块
-
定义MIME-Type :确定、区分网络资源的媒体类型。(如HTML、XML、GIF、JSON等)
在Nginx的配置文件中,默认有两行配置:
include mime.types; default_type application/octet-stream;
-
default_type —— 用来配置Nginx响应前端请求默认的MIME类型。
语法 default_type 资源类型 默认值 default_type text/plain 位置 http、server、location 例子:
location /get_text { default_type text/html; return 200 "<h1>This is nginx's text</h1>"; } location /get_json{ default_type application/json; return 200 '{"name":"TOM","age":18}'; }
-
-
自定义服务日志:
Nginx中日志的类型分access.log、error.log。 access.log用来记录用户所有的访问请求。 error.log记录nginx本身运行时的错误信息,不会记录用户的访问请 求。
Nginx服务器支持对服务日志的格式、大小、输出等进行设置,需要使 用到两个指令,分别是access_log和log_format指令。
-
access_log —— 用来设置用户访问日志的相关属性。
语法 access_log 路径 [格式名 [buffer=大小]] 默认值 access_log logs/access.log combined; 位置 http , server , location -
log_format —— 用来指定日志的输出格式。
语法 log_format 格式名 [escape=default|json|none]
string…;默认值 log_format combined “…” 位置 http
配置文件中的注释内容:
#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 —— 用来设置Nginx服务器是否使用sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性。
语法 sendfile on/off; 默认值 sendfile off; 位置 http、server、location -
keepalive_timeout —— 用来设置长连接的超时时间
语法 keepalive_timeout 时长; 默认值 keepalive_timeout 75s; 位置 http、server、location -
keepalive_requests —— 用来设置一个keep-alive连接使用的次数。
语法 keepalive_requests 数量; 默认值 keepalive_requests 100; 位置 http、server、location
案例
需求如下:
(1)有如下访问:
http://192.168.205.129:8081/server1/location1
访问的是:index_sr1_location1.html
http://192.168.205.129:8081/server1/location2
访问的是:index_sr1_location2.html
http://192.168.205.129:8082/server2/location1
访问的是:index_sr2_location1.html
http://192.168.205.129:8082/server2/location2
访问的是:index_sr2_location2.html
(2)如果访问的资源不存在,
返回自定义的404页面
(3)将/server1和/server2的配置使用不同的配置文件分割
将文件放到/home/www/conf.d目录下,然后使用include进行合并
(4)为/server1和/server2各自创建一个访问日志文件
相关文件目录如下:
/home/www
├── conf.d
└── myweb
├── 404.html
├── server1
│ ├── location1
│ │ └── index_sr1_location1.html
│ ├── location2
│ │ └── index_sr1_location2.html
│ └── logs
└── server2
├── location1
│ └── index_sr1_location1.html
├── location2
│ └── index_sr1_location2.html
└── logs
文件配置内容如下:
##全局块
user www; #配置允许运行Nginx工作进程的用户和用户组
worker_processes 2; #配置运行Nginx进程生成的worker进程数
error_log logs/error.log; #配置Nginx服务器运行对错误日志存放的路径
pid logs/nginx.pid; #配置Nginx服务器允许时记录Nginx的master进程的PID文件路径和名称
#daemon on; ##配置Nginx服务是否以守护进程方法启动
##events块
events{
accept_mutex on; #设置Nginx网络连接序列化
multi_accept on; #设置Nginx的worker进程是否可以同时接收多个请求
worker_connections 1024; #设置Nginx的worker进程最大的连接数
use epoll; #设置Nginx使用的事件驱动模型
}
##http块
http{
include mime.types; #定义MIME-Type
default_type application/octet-stream;
sendfile on; #配置允许使用sendfile方式运输
keepalive_timeout 65; #配置连接超时时间
#配置请求处理日志格式
log_format server1 '===>server1 access log';
log_format server2 '===>server2 access log';
##server块
include /home/www/conf.d/*.conf;
}
/home/www/conf.d目录下的 server1.conf:
server{
listen 8081; #配置监听端口和主机名称
server_name localhost;
#配置请求处理日志存放路径
access_log /home/www/myweb/server1/logs/access.log server1;
#配置错误页面
error_page 404 /404.html;
#配置处理/server1/location1请求的location
location /server1/location1{
root /home/www/myweb;
index index_sr1_location1.html;
}
#配置处理/server1/location2请求的location
location /server1/location2{
root /home/www/myweb;
index index_sr1_location2.html;
}
#配置错误页面转向
location = /404.html {
root /home/www/myweb;
index 404.html;
}
}
/home/www/conf.d目录下的 server2.conf:
server{
listen 8082;
server_name localhost;
#配置请求处理日志存放路径
access_log /home/www/myweb/server2/logs/access.log server2;
#配置错误页面,对404.html做了定向配置
error_page 404 /404.html;
#配置处理/server1/location1请求的location
location /server2/location1{
root /home/www/myweb;
index index_sr2_location1.html;
}
#配置处理/server2/location2请求的location
location /server2/location2{
root /home/www/myweb;
index index_sr2_location2.html;
}
#配置错误页面转向
location = /404.html {
root /home/www/myweb;
index 404.html;
}
}
将Nginx配置为系统服务
为了方便对Nginx服务的启动和停止等相关操作,可把Nginx应用服务设置成为系统服务,具体实现步骤:
-
在/usr/lib/systemd/system目录下添加nginx.service:
vim /usr/lib/systemd/system/nginx.service
内容如下:
[Unit] Description=nginx web service Documentation=http://nginx.org/en/docs/ After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s stop PrivateTmp=true [Install] WantedBy=default.target
-
如果是非root用户,可能有权限问题,需要进行权限设置:
chmod 755 /usr/lib/systemd/system/nginx.service
-
然后就可以使用系统命令来操作nginx服务了:
启动: systemctl start nginx 停止: systemctl stop nginx 重启: systemctl restart nginx 重新加载配置文件: systemctl reload nginx 查看nginx状态: systemctl status nginx 开机启动: systemctl enable nginx
Nginx命令配置到系统环境
Nginx安装目录下的二级制可执行文件nginx的很多命 令,要想使用这些命令前提是需要进入sbin目录下才能使用,很不方便。我们可以将该二进制可执行文件加入到系统的环境变 量,这样的话在任何目录都可以使用nginx对应的相关命令。具体实现步骤如下:
-
修改 /etc/profile 文件:
vim /etc/profile 在最后一行添加 export PATH=$PATH:/usr/local/nginx/sbin
-
使生效:
source /etc/profile
-
然后 就可以执行nginx命令了:
nginx -V
静态资源部署
- 静态资源即指在服务器端真实存在并且能直接拿来展示的一些文件,比如常见的html页面、css文件、 js文件、图片、视频等资源;
- 动态资源即指在服务器端真实存在但是要想获取需要经过一定的业务逻辑处理,根据不同的条件在页面展示不同内容,比如说报表数据展示、根据当前登录用户展示相关具体数据等资源;
配置指令
listen
-
listen指令:用来配置监听端口。
语法 listen address [:port] [default_server]…
listen port [default_server]默认值 listen *:80 或 *:8000 位置 server 例:
listen 127.0.0.1:8000; 或 listen localhost:8000 监听指定的IP和端口 listen 127.0.0.1; 监听指定IP的所有端口 listen 8000; 监听指定端口上的连接 listen *:8000; 监听指定端口上的连接
default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的 address:port,则会默认执行的。如果不指定默认使用的是第一个server。
server{ listen 8080; server_name 127.0.0.1; location /{ root html; index index.html; } } server{ listen 8080 default_server; server_name localhost; default_type text/plain; return 444 'This is a error request'; }
server_name
-
server_name指令:用来设置虚拟主机服务名称,可以是ip地址,localhost,域名。
语法 server_name name …;
name可以写多个,用空格分隔默认值 server_name “”; 位置 server 关于server_name的配置有三种:
-
精确匹配
server { listen 80; server_name www.zzc.cn www.vvl.cn; ... }
hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用 就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当 用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文 件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有 找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。
windows:C:\Windows\System32\drivers\etc centos:/etc/hosts
可以通过修改hosts文件,让访问域名对应想要的ip地址:
vim /etc/hosts 127.0.0.1 www.zzc.cn 127.0.0.1 www.vvl.cn
-
通配符匹配
可以将 ”*“ 加在域名的前面或后面,但不能加载中间。
server { listen 80; server_name *.zzc.cn www.itheima.*; ... }
如下配置会报错:
server_name www.\*.cn www.zzc.c\*
-
正则表达式匹配
需要用 ”~“ 作为正则表达式的开始标记。
代码 说明 ^ 匹配搜索字符串开始位置 $ 匹配搜索字符串结束位置 . 匹配除换行符\n之外的任何单个字符 \ 转义字符,将下一个字符标记为特殊字符 [xyz] 字符集,与任意一个指定字符匹配 [a-z] 字符范围,匹配指定范围内的任何字符 \w 与以下任意字符匹配 A-Z a-z 0-9 和下划线,等效于[A-Za-z0- 9_] \d 数字字符匹配,等效于[0-9] {n} 正好匹配n次 {n,} 至少匹配n次 {n,m} 匹配至少n次至多m次 * 零次或多次,等效于{0,} + 一次或多次,等效于{1,} ? 零次或一次,等效于{0,1} 例如:
server{ listen 80; server_name ~^www\.(\w+)\.com$; default_type text/plain; return 200 $1 $2 ..; } 注意 ~后面不能加空格,括号可以取值,分别赋予$1、$2...
关于匹配执行顺序:
如果一个名称可以被多个server_name匹配成功,则优先顺序为:
- 准确匹配server_name
- 通配符在开始时匹配server_name成功
- 通配符在结束时匹配server_name成功
- 正则表达式匹配server_name成功
- 被默认的default_server处理,如果没有指定默认找第一个 server
-
location
-
location指令
语法 location [ = 或 ~ 或 ~* 或 ^~ 或 @] uri{…} 默认值 — 位置 server,location uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式;
nginx服务器在搜索匹配location的时候,先使用不包含正则表达式的变量进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的变量进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。-
不带符号,则只要前缀与uri变量相同即可访问。
例:
server { listen 80; server_name 127.0.0.1; location /abc{ default_type text/plain; return 200 "access success"; } } 以下访问都是正确的 http://192.168.205.129/abc http://192.168.205.129/abc?p1=TOM http://192.168.205.129/abc/ http://192.168.205.129/abcdef
-
带符号:
-
= 用于不包含正则表达式的uri前,必须与指定的模式精确匹配
server { listen 80; server_name 127.0.0.1; location /abc{ default_type text/plain; return 200 "access success"; } } 可以匹配到 http://192.168.205.129/abc http://192.168.205.129/abc?p1=TOM 匹配不到 http://192.168.205.129/abc/ http://192.168.205.129/abcdef
-
~ 用于包含了正则表达式的uri,表示区分大小写
~* 用于包含了正则表达式的uri,表示不区分大小写即 uri包含了正则表达式,则需要用上述两个符号来标识
server { listen 80; server_name 127.0.0.1; location ~^/abc\w${ default_type text/plain; return 200 "access success"; } } server { listen 80; server_name 127.0.0.1; location ~*^/abc\w${ default_type text/plain; return 200 "access success"; } }
-
^~ 用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。
-
-
root/alias
-
root :设置请求的根目录
语法 root path 默认值 root html 位置 http、server、location path为Nginx服务器接收到请求以后查找资源的根目录路径。
-
alias:用来更改location的URI
语法 alias path 默认值 — 位置 location path为修改后的根路径
这两个指令都可以来指定访问资源的路径,区别是:
-
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径
-
alias是一个目录别名的定义,root则是最上层目录的含义。
-
如果location路径是以 / 结尾,则alias也必须是以 / 结尾,root没有要求
例如:
在/usr/local/nginx/html
目录下创建一个images目录,并在目录下放入一张图片mv.png
图片,访问路径为:http: //xxx.xxx.xxx.xxx/images/mv.png
两个指令的设置有所不同:
location /images {
root /usr/local/nginx/html;
}
location /images {
alias /usr/local/nginx/html/images; #alias是直接替换location的路径,所以/images需要加上
}
index
- index指令:设置网站的默认首页
语法 | index file |
---|---|
默认值 | index index.html |
位置 | http、server、location |
index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源, 则会依次进行查找,找到第一个为止。
location / {
root /usr/local/nginx/html;
index index.html index2.htm;
}
error_page
error_page指令:设置网站的错误页面
语法 | error_page code … [=[response]] uri; |
---|---|
默认值 | — |
位置 | http、server、location |
当出现对应的响应code后,如何来处理。 例:
(1)可以指定具体跳转的地址
server {
error_page 404 http://www.itcast.cn;
}
(2)可以指定重定向地址
server{
error_page 404 /50x.html;
error_page 500 502 503 504 /50x.html;
location =/50x.html{
root html;
}
}
(3)使用location的@符合完成错误信息展示
server{
error_page 404 @jump_to_error;
location @jump_to_error {
default_type text/plain;
return 404 'Not Found Page...';
}
}
静态资源优化配置
开启以下三个属性配置,可以对一些方面进行优化:
sendfile on;
tcp_nopush on;
tcp_nodeplay on;
-
sendfile,用来开启高效的文件传输模式。(减少服务器文件读写次数,硬盘数据不必读取到应用程序缓冲区,且不用多次切换用户态和核心态)
语法 sendfile on | off 默认值 sendfile off 位置 http、server、location 开启前后的文件读写过程:
- 开启前:硬盘数据 —读取—> 内核缓冲区 —读取—> 应用程序缓冲区 —写入—> Socket缓冲区 —写入—> 网络适配器
- 开启后:硬盘数据 —读取—> 内核缓冲区 —写入—> Socket缓冲区 —写入—> 网络适配器 (都在内核区完成)
-
tcp_nopush,该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输效率(先将数据存到缓冲区,存满了再发)
语法 tcp_nopush on | off 默认值 tcp_nopush off 位置 http、server、location -
tcp_nodelay:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的实时性(不必等缓冲区满,直接发送。默认开启)
语法 tcp_nodelay on | off 默认值 tcp_nodelay on 位置 http、server、location
linux2.5.9以后的版本中 "tcp_nopush"和”tcp_nodelay“ 是可以兼容的,三个指令都开启的好处是,sendfile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分“填满”, 这大大减少了网络开销,并加快了文件发送的速度。 然后,当它因为最后一个数据包可能没有“填满”而暂停时,Nginx会忽略 tcp_nopush参数, 然后,根据tcp_nodelay强制套接字发送数据。
静态资源压缩
在Nginx的配置文件中可以通过配置gzip来对静态资源进行压缩,相关的指令可以配置在http块、server块和 location块中,Nginx可以通过以下模块对gzip指令进行解析处理。
- ngx_http_gzip_module模块(默认安装)
- ngx_http_gzip_static_module模块(需手动安装)
- ngx_http_gunzip_module模块(需手动安装)
Gzip模块配置指令
-
gzip指令:用于开启或关闭gzip功能
语法 gzip on | off 默认值 gzip off; 位置 http、server、location 需要开启该指令,其他的gzip指令才能生效。
-
gzip_types指令:该指令可以根据响应页的MIME类型选择性地开启 Gzip压缩功能
语法 gzip_types mime-type …; 默认值 gzip_types text/html; 位置 http、server、location 所选择的值可以从mime.types文件中进行查找,也可以使用"*"代表所 有。
-
gzip_comp_level指令:该指令用于设置Gzip压缩程度,级别从1-9,1 表示压缩程度最低,压缩效率最高,9刚好相反,压缩程度最高,但是效率最低,最费时间。
语法 gzip_comp_level level; 默认值 gzip_comp_level 1; 位置 http、server、location -
gzip_vary指令:该指令用于设置使用Gzip进行压缩发送是否携 带“Vary:Accept-Encoding”头域的响应头部。主要是告诉接收方,所发送的数据经过了Gzip压缩处理
-
gzip_buffers指令:该指令用于处理请求压缩的缓冲区数量和大小。
语法 gzip_buffers number size 默认值 gzip_buffers 32 4k | 16 8k 位置 http、server、location 其中number是指定Nginx服务器向系统申请缓存空间个数,size指的是每 个缓存空间的大小。主要实现的是申请number个每个大小为size的内存 空间。
这个值的设定一般会和服务器的操作系统有关,所以建议此项不设置,使用默认值即可。
-
gzip_disable指令:针对不同种类客户端发起的请求,可以选择性地开启和关闭Gzip功能。
该指令一般是用来排除一些明显不支持Gzip的浏览器。可以用正则表达式,如下是指IE浏览器1~6版本就不使用gzip压缩
gzip_disable "MSIE [1-6]\.";
-
gzip_http_version指令:针对不同的HTTP协议版本,可以选择性地 开启和关闭Gzip功能。
#默认值,一般采用默认值即可 gzip_http_version 1.1;
-
gzip_min_length指令:该指令针对传输数据的大小,可以选择性地开启和关闭Gzip功能
#默认值 gzip_min_length 20;
gzip对大数据的压缩效果明显,但对小量数据效果差,甚至越压越大。一般建议设置为1K或以上。
-
gzip_proxied指令:该指令设置是否对服务端返回的结果进行Gzip压缩。
语法 gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any 默认值 gzip_proxied off 位置 http、server、location - off - 关闭Nginx服务器对后台服务器返回结果的Gzip压缩
- 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 - 无条件 启用压缩
Gzip压缩功能的实例配置:
gzip on; #开启gzip功能
gzip_types *; #压缩源文件类型,根据具体的访问资源类型设定
gzip_comp_level 6; #gzip压缩级别
gzip_min_length 1024; #进行压缩响应页面的最小长度,content-length
gzip_buffers 4 16K; #缓存空间大小
gzip_http_version 1.1; #指定压缩响应所需要的最低HTTP请求版
本
gzip_vary on; #往头信息中添加压缩标识
gzip_disable "MSIE [1-6]\."; #对IE6以下的版本都不进行压缩
gzip_proxied off; #nginx作为反向代理压缩服务端返回数据的条件
这些配置在很多地方可能用到,所以可以提取到一个配置文件nginx_gzip.conf,然后通过include指令引入加载
Gzip和sendfile共存
开启sendfile以后,在读取磁盘上的静态资源文件的时候,可以减少拷贝的次数,可以不经过用户进程将静态文件通过网络设备发送出去,但是Gzip要想对资源压缩,是需要经过用户进程进行操作的。
对于的解决方案:使用ngx_http_gzip_static_module模块的gzip_static指令来解决。
-
gzip_static指令:检查与访问资源同名的.gz文件时,response中以gzip相关的header返回 .gz文件的内容。
gzip_static on;
需要先添加ngx_http_gzip_static_module模块:
-
先查询并复制Nginx的配置参数:
nginx -V
-
将nginx安装目录下sbin目录中的nginx二进制文件进行更名:
cd /usr/local/nginx/sbin mv nginx nginxold
-
进入Nginx的安装目录,清空之前编译的内容
cd /root/nginx/core/nginx-1.20.1 make clean
-
使用configure来配置参数
./configure (这里写之前复制的配置参数的内容) --with-http_gzip_static_module
-
编译
make
-
将objs目录下的nginx二进制执行文件移动到nginx安装目录下的sbin 目录中,执行更新命令
mv objs/nginx /usr/local/nginx/sbin make upgrade
.gz文件:使用 gzip + 文件名,可以生成一个该文件的压缩文件,后缀为 .gz
-
缓存
缓存 cache ,通常使用昂贵但较快速的SRAM(静态存储器)技术,而不是系统主存所用的Dram(动态存储器)。
Web缓存: 指一个web资源存在于 Web服务器和客户端(浏览器)之间的副本。当下一个请求来到的时候,如果是相同的URL,可以直接使用本地缓存中的网页。
web缓存种类:
- 客户端 —— 浏览器缓存
- 服务端 —— Nginx / Redis / Memcached 等
浏览器缓存
浏览器缓存的优点:是成本最低的一种缓存实现, 减少网络带宽消耗, 降低服务器压力, 减少网络延迟,加快页面打开速度。
HTTP协议中和页面缓存相关的字段:
header 说明 Expires 缓存过期的日期和时间 Cache-Control 设置和缓存相关的配置信息 Last-Modified 请求资源最后修改的时间 ETag 请求变量的实体标签的当前值,如文件的MD5值
浏览器缓存的执行流程:
-
用户首次通过浏览器发送请求到服务端获取数据,客户端是没有对应的缓存,所以需要发送request请求来获取数据;
-
服务端接收到请求后,获取服务端的数据及服务端缓存的允许后, 返回200的成功状态码并且在响应头上附上对应资源以及缓存信息;
-
当用户再次访问相同资源的时候,客户端会在浏览器的缓存目录中 查找是否存在响应的缓存文件
-
如果没有找到对应的缓存文件,则走(2)步
-
如果有缓存文件,接下来对缓存文件是否过期进行判断,过期的判断标准是 (Expires);
-
如果没有过期,则直接从本地缓存中返回数据进行展示
-
如果Expires过期,接下来需要判断缓存文件是否发生过变化
判断的标准有两个,一个是ETag(Entity Tag),一个是Last-Modified
-
判断结果是未发生变化,则服务端返回304,直接从缓存文件中获取数据
-
如果判断是发生了变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置)来进行数据缓存。
浏览器缓存相关指令:
expires 指令 —— 控制页面缓存,可以通过该指令控制HTTP应 答中的“Expires"和”Cache-Control”
语法 | expires [modified] time expires epoch | max | off |
---|---|
默认值 | expires off; |
位置 | http、server、location |
- time 可以是整数也可以是负数,指定过期时间,如果是负数,Cache-Control 则为no-cache,如果为整数或0,则Cache-Control的值为max-age=time;
- epoch:指定Expires的值为’1 January,1970,00:00:01 GMT’(1970-01-01 00:00:00),Cache-Control 的值no-cache
- max:指定 Expires的值为 ‘31 December2037 23:59:59GMT’ (2037-12- 31 23:59:59) ,Cache-Control的值为10年
- off:默认不缓存。
例:对相应后缀的网页文件设置缓存时间为10天
location ~ .*\.(html|js|css|png|jpg)$ {
expires 10d;
}
"Expires"头信息 是HTTP1.0时的配置,返回服务端相关的时间值,会因为客户端与服务端的时间不一致而出现问题。 在HTTP1.1,使用”Cache-Control“的max-age代替了”Expires“。(不过为了适配,一般”Expires“也会一起配置)
add_header 指令 —— 用来添加指定的响应头和响应值。
语法 | add_header name value [always]; |
---|---|
默认值 | - |
位置 | http、server、location |
Cache-Control作为响应头信息,可以设置如下值: 缓存响应指令:
Cache-control: must-revalidate #可缓存但必须再向源服务器进行确认
Cache-control: no-cache #缓存前必须确认其有效性
Cache-control: no-store #不缓存请求或响应的任何内容
Cache-control: no-transform #代理不可更改媒体类型
Cache-control: public #可向任意方提供响应的缓存
Cache-control: private #仅向特定用户返回响应
Cache-control: proxy-revalidate #要求中间缓存服务器对缓存的响应有效性再进行
确认
Cache-Control: max-age=<seconds> #响应最大Age值
Cache-control: s-maxage=<seconds> #公共缓存服务器响应的最大Age值
例:
location ~ .*\.(html|js|css|png|jpg)$ {
expires 10d;
add_header Cache-Cont
}
跨域问题
浏览器的同源策略: 是一种约定,是浏览器最核心也是最基本的安全功能。
-
同源:协议、域名(IP)、端口相同即为同源
-
跨域问题:有两台服务器分别为A,B,如果服务器A的页面发送异步请求 到服务器B获取数据,如果服务器A和服务器B不满足同源策略,则就会出现跨域问题。
解决: 使用add_header指令,该指令可以用来添加一些头信息
语法 | add_header name value; |
---|---|
默认值 | - |
位置 | http、server、location |
解决跨域问题需要添加两个头信息:一个是 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods。
- Access-Control-Allow-Origin 指允许跨域访问的源地址信息,可以配置多个(逗号分隔),也可以用 * 代表所有源;
- Access-Control-Allow-Methods:指允许跨域访问的请求方式, 值可以为 GET POST PUT DELETE…,可以全部设置,也可以根据需要设 置,多个用逗号分隔
location /getUser {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}
防盗链
资源盗链: 指的是此内容不在自己服务器上,而是通过技术手段,绕过别人的限制将别人的内容放到自己页面上最终展示给用户。以此来盗取大 网站的空间和流量。简而言之就是用别人的东西成就自己的网站。
防盗链原理:
- 需要用到头信息Referer, Referer会声明网页是从哪个链接/URL过来的。
- 服务器根据Referer判断是否是自己信任的网站地址, 不是的话可以返回403(服务端拒绝访问)。
valid_referer 指令:
nginx会通就过查看referer自动和valid_referers后面的内 容进行匹配,如果匹配到了就将 i n v a l i d r e f e r e r 变量置 0 ,如果没有匹配到,则将 invalid_referer变量置0,如果没有匹 配到,则将 invalidreferer变量置0,如果没有匹配到,则将invalid_referer变量置为1,匹配的过程中不区分大小写。
语法 | valid_referers none | blocked |server_names | string… |
---|---|
默认值 | - |
位置 | server、location |
- none:如果Header中的Referer为空,允许访问
- blocked:在Header中的Referer不为空,但是该值被防火墙或代理进行伪装过,如不带"http://" 、"https://"等协议头的资源允许访问。
- server_names:指定具体的域名或者IP
- string: 可以支持正则表达式和*的字符串。如果是正则表达式,需要以~ 开头表示
例:
location ~*\.(png|jpg|gif){
valid_referers none blocked www.baidu.com 192.168.200.222 *.example.com example.* ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;
}
可以针对目录设置防盗链
location /images {
。。。
}
存在的问题:Referer的限制比较粗,比如随意加一个Referer,上面的方式是无法进行限制的。那么这个问题改如何解决? 那么需要用到Nginx的第三方模块ngx_http_accesskey_module。
Rewrite功能
Rewrite是Nginx服务器提供的一个重要基本功能,用来实现URL的重写。
地址重写 与 地址转发:
- 地址重写浏览器地址会发生变化而地址转发则不变
- 一次地址重写会产生两次请求而一次地址转发只会产生一次请求
- 地址重写到的页面必须是一个完整的路径而地址转发则不需要
- 地址重写因为是两次请求所以request范围内属性不能传递给新页面,而地址转发因为是一次请求所以可以传递值
- 地址转发速度快于地址重写
Rewrite规则
set指令
—— 用于设置一个新的变量
语法 | set $variabale value; |
---|---|
默认值 | __ |
位置 | server, location, if |
- variable:变量的名称,该变量名称要用"$"作为变量的第一个字符,且不能与Nginx服务器预设的全局变量同名。
- value:变量的值,可以是字符串、其他变量或者变量的组合等
Rewrite常用的全局变量
变量 | 说明 |
---|---|
$args | 变量中存放URL的请求指令,即 “?” 后的参数 |
$http_user_agent | 存储的是用户访问服务的代理信息(或是浏览器的版本信息) |
$host | 存放访问服务器的server_name值 |
$document_uri | 存放当前访问地址的uri, 即文件路径 |
$document_length | 变量存储的是请求头中的Content-Length的值 |
$content_type | 变量存储的是请求头中的Content-Type的值 |
$http_cookie | 存放客户端cookie信息,可以通过 add_header Set-Cookie 'cookieName=cookieValue’来添加cookie数 据 |
$limit_rate | 存放 Nginx服务器对网络链接速率的限制,即Nginx配置对limit_rate指令设置的值,默认是0,不限制 |
$remote_addr | 存放客户端的IP地址 |
$remote_port | 存放建立连接的端口号 |
$remote_user | 存放客户端的用户名,需要认证模块才能用 |
$scheme | 存放访问协议 |
$server_addr | 存放服务端的地址 |
$server_name | 存放请求到达的服务器名称 |
$server_port | 存放请求到达的服务器端口号 |
$server_protocol | 存放客户端请求协议的版本(HTTP) |
$request_body_file | 存放发给服务器的文件资源的名称 |
$request_method | 存放客户端的请求方式 |
$request_filename | 存放当前请求的资源的路径名 |
$request_uri | 存放当前请求的URI,且携带参数 |
if指令
语法 | if (condition){…} |
---|---|
默认值 | — |
位置 | server,location |
注:if 后面要留一个空格,不然报错
判定条件:
-
变量名的值为空或是0,则判为false,其余为true
-
使用 “=” 和 “!=”
-
使用正则表达式,匹配成功返回true;
变量与表达式之间用 “~”, “~*”, “!~”, “!~*” 来连接
- “~”,匹配过程 区分大小写
- “~*”,匹配过程 不区分大小写
- “!~”, “!~*” 匹配成功返回false,与上面两个相反。
if ($http_user_agent ~ Safari){ ... } #$http_user_agent的值中是否含有“Safari”字符串 #正则表达式不用加引号,除非有“}”或“;"
-
使用 “-f” 和 “!-f” 判断请求的文件是否存在。
if (-f $request_filename){ #判断请求的文件是否存在 } if (!-f $request_filename){ #判断请求的文件是否不存在 }
-
使用 “-d” 和 “!-d” 判断请求的目录是否存在
-
使用 “-e” 和 “!-e” 判断请求的目录或文件是否存在
-
使用 “-x” 和 “!-x” 判断请求的文件是否可执行
break指令
—— 用于中断当前作用域中的配置执行;
语法 | break; |
---|---|
默认值 | — |
位置 | server,location,if |
#例
location /{
if ($param){
set $id $1;
break;
limit_rate 10k;
}
}
return指令
—— 完成请求的处理,直接向客户端返回响应状态码
语法 | return 状态码 [响应内容] return 状态码 URL return URL |
---|---|
默认值 | — |
位置 | server,location,if |
rewrite指令
——通过正则表达式来改变URI,可以同时存在多个指令,按顺序依次对URL进行匹配,处理
语法 | rewrite 正则表达式 替换内容 [flag] |
---|---|
默认值 | — |
位置 | server,location,if |
- flag用于设置rewrite对URI的处理行为,可选值:
- last —— 终止当前location块后续对URI的处理,将得到的新URI,重新在server中执行,可能会匹配进入到其他location块。
- break —— 将得到的新URI在本块中继续处理,不会转向其他location块
- redirect —— 将重写后的URI返回给客户端,状态码为302,表示临时重定向
- permanent —— 将重写后的URI返回给客户端,状态码为301,表示永久重定向
location rewrite {
rewrite ^/rewrite/url\w*$ https://www.baidu.com;
rewrite ^/rewrite/(test)\w*$ /$1;
rewrite ^/rewrite/(demo)\w*$ /$1;
}
location /test{
default_type text/plain;
return 200 test_success;
}
location /demo{
default_type text/plain;
return 200 demo_success;
}
rewirte_log指令
—— 配置是否开启URL重写日志的输出功能
语法 | rewrite_log on|off |
---|---|
默认值 | rewrite_log off |
位置 | http,server,location,if |
开启后,URL重写的相关日志将以notice级别输出到error_log指令配置 的日志文件汇总。
rewrite_log on;
error_log logs/error.log notice;
使用命令提示符 简易发送POST请求:
curl -X POST http://.......
例子
域名跳转
访问旧域名时,跳转到新域名。
在本地机实验,可以在 /etc/hosts 文件中配置 ip和域名,如: 127.0.0.1 www.aaa.com
配置:
server {
listen 80;
server_name www.aaa.cn;
location /{
default_type text/html;
return 200 '<h1>welcome to itcast</h1>';
}
}
server {
listen 80;
server_name www.bbb.com www.bbb.cn;
rewrite ^/ http://www.aaa.cn;
}
如果要在域名跳转的过程中携带请求的URI,则:
server {
listen 80;
server_name www.bbb.com www.bbb.cn;
rewrite ^(.*) http://www.aaa.cn$1;
}
域名镜像
像上个例子中,就是将两个镜像域名跳转到主域名;而如果只想其中某个子目录的资源做镜像,可以在location块中配置rewrite功能:
server {
listen 80;
server_name www.bbb.cn www.bbb.com;
location /user {
rewrite ^/user(.*)$ http://www.aaa.cn$1;
}
location /emp{
default_type text/html;
return 200 '<h1>emp_success</h1>';
}
}
独立域名
一个完整的项目包含多个模块,如果要为多个模块分别设置独立的域名:
# 需求
主域名: www.aaa.cn
独立域名:
http://search.aaa.com:81 访问商品搜索模块
http://item.aaa.com:82 访问商品详情模块
http://cart.aaa.com:83 访问商品购物车模块
server{
listen 81;
server_name search.aaa.com;
rewrite ^(.*) http://www.aaa.cn/search$1;
}
server{
listen 82;
server_name item.aaa.com;
rewrite ^(.*) http://www.aaa.cn/item$1;
}
server{
listen 83;
server_name cart.aaa.com;
rewrite ^(.*) http://www.aaa.cn/cart$1;
}
合并目录
搜索引擎优化(SEO)是一种利用搜索引擎的搜索规则来提高目的网站在有 关搜索引擎内排名的方式。
其中有个方式就是 URL的目录层级不要超过3层,否则不利于引擎和客户端。
而将所有文件放在一个目录下又会使得文件管理混乱;
因此,可以利用rewrite将多层级的资源路径变成3层以下的资源路径。如:将 http: //192.168.205.129/server/11/22/33/44/20.html 转变为 http: //192.168.205.129/server-11-22-33- 44-20.html
server {
listen 8083;
server_name localhost;
location /server{
rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /server/$1/$2/$3/$4/$5.html last;
}
}
防盗链
针对盗链,除了拒绝返回资源外,还可以发送自定义的资源,以作警告等用途:
location /images {
root html;
valid_referers none blocked www.baidu.com;
if ($invalid_referer){
#return 403;
rewrite ^/ /images/forbidden.png break;
}
}
反向代理
Nginx可以实现正向和反向代理;
-
正向代理: 代理的对象是客户端;
-
反向代理:代理的对象是服务端;
正向代理例子:
代理服务器设置:
server { listen 82; resolver 8.8.8.8; #DNS地址 location /{ proxy_pass http://$host$request_uri; } }
客户端配置代理服务器的ip和端口号。
反向代理
Nginx反向代理模块的指令是由ngx_http_proxy_module 模块进行解析,下面是以下常用指令:proxy_pass
,proxy_set_header
,proxy_redirect
-
proxy_pass 指令 —— 该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号形式。
语法 proxy_pass URL 默认值 — 位置 location 例:
proxy_pass http://www.baidu.com; location /server{ proxy_pass http://192.168.205.130; } # 末尾不加 / ,路径名会加到ip地址后面,访问到的是 http://192.168.205.130/server/index.html # 末尾如果加 / ,访问到的是 http://192.168.205.130/index.html
-
proxy_set_header 指令 —— 用于更改收到的客户端的请求头信息,然后将新的请求头发送给代理的服务器。
语法 proxy_set_header field value 默认值 proxy_set_header Host $proxy_host;
proxy_set_header Connection close;位置 http、server、location 注:要看到结果,必须在被代理的服务器上获取添加的头信息。
如:
被代理服务器[192.168.205.130]
server { listen 8080; server_name localhost; default_type text/plain; return 200 $http_username; }
代理服务器
server { listen 8080; server_name localhost; location /server { proxy_pass http://192.168.205.130:8080/; proxy_set_header username TOM; } }
-
proxy_redirect —— 用于重置头信息中的”Location“和”Refresh“的值;
语法 proxy_redirect 被替换值 替换值;
proxy_redirect default;
proxy_redirect off;默认值 proxy_redirect default; 位置 http、server、location 例:不然服务器的ip暴露,用代理服务器的ip替换掉
# 服务器 192.168.205.130 server { listen 8080; server_name localhost; if (!-f $request_filename){ return 302 http://192.168.205.130; } }
# 代理服务器 192.168.205.129 server { listen 8081; server_name localhost; location / { proxy_pass http://192.168.205.130:8080/; proxy_redirect http://192.168.205.130 http://192.168.205.129; } }
安全控制
Nginx反向代理是通过安全隔离
的方式来提升服务器的安全的。
安全隔离:通过代理分开了客户端到服务器的连接,在反向代理之前设置了防火墙,仅留一个入口供代理服务器访问。
能够安全通信的HTTPS就是在HTTP的基础上,添加了SSL/TLS外壳,加密数据包,确保数据安全。
SSL —— 安全套接层 Secure Sockets Layer
TLS —— 传输安全层 Transport Layer Security
Nginx使用SSL,需要额外添加一个模块 --with-http_ssl_module,且该模块在编译过程中还需要OpenSSL的支持。
添加ssl支持,过程略。
SSL相关指令:
-
ssl_certificate:为当前这个虚拟主机指定一个带有PEM格式证书的证书。
-
ssl_certificate_key:该指令用来指定PEM secret key文件的路径
-
ssl_session_cache:该指令配置用于SSL会话的缓存。
语法:ssl_sesion_cache off |none| builtin[:size] | shared:name:size
- off:禁用会话缓存,客户端不得重复使用会话
- none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数
- builtin:内置OpenSSL缓存,仅在一个工作进程中使用。
- shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定
-
ssl_session_timeout:设置客户端能够反复使用储存在缓存中的会话参数的时间。
-
ssl_ciphers:指出允许的密码,密码指定为OpenSSL支持的格式
-
ssl_prefer_server_ciphers:指定是否服务器密码优先于客户端密码
nginx.conf文件配置:
其中的 ssl_certificate 和 ssl_certificate_key 需要设置证书,将购买的证书放在对应的目录下; 或者使用openssl自己生成证书:
# 确认当前系统是否有openssl openssl version # 生成证书 mkdir /root/cert cd /root/cert openssl genrsa -des3 -out server.key 1024 openssl req -new -key server.key -out server.csr cp server.key server.key.org openssl rsa -in server.key.org -out server.key openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /root/cert/server.crt;
ssl_certificate_key /root/cert/server.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;
}
}
}
负载均衡
概述
随着业务流量越来越大并且业务逻辑也跟着越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多要多台服务器进行拓展。
系统的拓展分为:
- 纵向拓展 —— 从单机的角度出发,通过增加系统的硬件处理能力来提升服务器的处理能力。
- 横向拓展 —— 通过添加机器来满足大型网站服务的处理能力。
系统拓展需要用到:
- 应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均衡设备分发的请求,进行处理并返回响应的数据。
- 负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群中的一台服务器进行处理。
负载均衡 作用:
- 解决服务器的高并发压力,提高应用程序的处理性能。
- 提供故障转移,实现高可用。
- 通过添加或减少服务器数量,增强网站的可扩展性。
- 在负载均衡器上进行过滤,可以提高系统的安全性。
常用处理方式
1.用户手动选择
提供不同线路 供用户自己选择访问的服务器,以提供负载均衡。
2.DNS轮询方式
DNS轮询: 对同一个主机名(域名)添加多条A记录(IP地址),DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就能完成简单的负载均衡。
DNS轮询虽然成本低,但是也缺点显著:
- 可靠性低 —— 假设一个域名DNS轮询多台服务器,如果其中的一台服务器发生故障, 那么所有的访问该服务器的请求将不会有所回应,即使将该服务器的 IP从DNS中去掉,但是由于各大宽带接入商将众多的DNS存放在缓存 中,以节省访问时间,导致DNS不会实时更新。所以DNS轮流上一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。
- 负载均衡不均衡 —— DNS负载均衡采用的是简单的轮询负载算法,不能区分服务器的差异, 不能反映服务器的当前运行状态,不能做到为性能好的服务器多分配请求,另外本地计算机也会缓存已经解析的域名到IP地址的映射,这也会导致使用该DNS服务器的用户在一定时间内访问的是同一台Web服务器,从而引发Web服务器减的负载不均衡。
3.四/七层负载均衡
四/七层是指OSI七层模型中的 传输层 和 应用层。
-
四层负载均衡 —— 主要基于 IP + PORT 的负载均衡。
实现四层负载均衡的方式:
- 硬件:F5 BIG-IP、Radware等
- 软件:LVS、Nginx、Hayproxy等
-
七层负载均衡 —— 主要基于虚拟的URL或主机IP的负载均衡。
实现七层负载均衡的方式:
- 软件:Nginx、Hayproxy等
区别:
- 四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。
- 四层负载均衡不识别域名,而七层负载均衡识别域名。
实际环境采用的模式为:四层负载(LVS,linux虚拟服务器) + 七层负载(Nginx)
七层负载均衡
Nginx的负载均衡是在Nginx的反向代理基础上把用户的请求根据指定的算法分发到一组 upstream虚拟服务池
。
指令
-
upstream 指令 —— 该指令用来定义一组服务器,可以监听不同端口的服务器,并且也可以同时监听TCP和Unix socket发服务器。
服务器可以指定不同的权重,默认为1 -
server 指令 —— 该指令用来指定后端服务器的名称和一些参数, 写在upstream里面。
语法:
upstream 服务器组名 { server ip地址:端口; server ip地址:端口; .... }
例如:
upstream backend { server 192.168.205.130:9001; server 192.168.205.130:9002; server 192.168.205.130:9003; } server { listen 8081; server_name localhost; location /{ proxy_pass http://backend; } }
状态
代理服务器在负责均衡调度中的状态有以下几个:
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后,服务暂停的时间 |
max_conns | 限制最大的接受连接数 |
-
down —— 将该服务器标记为永久不可用, 不再参与负载均衡。
该状态一般用于需要停机维护的服务器进行设置。
upstream backend { server 192.168.205.130:9001 down; server 192.168.205.130:9002; server 192.168.205.130:9003; } server { listen 8081; server_name localhost; location /{ proxy_pass http://backend; } }
-
backup —— 将该服务器标记为备份服务器,平时不会参与发在均衡;只有当主服务器不可用时,才会用来传递请求。
upstream backend { server 192.168.205.130:9001 down; server 192.168.205.130:9002 backup; server 192.168.205.130:9003; } server { listen 8081; server_name localhost; location /{ proxy_pass http://backend; } }
-
max_conns —— 用来设置代理服务器同时活动链接的最大数量,默认为0,表示不限制;
语法:max_conns=number -
max_fails —— 允许请求代理服务器失败的次数,默认为1;
fail_timeout —— 设置经过 max_fails 失败后,服务暂停的时间,默认10秒。upstream backend { server 192.168.205.130:9001 down; server 192.168.205.130:9002 backup; server 192.168.205.130:9003 max_fails=3 fail_timeout=15; } server { listen 8081; server_name localhost; location /{ proxy_pass http://backend; } }
策略
Nginx的upstream支持如下六种方式的分配算法,分别是:
算法名称 | 说明 |
---|---|
轮询 | 默认方式 |
weight | 权重方式 |
ip_hash | 依据ip分配 |
least_conn | 依据最少连接分配 |
url_hash | 依据URL分配 |
fair | 依据响应时间分配 |
-
轮询 —— 是upstream模块负载均衡默认的策略。每个请求会按时间顺序逐个分配 到不同的后端服务器。
轮询不需要额外的配置。 -
weight加权(加权轮询)—— 用来设置服务器的权重,默认为1,权重数据越大,被分配到请求的几率越大;适合服务器的硬件配置差别较大的情况。
upstream backend { server 192.168.205.130:9001 weight=10; server 192.168.205.130:9002 weight=5; server 192.168.205.130:9003 weight=3; } server { listen 8081; server_name localhost; location /{ proxy_pass http://backend; } }
-
ip_hash —— 将某个 客户端IP的请求通过哈希算法定位到同一台后端服务器上,保证在访问该站点的其他URL时,访问的还是同一个服务器,从而避免多次验证身份。
ip_hash指令无法保证服务器的负载均衡,且其他权重方法将不起作用。
upstream backend { ip_hash; server 192.168.205.130:9001; .... }
-
least_conn —— 最少连接方式,把请求转发给连接数较少的后端服务器。
轮询算法将请求平均转发给各个后端,使得负载大致相同; 但是,可能有些请求占用时间很长,导致某些服务器负载很高;因此,least_conn就可以达到较好的负载均衡效果。
适合请求处理时间长短不一造成服务器过载的情况。
upstream backend { least_conn; server 192.168.205.130:9001; .... }
-
url_hash —— 按访问 url 的 hash结果 来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。
如果同一个资源多次请求,可能会到达不同服务器上,导致不必要的多次下载,缓存命中率低,所以就可以使用url_hash。
upstream backend { hash &request_uri; server 192.168.205.130:9001; .... }
-
fair —— 根据页面大小,加载时间长短而进行负载均衡。
upstream backend { fair; server 192.168.205.130:9001; .... }
使用fair,需要添加 nginx-upstream-fair 模块。
四层负载均衡
缓存集成
缓存: 即数据交换的缓冲区(Cache);
场景 | 作用 |
---|---|
操作系统磁盘缓存 | 减少磁盘机械操作 |
数据库缓存 | 减少文件系统的IO操作 |
应用程序缓存 | 减少对数据库的查询 |
Web服务器缓存 | 减少对应用服务器请求次数 |
浏览器缓存 | 减少与后台的交互次数 |
缓存的优点:
- 减少数据传输,节省网络流量,加快响应速度,提升用户体验;
- 减轻服务器压力;
- 提供服务端的高可用性;
缓存的缺点
- 数据的不一致
- 增加成本
Nginx作为Web缓存服务器,介于客户端和应用服务器之间,当用户通过浏览器访问一个URL时,web缓存服务器会去应用服务器获取要展示给用户的内容, 将内容缓存到自己的服务器上,当下一次请求到来时,如果访问的是同一个URL,web缓存服务器就会直接将之前缓存的内容返回给客户端。
web缓存降低了应用服务器、数据库的负载,减少了网络延迟,提高了用户访问的响应速度,增强了用户 的体验。
指令
-
proxy_cache_path —— 用于设置缓存文件的存放路径。
位置:http
语法: proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
- path 为缓存路径地址
- levels 指定该缓存空间对应的目录,最多可设3层,每层只能取值1或2。如:levels=1:2,就是设置缓存空间有两层目录,第一次1个字母,第二次2个字母。
- keys_zone 为缓存区设置名称和指定大小。如:keys_zone=itcast:200m 缓存区的名称是itcast,大小为200M
- inactive 指定缓存的数据多久时间未被访问就会删除。
- max_size 设置最大缓存空间,如果存满,则覆盖缓存时间最长的资源。
配置实例:
http{ proxy_cache_path /usr/local/proxy_cache keys_zone=itcast:200m levels=1:2:1 inactive=1d max_size=20g; }
-
proxy_cache —— 该指令用来开启或关闭代理缓存,如果是开启则自定使用哪个缓存区来进行缓存。
语法:proxy_cache 缓存区名字/off
位置:http、server、location
-
proxy_cache_key —— 设置web缓存的key值,Nginx会根据key值计算MD5哈希缓存。
默认值:proxy_cache_key s c h e m e scheme schemeproxy_host&request_uri;
-
proxy_cache_valid —— 对返回不同状态码的URL设置不同的缓存时间
语法:proxy_cache_valid 状态码 缓存时间
proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; #为200和302的响应URL设置10分钟缓存,为404的响应URL设置1分钟缓存 proxy_cache_valid any 1m; #对所有响应状态码的URL都设置1分钟缓存
-
proxy_cache_methods —— 对哪些http方法设置缓存
语法:proxy_cache_methods GET|HEAD|POST;
默认:proxy_cache_methods GET HEAD
配置例子
-
环境准备
应用服务器的环境准备
- 在192.168.205.129服务器上的tomcat的webapps下面添加一个js 目录,并在js目录中添加一个jquery.js文件
- 启动tomcat
- 访问测试 :http 😕/192.168.205.119:8080/js/jquery.js
-
Nginx反向代理配置
http{ upstream backend{ server 192.168.205.130:8080; } server { listen 8080; server_name localhost; location / { proxy_pass http://backend/js/; } } }
-
Nginx缓存配置
http{ proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=itcast:200m inactive=1d max_size=20g; upstream backend{ server 192.168.205.130:8080; } server { listen 8080; server_name localhost; location / { proxy_cache itcast; proxy_cache_key itheima; proxy_cache_min_uses 5; proxy_cache_valid 200 5d; proxy_cache_valid 404 30s; proxy_cache_valid any 1m; add_header nginx-cache "$upstream_cache_status"; proxy_pass http://backend/js/; } } }
清除缓存
- 删除对应的缓存目录
- 使用第三方拓展模块ngx_cache_purge …
设置资源不缓存
对于一些经常发生变化的数据,如果进行缓存的话,可能用户访问到的不是服务器真实的数据。
要设置资源不缓存,可以用以下指令:
-
proxy_no_cache —— 用来定义数据不缓存的条件。
语法 proxy_no_cache string… 默认值 —— 位置 http、server、location 配置实例:
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
-
proxy_cache_bypass —— 该指令用来设置不从缓存中获取数据的条件。
语法 proxy_cache_bypass string… 默认值 —— 位置 http、server、location 配置实例:
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
上述两个指令都有一个指定的条件,这个条件可以是多个,并且多个条 件中至少有一个不为空且不等于"0",则条件满足成立。
设置不缓存资源的配置方案:
server{
listen 8080;
server_name localhost;
location / {
if ($request_uri ~ /.*\.js$){
set $nocache 1;
}
proxy_no_cache $nocache $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $nocache $cookie_nocache $arg_nocache $arg_comment;
}
}
服务器集群搭建
Nginx在高并发场景和处理静态资源时性能很高,而后台业务一般部署在tomcat,weblogic等web服务器上。 为了高效,一般是Nginx接受请求,并把请求分发到Tomcat上。
配置案例:
-
在Centos上部署Tomcat,将web项目打包为war,放到webapps下,进入bin目录“./startup.sh”启动。
-
使用Nginx反向代理,将请求转发给Tomcat进行处理。
upstream webservice { server 192.168.205.129:8080; } server{ listen 80; server_name localhost; location /demo { proxy_pass http://webservice; } }
动静分离
动,就是后台应用程序的业务处理; 静,就是网站的静态资源(html,javaScript,css,images等)
动静分离就是,将静态相关的都交给Nginx,非静态内容交给Tomcat等web服务器。
- 好处:降低动静资源耦合度,如动态资源宕机了也不影响静态资源展示。
配置案例:
upstream webservice{
server 192.168.205.130:8080;
}
server {
listen 80;
server_name localhost;
#动态资源
location /demo {
proxy_pass http://webservice;
}
#静态资源
location ~/.*\.(png|jpg|gif|js){
root html/web;
gzip on;
}
location / {
root html/web;
index index.html index.htm;
}
}
Tomcat集群搭建
只有一台web服务器的话,如果宕机了整个后台系统就缺失了。因此可以多搭建几台Tomcat服务器,提升服务器可用性,这就是集群。
upstream webservice{
server 192.168.205.130:8080;
server 192.168.205.130:8180;
server 192.168.205.130:8280;
}
Nginx高可用方案
只有一台Nginx服务器也容易因宕机而缺失前端系统。
不过有多台Nginx服务器的话,也就有两个IP地址,用户不知道应该访问哪台才是对的。
解决:使用keepalived软件来解决,其主要是通过VRRP协议来实现高可用功能。
VRRP(Virtual Route Redundancy Protocol),即虚拟路由冗余协议。
VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP,而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,MASTER实现针对虚拟路由器IP的各种网络功能。其他设备不拥有该虚拟IP,状态为BACKUP,除了接收MASTER的VRRP状态通告信息以外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。
- Master路由和Backup路由之间会有一个心跳检测,Master会定时告知 Backup自己的状态,如果在指定的时间内,Backup没有接收到这个通知 内容,Backup就会替代Master成为新的Master。
- Master路由有一个特权就是虚拟路由和后端服务器都是通过Master进行数据传递交互的,而备份节点则会直接丢弃这些请求和数据,不做处理,只是去监听Master的状态。