nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的。 Nginx是一款免费的开源,高性能,可靠,可扩展且可完全扩展的Web服务器,负载均衡器和反向代理软件。也是一个 IMAP/POP3/SMTP 代理服务器。它使用Nginx这样一款轻量级的网页服务器更是能让你节省不必要的开支!以下是nginx的核心功能介绍和相关配置。
nginx的核心配置在conf/nginx.conf中。
user nobody; worker_processes 7; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; pid logs/nginx.pid; worker_rlimit_nofile 65535;
user 用户 [组]
指定运行nginx工作进程的用户、组,默认以nobody账户运行。
worker_processes 工作进程数
指定要使用几个工作进程,可以设置数值,也可以设置为auto,根据机器配置自动设置,默认值1。
实际运营时一般设置为很接近CPU的线程数,比如说CPU是8线程,一般设置为6、7。
我们自己开发、用时一般设置为1、2即可,不然太吃资源。
设置的只是工作进程数,不管设置多少个worker进程,主进程只有一个(即运行sbin/nginx)。
主进程由Linux当前登录的账户运行,工作进程由user指令指定的账户运行。第一列数字是进程的PID。
nginx工作进程和nginx主进程都是Linux中的进程,但主进程(父进程)可以控制worker进程(子进程)的开启、结束。master进程可以看做老板,worker进程可以看做打工仔。
error_log 保存位置 输出级别
指定nginx进程(主进程+工作进程)的信息(启动、结束、发生错误)的输出设置 。
保存位置默认是logs/error.log,输出级别由低到高依次为:debug(输出信息最多),info,notice,warn,error,erit(输出信息最少)。
pid 保存位置
指定nginx主进程的pid的保存位置,只保存nginx主进程的pid。
默认值为logs/nginx.pid
#worker_rlimit_nofile 65535;
指定单个worker进程最多可打开的文件描述符数。
r是read,limit是限制,单个worker进程最多只能打开指定个数的文件,超过便不能再读取文件。打开一次文件便会产生一个文件描述符。
此设置是为了防止单个worker进程消耗大量的系统资源。
events { accept_mutex on; multi_accept on; use epoll; worker_connections 1024; }
惊群现象:一个网络连接到来,所有沉睡的worker进程都会被唤醒,但只用一个worker处理连接,其余被唤醒的worker又开始沉睡。
设置为on:要使用几个worker就唤醒几个,不全部唤醒,默认值就是on。
设置为off:一律全部唤醒。一片worker醒来是要占用资源的,会影响性能。
一个进程是否同时接受多个网络连接,默认为off。
指定nginx的工作模式,可选的值:select、poll、kqueue、epoll、rtsig、/dev/poll。
其中select、poll都是标准模式,kqueue、epoll都是高效模式,
kqueue是在BSD系统中用的,epoll是在Linux系统中用的。(BSD是Unix的一个分支,Linux是一种类Unix系统)。
指定单个worker进程最多可建立多少个网络连接,默认值1024。
全局块中的worker_processes、events块中的worker_connections是nginx支持高并发的关键,这2个数值相乘即nginx可建立的最大连接数。
一个连接要用一个文件来保存,
events块的worker_connections设置的单个worker进程的最大连接数,受全局块中worker_rlimit_nofile设置的单个worker进程可打开的最大文件数限制。
而worker_rlimit_nofile只是nginx对单个worker进程的限制,要受Linux系统对单个进程可打开的最大文件描述符数限制。
Linux默认单个进程最多只能打开1024个文件描述符,所以需要我们修改下Linux的资源限制,设置单个进程可打开的最大文件描述符数:
ulimit -n 65536
ulimit命令可以限制单个进程使用的系统资源的尺寸、数量,包括内存、缓冲区、套接字、栈、队列、CPU占用时间等。
可用ulimit --help查看参数。
http{ #http全局块 #server块 }
可以有多个server块。
http全局块的配置作用于整个http块(http块内的所有server块)。
include mime.types; default_type application/octet-stream;
这2句指定请求、响应中要使用的MIMI-Type。
conf/mime.types文件中已经设置了大量的文件类型,比如html、css、js、json、xml、txt、m3u8、ts、avi、mp4、mp3、jpg、doc等等,使用include将该文件包含进来。
default_type指定默认类型,当请求、响应中的数据不是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 logs/access.log main;
log_format定义日志格式,main是格式名。上面的格式就是默认格式,包括客户端地址、使用的浏览器、浏览器内核版本、请求的url、请求时间、请求方式、响应状态等。
access_log指定日志保存位置、要使用的日志格式,未指定格式时使用默认格式。默认保存路径是logs/access_log。
$remote_addr 客户端的ip地址 $time_local : 访问时间与时区 $request : 请求的url与http协议 $status : 请求状态,成功是200 $http_referer :从那个页面链接访问过来的 $http_user_agent :客户端浏览器的信息
sendfile on; #tcp_nopush on; #tcp_nodelay on;
sendfile指定是否开启文件高效传输模式,默认为off,不开启。
tcp_nopush、tcp_nodelay设置为on,可以防止网络阻塞。
keepalive_timeout 65;
keepalive_timeout设置与客户端保持活动的超时时间,在指定时间内,如果客户端没有向Nginx发送任何数据(无活动),Nginx会关闭该连接。
gzip on;
是否使用gzip模块,on表示开启GZIP压缩,nginx压缩响应数据,客户端浏览器拿到响应后自动解压。
启用后响应体积变小,传输到客户端所需时间更少,节省带宽,但压缩、解压都有额外的时间、资源开销,nginx的负担也会加大。
upstream servers{ server 192.168.1.7:8080; server 192.168.1.8:8081; }
设置负载均衡器,指定服务器节点(ip:port)、使用的负载均衡算法。
可配置多个负载均衡器,负载均衡器的名称中不能含有_,此处的名称是servers。
server 192.168.1.7:8080 down; server 192.168.1.8:8081 backup; server 192.168.1.8:8081 max_fails=3 fail_timeout=60s;
down表示该节点下线,暂时不提供服务。 backup表示该节点是预备的,只有在其他节点忙不过来时才会启用(比如一些节点出故障了、其他节点负载变大)。 max_fails:允许对该节点请求失败的次数,默认为1。 fail_timeout:对该节点请求失败的次数达到max_fails时,多少时间内暂时不使用该节点。
nginx有5种负载均衡算法:
轮询
将列表中的服务器排成一圈,从前往后,找空闲的服务器来处理请求。
轮询适合服务器性能差不多的情况。默认使用的就是轮询,不需要设置什么。
加权轮询
upstream servers{ server 192.168.1.7:8080 weight=1; server 192.168.1.8:8081 weight=2; }
设置权重,权重大的轮到的机会更大,适合服务器性能有明显差别的情况。
ip_hash
upstream servers{ ip_hash; server 192.168.1.7:8080; server 192.168.1.8:8081; }
根据客户端ip的hash值来转发请求,同一客户端(ip)的请求都会被转发给同一个服务器处理,可解决session问题。
url_hash(第三方)
upstream servers{ hash $request_uri; server 192.168.1.7:8080; server 192.168.1.8:8081; }
根据请求的url来转发,会将url相同的请求转发给同一服务器处理。
一直处理某个url,服务器上一般都有该url的缓存,可直接从缓存中获取数据作为响应返回,减少时间开销。
fair(第三方)
upstream servers{ fair; server 192.168.1.7:8080; server 192.168.1.8:8081; }
根据服务器响应时间来分发请求,响应时间短的分发的请求多。
fair 公平,nginx先计算每个节点的平均响应时间,响应时间短说明该节点负载小(闲),要多转发给它;响应时间长说明该节点负载大,要少转发给它。
url_hash、fair都依赖相应的软件包,需要在Linux上安装相应的软件包。
listen 80; server_name localhost; charset utf-8; #access_log logs/host.access.log main;
要监听的端口
server_name即主机名(域名),要在DNS上注册过才有效,没有注册的话只能用localhost。可通知指定多个域名,空格分隔即可。
请求、响应使用的编码字符集。
日志设置。http全局块已经设置了日志,此处可以不设置。
error_page 404 /404.html; location = /404.html { root html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }
设置404页面、50x页面。
这些设置nginx本身处理请求出现问题显示的页面,比如nginx上的静态资源找不到,才显示这里配置的404页面。如果是tomcat出现的问题,比如tomcat上的xxx.jsp找不到,显示的是tomcat的404页面,不是nginx的。
error_page指定发生该问题时要调用哪个页面返回给客户端:
error_page 错误代码 /要调用的页面
location指定该页面的位置:
location = /要调用的页面 {
root html;
}
表示该页面在html目录下。一般写相对路径,相对于nginx主目录,也可以写绝对路径。
需要注意的是html目录下默认只有index.html(nginx的首页)、50x.html,需要自己写404页面。
location ~* .(html|css|js|gif|jpg|png|mp4)$ { root static; #proxy_pass http://192.168.1.10:80; }
代理静态资源,()中指定要代理哪种类型的资源|文件。
如果就使用nginx处理静态资源,那就用root指定静态资源所在目录。此处指定为nginx主目录下的static目录,在nginx下新建static目录,把项目中的静态资源放进去。
需要注意的是,要将全局块user的用户账户设置为运行nginx的账户(就是当前登陆Linux的账户),否则worker进程(nobody账户)无权限读取当前账户(即运行nginx主进程的账户)的静态资源,客户端会显示403禁止。
如果要使用其它节点(比如apache)处理静态资源,使用proxy_pass转发给其他节点即可,如果处理静态资源的机器要集群,设置、引用一个新的负载均衡器即可。
location / { root html; index index.html index.htm; proxy_pass http://servers; }
处理静态资源、处理.php等等,其实都是通过正则表达式来匹配url。
这个设置是设置默认的请求处理,如果其他都不匹配,就调用此设置来处理请求,一般我们把负载均衡设置在这里面。
index指定nginx服务器的首页,root指定页面所在路径,此处使用相对路径,nginx主目录下的html目录。这2个是必需的,不然客户端会报500。
proxy_pass指定要将请求转发给哪个服务器处理,http://负载均衡器; 如果只有一个tomcat节点,可以直接写http://tomcat的ip:port
nginx是可以作为web服务器的,如果没设置proxy_pass,那就不使用代理,会把请求交给root指定目录下的页面来处理。
比如客户端请求login.jsp,不使用代理,那就调用root指定的目录下的login.jsp来处理请求。
可以使用正则表达式来过滤客户端ip,也可以把客户端的ip过滤规则写在文件中,然后包含进来。