Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/PO3)代理服务器,并在一个BSD协议下发行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及Microsoft Windows等操作系统中运行。
由俄罗斯的码农lgor Sysover所开发,最初供俄国大型的入口网站及搜寻引擎Rambler使用。其特点是占用内存少,并发能力强(用于解决C10K问题,现在可轻松处理C100K),事实上nginx的并发能力确实在同类型的网页服务器中表现较好。
安装
Install the prerequisites:
sudo yum install yum-utilsTo set up the yum repository, create the file named
/etc/yum.repos.d/nginx.repo
with the following contents:[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=trueBy default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command:
sudo yum-config-manager --enable nginx-mainlineTo install nginx, run the following command:
sudo yum install nginx
一、Nginx负载均衡
类似一个跳板机,代理访问外部资源
实际运行方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
1.保证内网的安全,可以使用反向代理提供的WAF功能,阻止web攻击。大型网站,通常将反向代理作为公网访问地址,web服务器是内网
2.负载均衡,通过反向代理服务器来优化网站的负载
负载均衡,但从字面上的意思来理解可以解释为N台服务器平均分担负载,不会因为某台服务器负载高宕机和某台服务器闲置的情况。负载均衡的前提就是2台以上服务器才能实现。
1.轮询
Round Robin,根据Nginx配置文件中的顺序,依次把客户端的web请求分发到不同的后端服务器上。
2.最少连接least_conn
Web请求会被转发到连接数最少的服务器
3.IP地址哈希ip_hash
前述的两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话session,那么会话会比较复杂。常见的基于数据库的会话持久化。要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。这样的话,同一客户端连续的Eeb请求都会被分发到同一服务器进行处理。
4.基于权重weight
基于权重的负载均衡(weighted load balancing),可以配置Nginx把请求更多地分发到高配置的后端服务器上,把相对较少的请求分发到低配服务器。
注意:
1.缺省配置就是轮询策略。
2.nginx负载均衡支持http和https协议,只要修改proxy_pass后协议即可。
3.nginx支持FastCGI,uwsgi,SCGI,memcached的负载均衡,只需将proxy_pass改为fastcgi,uwsgi_pass,sci_pass,memcached_pass即可。
4.此策略适合服务器配置相当,无状态且短平快的服务使用。
worker_processes 设为auto表示,cpu有多少核,就启动多少worker进程
pid 进程编号所放的位置
events nginx采用了基于事件的网络IO,比如多路复用的NIO技术,最成熟的是linux下的epoll
http upstream转发,netease.com是我们配置的后端服务,下面的三台服务器,是要轮询的服务器
server 监听80端口,server_name,location
注意:
1.ip哈希负载均衡使用ip_hash指令定义
2.nginx使用请求客户端的ip地址进行哈希计算,确保使用同一个服务器响应请求
3.此策略适合有状态服务,比如session
注意:
1.最少链接负载均衡通过least_conn指令定义
2.此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况
注意:
1.权重负载均衡需要使用weight指令定义
2.权重越高分配到需要处理的请求越多
3.此策略可以与最少链接负载和ip哈希策略结合使用
4.此策略比较适合服务器的硬件配置差别比较大的情况
nginx的http_proxy模块,可以实现类似于Squild的缓存功能
nginx对客户已经访问过的内容在nginx服务器本地建立副本,这样在一段时间内再次访问该数据,就不需要通过nginx服务器再次向后端服务器发出请求,所以能够减少nginx服务器与后端服务器之间的网络流量,减轻网络拥塞,同时还能减小数据传输延迟,提高用户访问速度。
同时,当后端服务器宕机时,nginx服务器上的副本资源还能够回应相关的用户请求,这样能够提高后端服务器的鲁棒性。
proxy_cache_path:nginx使用该参数指定缓存位置
proxy_cache:该参数为之前指定的缓存名称
proxy_cache_path:有两个必填参数
第一个参数为缓存目录
第二个参数keys_zone指定缓存名称和占用内存空间的大小
下面示例中的10m是对内存中缓存内容元数据信息大小的限值,如果想限值缓存总量大小,需要用max_size参数
1.nginx默认会缓存所有get和head方法的请求结果,缓存的key默认使用请求字符串。
2.自定义key
例如proxy_cache_key $host$request_uri$cookie_user
3.指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存
例如proxy_cache_min_uses 5
4.指定哪些方法的请求被缓存
例如proxy_cache_methods GET HEAD POST
缓存有效期
默认情况下,缓存内容长期留存,除法缓存的总量超出限制。可以指定缓存有效时间,例如:
对于某些请求,是否可以不走缓存?
prox_cache_bypass:该指令响应来自原始服务器而不是缓存
例如:proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment
如果任何一个参数值不为空,或者不等于0,nginx就不会查找缓存,直接进行代理转发
网页的缓存是由HTTP消息头“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。其作用根据不同的重新浏览方式分为下面几种情况。
nginx模块需要用C开发,而且必须符合一系列复杂的规则,用C开发模块必须熟悉nginx的源代码,使得开发者望而生畏。
ngx_lua模块通过将lua解释器集成进nginx,可以采用lua脚本实现业务逻辑。
该模块具备以下特性:
1.高并发、非阻塞的处理各种请求
2.Lua内建协程,可以很好的将异步回调转换成顺序调用的形式
3.每个协程都有一个独立的全局环境(变量空间),继承全局共享的、只读的comman data
得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存,非常适合用于实现可扩展的、高并发的服务。
协程(Coroutine) 进程是资源分配的基本单位,线程是资源调度的基本单位
协程类似一种多线程,与多线程的区别有:
1.协程并发os线程,所以创建、切换开销比线程相对要小。
2.协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。
3.多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程键协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。
4.由于多个协程只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
5.多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。
nginx的每个Worker进程都是在epoll或kqueue这样的事件模型上,封装成协程,每个请求都有一个协程进行处理。这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力。
nginx采用多进程模型,单Master-多Worker,Master进程主要用了管理Worker进程。
Worker进程采用单线程、非阻塞的事件模型(Event Loop,事件循环)来实现端口的监听及客户端请求的处理和响应,同时Worker还要处理来自Master的信号。Worker进程个数一般设置为机器CPU核数。
Master进程具体包括如下4个主要功能:
(1)接收来自外界的信号
(2)向各worker进程发送信号
(3)监控worker进程的运行状态
(4)当worker进程退出后(异常情况下),会自动重新启动新的worker进程
HTTP请求处理
属于nginx的一部分,它的执行指令都包含在nginx的11个步骤中,相应的处理阶段可以做插入式处理,即可插拔式架构,不过ngx_lua并不是所有阶段都会运行的;另外指令可以在http、server if、location、location if几个范围进行配置:
是一个基于nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块
以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。
工作原理:通过汇聚各种设计精良的nginx模块,从而将nginx有效地变成一个强大的通用Web应用平台。这样,Web开发人员和系统工程师可以使用Lua脚本语言调动nginx支持的各种C以及Lua模块,快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。
目标:让你的Web服务直接跑在nginx服务内部,充分利用nginx的非阻塞I/O模型,不仅仅对HTTP客户端请求,甚至对于远程后端诸如MySQL、PostgreSQL、Memcached以及Redis等都进行一致的高性能响应。
OpenResty是个package,打包了nginx和各种精良的库
将简单的转发工作,扩充为可以编写动态脚本
nginx转变为业务服务器,可以进行增删改查,可以进行业务处理
ngx_lua实例
四个例子
helloworld
content_by_lua:内容处理器,接收请求处理并输出响应
该指令工作在nginx处理流程的content阶段,即内容生产阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的
输出:
异步输出helloworld
读取请求参数
访问存储(redis)
基本语法:listen address:port
默认:listen 80
作用:listen参数决定nginx服务器如何监听端口。在listen后可以加IP地址,端口和主机名,非常灵活。
例如:
listen 127.0.0.1:8000 listen 127.0.0.1; //默认80端口 listen 8000 ;// listen *:8000;// listen localhost:8000;
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { use epoll; worker_connections 65535; } http { server { listen 80; location /{ default_type text/html; return 200 "Hello, Nginx! I am working on 80!\n"; } } server { listen 8080; location /{ default_type text/html; return 200 "Hello, Nginx! I am working on 8080!\n"; } } }
会启动两个server
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { use epoll; worker_connections 65535; } http { upstream origin.163.com { server 127.0.0.1:8080; } server { listen 80; server_name yes.163.com; location / { proxy_pass http://origin.163.com; } } server { listen 8080; location / { default_type text/html; return 200 "Hello, Nginx! I am working on 8080!\n"; } } }
通过proxy_pass把请求转发给upstream,upstream会从列表里按策略(默认轮询)选一server,这里最终发到了8080端口,监听8080端口
修改hosts
127.0.0.1 yes.163.com
结果
[root@node02 nginx]# curl -i http://yes.163.com HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Thu, 24 Oct 2019 09:47:29 GMT Content-Type: text/html Content-Length: 36 Connection: keep-alive Hello, Nginx! I am working on 8080!
location用来指定请求是如何被处理的
域名后面的一串成为uri,指定uri如何被处理,应该被哪个块接收和处理
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { use epoll; worker_connections 65535; } http { server { listen 80; location / { default_type text/html; return 200 "location /: I am default location!\n"; } location = /goodjob { default_type text/html; return 200 "location = /goodjob\n"; } location ~ /GoodJob { default_type text/html; return 200 "location ~ /GoodJob\n"; } location ~* /goodjob{ default_type text/html; return 200 "location ~* /goodjob\n"; }
location ^~ /goodjob{
default_type text/html;
return 200 "location ^~ /goodjob\n";
}
}
}
结果
[root@node02 nginx]# curl -i http://127.0.0.1/goodjob 完全匹配 HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Thu, 24 Oct 2019 10:44:34 GMT Content-Type: text/html Content-Length: 20 Connection: keep-alive location = /goodjob [root@node02 nginx]# curl -i http://127.0.0.1/GoodJob 大小写敏感 HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Thu, 24 Oct 2019 10:44:38 GMT Content-Type: text/html Content-Length: 20 Connection: keep-alive location ~ /GoodJob [root@node02 nginx]# curl -i http://127.0.0.1/Goodjob 大小写不敏感 HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Thu, 24 Oct 2019 10:44:44 GMT Content-Type: text/html Content-Length: 21 Connection: keep-alive
[root@node02 nginx]# curl -i http://127.0.0.1/goodjob/hello 只要goodjob匹配就可以
HTTP/1.1 200 OK
Server: openresty/1.15.8.2
Date: Thu, 24 Oct 2019 10:51:31 GMT
Content-Type: text/html
Content-Length: 21
Connection: keep-alive
location ^~ /goodjob
注意:location是有顺序的,如果一个请求有可能被多个location匹配,实际上这个请求会被第一个location处理
location / {}会处理所有的请求
语法:evn VAR|VAR=VALUE
作用:用户可以直接设置操作系统上的环境变量
举例:evn TESTPATH=/tmp
语法:include /path/file;
作用:可以把其他配置文件引入进来,路径可以使用绝对路径也可以使用相对路径,还可以含有通配符*
例如,下面的basic.conf
引用了expires.conf
语法:pid path/file;
默认:pid logs/nginx.pid;
作用:保存master进程ID的pid文件存放路径。
语法:user username [groupname];
默认:user nobody nobody;
作用:master进程fork出的进程在哪个用户和用户组下。
语法:worker_rlimit_nofile limit;
作用:设置一个worker可以打开的最大句柄数。
限制信号对列
语法:worker_rlimit_sigpending limit;
作用:设置每个用户发往nginx的信号对列的大小。也就是说,当某个用户的信号对列满了,这个用户再发送的信号量就会被丢掉。
语法:worker_processs number;
默认:worker_processes 1;
作用:在master_worker运行方式下,定义worker进程的个数。worker进程的数量会直接影响性能。每个worker都是单线程的进程,他会调用各个模块来实现各种功能。如果确定这些模块不会出现堵塞式调用,那么进程数可以和CPU核心数一样;反之,则稍少一些。
语法:worker_cpu_affinity cpumask [cpumask...]
作用:假设每个worker都是很繁忙的,如果多个进程都在抢同一个CPU,那么就会出现同比问题。反之,如果每个worker进程独享一个CPU,就实现了完全的并发。
举例:
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
user nginx; worker_processes auto; worker_cpu_affinity 1000 0100 0010; pid /var/run/nginx.pid; events { use epoll; worker_connections 65535; } http { server { listen 80; location / { default_type text/html; return 200 "location /: I am default location!\n"; } location = /goodjob { default_type text/html; return 200 "location = /goodjob\n"; } location ~ /GoodJob { default_type text/html; return 200 "location ~ /GoodJob\n"; } location ~* /goodjob{ default_type text/html; return 200 "location ~* /goodjob\n"; } location ^~ /goodjob{ default_type text/html; return 200 "location ^~ /goodjob\n"; } } }
语法:ssl_engine device;
作用:如果服务器上有SSL硬件加速设备,那么就可以进行配置加快SSL协议的处理速度。用户可以用OpenSSL提供的命令来查看是否有SSL硬件加速设备:openssl engine -t
语法:worker_priority nice;
默认:worker_priority 0;
作用:在Linux和Unix中,当许多进程都处于可执行状态时,按照优先级来决定内核选择哪一个进程执行。进程分配的CPU时间片大小也与优先级有关,优先级越高,时间片越长(如,在默认的情况下,最小时间片是5ms,最大则有800ms)。优先级由静态优先级和内核根据进程的执行情况所做的动态调整(目前只有+-5的调整)共同决定。nice是进程的优先级,它的取值范围是-20~+19,-20是最高级,+19是最低优先级。不建议把nice值设为比内核进程(t通常为-5)还要小
语法:accept_mutex [on|off];
默认:accept_mutex on;
作用:负载均衡锁,这把锁可以让多个worker进程轮流的,序列化的与新的客户端建立TCP连接。accept锁默认是打开的,如果关闭它,那么建立TCP连接的耗时会更短,但不利于负载均衡,因此不建议关闭。
语法:accept_mutex_delay Nms;
默认:accept_mutex_delay 500ms;
作用:在使用accept锁后,同一时间只有一个worker进程能够取到accept锁。这个accept锁不是堵塞锁,如果取不到会立刻返回。如果只有一个worker进程试图取锁而没有取到,它至少要等待accept_mutex_delay定义的时间才能再次试图取锁。
语法:multi_accept [on|off];
默认:multi_accept off;
作用:当事件模型有新连接时,尽可能的对本次调度客户端发起的所有TCP请求都建立连接。
语法:use [kqueue|rtsig|epoll|/dev/poll|select|eventport];
默认:nginx会选出最合适的时间模型
作用:对于Linux系统,可供选择的事件驱动模型有:poll,select,epoll三种,一般来说,epoll是性能最高的。
语法:worker_connections number;
作用:定义每个worker进程可以同时处理的最大连接数
原文:https://www.cnblogs.com/aidata/p/11734567.html