当前位置: 首页 > news >正文

企业级Nginx Web服务优化实战(上)

一 ,Nginx基本安全优化

1.1 调整参数隐藏Nginx软件版本号信息

一般来说 ,软件的漏洞都和版本有关 ,这个很像汽车的缺陷 ,同一批次的要有问题就 都有问题 ,别的批次可能就都是好的。 因此 ,我们应尽量隐藏或消除Web服务对访 问用户显示各类敏感信息(例如Web软件名称及版本号等信息) ,这样恶意的用户 就很难猜到他攻击的服务器所用的是否有特定漏洞的软件 ,或者是否有对应漏洞的某 一特定版本 ,从而加强Web服务的安全性。这在武侠小说里 ,就相当于隐身术 ,你 隐身了 ,对手就很难打着你了。

想要隐身 ,首先要了解所使用软件的版本号 ,对于Linux客户端 ,可通过命令行查看 Nginx版本号 ,最简单的方法就是在Linux客户端系统命令行执行如下curl命令 :

[root@LNMP html]# curl -I 192.168 .0.220
HTTP/1.1 200 OK
Server: nginx/1.6.2             #这里清晰的暴露了Web版本号( 1.6.2)及软件名称 (nginx)
Date : Wed, 23 Aug 2017 10 :45 :47 GMT
Content-Type : text/html; charset=UTF-8
Connection : keep-alive
X-Powered-By : PHP/5.3.28
Link : <http ://192.168.0.220/wp-json/>; rel="https://api.w.org/"

在Windows客户端上 ,通过浏览器访问Web服务时 ,若找不到页面 ,默认报错的信息如下图 所示 :

以上虽然是不同的客户端 ,但是都获得了Nginx软件名称 ,而且查到了Nginx的版本号 , 这就使得Nginx Web服务的安全存在一定的风险 ,因此 ,应隐藏掉这些敏感信息或用一 个其他的名字将其替代。例如 ,下面是百度搜索引擎网站Web软件的更名做法 :

[root@localhost ~]# vim 1.txt 
[root@localhost ~]# cat 1.txt | sed 's/^[0-9]\+\s*\.\s*//'
[root@LNMP html]# curl -I baidu .com
HTTP/1.1 200 OK
Date : Fri, 25 Aug 2017 12 :22 :29 GMT
Server: Apache          #将Web服务软件更名为了Apache,并且版本号也去掉了
[root@LNMP html]# curl -I -s www.baidu.com
HTTP/1.1 200 OK
Server: bfe/1.0.8.18        #将Web服务软件更名为了bfe,并且版本号改为 1.0.8.18 (闭源软件名称和版本就无所谓了)

门户网站尚且如此 ,我们也学着隐藏或改掉应用服务软件名和版本号把 !事实上 ,还可 以通过配置文件加参数来隐藏Nginx版本号。编辑nginx.conf配置文件增加参数 ,实现 隐藏Nginx版本号的方式如下 :

 #在Nginx配置文件nginx.conf中的http标签段内加入“server_tokens off” 2.http
{...............server_tokens off;...............
}

此参数放置在http标签内 ,作用是控制http response header内的Web服务版本信息的 显示 ,以及错误信息中Web服务版本信息的显示。

1. server_tokens参数的官方说明如下 :

| 2. | syntax:
状态 | server_tokens on |off; | #此行为参数语法 , on为开启状态 , off为关闭 |
| — | — | — | — |
| 3. | default :
果 | server_tokens on; | #此行意思是不配置该参数 ,软件默认情况的结 |
| 4. | context : | http,server,location | #此行为server_tokens参数可以放置的位置 |

参数作用 :激活或禁止Nginx的版本信息显示在报错信息和Server的响应首部位置中。

官方资料地址 :http://nginx.org/en/docs/http/ngx_http_core_module.html

配置完毕后保存 ,重新加载配置文件 ,再次通过curl查看 ,结果如下 :

[root@LNMP nginx]# curl -I 192.168 .0.220
HTTP/1.1 200 OK
Server: nginx                   #版本号已经消失
Date : Wed, 23 Aug 2017 11 :22 :15 GMT
Content-Type : text/html; charset=UTF-8
Connection : keep-alive
X-Powered-By : PHP/5.3.28
Link : <http ://192.168.0.220/wp-json/>; rel="https://api.w.org/"

此时 ,浏览器的报错提示中没有了版本号 ,如下图所示 ,修改成功。

1.2 更改源码隐藏Nginx软件名及版本号

隐藏了Nginx版本号后 ,更进一步 ,可以通过一些手段把Web服务软件的名称也隐藏起 来 ,或者更改为其他Web服务软件名以迷惑黑客。但软件名字的隐藏修改 ,一般情况下 不会有配置参数和入口 ,Nginx也不例外 ,这可能是由于商业及品牌展示等原因 ,软件 提供商不希望使用者把软件名字隐藏起来。 因此 ,此处需要更改Nginx源代码 ,具体的 解决方法如下 :

1.2.1 第一步 :依次修改3个Nginx源码文件。

修改的第一个文件为nginx-1.6.3/src/core/nginx.h,如下 :

[root@LNMP ~]# cd /usr/src/nginx-1.6.2/src/core/
[root@LNMP core]# ls -l nginx .h
-rw-r--r--. 1 1001 1001 351 Sep 16  2014 nginx.h
[root@LNMP core]# sed -n '13,17p ' nginx.h
#define NGINX_VERSION      "1.6.2"      #修改为想要显示的版本号
#define NGINX_VER          "nginx/" NGINX_VERSION
#将nginx修改为想要修改的软件名称。
#define NGINX_VAR          "NGINX"      #将nginx修改为想要修改的软件名称
#define NGX_OLDPID_EXT     ".oldbin"

修改后的结果如下 :

修改的第二个文件是nginx-1.6.3/src/http/ngx_http_header_filter_module.c的第49行 , 需要修改的字符串内容如下 :

ls -l /usr/src/nginx-1.6.2/src/http/ngx_http_header_filter_module.c
-rw-r--r--. 1 1001 1001 19321 Sep 16  2014 /usr/src/nginx-1.6.2/src/htt p/ngx_http_header_filter_module.c
[root@LNMP http]# grep -n 'Server: nginx ' ngx_http_header_filter_module.c
49:static char ngx_http_server_string [] = "Server: nginx" CRLF;
#修改本行结尾的nginx

通过sed替换修改 ,后如下 :

 [root@LNMP http]# grep -n 'Server: nginx ' ngx_http_header_filter_module.c
49 :static char ngx_http_server_string [] = "Server: nginx" CRLF;
[root@LNMP http]# sed -i 's#Server: nginx#Server: yunjisuan#g '
ngx_http_header_filter_module.c
[root@LNMP http]# grep -n 'Server: yunji suan ' ngx_http_header_filter_module.c
49 :static char ngx_http_server_string [] = "Server: yunji suan" CRLF;

修改的第三个文件是nginx-1.6.3/src/http/nginx_http_special_response.c,对面页面报错 时 ,它会控制是否展开敏感信息。这里输出修改前的信息ngx_http_special_response.c中的 第21~30行 ,如下 :

[root@LNMP http]# sed -n '21,30p ' ngx_http_special_response.c
static u_char ngx_http_error_full_tail [] ="<hr><center>" NGINX_VER "</center>" CRLF       #此行需要修改"</body>" CRLF
"</html>" CRLF
static u_char ngx_http_error_tail [] =
"<hr><center>nginx</center>" CRLF               #此行需要修改"</body>" CRLF

修改后的结果如下 :

[root@LNMP nginx-1.6.2]# sed -n '21,32p ' src/http/ngx_http_special_response .c
static u_char ngx_http_error_full_tail [] =
"<hr><center>" NGINX_VER "  (Mr.chen 2018-08-26)</center>"  CRLF    #此 行是定义对外展示的内容
"</body>" CRLF
"</html>" CRLF
; 7.static u_char ngx_http_error_tail [] =
"<hr><center>yunjisuan</center>" CRLF       #此行将对外展示的Nginx名字更改 为yunji suan
"</body>" CRLF
"</html>" CRLF
;

1.2.2 第二步是修改后编辑软件 ,使其生效修改后再编译安装软件 ,如果是已经安装好的服务 ,需要重新编译Nginx ,配好配置 , 启动服务。

再次使浏览器出现404错误 ,然后看访问结果 ,如下图所示 :

如上面所示 :Nginx的软件和版本名都被改掉了 ,并且加上了本人的大名。 再看看Linux curl命令响应头部信息 ,如下 :

[root@LNMP conf]# curl -I localhost/xxx/
HTTP/1.1 404 Not Found
Server: yunjisuan/0.0.0.0           #也更改了
Date : Wed, 23 Aug 2017 15 :33 :54 GMT
Content-Type : text/html
Content-Length: 196
Connection : keep-alive

1.3 更改Nginx服务的默认用户

为了让Web服务更安全 ,要尽可能地改掉软件默认的所有配置 ,包括端口 ,用户 等。

下面就来更改Nginx服务的默认用户

首先 ,查看Nginx服务对应的默认用户。一般情况下 ,Nginx服务启动后 ,默认使用 的用户是nobody ,查看默认的配置文件 ,如下 :

1. [root@LNMP conf]# cd /usr/local/nginx/conf/

2. [root@LNMP conf]# grep “#user” nginx.conf .default

3. #user nobody;

为了防止黑客猜到这个Web服务的用户 ,我们需要更改成特殊的用户名 ,例如nginx或 特殊点的inca ,但是这个用户必须是系统里事先存在的 ,下面以nginx用户为例进行说 明。

( 1 )为Nginx服务建立新用户

1. useradd nginx -s /sbin/nologin -M

2. #不需要有系统登录权限 ,应当禁止登陆。

( 2 )配置Nginx服务 ,让其使用刚建立的nginx用户

更改Nginx服务默认使用用户 ,方法有二 :

第一种 :直接更改配置文件参数 ,将默认的#user nobody ;改为如下内容 :

user nginx nginx;

如果注释或不设置上述参数 ,默认为nobody用户 ,不推荐使用nobody用户名 ,最好采 用一个普通用户 ,此处用大家习惯的 ,前面建立好的nginx用户。

第二种 :直接在编译nginx软件时指定编译的用户和组 ,命令如下 :

 ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx -
-with-http_stub_status_module --with-http_ssl_module#提示 :#前文在编译Nginx服务时 ,就是这样带着参数的 , 因此无论配置文件中是否加参数 ,默认都是n ginx用户。

( 3 )检查更改用户的效果

重新加载配置后 ,检查Nginx服务进程的对应用户 ,如下 :

 [root@LNMP conf]# ps -ef | grep nginx | grep -v greproot      52023      1  0 11 :30 ?         00 :00 :00 nginx: master process
/usr/local/nginx/sbin/nginxnginx     52024  52023  0 11 :30 ?         00 :00 :00 nginx: worker process

通过查看上述更改后的Nginx进程 ,可以看到worker processes进程对应的用户都变成 了nginx。所以 ,我们有理由得出结论 ,上述的两种方法都可设置Nginx的worker进程运 行的用户。 当然 ,Nginx的主进程还是以root身份运行的。

二 ,根据参数优化Nginx服务性能

2.1 优化Nginx服务的worker进程个数

在高并发 ,高访问量的Web服务场景 ,需要事先启动好更多的Nginx进程 ,以保证快 速响应并处理大量并发用户的请求。

这类似于开饭店 ,在营业前 ,需要事先招聘一定数量的服务员准备接待顾客 ,但这里 就有一个问题 ,如果饭店对客流没有正确预估 ,就会导致一些问题发生 ,例如 :服务 员人数招聘多了 ,但是客流很少 ,那么服务员就可能很闲 ,没事干 ,饭店的成本也高 了 ;如果客流很大 ,而服务员人数少了 ,可能就接待不过来顾客 ,导致顾客吃饭体验 差。 因此 ,饭店要根据客户的流量及并发量来调整接待的服务人员数量 ,然后根据检 测顾客量变化及时调整到最佳配置。

Nginx服务就相当于饭店 ,网站用户就相当于顾客 ,Nginx的进程就相当于服务员 , 下面就来优化Nginx进程的个数。

2.1.1 优化Nginx进程对应的配置

1. #优化Nginx进程对应Nginx服务的配置参数如下 :

2. worker_processes 1; #指定了Nginx要开启的进程数 ,结尾数字就是进程个数

上述参数调整的是Nginx服务的worker进程数 ,Nginx有Master进程和worker进程之 分 ,Master为管理进程 ,真正接待“顾客”的是worker进程。

2.1.2 优化Nginx进程个数的策略

前面已经讲解过 ,worker_processes参数大小的设置最好和网站的用户数量相关联 ,可如果是新配置 ,不知道网站的用户数量该怎么办呢 ?

搭建服务器时 ,worker进程数最开始的设置可以等于CPU的核数 ,且worker进程数 要多一些 ,这样起始提供服务时就不会出现因为访问量快速增加而临时启动新进程提 供服务的问题 ,缩短了系统的瞬时开销和提供服务的时间 ,提升了服务用户的速度。 高流量高并发场合也可以考虑将进程数提高至CPU核数*2 ,具体情况要根据实际的业 务来选择 ,因为这个参数除了要和CPU核数匹配外 ,也和硬盘存储的数据及系统的负 载有关 ,设置为CPU的核数是一个好的起始配置 ,这也是官方的建议。

2.1.3 查看Web服务器CPU硬件资源信息

下面介绍查看Linux服务器CPU总核数的方法 :

( 1 )通过/proc/cpuinfo可查看CPU个数及总核数。查看CPU总核数的示例如下 :

[root@LNMP ~]# grep processor /proc/cpuinfo
processor   : 0
processor   : 1
processor   : 2
processor   : 3
[root@LNMP ~]# grep processor /proc/cpuinfo | wc -l
4               #表示为1颗CPU四核
[root@LNMP ~]# grep -c processor /proc/cpuinfo
4               #表示为1颗CPU四核 10 .
#查看CPU总颗数示例如下 :
[root@LNMP ~]# grep "physical id" /proc/cpuinfo
physical id : 0     #物理ID一致 , 同一颗CPU
physical id : 0     #物理ID一致 , 同一颗CPU
physical id : 0     #物理ID一致 , 同一颗CPU
physical id : 0     #物理ID一致 , 同一颗CPU
[root@LNMP ~]# grep "physical id" /proc/cpuinfo | sort | uniq | wc -l
1               #去重复 ,表示1颗CPU

( 2 )通过执行top命令 ,然后按数字1 ,即可显示所有的CPU核数 ,如下 :

2.1.4 实践修改Nginx配置

假设服务器的CPU颗数为1颗 ,核数为4核 ,则初始的配置可通过查看默认的nginx.conf 里的worker_processes数来了解 ,命令如下:

[root@LNMP ~]# grep worker_processes /usr/local/nginx/conf/nginx.conf
worker_processes  1;
[root@LNMP ~]# sed -i 's#worker_processes  1#worker_processes  4# ' /usr /local/nginx/conf/nginx.conf
[root@LNMP ~]# grep worker_processes /usr/local/nginx/conf/nginx.conf
worker_processes  4;        #提示可以通过vi修改 6.
#优雅重启Nginx,使修改生效 ,如下 :
[root@LNMP ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@LNMP ~]# /usr/local/nginx/sbin/nginx -s reload 12 .
#现在检查修改后的worker进程数量 ,如下 :
[root@LNMP ~]# ps -ef | grep "nginx" | grep -v grep
root       1110      1  0 11 :12 ?         00 :00 :00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      1429   1110  0 11 :33 ?         00 :00 :00 nginx: worker process
nginx      1430   1110  0 11 :33 ?         00 :00 :00 nginx: worker process
nginx      1431   1110  0 11 :33 ?         00 :00 :00 nginx: worker process
nginx      1432   1110  0 11 :33 ?         00 :00 :00 nginx: worker process

从“worker_processes 4”可知 ,worker进程数为4个。 Nginx Master主进程不包含在 这个参数内 ,Nginx Master的主进程为管理进程 ,负责调度和管理worker进程。

有关worker_processes参数的官方说明如下 :

1. syntax: worker_processes number; #此行为参数语法 ,number为数量

2. default: worker_processes 1; #此行意思是不匹配该参数 ,软件默认情况 数量为1

3. context: main; #此行为worker_processes参数可以放置的位置

worker_processes为定义worker进程数的数量 ,建议设置为CPU的核数或CPU核数

*2 ,具体情况要根据实际的业务来选择 ,因为这个参数 ,除了要和CPU核数匹配外 ,和 硬盘存储的数据以系统的负载也有关 ,设置为CPU的个数或核数是一个好的起始配置。 From :http://nginx.org/en/docs/ngx_core_module.html

2.2 优化绑定不同的Nginx进程到不同的CPU上

默认情况下 ,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上 ,导致

Nginx进程使用硬件的资源不均 ,本节的优化是尽可能地分配不同的Nginx进程给不 同的CPU处理 ,达到充分有效利用硬件的多CPU多核资源的目的。

在优化不同的Nginx进程对应不同的CPU配置时 ,四核CPU服务器的参数配置参考如 下 :

worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
#worker_cpu_affinity就是配置Nginx进程与CPU亲和力的参数 , 即把不同的进程分给不同 的CPU处理。这里0001 0010 0100 1000是掩码 ,分别代表第1, 2, 3, 4核CPU, 由于worker_processes进程数为4, 因此 ,上述配置会把每个进程分配一核CPU处理 ,默认情况下 进程不会绑定任何CPU,参数位置为main段。

