概念介绍
Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。
功能作用
HTTP代理和Web服务器功能
- 能够以较低的内存占用率处理10,000多个并发连接(每10k非活动HTTP保持活动连接约2.5 MB )
- 处理静态文件,索引文件和自动索引
- 具有缓存的反向代理
- 使用带内健康检查进行负载平衡
- TLS / SSL与SNI和OCSP装订支持,通过OpenSSL的。
- FastCGI,SCGI,uWSGI支持缓存
- 自2018年3月以来的gRPC支持,版本1.13.10。
- 基于名称和IP地址的虚拟服务器
- IPv6兼容
- WebSockets,HTTP / 1.1升级(101交换协议),HTTP / 2协议支持
- URL重写和重定向
邮件代理功能
- TLS / SSL支持
- STARTTLS支持
- SMTP,POP3和IMAP 代理
- 使用外部HTTP服务器进行身份验证[30]
结构特性
模块化设计
核心模块(core modules): 核心模块分为标准模块和可选模块,标准模块就是只要你编译了Nginx就必须会编译的模块,不可选择;可选模块就是编译的时候可以选择用或者不用。
邮件模块(Mail modules): Nginx不光是一个web服务器,还是一个后端代理服务器,且可以为邮件相关的服务进行代理,所以如果需要此功能就可以装载邮件模块即可。
第三方模块(3rd party modules): Nginx还支持许多第三方模块,这些第三方模块我们在编译时要手动指明加载方式进行加载。
高可靠性
Nginx采用一个主进程(master)和N个工作进程(worker)的工作模式,而worker进程才是真正复制相应用户请求的进程。配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等。所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户身份运行。
支持热部署
由于Nginx使用主进程和工作进程的机制,使得Nginx支持热部署,这个热部署包括不停止服务更新配置文件、更新日志文件、以及更新服务器程序版本;有人也称这位平滑升级。
低内存消耗
Nginx对于内存的消耗是非常小的,特别是对于非活动连接,官方数据在持久连接模式下10000个非活动连接只需要占用2.5M内存。Nginx对于非活动连接是指,当我们开启持久连接功能时,用户连接不再发送数据后就会立即转为非活动连接,直到持久连接超时时间到达,即销毁。
高扩展性
Nginx 的设计极具扩展性,它完全是由多个不同功能、不同层次、不同类型且耦合度极低的模块组成。 因此,当对某一个模块修复 Bug 或进行升级时,可以专注于模块自身,无须在意其他。而且在HTTP模块中,还设计了 HTTP过滤器模块 : 一个正常的HTTP模块在处理完请求后,会有一串HTTP过滤器模块对请求的结果进行再处理。这样,当我们开发一个新的HTTP模块时, 不但可以使用诸如HTTP核心模块、events 模块、log 模块等不同层次或者不同类型的模块, 还可以原封不动地复用大量已有的HTTP过滤器模块。这种低耦合度的优秀设计,造就了Nginx庞大的第三方模块,当然,公开的第三方模块也如官方发布的模块一样容易使用。Nginx的模块都是嵌入到二进制文件中执行的,无论官方发布的模块还是第三方模块都是如此。这使得第三方模块一样具备极其优秀的性能,充分利用 Nginx 的高并发特性,因此,许多高流量的网站都倾向于开发符合自己业务特性的定制模块。
架构模式
从上图可以看出Ningx启动一个主进程Master和多个工作进程worker,工作进程以非特权用户运行。
Master进程的主要工作如下
1)读取并验正配置信息;
2)创建、绑定及关闭套接字;
3)启动、终止及维护worker进程的个数;
4)无须中止服务而更新程序;
5)控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本;
6)重新打开日志文件,实现日志滚动;
7)编译嵌入式perl脚本;
Worker进程主要工作如下
1)接收、传入并处理来自客户端的连接,可以是http或者是https协议;
2)提供反向代理功能,根据不同的协议提供给后端真正的应用程序服务器处理请求,如http协议,说明nginx可以自己处理静态请求,也可以代理到后端的web服务器处理静态请求;基于fastcgi协议把用户的动态请求代理到后端的php-fpm服务器;同时还可以根据memcache协议把用户请求提交给后端的memcached服务器进行缓存。Nginx支持的后端存储还有很多,比如mongofs协议,与mongofs这样的分布式存储进行交互,当然这需要装载第三方模块。
3)每个worker进程内部组合了多个模块,如http的核心模块、http协议的负载均衡模块、http的反向代理模块、fastcgi模块等等;事实上worker用到什么模块就会自动装载进来的,用户请求就是在这里模块之间流动。
4)另外面向客户端请求时,每一个worker进程是如何响应客户端的呢?上图也有说明,nginx支持各种客户端连接处理方法,特定方法的有效性取决于所使用的平台上。在支持的几种方法中,nginx通常会自动选择最有效的方法根据其平台。然而,如果需要的话,一个连接处理方法,可以明确地使用use指令指定连接处理方法,前提是此方法必须编译进Nginx。支持的方式(事件驱动模型)有: 如FreeBSD系统支持的kqueue、Linux2.6+支持的epoll、Solaris系统支持的/dev/poll等机制实现进程复用,因此一个进程可以处理N个请求。
5)与本地磁盘进行交互时,Nginx支持高级I/O机制、支持sendfile、sendfilev、sendfile64(sendfile是一种当用户请求一个文件时进程发起系统调用内核到硬盘加载文件可以直接响应给用户;不需在回应给用户空间进程而进程再通过内核TCP/IP协议栈发送给用户节约了时间;sendfile64支持大文件);支持文件AIO(使用AIO必须开启DIRECTIO);支持MMAP等机制。
6)一般反向代理时,Nginx支持直接在本地缓存的机制,当启用缓存功能后,为了能够管理缓存中的缓存对象,需要经常对缓存进行装载和清理等工作。这就需要两个助类的进程来管理,一个叫cache loader、一个叫cache manager。Cache loader进程主要工作是检查缓存存储中的缓存对象,使用缓存元数据建立内存数据库;而Cache manager进程主要工作是缓存的失效时间及过期检验等。
安装使用
nginx支持windows和Linux安装部署使用,下载nginx最新版,请点击查看
windows点击 nginx/Windows-1.15.9 下载已经编译好的版本,可直接使用。
Linux使用系统的源安装或者下载源码,自行编译安装即可。
常用命令
启动nginx服务
service nginx start
或者 在nginx目录下执行 ./nginx
或者以指定配置文件启动 nginx -c /home/nginx.conf
重新载入配置文件
nginx -s reload
nginx在加载期间仍然可以不间断提供服务,不保证所有的参数及时生效,必要时重启nginx
优雅停止nginx服务
nginx -s quit
有连接时会等连接请求完成再杀死worker进程
查看nginx版本和编译参数信息
nginx -V
重新打开日志文件
nginx -s reopen
适合切割日志文件
测试配置文件语法是否正确
nginx -t
查看nginx进程信息
ps -ef |grep nginx
常用参数
在nginx.conf配置文件中有非常多的配置参数,哪些参数是什么意思,具体要注意什么,如何设置合理的阀值,如何配置一份需要的配置文件呢?
由于nginx配置参数非常之多,我们单独开设一篇文章讲解,请点击查看
虚拟主机
虚拟主机,也叫“网站空间”,就是把一台运行在互联网上的物理服务器划分成多个虚拟服务器。有时候我们需要在一个服务器上部署多个web应用程序,如博客,论坛,个人网站等,这些程序对外提供访问,如何在保证共用一个80端口的情况实现不同域名的访问,或者多端口下只是启动一个web服务器访问,这就需要用到web服务器中的虚拟主机功能。nginx的虚拟主机使用server大括号表示,并且可以支持三种方式:
- 基于域名的虚拟主机
server {
listen 80; # web浏览器默认80端口,在浏览器上不需要输入端口号 http://host
server_name www.520code.net; # 设置你的访问域名
location / {
root html/www;
index index.html;
}
}
- 基于IP地址的虚拟主机
server {
listen 80; # 访问你的网站 http://192.168.1.2
server_name 192.168.1.2; # 设置本机的ip地址
location / {
root html/www
index index.html;
}
}
- 基于端口的虚拟主机
server {
listen 8080; # 需要在浏览器输入端口号 http://host:8080 访问你的网站
server_name www.520code.net;
location / {
root html/www;
index index.html;
}
}
静态网站
nginx默认支持静态资源文件,且无需任何复杂配置,即可完成,通常你只需要告诉 nginx你的请求路径和静态资源路径,
在nginx中使用location表示定位请求路径,使用 root 和 alias 表示静态资源路径,它们二者在表现形式有以下区别:
- 作用范围不同
root:可以出现在server、http和location中
alias: 只能出现在location中
- 后缀带正斜杠 /
root:可有可无
alias:强制必须带 /
- 请求路径变化
root:会带上location后面 http://host/location+root/资源文件名
alis:是别名路径,不会带上location http://host/alias/资源文件名
server {
listen 80;
server_name www.520code.net;
location /bbs {
root html/www;
index index.html;
}
location /blog {
alias /usr/www/;
index index.html;
}
}
反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给其他网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。反向代理的好处就是屏蔽了连接的透明性,带来的好处就是可以控制权限访问,可以智能分配请求压力,可以减少客户端正向代理配置的繁琐,可以实现跨多台服务器的访问,可以跨域访问,可以记录请求日志,这些对于客户端都是不可知的。
# 使用 proxy_pass 代理一个网站
server {
listen 80;
server_name www.oneinlet.com;
location / {
proxy_pass http://www.520code.net;
}
}
# 使用 upstream+proxy_pass 配置多个代理服务器,既可以实现反向代理还可以配置负载均衡
http{
upstream backend {
server www..520code.net;
server www..oneinlet.com;
}
server {
listen 80;
server_name www.oneinlet.com;
location / {
proxy_pass http://backend;
}
}
}
location语法
location指令的作用是根据用户请求URI来执行不同的应用,location会根据用户请求网站URL进行匹配定位到某个location区块。 如果匹配成功将会处理location块的规则。
语法规则
location = /uri
┬ ┬ ┬
│ │ │
│ │ │
│ │ │
│ │ │
│ │ └─────────────── 前缀|正则
│ └──────────────────── 可选的修饰符(用于匹配模式及优先级)
└───────────────────────── 必须关键字
修饰符说明
从上到下,第一个优先级最高
= | location = /uri 表示精准匹配
^~ | location ^~ /uri 表示以某个常规字符串开头,不是正则匹配
~ | location ~ pattern 表示区分大小写的正则匹配
~* | location ~* pattern 表示不区分大小写的正则匹配
/uri | location /uri 表示匹配以/uri开头的地址
@ | location @err 表示用于定义一个Location块,只能被nginx内部配置指令所访问
/ | locatioon / 表示通用匹配, 如果没有其它匹配,任何请求都会匹配到
1、 = ,精确匹配,表示严格相等
location = /static {
default_type text/html;
return 200 "hello world";
}
# http://localhost/static [成功]
# http://localhost/Static [失败]
2、 ^~ ,匹配以URI开头
location ^~ /static {
default_type text/html;
return 200 "hello world";
}
# http://localhost/static/1.txt [成功]
# http://localhost/public/1.txt [失败]
3、 ~ ,对大小写敏感, 使用正则 注意:某些操作系统对大小写敏感是不生效的,比如windows操作系统
location ~ ^/static$ {
default_type text/html;
return 200 "hello world";
}
# http://localhost/static [成功]
# http://localhost/static?v=1 [成功] 忽略查询字符串
# http://localhost/STATic [失败]
# http://localhost/static/ [失败] 多了斜杠
4、 ~* ,与~相反,忽略大小写敏感, 使用正则
location ~* ^/static$ {
default_type text/html;
return 200 "hello world";
}
# http://localhost/static [成功]
# http://localhost/static?v=1 [成功] 忽略查询字符串
# http://localhost/STATic [成功]
# http://localhost/static/ [失败] 多了斜杠
5、 /uri ,匹配以/uri开头的地址
location /static {
default_type text/html;
return 200 "hello world";
}
# http://localhost/static [成功]
# http://localhost/STATIC?v=1 [成功]
# http://localhost/static/1 [成功]
# http://localhost/static/1.txt [成功]
6、 @ 用于定义一个 Location 块,且该块不能被外部 Client 所访问,只能被nginx内部配置指令所访问,比如 try_files or error_page
location / {
root /root/;
error_page 404 @err;
}
location @err {
# 规则
default_type text/html;
return 200 "err";
}
# 如果 http://localhost/1.txt 404,将会跳转到@err并输出err
修饰符优先级
- 先判断精准匹配,如果匹配,立即返回结果并结束解析过程
- 然后,判断普通命中没如果有多个命中,记录最长的匹配结果
- 再然后判断正则表达式的解析过程,按配置里的正则表达式顺序为准,由上到下开始匹配,一旦匹配成功立即返回结果并结束解析过程。
注意:
- 普通匹配与顺序无关,因为按照匹配的长短来取匹配结果。
- 正则匹配与顺序有关,因为是从上往下匹配。(首先匹配,取其之。结束解析过程)
SSL配置
nginx 针对https提供ssl/tls配置功能的支持。
server {
server_name www.oneinelt.com;
listen 443 ssl; # 指定监听443端口 https专有默认的端口
ssl_certificate E:/nginx/nginx-1.13.11/cert/daluu.pem; # 申请的证书
ssl_certificate_key E:/nginx/nginx-1.13.11/cert/daluu.key; # 申请的证书密钥
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
缓存机制
通过设置缓存,可以加速网站请求的访问,减少服务器压力和代理请求,设置合理的缓存为我们节约大量资源,处理更多的任务。启用缓存后,nginx会将响应保存在磁盘缓存中,并使用它们响应客户端,而无需每次都代理对相同内容的请求。官网文档资料查询详细的配置说明,英文请点击我 中文资料请点击我
启用缓存
http {
# proxy_cache_path 缓存文件路径 keys_zone 缓存项目的元数据的共享内存区域的名称和大小
proxy_cache_path /data/nginx/cache keys_zone=one:10m;
server {
# 使用缓存名称 one
proxy_cache one;
location / {
proxy_pass http://localhost:8000;
}
}
}
指定缓存请求
Nginx使用缓存key作为密钥,如果请求具有与缓存响应相同的密钥,则NGINX将缓存的响应发送给客户端。缓存密钥就是指请求主机,地址,请求参数等等,还可以设置http请求方法是GET,POST,PUT,包括缓存触发次数。
location / {
proxy_cache content; #设置keys_zone后的缓存名称
proxy_pass http://192.168.56.1:8080/; #反向代理地址
proxy_cache_key "$host$request_uri$cookie_user"; #通过key来hash,定义KEY的值,即是缓存命中的key
proxy_cache_methods GET HEAD POST; #设置需要缓存的http请求方法
proxy_cache_min_uses 5; #设置具有请求相同key密钥的最低缓存触发次数,即是访问某个请求多少次触发缓存
}
限制或绕过缓存
默认情况下,响应将无限期地保留在缓存中。 只有缓存超过最大配置大小,然后按照最后一次请求的时间长度,它们才被删除。要限制缓存响应与特定状态代码被认为有效的时间,请使用 proxy_cache_valid 指令。
location / {
proxy_cache_valid 200 302 10m; # 设置需要缓存的http状态码 和 缓存的时间 d天数 h小时 m分钟 s秒
proxy_cache_valid 404 1m; # 可以设置多个proxy_cache_valid 指令 以区分缓存时间
proxy_cache_valid any 5m; # 设置缓存所有状态码,请使用 any 关键字
proxy_cache_bypass $ cookie_nocache $ arg_nocache $ arg_comment; # 如果参数不为空且不为0,则不会缓存,会将请求转发
proxy_no_cache $http_pragma $http_authorization; #设置不缓存响应的条件
proxy_ignore_headers Cache-Control Set-Cookie;# 设置不缓存的header项
}
负载均衡缓存
跨多个应用程序实例的负载平衡是一种常用技术,用于优化资源利用率,最大化吞吐量,减少延迟并确保容错配置
官网文档资料查询详细的配置说明, 请点击我
下面介绍Nginx负载均衡七种策略,有些是需要下载第三方模块编译安装的。
1. 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}
2. 指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backserver {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
3. IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
注意:
- 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)。
- ip_hash不能与backup同时使用。
- 此策略适合有状态服务,比如session。
- 当有服务器需要剔除,必须手动down掉。
4、least_conn
把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
#动态服务器组
upstream dynamic_zuoyu {
least_conn; #把请求转发给连接数较少的后端服务器
server localhost:8080 weight=2;
server localhost:8081;
server localhost:8082 backup;
server localhost:8083 max_fails=3 fail_timeout=20s;
}
注意:
- 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。
5、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
6、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
在需要使用负载均衡的server中增加
proxy_pass http://backserver/;
upstream backserver{
ip_hash;
server 127.0.0.1:9090 down; (down 表示单前的server暂时不参与负载)
server 127.0.0.1:8080 weight=2; (weight 默认为1.weight越大,负载的权重就越大)
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器)
}
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
fail_timeout:max_fails次失败后,暂停的时间
7、Sticky
Sticky工作原理 :
Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、Hash值
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
http {
#OK include vhost/xxx.conf;
upstream shop_server{
sticky;
#Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上
# server 192.168.1.23;
server 192.168.1.24;
# server 192.168.1.25;
keepalive 32;
}
性能调优
....
本教程涵盖nginx绝大数应用配置,学会如何使用配置nginx帮助你搭建高性能灵活的web应用