1.1 Nginx优化分类
安全优化(提升网站安全性配置)
性能优化(提升用户访问网站效率)
1.2 Nginx安全优化
1.2.1 隐藏nginx版本信息优化
官方配置参数说明:http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
官方参数:
1 | Syntax: server_tokens on | off | build | string; |
配置举例:
1 | $ cat /application/nginx/conf/nginx.conf |
测试结果:
1 | $ curl -I 10.0.0.8 |
1.2.2 修改nginx版本信息
修改版本信息需要修改程序源文件信息
修改内核信息
1 | $ vim src/core/nginx.h |
修改头部信息
1 | $ vim src/http/ngx_http_header_filter_module.c |
修改错误页显示
1 | $ vim src/http/ngx_http_special_response.c |
修改完成后重新编译
1 | $ ./configure --prefix=/application/nginx-1.10.2 --user=www --group=www --with-http_stub_status_module --with-http_ssl_module |
重启服务
1 | $ /etc/init.d/nginx restart |
访问测试是否修改成功
1 | $ curl -I 127.0.0.1 |
1.2.3 修改worker进程的用户
第一种方法:利用编译安装配置参数,设定nginx默认worker进程用户
1 | useradd -s /sbin/nologin -M www |
第二种方式:编写nginx服务配置文件,设定nginx默认worker进程用户
官方配置参数说明:http://nginx.org/en/docs/ngx_core_module.html#user
1 | Syntax:user user [group]; |
配置举例:
1 | $ cat nginx.conf |
查看是否生效
1 | $ ps -ef|grep nginx |
1.2.4 上传文件大小的限制(动态应用)
默认语法说明:
1 | syntax:client_max_body_size size; #<==参数语法 |
举例配置:
1 | http { |
1.2.5 站点 Nginx站点目录及文件URL访问控制
\01. 根据目录或扩展名,禁止用户访问指定数据信息
1 | location ~ ^/images/.*\.(php|php5|sh|pl|py|html)$ |
\02. 当访问禁止的数据信息时,进行页面跳转
Nginx下配置禁止访问.txt和.doc文件。
实际配置信息如下:
1 | location ~* \.(txt|doc)$ { |
\03. 根据IP地址或网络进行访问策略控制
1 | location / { |
\04. 采用if判断方式,进行访问控制
1 | if ($remote_addr = 10.0.0.7 ){ |
1.2.6 配置Nginx,禁止非法域名解析访问企业网站
第一种方式:配置一个server虚拟主机区块,放置在所有server区块最前面
1 | server { |
第二种方式:将计就计,通过你的域名访问时候,自动跳转到我的域名上
1 | server { |
1.2.7 Nginx图片及目录防盗链解决方案
什么是资源盗链 ?
简单地说,就是某些不法网站未经许可,通过在其自身网站程序里非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,达到填充自身网站的效果。
实现盗链过程:
\01. 真正的合法网站(盗链的目标) web01 www.nmtui.com www站点目录有一个oldboy.jpg图片
1 | # 配置静态虚拟主机 |
\02. 不合法的网站(真正盗链网站) www.daolian.com
1 | # 编写一个html盗链文件 |
编写盗链虚拟主机
1 | server { |
至此就实现了盗链。
03 常见防盗链解决方案的基本原理
1) 根据HTTP referer实现防盗链
利用referer,并且针对扩展名rewrite重定向,下面的代码为利用referer且针对扩展名rewrite重定向,即实现防盗链的Nginx配置。
1 | location ~* /\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ { |
设置expires的方法如下:
1 | $ cat /application/nginx/conf/extra/www.conf |
2) 根据cookie防盗链
3) 通过加密变换访问路径实现防盗链
4) 在所有网站资源上添加网站信息,让盗链人员帮你做推广宣传
1.2.8 NGINX错误页面友好显示
范例1:对错误代码403实行本地页面跳转,命令如下:
1 | ###www |
# 上面的/403.html是相对于站点根目录html/www的。
范例2:50x页面放到本地单独目录下,进行优雅显示。
1 | # redirect server error pages to the static page /50x.html |
范例3:改变状态码为新的状态码,并显示指定的文件内容,命令如下:
1 | error_page 404 =200 /empty.gif; |
范例4:错误状态码URL重定向,命令如下:
1 | server { |
1.2.9 Nginx站点目录文件及目录权限优化
服务器角色 | 权限处理 | 安全系数 |
---|---|---|
动态**Web**集群 | 目录权限755文件权限644所用的目录,以及文件用户和组都是root | 环境为Nginx+PHP 文件不能被改,目录不能被写入,安全系数10 |
static**图片集群** | 目录权限755文件权限644所用的目录,以及文件用户和组都是root | 环境为Nginx 文件不能被改,目录不能被写入,安全系数10 |
上传**upload**集群 | 目录权限755文件权限644所用的目录,以及文件用户和组都是root | 特别:用户上传的目录设置为755,用户和组使用Nginx服务配置的用户 文件不能被改,目录不能被写入,但是用户上传的目录允许写入文件且需要通过Nginx的其他功能来禁止读文件,安全系数8 |
1.2.10 Nginx防爬虫优化
范例1:阻止下载协议代理,命令如下:
1 | ## Block download agents ## |
范例2:添加内容防止N多爬虫代理访问网站,命令如下:
这些爬虫代理使用“|”分隔,具体要处理的爬虫可以根据需求增加或减少,添加的内容如下:
1 | if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo!Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot") |
1.2.11 利用Nginx限制HTTP的请求方法
#Only allow these request methods
1 | if ($request_method !~ ^(GET|HEAD|POST)$ ) { |
#Do not accept DELETE,SEARCH and other methods
1.2.12 使用普通用户启动nginx
1、切换到普通用户家目录下,创建nginx所需文件
1 | $ mkdir -p blog/{conf,logs,html} |
2、编写配置文件
1 | $ cat blog/conf/nginx.conf |
注意:普通用户不能使用知名端口,需要使用其他端口启动服务
3、检查配置文件语法,并启动nginx服务
1 | /application/nginx/sbin/nginx -t -c /home/nginx/blog/conf/nginx.conf |
注意:忽略一些不正确的输出信息
1.3 Nginx性能优化
1.3.1 优化nginx worker进行个数
nginx服务主要有两个重要进程:
01) master进程:可以控制nginx服务的启动 停止 或重启
02) worker进程:处理用户请求信息,帮助用户向后端服务进行请求(php mysql)
添加worker进程方法
1 | vim nginx.conf |
建议:worker进程数量=等于CPU的核数 worker进程数量=等于CPU的核数*2
如何在一个系统中获悉CPU核心是多少?
1 | ①. 利用top命令--按数字1,获取到CPU核数信息 |
查看cpu核心数命令示例
示例一
1 | $ top # 按数字1 |
示例二
1 | $ lscpu |grep CPU |
示例三
1 | $ grep processor /proc/cpuinfo |
1.3.2 绑定不同的nginx进程到不同的CPU上
4个worker进程分配CPU资源方法:
1 | worker_processes 4; |
8个worker进程分配CPU资源方法;
1 | worker_processes 8; |
4个worker进程分配CPU资源方法:
1 | worker_processes 4; |
1.3.3 优化nginx事件处理模型
官方配置参数说明:http://nginx.org/en/docs/ngx_core_module.html#use
1 | Syntax: use method; |
关于事件处理模型可以参考:https://clsn.cnblogs.com/p/7750615.html#auto_id_10
举例配置:
1 | user www www; |
1.3.4 调整nginx单个进程允许的客户端最大连接数
查看nginx当前的打开文件数
1 | $ lsof -i:80 |
修改最大连接数方法
1 | vim nginx.conf |
说 明:此数值设置不要超过系统最大打开文件数量。
1.3.5 配置Nginx worker进程最大打开文件数
举例配置:
1 | $ cat nginx.conf |
1.3.6 优化nginx高效文件传输模式
sendfile参数的官方说明如下:
1 | syntax:sendfile on | off; #<==参数语法 |
说明:在系统内核中,利用零拷贝方式实现数据传输
实现高效数据传输的两种方式
第一种方式:tcp_nopush
1 | syntax: tcp_nopush on | off; #<==参数语法 |
说明:将数据包积攒到一定量时再进行传输
参数作用:
激活或禁用Linux上的TCP_NODELAY选项。这个参数启用只在连接传输进入到 keep-alive状态。TCP_NODELAY和TCP_CORK基本上控制了包的”Nagle化”,Nagle化在这里 的含义是采用Nagle算法把较小的包组装为更大的帧。John Nagle是Nagle算法的发明人,后者就是用他的名字来命名的。
此算法解决的问题就是所谓的silly window syndrome,中文称”愚蠢窗口症候群”,具体含义是,因为普遍终端应用程序每产生一次击键操作就会发送一个包,很轻易地就能令网络发生拥塞,Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为缺省配置了,但在我们看来,有些场合下希望发送小块数据,把这一选项关掉也是合乎需要的。
第二种方式:tcp_nodelay
1 | Syntax: tcp_nodelay on | off; |
说明:只要有数据包产生,不管大小多少,就尽快传输
参数作用:
激活或禁用Linux上的TCP_CORK socket选项,tcp_cork是linux下tcp/ip传输的一个标准了,这个标准的大概的意思是,一般情况下,在tcp交互的过程中,当应用程序接收到数据包后马上传送出去,不等待,而tcp_cork选项是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞,已经是默认了。
此选项仅仅当开启sendfile时才生效, 激活这个.tcp_nopush参数可以允许把http response header和响应数据文件的开始部分放在一个文件里发布,其积极的作用是减少网络报文段的数量。
强调:两个指令是相悖的,请选择其一开启,不要同时开启;
默认采用tcp_nodelay方式进行传输。
1.3.7 设置nginx服务超时参数
Nginx连接超时的参数设置
1) 设置参数: keepalive_timeout 60; # 长连接才有意义
keepalive_timeout参数的官方说明如下:
1 | syntax:keepalive_timeout timeout [header_timeout];#<==参数语法 |
说明:客户端和服务端都没有数据传输时,进行超时时间倒计时,一旦超时时间读取完毕还没有数据传输,就断开连接
2) 设置参数:client_header_timeout 55;
1 | syntax:client_header_timeout time; #<==参数语法 |
说明:表示定义客户端请求报文发送的间隔超时时间,客户端发送的请求报文中请求头信息的间隔时间
3)设置参数:client_body_timeout 55;
1 | syntax:client_body_timeout time; #<==参数语法 |
说明:表示定义服务端响应报文发送的间隔超时时间,客户端发送的请求报文中请求主体信息的间隔时间
4)设置参数:send_timeout 60s
1 | syntax:send_timeout time; #<==参数语法 |
说明:表示定义客户端读取服务端响应报文的间隔超时时间,服务端发送的响应报文间隔时间
1.3.8 配置Nginx gzip压缩实现性能优化
\1. Nginx gzip压缩功能介绍
Nginx gzip压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到用户客户端之前, Nginx服务器会根据一些具体的策略实施压缩,以节约网站出口带宽,同时加快数据传输效率,来提升用户访问体验。
\2. Nginx gzip压缩的优点
提升网站用户体验:
发送给用户的内容小了,用户访问单位大小的页面就加快了,用户体验提升了,网站口碑就好了。
节约网站带宽成本:
数据是压缩传输的,因此节省了网站的带宽流量成本,不过压缩时会稍 微消耗一些CPU资源,这个一般可以忽略。
此功能既能提升用户体验,又能使公司少花钱,一举多得。对于几乎所有的Web服务来说,这 是一个非常重要的功能,Apache服务也有此功能。
官方用法参考链接:http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip
1 | gzip on; |
说明:将服务端响应的数据信息进行压缩,可以有效节省带宽,提高用户访问效率
需要和不需要压缩的对象
- 纯文本内容压缩比很高,因此,纯文本的内容最好进行压缩,例如:html、js、css、xml、shtml等格式的文件。
- 被压缩的纯文本文件必须要大于1KB,由于压缩算法的特殊原因,极小的文件压缩后可能反而变大。
- 图片、视频(流媒体)等文件尽量不要压缩,因为这些文件大多都是经过压缩的。
- 如果再压缩很可能不会减小或减小很少,或者有可能增大,同时压缩时还会消耗大量的CPU、内存资源。
压缩配置参数说明
1 | gzip on ; |
1.3.9 配置Nginx expires缓存实现性能优化
简单地说,Nginx expires的功能就是为用户访问的网站内容设定一个过期时间,当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及以后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器下载了,直到缓存的内容过期或被清除为止。
Nginx expires**功能优点**
- expires可以降低网站的带宽,节约成本。
- 加快用户访问网站的速度,提升用户访问体验。
- 服务器访问量降低了,服务器压力就减轻了,服务器成本也会降低,甚至可以节约人力成本。
- 对于几乎所有的Web服务来说,这是非常重要的功能之一,Apache服务也有此功能。
实践配置
1 | $ cat blog.conf |
企业网站有可能不希望被缓存的内容
- 广告图片,用于广告服务,都缓存了就不好控制展示了。
- 网站流量统计工具(JS代码),都缓存了流量统计就不准了。
- 更新很频繁的文件(google的logo),这个如果按天,缓存效果还是显著的。
1.3.10 配置FastCGI优化
FastCGI Cache资料见:
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache
FastCGI常见参数的Nginx配置示例如下:
1 | $ cat nginx.conf |
FastCGI**常见参数列表说明:**
Nginx FastCGI 相关参数 | 说明 | |
---|---|---|
fastcgi_connect_timeout | 表示nginx服务器和后端FastCGI服务器连接的超时时间,默认值为60秒,这个参数值通常不要超过75秒,因为建立的连接越多,消耗的资源就越多 | |
fastcgi_send_timeout | 设置nginx传输请求到FastCGI服务器的超时时间,这个超时时间不是整个请求的超时时间,而是两个成功请求的之间间隔时间为超时时间,如果这个时间内,FastCGI服务没有收到任何信息,连接将关闭 | |
fastcgi_read_timeout | 设置nginx从FastCGI服务器读取响应信息的超时时间苯示连捿建立成功后, nginx等待后端服务器的响应时间,是nginx进入后端的排队之中的等候处理的时间,实际上是读取FastCGI响应成功信息的间隔时间, | |
fastcgi_buffer_size | 这是Nginx FastCGI的缓冲区大小参数,设定用来读取从FastCGI服务器端收到的第一部分响应信息的缓冲区大小,这里的第一部分通常会包含一个小的响应头部s默认情况下,这个参数的大小等价于_个内存页。不是4k就是8k 根据相应系统平台来决定,也可以更小。 | |
fastcgi_buffers | 设定用来读取从FastCGI服务器端收到的响应信息的缓冲区大小和缓冲区数是,默认值为fastcgi_buffer 8 4k\ | 8k;指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个 PHP脚本产生的页面大小为256KB ,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB ,那么大于256KB的部分会缓存到fastcgi_temp 指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB ,那么可以把这个值设置为”16 16k” , “4 64k”等 |
fastcgi_busy_buffers_size | 用于设置系统很忙时可以使用的fastcgi_buffers大小,言方推荐的大小为fastcgi_buffers*2 ;默认值为fastcgi_busy_buffers_size 8k\ | 16k |
fastcgi_temp_file_write_size | FastCGI临时文件的大小,可以设置为128~256KB ; 默认fastcgi_temp_file_write_size 8k\ | 16k; |
fastcgi_cache oldboy_nginx | 表示开后FastCGI缓存并为其指定一个名称。开后缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开后缓存也可能引起其它问题,要根据具体情况来选择 | |
fastcgi_cache_path | 实例:fastcgi_cache_path /data/nginx/cache levels = 2:2 keys_zone = ngx_fcgi_cache:512m inactive = ld max_size=40g; fastcgi_cache缓存目录,可以设置目录前列层级,比如2:2会生成256*256 个子目录,keys_zone是这个缓存空间的名字,cache是用多少内存(这样热门的内容,nginx会直接放入内存,提高访问速度)。inactive表示默认失效时间,max_size表示最多用多少硬盘空间,雲要注意的是fastcgi_cache缓存是先写在fastcgi_temp_path在移到fastcgi_cache_path中去的,所以这个两个目录最好在同一个分区,从0.8.9之后可以在不同的分区,不过还是建议放在同_分区。 | |
fastcgi_cache_valid | 示例:fastcgi_cache_valid 200 302 lh; 用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存1个小时; 示例:fastcgi_cache_valid 301 Id; 将301应答缓存1天; | |
fastcgi_cache_min_uses | 示例:fastcgi_cache_min_uses 1; 设置清求几次之后晌应将被缓存,1表示一次即被缓存 | |
fastcgi_cache_use_stale | 示例:fastcgi_cache_use_stale error timeout invalid_header http_500 定义在哪些情况下使用过期缓存 | |
fastcgi_cache_key | 示例:fastcgi_cache_key requestmethod://requestmethod://hostrequesturi;fastcgi.cache.keyhttp://requesturi;fastcgi.cache.keyhttp://host$request_uri;定义fastcgi_cache的key ,示例中以请求的URI作为缓存的key,nginx会取这个key的md5作为缓存文件,如果设置了缓存散列目录,nginx会从后往前取梠应的位数作为目录。注意一定要加作为cache key,否则如果先请求的为head 类型,后面的GET清求返回为空。 |
1.4 日志方面优化
1.4.1 配置Nginx服务相关日志操作
\01. 进行日志的切割
1 | $ mkdir /server/scripts/ -p |
提示:实际上脚本的功能很简单,就是改名日志,然后加载nginx,重新生成文件记录日志
说明:也可以编辑使用logrotate日志切割服务,进行日志切割
\02. 进行日志的选择记录
1 | location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ { |
\03. 进行日志文件授权
假如日志目录为/app/logs,则授权方法如下:
1 | chown -R root.root /app/logs |
\04. 日志信息尽量汇总备份
1 | $ zgrep 456 clsn.tar.gz |
1.4.2 查看软件编译时的参数
①. 查看nginx安装时编译了哪些参数
1 | /application/nginx/sbin/nginx -V |
②. 查看apache安装时编译了哪些参数
1 | cat /application/apache/build/config.nice |
③. 查看mysql安装时编译了哪些参数
1 | grep CONFIGURE_LINE /application/mysql/bin/mysqlbug |
PS:mysql二进制包的安装方式,是无法看到编译参数的,默认为空
④. 查看php安装时编译了哪些参数
1 | /application/php/bin/php -i|grep configure |