四核和八核CPU服务器的参数配置参考如下 :

 #八核掩码worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 001000 00 01000000 10000000 ;#四核掩码worker_cpu_affinity 0001 0010 0100 1000 ;

worker_cpu_affinity 的作用是绑定不同的worker进程数到一组CPU上。通过设置

bitmask控制进程允许使用的CPU ,默认worker进程不会绑定到任何CPU( 自动平均分 配。 )

2.2.1 实验环境准备

主机名 IP地址 备注

Nginx 192.168.0.220 nginxWeb

测试机1 192.168.0.240 Webbench压力测试

测试机2 192.168.0.245 Webbench压力测试

1. #安装webbench

2. tar xf webbench-1.5.tar.gz

3. cd webbench-1.5

4. mkdir /usr/local/man

5. make install clean

6. which webbench.

虚拟机开启4核心

2.2.2 第一步 :不绑定worker进程进行压力测试

#配置文件如下 :(未绑定worker进程)
[root@LNMP nginx]# cat conf/nginx.conf
worker_processes  4;
#worker_cpu_affinity 0001 0010 0100 1000;
events {
worker_connections  10240;
}
http {
include       mime .types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
listen       80;
server_name  bbs.yunji suan .com;
location / {
root   html;
index  index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
}
} 26 .
#在NginxWeb上执行如下命令 :
[root@LNMP nginx]# top -u nginx
Tasks: 120 total,   1 running, 119 sleeping,   0 stopped,   0 zombie
Cpu (s):  0.0%us,  0.2%sy,  0.0%ni, 99.8%id,  0.0%wa,  0.0%hi,  0.0%si,0.0%st
Mem:   1004412k total,   911632k used,    92780k free,     6952k buffer s
Swap :  2031608k total,        0k used,  2031608k free,   749976k cached 33 .
PID USER      PR  NI  V IRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1454 nginx     20   0 49240 5640  468 S  0.0  0.6   0:00.00 nginx
1455 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx
1456 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx
1457 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx 39 .#在以上界面时按键盘的数值1键 , 出现如下界面 :
top - 14 :44 :46 up 36 min,  1 user,  load average: 0.00, 0.00, 0.00
Tasks: 120 total,   1 running, 119 sleeping,   0 stopped,   0 zombie
Cpu0   :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si, 0.0%st
Cpu1   :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si, 0.0%st
Cpu2   :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si, 0.0%st
Cpu3   :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si, 0.0%st
Mem:   1004412k total,   911384k used,    93028k free,     6960k buffer s
Swap :  2031608k total,        0k used,  2031608k free,   749976k cached 50 .
PID USER      PR  NI  V IRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1454 nginx     20   0 49240 5640  468 S  0.0  0.6   0:00.00 nginx
1455 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx
1456 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx
1457 nginx     20   0 49240 5672  500 S  0.0  0.6   0:00.00 nginx

在另外的两台测试机器上同时进行压力测试 ,命令如下 :

webbench -c 2000 -t 60 http://192.168.0.220/

结果如下 :

2.2.3 第二步 :绑定worker进程进行压力测试

#配置文件如下(绑定worker进程)
[root@LNMP nginx]# cat conf/nginx.conf
worker_processes  4;
worker_cpu_affinity 0001 0010 0100 1000;    #修改本行
events {
worker_connections  1024;
}
http {
include       mime .types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
listen       80;
server_name  bbs.yunji suan .com;
location / {
root   html;
index  index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
}
}

在另外的两台测试机器上同时进行压力测试 ,命令如下 :

webbench -c 2000 -t 60 http://192.168.0.220/

结果如下 :

根据图示 ,我们基本可以看出 ,平均绑定worker进程和不绑定的实验效果基本是一致的 ( CPU0是默认会被使用的 )。原因在nginx在经过不断的优化后 ,会自动对worker进程 进行动态的平均分配。

2.2.4 第三步 :修改nginx配置 ,将所有worker进程绑定到CPU3上

#配置文件如下所示 :
[root@LNMP nginx]# cat conf/nginx.conf
worker_processes  4;
worker_cpu_affinity 1000 1000 1000 1000;    #修改本行
events {
worker_connections  1024;
}
http {
include       mime .types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
listen       80;
server_name  bbs.yunji suan .com;
location / {
root   html;
index  index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
}
}

在另外的两台测试机器上同时进行压力测试 ,命令如下 :

webbench -c 2000 -t 60 http://192.168.0.220/

结果如下 :

从上图我们可以得知 ,worker进程的压力被集中分配到了CPU3上。( CPU0是默认被使 用的 )

2.3 Nginx事件处理模型优化

Nginx的连接处理机制在不同的操作系统会采用不同的额I/O模型 ,在Linux

下 ,Nginx使用epoll的I/O多路复用模型 ,在Freebsd中使用kqueue的I/O多路复用 模型 ,在Solaris中使用/dev/poll方式的I/O多路复用模型 ,在Windows中使用的是 icop ,等等。

要根据系统类型选择不同的事件处理模型 ,可供使用的选择有“ use

[kqueue|rtsig|epoll|/dev/poll|select|poll];” 。 因为教学使用的是CentOS 6.5 Linux ,因此将Nginx的事件处理模型调整为epoll模型。

#具体的配置参数如下 :events      #events指令是设定Nginx的工作模式及连接数上限{use epoll ;          #use是一个事件模块指令 ,用来指定Nginx的工作模式。Nginx支持 的工作模式有select,poll, kqueue, epoll, rtsig和/dev/poll。其中select和poll 都是标准的工作模式 , kqueue和epoll是高效的工作模式 ,不同的是epoll用在Linux平台上   ,  而kqueue用在BSD系统中。对于Linux系统Linux2.6+内核 ,推荐选择epoll工作模式 ,这  是高性能高并发的设置}

根据Nginx官方文档建议 ,也可以不指定事件处理模型 ,Nginx会自动选择最佳的事件处 理模型服务。

对于使用连接进程的方法 ,通常不需要进行任何设置 ,Nginx会自动选择最有效办法。

2.4 调整Nginx单个进程允许的客户端最大连接数

接下来 ,调整Nginx单个进程允许的客户端最大连接数 ,这个控制连接数的参数为 work_connections。

worker_connections的值要根据具体服务器性能和程序的内存使用量来指定(一个进程 启动使用的内存根据程序确定) ,如下 :

 events  #events指令是设定Nginx的工作模式和连接数上线{worker_connections 20480;#worker_connections也是个事件模块指令 ,用于定义Nginx每个进程的最大连接数,
默认是1024.最大客户端连接数由worker_processes和worker_connections决定 , 即Max _client=  worker_processes*worker_connections。进程的最大连接数受Linux系统  进程的最大打开文件数限制 ,在执行操作系统命令 “ulimit   -HSn    65535”或配置相应文 件后 ,worker_connections的设置才能生效。}

下面是worker_connections的官方说明

参数语法 :worker_connections number

默认配置 :worker_connections 512

放置位置 :events

说明 :

worker_connections用来设置一个worker process支持的最大并发连接数 ,这个连接 数包括了所有链接 ,例如 :代理服务器的连接 ,客户端的连接等 ,实际的并发连接数除 了受worker_connections参数控制外 ,还和最大打开文件数worker_r limit_nofile有关 (见下文) ,Nginx总并发连接 =worker数量*worker_connections。

参考资料 :http://nginx.org/en/docs/ngx_core_module.html

2.5 配置Nginx worker进程最大打开文件数

接下来 ,调整配置Nginx worker进程的最大打开文件数 ,这个控制连接数的参数为 worker_r limit_nofile。该参数的实际配置如下 :

1. worker_rlimit_nofile 65535;

2. #最大打开文件数 ,可设置为系统优化后的ulimit -HSn的结果

下面是worker_r limit_nofile number的官方说明 :

参数语法 :worker_r limit_nofile number

默认配置 :无

放置位置 :主标签段

说明 :此参数的作用是改变worker processes能打开的最大文件数

参考资料 :http://nginx.org/en/docs/ngx_core_module.html

备注 :

Linux系统文件最大打开数设置 :u limit -n 65535

2.5.1 实验环境准备

主机名 IP地址 备注

Nginx 192.168.0.220 nginxWeb

测试机1 192.168.0.240 Webbench压力测试

测试机 2 192.168.0.245 Webbench压力测试

2.5.2 修改nginx.conf配置文件

[root@LNMP nginx]# cat conf/nginx.conf
worker_processes  1;
#worker_cpu_affinity 0000 0010 0100 1000;
#worker_rlimit_nofile 65535;
events {
worker_connections  1024;
}
http {
include       mime .types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
listen       80;
server_name  bbs.yunji suan .com;
location / {
root   html;
index  index.html index.htm;
}
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
}
}

先定1核1024连接数。 同学们注意多开几个虚拟机进行压力测试。不然的话 ,web服务 器还没出问题 ,你测试服务器先down掉了。

