基本配置
worker_processes
工作进程是单线程进程。 如果Nginx正在进行CPU密集型工作(如SSL或gzipping),并且您有2个或更多CPU /核心,则可以将worker_processes设置为等于CPU或核心数。 如果您提供大量静态文件并且文件的总大小大于可用内存,那么您可以增加worker_processes以充分利用磁盘带宽。
在未配置该内容时,我可以查看我们的进程
1 | [root@localhost conf]# ps -ef | grep nginx |
此时可以看到nginx一个为主进程和一个工作进程。
nginx有一个主进程和几个工作进程。主进程的主要目的是读取和评估配置,并维护工作进程。工作进程会对请求进行实际处理。nginx使用基于事件的模型和依赖于操作系统的机制来有效地在工作进程之间分发请求。工作进程数在配置文件中定义,可以针对给定配置进行修复,也可以自动调整为可用CPU内核数
将1改为2,重新加载然后进行查看进程
1 | [root@localhost conf]# vim nginx.conf |
默认值为1,官网上说正常情况下1足够了
可以设置为CPU核心数,2或者4或者8,再多没有意义(top命令后按1可以查看CPU的核数)
- 如果省事的话设置为auto
worker_connetions
main部分中的worker_connections和worker_processes允许您计算可以处理的最大客户端: max clients = worker_processes * worker_connections
也就是说如果worker_processes为2,worker_connetions 为100,那么最大客户端连接数为2*100 = 200。
该数值不能超过 worker_rlimite_nofile
worker_cpu_affinity
nginx默认是没有开启利用多核cpu的配置的。需要通过增加worker_cpu_affinity配置参数来充分利用多核cpu,cpu是任务处理,当计算最费时的资源的时候,cpu核使用上的越多,性能就越好。
2核cpu,开启2个进程
1 | worker_processes 2; |
解释:01表示启用第一个CPU内核,10表示启用第二个CPU内核
worker_cpu_affinity 01 10;表示开启两个进程,第一个进程对应着第一个CPU内核,第二个进程对应着第二个CPU内核。
2核cpu,开启4个进程
1 | worker_processes 4; |
开启了四个进程,它们分别对应着开启2个CPU内核
4个cpu,开启4个进程
1 | worker_processes 4; |
0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推
4核cpu,开启2个进程
1 | worker_processes 2; |
0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核;2个进程对应着四个内核;worker_cpu_affinity配置是写在/etc/nginx/nginx.conf里面的;2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。
8核cpu,开启8个进程
1 | worker_processes 8; |
0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推;worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了
说明:
配置完之后可以重启nginx,用ab工具或者wrk工具,可以进行性能测试,在服务器上执行
top
,然后按1,就可以看到cpu工作情况,如果多个cpu内核的利用率差不多,就证明nginx已经成功利用了多核cpu,测试结束后,cpu内核的负载都同时降低。
worker_rlimit_nofile
语法:
1 | worker_rlimit_nofile 204800; |
为nginx工作进程改变打开最多文件描述符数目的限制。用来在不重启主进程的情况下增加限制
理论上这个值是最多打开文件数(ulimit -n)与nginx工作进程相除。
日志配置
日志格式
nginx日志文件在logs下面
- access.log 记录请求日志
- error.log 记录错误日志
在配置文件中有配置日志格式话的地方
1 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
将log_format与access_log前面的注释放开,我们来进行查看日志:
1 | 192.168.2.118 - - [27/Jul/2019:07:22:02 -0700] "GET /gms/index2.html HTTP/1.1" 200 429 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36" "-" |
请求头
参数 | 说明 | 示例 |
---|---|---|
$remote_addr | 客户端地址 | 192.168.2.118 |
$remote_user | 客户端用户名称 | – |
$time_local | 访问时间与时间 | [27/Jul/2019:07:22:02 -0700] |
$request | 请url和http协议 | “GET /gms/index2.html HTTP/1.1” |
$status | 请求状态 | 200 |
$body_bytes_sent | 发给客户端文件内容大小 | 429 |
$http_referer | url跳转来源 | - |
$http_user_agent | 用户终端浏览器信息 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36 |
$http_x_forwarded_for | 被转发的请求的原始IP | - |
$http_host | 请求地址,即浏览器中你输入的地址 | |
$upstream_status | upstream状态 | |
$ssl_protocol | SSL协议版本 | |
$ssl_cipher | 交换数据中的算法 | |
$upstream_addr | 后台upstream的地址,即真正提供服务的主机地址 | |
$request_time | 整个请求的总时间 | |
$upstream_response_time | 请求过程中,upstream响应时间 | |
请求头配置:
proxy_set_header X-real-ip $remote_addr
其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了 ,web端进行获取:request.getHeader(“X-real-ip”)
proxy_set_header X-Forwarded-For $remote_addr
真实的显示出客户端原始ip
proxy_set_header Host $http_host
如果想获取客户端访问的头部,可以这样来设置。但是,如果客户端请求头中没有携带这个头部,那么传递到后端服务器的请求也不含这个头部
proxy_set_header Host $host
个配置相当于上面配置的增强。它的值在请求包含”Host”请求头时为”Host”字段的值,在请求未携带”Host”请求头时为虚拟主机的主域名。
proxy_set_header Host $host:$proxy_port
服务器名和后端服务器的端口(访问端口)一起传送
proxy_set_header <<<*>>> “”
请求头的值为空,请求头将不会传送给后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。
添加这条配置之后:
意思是增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖,当然由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,那你会发现在web服务器端通过request.getHeader(“X-Forwarded-For”)获得的将会是客户端***ip和第一台*nginx的ip。
在第一台nginx中,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量的”X-Forwarded-For”部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。
到了第二台nginx,也使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
现在的$proxy_add_x_forwarded_for变量,
X-Forwarded-For部分包含的是用户的真实ip,
$remote_addr部分的值是上一台nginx的ip地址,
于是通过这个赋值以后现在的X-Forwarded-For的值就变成了”用户的真实**ip,第一台nginx的ip**”。
日志切割
由于日志文件在运行中过大,会导致写入写出以及排查问题的困难,会进行sh脚本进行日志切割,每天进行定时命令进行切割
1 |
|
location配置
精准匹配
1 | location =/uri{} |
优先级最高的匹配,=表示必须与指定的模式精确匹配
一般匹配
1 | location /uri{} |
优先级高于正则匹配,如果存在多个相同的前缀的一般匹配,那么最终会按照最大长度来做匹配
正则匹配
- ~ 表示:指定的正则表达式要区分大小写
- ~* 表示:指定的正则表达式不区分大小写
- ^~ 类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,
那么就停止搜索其他模式了 - @ :定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请
求来访问,如try_files或error_page等
1 | Location区段匹配示例 |
root 、alias指令区别
1 | location /img/ { |
1
2 > 若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件
>
1 | location /img/ { |
1
2 > 若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。
>
alias是一个目录别名的定义,root则是最上层目录的定义。
还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的。。。而root则可有可无~~
event配置
accept_mutex
语法:
1 | accept_mutex on | off ; |
设置网络连接的序列化 (默认为开启状态)
当某一个时刻只有一个网络连接到来时,多个睡眠进程会被同时叫醒,,但只有一个进程可获得连接。如果每次唤醒的进程数太多,会影响一部分系统性能。为解决这样的问题,Nginx配置中包含了一条指令 accept_mutex,当其设置为开启的时候,就会对多个Nginx进程接收连接进行序列化,防止多个进程对连接争抢。
multi_accept
语法:
1 | multi_accept on | off; |
设置是否允许同时接收多个网络连接
此指令默认为关闭(off)状态,即每个worker process 一次只能接收一个新到达的网络连接。
每个Nginx 服务器 的worker process 都有能力同时接收多个新到达的网络连接,但是这需要在配置之文件中进行设置,其指令为multi_accept
use
语法为:
1 | use method; |
事件驱动模型的选择 -> method可选择的内容有:select , poll、kqueue、cpoll、rtsig、/dev/poll以及wcentport,其中几种模型是比较常用的
Nginx 服务器提供了多种事件驱动模型来处理网络消息。配置文件中为我们提供了相关指令来强制 Nginx 服务器选择那种事件驱动模型进行消息处理,其指令为use
可以在编译时使用–with-select_module 和 –without-select_module 设置是否强制编译select 模块到 Nginx 内核;使用–with-poll_module 和 –without-poll_module 设置是否强制编译poll模块到 Nginx 内核;
worker_connections
语法:
1 | worker_connections number; |
配置最大的连接数
指令worker_connections 主要用来社会允许每一个worker process 同时开启的的最大连接数
这里的number 不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number 值 不能大于操作系统支持打开的最大文件句柄数量。
keepalived
介绍
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件
如何实现故障转移
Keepalived高可用服务对之间的故障切换转移,是通过 VRRP 来实现的。在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。
GZIP
在进行安装nginx时,依赖中有Gzip,此时我们来进行使用
gzip on|off
开启或者关闭gzip功能
gzip_buffers 4 4k/8k
设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 例如 4 8k 代表以8k为单位的4倍申请内存
gzip_comp_level
默认值:1(建议选择为4) gzip压缩比/压缩级别,压缩级别 1-9,级别越高压缩率越大,当然压缩时间也就越长(比较消耗cpu)
gzip_types mime-type
默认值: gzip_types text/html (默认不对js/css文件进行压缩)
一般情况下,在压缩常规文件时可以设置为:
gzip_types text/plain application/x-javascript text/css application/xml text/javascript;
注意: 图片/mp3这样的二进制文件,不必压缩。因为压缩率比较小, 比如100->80字节,而且压缩也是耗费CPU资源的。gzip_min_length
默认值: 0 ,不管页面多大都压缩 ,设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。建议设置成大于1k的字节数,小于1k可能会越压越大
gzip_http_version 1.0|1.1
默认值: gzip_http_version 1.1(就是说对HTTP/1.1协议的请求才会进行gzip压缩)
注:99.99%的浏览器基本上都支持gzip解压了。但是假设我们使用的是默认值1.1,如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的,如果我们使用nginx通过反向代理做Cache Server,而且前端的nginx没有开启gzip,同时,我们后端的nginx上没有设置gzip_http_version为1.0,那么Cache的url将不会进行gzip压缩gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any]
默认值:off,Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
off - 关闭所有的代理结果数据的压缩
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_vary on | off
开启时,将带着 ‘Vary: Accept-Encoding’头域的响应头部,主要功能是告诉浏览器发送的数据经过了压缩处理。开启后的效果是在响应头部添加了Accept-Encoding: gzip,这对于本身不支持Gzip压缩的浏览器是有用的。
gzip_disable “MSIE [1-6].”
禁用IE6的gzip压缩
针对不同类型的浏览器发起的请求,选择性地开启或关闭Gzip功能,支持使用正则表达式。gzip_static on|off
nginx对于静态文件的处理模块
该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。该模块启用后,nginx首先检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容。为了要兼容不支持gzip的浏览器,启用gzip_static模块就必须同时保留原始静态文件和gz文件。这样的话,在有大量静态文件的情况下,将会大大增加磁盘空间。我们可以利用nginx的反向代理功能实现只保留gz文件
1 | gzip on; #开启gzip功能 |
文件服务器
一些静态资源一般会进行放在文件服务器中
1 | # 文件服务器 |
参考内容: