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