2.5.2 测试nginx服务连接数的极值

#使用这个命令可以抓取nginx的连接数
[root@LNMP nginx]# netstat -antp | grep nginx | wc -l
554
[root@LNMP nginx]# netstat -antp | grep nginx | wc -l
471

逐渐提高压力 ,抓连接数 ,看看nginx啥时候down

2.6 开启高效文件传输模式

( 1 )设置参数 :sendfile on;

sendfile参数用于开启文件的高效传输模式。 同时将tcp_nopush和tcp_nodelay两个指 令设置为on ,可防止网络及磁盘I/O阻塞 ,提升Nginx工作效率。

1. #sendfile参数的官方说明如下 :

2. syntax: sendfile on | off; #参数语法

3. default : sendfile off; #参数默认大小

4. context : http,server,location,if in location #可以放置的标签段

参数作用 :

激活或禁用sendfile()功能功能。 sendfile()是作用于两个文件描述符之间的数据拷贝函 数 ,这个拷贝操作是在内核之中的 ,被称为“零拷贝” ,sendfile()比read和write函数 要高效很多 ,因为 ,read和write函数要把数据拷贝到应用层再进行操作。相关控制参数 还有sendfile_max_chunk,同学们可以执行查询。细节

见http://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile

( 2 )设置参数 :tcp_nopush on;

1. #tcp_nopush参数的官方说明如下 :
2. syntax: tcp_nopush on off;
3. default : tcp_nopush off;#参数默认大小
4. context : http,server,location#可以放置的标签段

参数作用 :

激活或禁用Linux上的TCP_CORK socket选项 ,此选项仅仅当开启sendfile时才生效 ,激 活这个tcp_nopush参数可以允许把http response header和文件的开始部分放在一个 文件里发布 ,其积极的作用是减少网络报文段的数量。细节

见http://nginx.org/en/docs/http/ngx_http_core_module.html。

2.7 优化Nginx连接参数 ,调整连接超时时间

2.7.1 什么是连接超时

先来个比喻吧 ,某饭店请了服务员招待顾客 ,但是现在饭店不景气 ,此时 ,为多余的 服务员发工资使得成本被提高 ,想减少饭店开支成本就得解雇服务员。

这里的服务员就相当于Nginx服务建立的连接 ,当服务器建立的连接没有接收处理请 求时 ,可在指定的时间内就让它超时自动退出。还有当Nginx和FastCGI服务建立连 接请求PHP时 ,如果因为一些原因(负载高 ,停止响应) ,FastCGI服务无法给

Nginx返回数据 ,此时可以通过配置Nginx服务参数使其不会死等 ,因为前面用过户 还等着它返回数据呢 ,例如 ,可设置为如果请求FastCGI 10秒内不能返回数据 ,那么Nginx就中断本次请求 ,向用户汇报取不到数据的错误。

2.7.2 连接超时的作用

将无用的连接设置为尽快超时 ,可以保护服务器的系统资源( CPU ,内存 ,磁盘)。

当连接很多时 ,及时断掉那些已经建立好的但又长时间不做事的连接 ,以减少其占用的服 务器资源 ,因为服务器维护连接也是消耗资源的。

有时黑客或恶意用户攻击网站 ,就会不断地和服务器建立多个连接 ,消耗连接数 ,但是啥 也不干 ,大量消耗服务器的资源 ,此时就应该及时断掉这些恶意占用资源的连接。

LNMP环境中 ,如果用户请求了动态服务 ,则Nginx就会建立连接 ,请求FastCGI服务以及 后端MySQL服务 ,此时这个Nginx连接就要设定一个超时时间 ,在用户容忍的时间内返回 数据 ,或者再多等一会儿后端服务返回数据 ,具体的策略要根据具体业务进行具体分析。

当然了 ,后端的FastCGI服务及MySQL服务也有对连接的超时控制。

简单的说 ,连接超时是服务的一种自我管理 ,自我保护的重要机制。

2.7.3 连接超时带来的问题 ,以及不同程序连接设定知识

服务器建立新连接也是要消耗资源的 ,因此 ,超时设置得太短而并发很大 ,就会导致 服务器瞬间无法响应用户的请求 ,导致用户体验下降。

企业生产有些PHP程序站点会希望设置成短连接 ,因为PHP程序建立连接消耗的资源 和时间相对要少些。而对于Java程序站点来说 ,一般建议设置长连接 ,因为Java程序 建立连接消耗的资源和时间更多 ,这是语言运行机制决定的。

2.7.4 Nginx连接超时的参数设置

( 1 )设置参数 :keepalive_timeout 60;

用于设置客户端连接保持会话的超时时间为60秒。超过这个时间 ,服务器会关闭该连 接 ,此数值为参考值。

1. keepalive_timeout参数的官方说明如下 :
2. syntax: keepalive_timeout timeout[header_timeout] #参数语法
3. default : keepalive_timeout 75s;#参数默认大小
4. context : http,serverr,location#可以放置的标签段

参数作用 :

keep-alive可以使客户端到服务器端已经建立的连接一直工作不退出 ,当服务器有持 续请求时 ,keep-alive会使用已经建立的连接提供服务 ,从而避免服务器重新建立新 连接处理请求。

此参数设置一个keep-alive(客户端连接在服务器端保持多久后退出) ,其单位是秒 , 和HTTP响应header域的“ Keep-Alive:timeout =time”参数有关 ,这些header信息 也会被客户端浏览器识别并处理 ,不过有些客户端并不能按照服务器端的设置来处

理 ,例如 :MSIE大约60秒后会关闭keep-alive连接。细节

见 :http://nginx.org/en/docs/http/ngx_http_core_module.html

( 2 )设置参数 :tcp_nodelay on;

用于激活tcp_ondelay功能 ,提高I/O性能。

1. #tcp_nodelay参数的官方说明如下 :
2. syntax: tcp_nodelay on off
3. default : tcp_nodelay on;#参数默认大小
4. context : http,server,location#可以放置的标签段

参数作用 :

默认情况下当数据发送时 ,内核并不会马上发送 ,可能会等待更多的字节组成一个数据

包 ,这样可以提高I/O性能。但是 ,在每次只发送很少字节的业务场景中 ,使用 tcp_nodelay功能 ,等待时间会比较长。

参数生效条件 :

激活或禁用TCP_NODELAY选项 ,当一个连接进入keep-alive状态时生效。细节 见http://nginx.org/en/docs/http/ngx_http_core_module.html。

( 3 )设置参数 :client_header_timeout 15;

用于设置读取客户端请求头数据的超时时间。此处的数值15 ,其单位是秒 ,为经验参考 值。

1. #client_header_timeout参数的官方说明如下 :

2. syntax: client_header_timeout time; #参数语法

3. default : client_header_timeout 60s; #参数默认大小

4. context: http,server #可以放置的标签段

参数作用 :

设置读取客户端请求头数据的超时时间。如果超过这个时间 ,客户端还没有发送完整的 header数据 ,服务器端将返回“ Request time out (408)”错误 ,可指定一个超时时 间 ,防止客户端利用http协议进行攻击。细节

见 :http://nginx.org/en/docs/http/ngx_http_core_module.html。

( 4 )设置参数 :client_body_timeout 15;

用于设置读取客户端请求主体的超时时间 ,默认值60

1. #client_body_timeout参数的官方说明如下 :

2. syntax: client_body_timeout time; #参数语法

3. default : client_body_timeout 60s; #默认60

4. context : http,server,location #可以放置的标签段

参数作用 :

设置读取客户端请求主体的超时时间。这个超时仅仅为两次成功的读取操作之间的一个 超时 ,非请求整个主体数据的超时时间 ,如果在这个超时时间内 ,客户端没有发送任何 数据 ,Nginx将返回“ Request time out(408)”错误 ,默认值60 ,细节

见:http://nginx.org/en/docs/http/ngx_http_core_module.html

( 5 )设置参数 :send_timeout 25;

用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间 ,如果超过 这个时间 ,客户端没有任何活动 ,Nginx将会关闭连接 ,默认值为60秒 ,可以改为参考 值25秒。

1. #send_timeout参数的官方说明如下 :

2. syntax: send_timeout time; #参数语法

3. default : send_timeout 60s; #默认值60

4. context : http,server,location #可以放置的标签段

参数作用 :

设置服务器端传送HTTP响应信息到客户端的超时时间 ,这个超时仅仅为两次成功握手后 的一个超时 ,非请求整个响应数据的超时时间 ,如在这个超时时间内 ,客户端没有接收 任何数据 ,连接将被关闭。细节

见http://nginx.org/en/docs/http/ngx_http_module.html。

备注 :结合http原理画图讲解超时参数

2.8 上传文件大小的限制(动态应用 )

下面我们学习如何调整上传文件的大小( http Request body size )限制。

1. #首先 ,我们可以在Nginx主配置文件里加入如下参数 :

2. client_max_body_size 8m; 3.

4. #具体大小根据公司的业务做调整 ,如果不清楚就先设置为8m把 ,有关客户端请求主体的解释在 HTTP原理一节已经解释过了 ,一般情况下 ,HTTP的post方法在提交数据时才会携带请求主体信 息。

5. #client_max_body_size参数的官方说明如下 :
6. syntax: client_max_body_size size;#参数语法
7. default : client_max_body_size 1m;#默认值1m
8. context : http,server,location#可以放置的1标签段

参数作用 :

设置最大的允许的客户端请求主体大小 ,在请求头域有“Content-Length” ,如果超过 了此配置值 ,客户端会受到413错误 ,意思是请求的条目过大 ,有可能浏览器不能正确显 示。设置为0表示禁止检查客户端请求主体大小。此参数对提高服务器端的安全性有一定 作用。细节见http://nginx.org/en/docs/http/ngx_http_core_module.html

2.9 FastCGI相关参数调优(配合PHP引擎动态服务)

FastCGI参数是配合Nginx向后请求PHP动态引擎服务的相关参数。 Nginx FastCGI工作 的逻辑图如下图所示 :

此处讲解的参数均为Nginx FastCGI客户端向后请求PHP动态引擎服务( php- fpm( FastCGI服务器端) )的相关参数 ,属于Nginx的配置参数。下表是Nginx FastCGi常见参数的说明。

FastCGI Cache资料

见http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache。

FastCGI常见参数的Nginx配置示例如下 :

[root@LNMP nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;
user nginx;
events {
use epoll;
worker_connections  10240;
}
http {
include       mime .types;
default_type  application/octet-stream;
sendfile        on;
tcp_nopush      on;
keepalive_timeout  65;
tcp_nodelay     on;
client_header_timeout 15;
client_body_timeout   15;
send_timeout          15;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent""$http_x_forwarded_for" ';
server_tokens off;
fastcgi_connect_timeout 240;        #Nginx允许fcgi连接超时时间
fastcgi_send_timeout 240;           #Nginx允许fcgi返回数据的超时时间
fastcgi_read_timeout 240;           #Nginx读取fcgi响应信息的超时时间
fastcgi_buffer_size 64k;            #Nginx读取响应信息的缓冲区大小
fastcgi_buffers 4 64k;              #指定Nginx缓冲区的数量和大小
fastcgi_busy_buffers_size 128k;     #当系统繁忙时buffer的大小
fastcgi_temp_file_write_size 128k;  #Nginx临时文件的大小
#   fastcgi_temp_path   /data/ngx_fcgi_tmp; #指定Nginx临时文件放置路径
fastcgi_cache_path  /data/ngx_fcgi_cache    levels=2:2  keys_zone=n gx_fcgi_cache:512m   inactive=1d;    #指定Nginx缓存放置路径# web 35 .
server {
listen       80;
server_name  www.yunji suan .com;
location / {
root html;
index index.php index .html index.htm;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if ( !-f $request_filename){
rewrite (.*) /index.php;
}
}
access_log  logs/web_www_access.log     main;
location ~ .*\. (php |php5)?$ {
root   html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi .conf;
fastcgi_cache ngx_fcgi_cache;       #开启fcgi缓存并起名叫 ngx_fcgi_cache,很重要 ,有效降低CPU负载 ,并且防止502错误发生。
fastcgi_cache_valid 200 302 1h; #指定应答代码的缓存时间 , 1h=1小时
fastcgi_cache_valid 301 1d;     #1d=1天
fastcgi_cache_valid any 1m;     #and 1m :将其他应答缓存1分钟
fastcgi_cache_min_uses 1;       #待缓存内容至少要被用户请求过1次
fastcgi_cache_use_stale error timeout invalid_header http_500;  #当遇 到error, timeout,或者返回码500时 ,启用过期缓存返回用户(返回过期也比返回错误强)
#  fastcgi_cache_key  http://$host$request_uri; 65 .
}
}
upstream    www_yunji suan { 69 .
server 192.168 .0.225:8000 weight=1; 71 .
}
server { 74 .
listen 8000;
server_name www.yunji suan .com;
location / {
#       root    html;
proxy_pass      http://www_yunji suan;
proxy_set_header    host    $host;
proxy_set_header x-forwarded-for $remote_addr; 82 .
}
access_log  logs/proxy_www_access.log   main;
}
}

Nginx的FastCGI的相关参数和反向代理proxy的相关参数非常接近 ,同学们可以拿来比 对 ,一起理解。

2.10 配置Nginx gzip压缩实现性能优化

2.10.1 Nginx gzip压缩功能介绍

Nginx gzip压缩模块提供了压缩文件内容的功能 ,用户请求的内容在发送到用户客户端 之前 ,Nginx服务器会根据一些具体的策略实施压缩 ,以节约网站出口带宽 ,同时加快 数据传输效率 ,来提升用户访问体验。

2.10.2 Nginx gzip压缩的优点

提升网站用户体验 :发送给用户的内容小了 ,用户访问单位大小的页面就加快了 ,用户体 验提升了 ,网站口碑就好了。

节约网站带宽成本 :数据是压缩传输的 ,因此节省了网站的带宽流量成本 ,不过压缩时会 稍微消耗一些CPU资源 ,这个一般可以忽略。

此功能既能提升用户体验 ,又能使公司少花钱 ,一举多得。对于几乎所有的Web服务来 说 ,这是一个非常重要的功能 ,Apache服务也有此功能。

2.10.3 需要和不需要压缩的对象

纯文本内容压缩比很高 ,因此 ,纯文本的内容最好进行压缩 ,例如 : html ,js ,css ,xml ,shtml等格式的文件。

被压缩的纯文本文件必须要大于1KB ,由于压缩算法的特殊原因 ,极小的文件压缩后可能 反而变大。

图片 ,视频(流媒体)等文件尽量不要压缩 ,因为这些文件大多都是经过压缩的 ,如果再 压缩很可能不会减少或减少很少 ,或者有可能增大 ,同时压缩时还会消耗大量的CPU ,内 存资源。

2.10.4 参数介绍及配置说明

此压缩功能与早期Apache服务的mod_deflate压缩功能很相似 ,Nginx的gzip压缩功能 依赖于ngx_http_gzip_module模块 ,默认已安装。

对应的压缩参数说明如下 :

#######压缩的配置介绍######
gzip on ;
#开启gzip压缩功能
gzip_min_length 1k;
#设置允许压缩的页面最小字节数 ,页面字节数从header头的Content-Length中获取。默认 值0,表示不管页面多大都进行压缩。建议设置成大于1K,如果小于1K可能会越压越大。
gzip_buffers 4 16K;
#压缩缓冲区大小。表示申请4个单位为16K的内存作为压缩结果流缓存 ,默认值是申请与原始数 据大小相同的内存空间来存储gzip压缩结果。
gzip_http_version 1.1;
#压缩版本(默认1.1,前端为squid2.5时使用1.0),用于设置识别HTTP协议版本 ,默认是1 .1, 目前大部分浏览器已经支持GZIP解压 ,使用默认即可。
gzip_comp_level 2;
#压缩比率。用来指定gzip压缩比 , 1压缩比最小 ,处理速度最快 ;9压缩比最大 ,传输速度快, 但处理最慢 ,也比较消耗CPU资源。
gzip_types text/plain application/x-javascript text/css application/xm l;
#用来指定压缩的类型 ,“text/html”类型总是会被压缩 ,这个就是HTTP原理部分讲的媒体类 型。
gzip_vary on;
#vary header支持。该选项可以让前端的缓存服务器缓存经过gzip压缩的页面 ,例如用Squi d缓存经过Nginx压缩的数据。

不同的Nginx版本中 ,gzip_types的配置可能会有不同 ,上述配置示例适合Nginx

1.6.3。对应的文件类型 ,请查看安装目录下的mime.types文件。

更多官方资源请看http://nginx.org/en/docs/http/ngx_http_gzip_module.html

2.10.5 Nginx压缩配置效果检查

可通过火狐浏览器+firebug插件+yslow插件查看gzip压缩及expires缓存结果。提前安 装好yslow插件 ,开启监控 ,然后打开LNMP时安装的博客地址 ,就可以看到如下图所示 的压缩结果 :

2.10.6 重要的前端网站调试工具介绍

常见的前端网站调试工具有如下几种 :

Google浏览器( Chrome ):通过该浏览器直接按F12键即可查看压缩及缓存结果 ,另 外 ,谷歌浏览器( Chrome )上也可以直接安装yslow插件

火狐浏览器 :在该浏览器上安装firebug ,yslow ,即可进行调试(火狐要用老版本比如 V28 )

IE浏览器 :在该浏览器上安装httpwatch即可进行调试(省略)

2.11 配置Nginx expires缓存实现性能优化

2.11.1 Nginx expires功能介绍

简单说 ,Nginx expires的功能就是为用户访问的网站内容设定一个过期时间 ,当用 户第一次访问这些内容时 ,会把这些内容存储在用户浏览器本地 ,这样用户第二次及 以后继续访问该网站时 ,浏览器会检查加载已经缓存在用户浏览器本地的内容 ,就不 会去服务器下载了 ,直到缓存的内容过期或被清除位置。

更深入的理解 :expires的功能就是允许通过Nginx配置文件控制HTTP

的“ Expires”和“Cache-Control” 响应头部内容 ,告诉客户端浏览器是否缓存和 缓存多久以内访问的内容。这个expires模块控制Nginx服务器应答时的expires头内 容和Cache-Control头的max-age指令。缓存的有效期可以设置为相对于源文件的最 后修改时刻或客户端的访问时刻。

这些HTTP头向客户端表明了额内容的有效性和持久性。如果客户端本地有内容缓

存 ,则内容就可以从缓存而不是从服务器中读取 ,然后客户端会检查缓存中的副本 , 看其是否过期或失效 ,以决定是否重新从服务器获得内容更新。

2.11.2 Nginx expires作用介绍

在网站的开发和运营中 ,视频 ,图片 ,CSS ,JS等网站元素的更改机会较少 ,特别是图 片 ,这时可以将图片设置在客户浏览器本地缓存365天或3650天 ,而将CSS ,JS ,html 等代码缓存10~30天。这样用户第一次打开页面后 ,会在本地的浏览器按照过期日期缓 存相应的内容 ,下次用户再打开类似的页面时 ,重复的元素就无需下载了 ,从而加快用 户访问速度。用户的访问请求和数据减少了 ,也可节省大量的服务器端带宽。此功能同 Apache的expires功能类似。

2.11.3 Nginx expires功能优点

expires可以降低网站的带宽 ,节约成本。

加快用户访问网站的速度 ,提升用户访问体验。

服务器访问量降低了 ,服务器压力就减轻了 ,服务器成本也会降低 ,甚至可以节约人力成 本。

对于几乎所有的Web服务来说 ,这是非常重要的功能之一 ,Apache服务也有此功能。

2.11.4 Nginx expires配置详解

前面已经介绍了expires的功能原理 ,接下来就来配置Nginx expires的功能。这里以

location标签为例进行讲解 ,通过location URI规则将需要缓存的扩展名列出来 ,然后指 定缓存时间。如果针对所有内容设置缓存 ,也可以不用location。 Nginx默认安装了

expires功能。

( 1 )根据文件扩展名进行判断 ,添加expires功能范例 范例1 :

 location ~ .*\. (gif |jpg |jpeg |png|bmp |swf)${expires 3650d;}

该范例的意思是当用户访问网站URL结尾的文件扩展名为上述指定类型的额图片时 ,设 置缓存3650天 ,即10年。

范例2 :

 location ~ .*\. (js |css)${expires 30d;}

该范例的意思是当用户访问网站URL结尾的文件扩展名为js ,css类型的元素时 ,设置缓 存30天 ,即1个月。

( 2 )根据URL中的路径( 目录)进行判断 ,添加expires功能范例 范例3 :

 location ~ ^/ (images |javascript |js |css |flash |media |static)/{expires 360d;}

该范例的意思是当用过户访问网站URL中包含上述路径(例 :images ,js ,css ,这些在 服务器端是程序目录)时 ,把访问的内容设置缓存360天 ,即1年。

2.11.5 Nginx expires配置效果检查

检查Nginx expires的方法和检查Nginx gzip的方法相同。

通过火狐浏览器加yslow插件查看gzip压缩及expires缓存结果时 ,要提前安装好火狐浏 览器 ,并且要安装好yslow插件 ,开启监控 ,然后打开LNMP时安装的博客地址(带有图 片 ,JS ,CSS ),就可以看到如下图所示的缓存结果了。

在Linux客户端可通过如下curl命令查看图片URL的缓存header信息 :

[root@localhost ~]# curl -I 192.168 .0.220:8000
HTTP/1.1 200 OK
Server: nginx
Date : Wed, 30 Aug 2017 02 :15 :54 GMT
Content-Type : text/html
Content-Length: 18
Connection : keep-alive
Last-Modified: Tue, 29 Aug 2017 19 :37 :44 GMT
ETag : "59a5c288-12"
Expires : Sat, 09 Sep 2017 02 :15 :54 GMT       #缓存的过期时间
Cache-Control : max-age=864000               #缓存的总时间 ,单位秒
Accept-Ranges: bytes

2.11.6 Nginx expires功能缺点及解决方法

几乎所有的事物都是有两面性 ,没有十全十美的人和事。 Nginx expires功能也不例 外 ,虽然这个功能很好 ,但是也会给企业带来一些困惑。

当网站被缓存的页面或数据更新了 ,此时用户端看到的可能还是旧的已经缓存的内 容 ,这样就会影响用户体验 ,那么如何解决这个问题呢?解决方法如下。

第一 ,对于经常需要变动的图片等文件 ,可以缩短对象缓存时间 ,例如 :谷歌和百度 的首页图片经常根据不同的日期换成一些节日的图 ,所以这里可以将这个图片设置为 缓存期1天。

第二 ,当网站改版或更新时 ,可以在服务器将缓存的对象改名( 网站代码程序)。

对于网站的图片 ,附件 ,一般不会被用户直接修改 ,用户层面上的修改图片 ,实际上 是重新传到服务器 ,虽然内容一样但是是一个新的图片名了。

网站改版升级会修改JS ,CSS元素 ,若改版时对这些元素改了名 ,会使得前端的CDN 及用户端需要重新缓存内容。

2.11.7 企业网站缓存日期曾经的案例参考

若企业的业务和网站访问量不同 ,那么网站的缓存期时间设置也是不同的 ,比如 ,如下 企业所用的缓存日期就是不一样的。

51CTO :1周 新浪 :15天 京东 :25年 淘宝 :10年

2.11.8 企业网站有可能不希望被缓存的内容

广告图片 ,用于广告服务 ,都缓存了就不好控制展示了。

网站流量统计工具( JS代码 ),都缓存了流量统计就不准了。

更新很频繁的文件(google的logo ),这个如果按天 ,缓存效果还是显著的。

三 ,Nginx日志相关优化与安全

3.1 编写脚本实现Nginx access日志轮询

当用户请求一个软件时 ,绝大多数软件都会记录用户的访问情况 ,Nginx服务也不例

外。 Nginx软件目前还没有类似Apache的通过cronolog或rotatelog对日志分割处理的 功能 ,但是 ,运维人员可以利用脚本开发 ,Nginx的信号控制功能或reload重新加载 , 来实现日志的自动切割 ,轮询。

日志切割脚本如下 :

[root@localhost nginx]# cat /server/scripts/cut_nginx_log.sh
# !/bin/bash
#日志切割脚本可挂定时任务 ,每天00点整执行
Dateformat=`date +%Y%m%d`
Basedir="/usr/local/nginx"
Nginxlogdir="$Basedir/logs"
Logname="access" 
[ -d $Nginxlogdir ] && cd $Nginxlogdir || exit 1
[ -f ${Logname}.log ] || exit 1
/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log
$Basedir/sbin/nginx -s reload 
[root@localhost nginx]# cat >>/var/spool/cron/root << KOF
#cut nginx access log by Mr.chen
00 00 * * * /bin/bash /server/scripts/cut_nginx_log.sh >/dev/null 2>&1

3.2 不记录不需要的访问日志

在实际工作中 ,对于负载均衡器健康节点检查或某些特定文件( 比如图片 ,JS ,CSS ) 的日志 ,一般不需要记录下来 ,因为在统计PV时是按照页面计算的 ,而且日志写入太频 繁会消耗大量磁盘I/O ,降低服务的性能。

具体配置方法如下 :

location ~ .*\. (js |jpg |JPG |jpeg |JPEG |css |bmp|gif |GIF)$
{access_log  off;
}
#这里用location标签匹配不记录日志的元素扩展名 ,然后关闭日志

3.3 访问日志的权限设置

假如日志目录为/app/logs,则授权方法如下 :

 chown -R root.root /app/logschown -R 700 /app/logs

不需要在日志目录上给Nginx用户读或写许可 ,但很多网友都没注意这个问题 ,他们把 该权限直接给了Nginx或Apache用户 ,这就成为了安全隐患。

相关文章:

企业级Nginx Web服务优化实战(上)

一 &#xff0c;Nginx基本安全优化 1.1 调整参数隐藏Nginx软件版本号信息 一般来说 &#xff0c;软件的漏洞都和版本有关 &#xff0c;这个很像汽车的缺陷 &#xff0c;同一批次的要有问题就 都有问题 &#xff0c;别的批次可能就都是好的。 因此 &#xff0c;我们应尽量隐藏或…...

Redisson常用方法

Redisson 参考: 原文链接 定义&#xff1a;Redisson 是一个用于与 Redis 进行交互的 Java 客户端库 优点&#xff1a;很多 1. 入门 1.1 安装 <!--redission--> <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifa…...

【树莓派4B】MindSpore lite 部署demo

一个demo&#xff0c;mindspore lite 部署在树莓派4B ubuntu22.04中&#xff0c;为后续操作开个门&#xff01; 环境 开发环境&#xff1a;wsl-ubuntu22.04分发版部署环境&#xff1a;树莓派4B&#xff0c;操作系统为ubuntu22.04mindspore lite版本&#xff1a;mindspore-li…...

ESP32-S3模组上跑通ES8388(30)

接前一篇文章:ESP32-S3模组上跑通ES8388(29) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回终于解析完了es8388_init函数的所有代码。本回回到调用它的地方,继续往下讲解。 我们是从ESP32-S3模组上跑通ES8388(7)-CSDN博客开始进入es8388_init函数,展开对于它的解析的…...

网络安全渗透测试概论

渗透测试&#xff0c;也称为渗透攻击测试是一种通过模拟恶意攻击者的手段来评估计算机系统、网络或应用程序安全性的方法。 目的 旨在主动发现系统中可能存在的安全漏洞、脆弱点以及潜在风险&#xff0c;以便在被真正的恶意攻击者利用之前&#xff0c;及时进行修复和加固&…...

.NET6 WebAPI从基础到进阶--朝夕教育

1、环境准备 1. Visual Studio 2022 2. .NET6 平台支持 3. Internet Information Services 服务器&#xff08; IIS &#xff09; 4. Linux 服务器 【 CentOS 系统】 ( 跨平台部署使用 ) 5. Linux 服务器下的 Docker 容器&#xff08; Docker 部署使用&#xff09; …...

opencv通过3种算子进行边缘提取

Scharr算子是效果比较好的,但从肉眼看sobel算子比较顺眼 # 导入OpenCV库&#xff0c;用于图像处理 import cv2 import numpy as np # 从matplotlib库中导入pyplot模块&#xff0c;用于绘制图像 from matplotlib import pyplot as plt # 创建一个名为window的窗口&#xff0c;窗…...

【KodExplorer】可道云KodExplorer-个人网盘安装使用

说明&#xff1a;安装kodExplorer &#xff08;不是Kodbox&#xff09;&#xff1b;Kodbox需求服务器至少2核4G内存&#xff0c;要求环境具备php/redis/mysql/。安装kodExplorer 就是比较方便简单部署&#xff0c;个人版免费。 一、安装环境需求 服务器: Windows&#xff0c;…...

并查集基础

abstract 并查集&#xff08;Union-Find Set&#xff09;是一种数据结构&#xff0c;主要用于处理动态连通性问题&#xff08;Dynamic Connectivity Problem&#xff09;&#xff0c;例如在图论中判断两点是否属于同一个连通分量&#xff0c;以及动态地合并集合。 它广泛应用…...

FPGA 16 ,Verilog中的位宽:深入理解与应用

目录 前言 一. 位宽的基本概念 二. 位宽的定义方法 1. 使用向量变量定义位宽 ① 向量类型及位宽指定 ② 位宽范围及位索引含义 ③ 存储数据与字节数据 2. 使用常量参数定义位宽 3. 使用宏定义位宽 4. 使用[:][-:]操作符定义位宽 1. 详细解释 : 操作符 -: 操作符 …...

day2 数据结构 结构体的应用

思维导图 小练习&#xff1a; 定义一个数组&#xff0c;用来存放从终端输入的5个学生的信息【学生的信息包含学生的姓名、年纪、性别、成绩】 1>封装函数 录入5个学生信息 2>封装函数 显示学生信息 3>封装函数 删除第几个学生信息&#xff0c;删除后调用显示学…...

原创 传奇996_55——后端如何点击npc隐藏主界面

点击图片退出&#xff0c;举例&#xff1a; |linkexit Img|ax0.5|ay0.5|percentx50|percenty50|imgpublic/touming2.png|hideMain1|linkexit <Img|x0|y0|esc1|show4|bg1|move0|imgcustom/new/longhun/bg.png|loadDelay0|reset1|hideMain1>...

java+springboot+mysql法律咨询网

项目介绍&#xff1a; 使用javaspringbootmysql开发的法律咨询网&#xff08;文书&#xff09;&#xff0c;系统包含管理员、用户角色&#xff0c;功能如下&#xff1a; 管理员&#xff1a;登录系统&#xff1b;用户管理&#xff1b;文章管理&#xff08;法律知识&#xff09…...

【AIGC】如何高效使用ChatGPT挖掘AI最大潜能?26个Prompt提问秘诀帮你提升300%效率的!

还记得第一次使用ChatGPT时&#xff0c;那种既兴奋又困惑的心情吗&#xff1f;我是从一个对AI一知半解的普通用户&#xff0c;逐步成长为现在的“ChatGPT大神”。这一过程并非一蹴而就&#xff0c;而是通过不断的探索和实践&#xff0c;掌握了一系列高效使用的技巧。今天&#…...

HarmonyOS-高级(四)

文章目录 应用开发安全应用DFX能力介绍HiLog使用指导HiAppEvent &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;HarmonyOS专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月11日11点18分 应用开发安全 应用隐私保护 隐私声明弹窗的作…...

国科大智能设备安全-APK逆向分析实验

APK逆向分析实验 使用APK常用逆向分析工具&#xff0c;对提供的移动应用程序APK文件进行逆向分析&#xff0c;提交逆向后代码和分析报告。具体任务如下&#xff1a; 任务一&#xff1a;安装并熟悉Apktool、Jadx等APK常用逆向工具的使用方法&#xff0c;对提供的Facebook Updat…...

Batch Normalization和 Layer Normalization

Batch Normalization和 Layer Normalization Batch Normalization (BN) 和 Layer Normalization (LN) 是深度学习中常用的归一化技术&#xff0c;它们的主要目的是加速训练、提高模型的收敛速度和稳定性。以下是对这两种归一化技术的详细讲解&#xff1a; 1. Batch Normalizat…...

数据结构——顺序表

顺序表的简单介绍 顺序表的概念&#xff1a;顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改。 特点&#xff1a;顺序表的特点是可以通过元素的索引快速访问数据&#xff0c;其访问时间复杂度…...

C语言中互斥锁、信号量和条件变量的所有相关函数、参数、返回值和说明

1. 互斥锁&#xff08;Mutex&#xff09;的使用 互斥锁用于保护共享数据&#xff0c;防止多个线程同时修改它。 #include <pthread.h> #include <stdio.h> #include <stdlib.h> // 定义一个全局共享变量 int shared_counter 0; // 定义一个互斥锁 pthrea…...

(前序 简单)leetcode 226翻转二叉树

代码随想录说用前序遍历和后序遍历方便&#xff0c;而中序遍历比较绕。 活用自定义函数使程序结构更为清晰 这里用的是前序遍历&#xff0c;根结点root指向left和root&#xff0c;交换root的左右指向 执行过程&#xff1a; 也就是交换下例的 2 &#xff0c;7 使得交换后&…...

搭建springmvc项目

什么是springmvc MVC它是一种设计理念。把程序按照指定的结构来划分: Model模型 View视图 Controller控制层 springmvc框架是spring框架的一个分支。它是按照mvc架构思想设计的一款框架。 springmvc的主要作用: 接收浏览器的请求数据&#xff0c;对数据进行处理&#xff0c;…...

解惑(一) ----- super(XXX, self).__init__()到底是代表什么含义

转载&#xff1a;self参数 - __ init__ ()方法 super(Net, self).__init__()是什么_super(net, self).init()-CSDN博客 相信大家在很多场合特别是写神经网络的代码的时候都看到过下面的这种代码&#xff1a; import torch import torch.nn as nn import torch.nn.functional …...

23种设计模式之责任链模式

目录 1. 简介2. 代码2.1 AbstractLogger&#xff08;抽象处理者&#xff09;2.2 InfoLogger &#xff08;具体处理者&#xff09;2.3 DebugLogger &#xff08;具体处理者&#xff09;2.4 ErrorLogger &#xff08;具体处理者&#xff09;2.5 Test &#xff08;测试&#xff09…...

电感2222

1 电感 1电感是什么 2 电感的电流不能突变&#xff1a;电容是两端电压不能突变 3 电感只是限制电流变化速度...

车牌识别OCR授权:助力国产化升级,全面提升道路监控效率

政策背景&#xff1a;国产化升级&#xff0c;推动道路监控产业转型 随着国家对信息安全的重视&#xff0c;国内各大公安、政企机构已进入全面升级国产化平台的实施阶段。根据最新的政策要求&#xff0c;公安和政府部门必须在未来三年内完成平台的国产化替换工作。这一举措不仅…...

【人工智能-中级】卷积神经网络(CNN)的中阶应用:从图像分类到目标检测

文章目录 卷积神经网络(CNN)的中阶应用:从图像分类到目标检测1. 图像分类:CNN的基础应用CNN结构概述经典网络架构2. 目标检测:从分类到定位基于区域的目标检测方法单阶段目标检测方法边界框回归与NMS(Non-Maximum Suppression)3. 深度学习中的目标检测挑战与解决方案4. …...

从资产流动分析WIF市场潜力X.game深究其他未知因素

近日&#xff0c;两则关于WIF最新消息引起了投资者们的注意。据报道&#xff0c;11月28日Vintermute在过去13小时内累计从Binance交易所提取了价值533万美元的WIF&#xff0c;此举不仅彰显了其强大的资金实力&#xff0c;更在某种程度上推动了WIF币价的反弹&#xff1b;另一方面…...

【工具变量】上市公司企业经营困境指数数据(Zscore、Oscore、RLPM、Merton DD)2000-2021年

一、资料范围&#xff1a;包括Zscore、Oscore、RLPM、Merton DD&#xff0c;经营困境说明如下&#xff1a;&#xff08;1&#xff09;Zscore&#xff1a;以2.67和1.81作为临界值计算样本得分所处的范围。Zscore>2.67 为财务状况良好&#xff0c;发生破产的可能性较小。Zscor…...

freeswitch(监听、旁听)

亲测版本centos 7.9系统–》 freeswitch1.10.9 本人freeswitch安装路径(根据自己的路径进入) /usr/local/freeswitch/etc/freeswitch使用场景: 比如A和B在通话,C想监听他们通话内容,其他设备是不知道有人在监听的使用方法: 进入dialplan/default.xml 在配置表添加 <…...

php基础:命名空间

1.PHP 命名空间可以解决以下两类问题&#xff1a; 1.用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。 2.为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名&#xff08;或简短&#xff09;的名称&#xff0c;以提高源代码的可读…...

SAP FICO物料分类账实操

物料分类账所涉及到的差异从采购入库的时候就可能已经产生&#xff0c;接下来从创建物料主数据开始对可能产生差异地方进行分析。其中有些操作步骤在标准价格估算这一篇博文中已经有过演示&#xff0c;可以先做了解。 其中的某些创建在有直接可用的情况下是非必须的&#xff0…...

【信息系统项目管理师】高分论文:论信息系统项目的整合管理(移动警务通系统)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 正文1、制定项目章程2、制定项目管理计划3、指导与管理项目工作4、管理项目知识5、监控项目工作6、实施整体变更控制7、结束项目或阶段正文 2022年2月,我有幸作为项目经理参加了“某市公安移动警务通系统”项…...

学习笔记069——Java集合框架

文章目录 集合1、List 接口2、Set 接口3、Map3.1、Map 常用实现类 集合 需要创建多个对象&#xff0c;但是数量和类型不确定。 集合是 Java 提供的一种类型&#xff0c;功能和数组类似&#xff0c;但是长度和数据类型都是动态。 集合框架&#xff08;包括很多类和接口&#…...

JIS-CTF: VulnUpload靶场渗透

JIS-CTF: VulnUpload来自 <https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/> 1,将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 靶机IP地址192.168.23.162&#xff0c;攻击机IP地址192.168.23.140…...

2024年食堂采购系统源码技术趋势:如何开发智能的供应链管理APP

本篇文章&#xff0c;小编将与大家一同探讨2024年食堂采购系统的技术趋势&#xff0c;并提供开发更智能的供应链管理APP的策略。 一、2024年食堂采购系统的技术趋势 1.人工智能与机器学习的深度应用 在2024年&#xff0c;AI和机器学习在食堂采购系统中的应用将更加普遍。这些…...

Flink CDC实时同步mysql数据

官方参考资料&#xff1a; https://nightlies.apache.org/flink/flink-cdc-docs-master/zh/docs/connectors/flink-sources/mysql-cdc/ Apache Flink 的 Change Data Capture (CDC) 是一种用于捕获数据库变化&#xff08;如插入、更新和删除操作&#xff09;的技术。Flink CDC…...

解决MAC装win系统投屏失败问题(AMD显卡)

一、问题描述 电脑接上HDMI线后&#xff0c;电脑上能显示有外部显示器接入&#xff0c;但是外接显示器无投屏画面 二、已测试的方法 1 更改电脑分辨&#xff0c;结果无效 2 删除BootCamp&#xff0c;结果无效 3更新电脑系统&#xff0c;结果无效 4 在设备管理器中&#…...

【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现二叉排序树的基本算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;二叉树的创建、查找和删除算法。具体如下&#xff1a; (1)由…...

【NumPy进阶】:内存视图、性能优化与高级线性代数

目录 1. 深入理解 NumPy 的内存视图与拷贝1.1 内存视图&#xff08;View&#xff09;1.1.1 创建视图1.1.2 视图的特点 1.2 数组拷贝&#xff08;Copy&#xff09;1.2.1 创建拷贝1.2.2 拷贝的特点 1.3 视图与拷贝的选择 2. NumPy 的优化与性能提升技巧2.1 向量化操作示例&#x…...

[C++]多态

1. 什么是多态性&#xff1f; 1.定义 多态性是指同一个函数或操作在不同对象上表现出不同的行为。 2.分类 C 中的多态性主要分为两种&#xff1a; 1.编译时多态性&#xff08;静态多态性&#xff09;&#xff1a; 编译时决定调用哪个函数。通过 函数重载 和 运算符重载 实…...

文本编辑器与正则表达式

1. VIM 编辑器 1.1 VIM 基本概念 VIM 是一个高度可定制的文本编辑器&#xff0c;广泛用于程序员的日常开发中。与传统的文本编辑器不同&#xff0c;VIM 基于模式操作&#xff0c;具有以下几个主要特点&#xff1a; 普通模式&#xff1a;用于浏览和修改文本。插入模式&#x…...

鲲鹏麒麟安装Kafka-v1.1.1

因项目需要在鲲鹏麒麟服务器上安装Kafka v1.1.1&#xff0c;因此这里将安装配置过程记录下来。 环境说明 # 查看系统相关详细信息 [roottest kafka_2.12-1.1.1]# uname -a Linux test.novalocal 4.19.148 #1 SMP Mon Oct 5 22:04:46 EDT 2020 aarch64 aarch64 aarch64 GNU/Li…...

scala基础_数据类型概览

Scala 数据类型 下表列出了 Scala 支持的数据类型&#xff1a; 类型类别数据类型描述Scala标准库中的实际类基本类型Byte8位有符号整数&#xff0c;数值范围为 -128 到 127scala.Byte基本类型Short16位有符号整数&#xff0c;数值范围为 -32768 到 32767scala.Short基本类型I…...

【重生之我要苦学C语言】文件操作

文件操作 为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久化的保…...

Python中PyTorch详解

文章目录 Python中PyTorch详解一、引言二、PyTorch核心概念1、张量&#xff08;Tensor&#xff09;1.1、创建张量1.2、张量操作 2、自动求导&#xff08;Autograd&#xff09;2.1、自动求导示例 三、构建神经网络1、使用nn模块2、优化器&#xff08;Optimizer&#xff09; 四、…...

Codigger SIDE之Helix编辑器

在Codigger的多维世界中&#xff0c;Helix编辑器以其卓越的性能和灵活性&#xff0c;成为开发者手中的利剑。基于Rust构建&#xff0c;Helix不仅继承了Vim编辑器的经典特性&#xff0c;更以其现代化的功能&#xff0c;重新定义了代码编辑的边界。 模式切换的艺术 Helix的模式切…...

vue3+echarts+websocket分时图与K线图实时推送

一、父组件代码&#xff1a; <template> <div class"chart-box" v-loading"loading"> <!-- tab导航栏 --> <div class"tab-box"> <div class"tab-list"> <div v-for"(item, index) in tabList…...

Maven常用插件清单

Maven 是一个强大的项目管理和构建工具&#xff0c;它使用插件来执行各种构建生命周期任务。以下是常用的一些 Maven 构建插件及其主要用途&#xff1a; 1. Maven Compiler Plugin 用途&#xff1a;编译Java源代码。配置示例&#xff1a;<build><plugins><plu…...

敏捷项目管理

虽然一直在践行敏捷开发&#xff0c;包括站会、尝试使用Confluence做知识wiki、每周分享等等&#xff0c;当然项目日常使用的coding、禅道、jira 项目管理和 jenkins 、git之类的CICD工具更不必说&#xff0c;但确实没有系统地去学习过敏捷开发管理。昨天被人问到敏捷开发到底是…...

牛客小白月赛107(A~E)

文章目录 A Cidoai的吃饭思路code B Cidoai的听歌思路code C Cidoai的植物思路code D Cidoai的猫猫思路code E Cidoai的可乐思路code 牛客小白月赛107 A Cidoai的吃饭 思路 签到题&#xff0c;按题意模拟即可 code void solve(){int n,a,b,c;cin >> n >> a &g…...