网站打开慢引发的血案
我们经常会遇到一个问题,网站打开速度特别慢,当我们遇到此种问题时该从哪些地方去排查?
我们先拿出一个博客为例看下:https://www.devilf.cc/index.php/2018/09/19/confluence6-3安装与破解/
我们首先需要看下我们的这篇博客的time这一栏中哪些响应的时间较长,点击做一下排序
可以看到我们的这个网页打开慢主要是在加载图片,所以我们可以针对图片做一些优化
- 可以在nginx配置文件中指定静态资源在本地做缓存
- 设置静态资源的压缩
- 可以接入CDN,做静态资源的缓存
对于类似的问题我们做一个总结
- 首先通过抓包,看下是哪些资源加载慢
- 如果是一些静态资源,则可以做缓存
- 如果是一些动态的请求,我们需要对程序或者数据库做一些优化
- 看下机器负载和带宽等一些系统参数
- 通过dstat查看带宽占用情况
- 通过top查看进程的资源占用情况
- 通过iostat查看磁盘IO情况,例如可以使用 iostat -x -k 1 100查看IO情况,-x表示输出详细信息,-k表示以KB单位显示,后面分别表示时间间隔和刷新次数
- 通过ss或netstat查看连接数情况,可以对/etc/sysctl.conf的一些内核参数做一些优化
- 看下是否是我们本地网络状况不好导致
下面是针对系统和服务做的一些优化
如果是程序或者机器的问题导致,我们需要在设计架构时就要做好压测或者程序优化,例如,在系统初始化的时候,我们需要针对负载和网站高并发等对内核做优化,
直接修改配置文件:vim /etc/sysctl.conf
代码语言:javascript复制#开启SYN cookies,当出现SYN等待队列溢出时,启动cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
<code>net.ipv4.tcp_syncookies = 1 </code>
#开启重用,允许将TIME_WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
<code>net.ipv4.tcp_tw_reuse = 1</code>
#开启TCP连接中TIME_WAIT sockets的快速回收,默认为0,表示关闭
<code>net.ipv4.tcp_tw_recycle = 1</code>
#修改系统默认的超时时间
<code>net.ipv4.tcp_fin_timeout = 30</code>
经过以上修改,可以提升服务器的负载能力,还能够防御小流量的Ddos、CC、SYN攻击
如果想要提升服务器的并发能力,需要增加:
代码语言:javascript复制#表示当keepalive启动的时候,TCP发送keepalive消息的频度,默认2小时,可以设置为20分钟
<code>net.ipv4.tcp_keepalive_time = 1200</code>
#表示用于向外连接的端口范围
<code>net.ipv4.ip_local_port_range = 10000 65500</code>
#表示SVN队列的长度,默认1024,增加长度可以容纳更多等待连接的网络连接数
<code>net.ipv4.tcp_max_syn_backlog = 8192</code>
#表示系统同时保持TIME_WAIT的最大数量
<code>net.ipv4.tcp_max_tw_buckets = 5000</code>
增加文件描述符
代码语言:javascript复制<code>echo '* - nofile 65535' > /etc/security/limits.conf</code>
<code>echo 'ulimit -HSn 65535' >> /etc/rc.local</code>
<code>echo 'ulimit -s 65535' >> /etc/rc.local</code>
我们的web服务也需要做好优化,例如:
nginx方面:
- gzip压缩优化
- expires缓存优化
- 网络IO事件模型优化
- 隐藏软件名和版本号
- 防盗链优化
- 禁止恶意域名解析
- 禁止通过IP地址访问网站
- http请求方法优化
- 放DDOS攻击单IP并发连接的控制,与连接速率控制
- 严格设置web站点目录的权限
- 将nginx进程以及站点运行于监牢模式
- 通过robot协议以及HTTP_USER_AGENT放爬虫优化
- 配置错误页面根据错误码指定网页反馈给用户
- nginx日志相关优化访问日志切割,不记录指定元素日志,最小化日志目录权限
- 限制上传到资源目录的程序被访问,防止木马入侵系统破坏文件
- FastCGI参数buffer和cache配置文件的优化
- php.ini和php-fpm.conf配置文件的优化
- 有关web服务的linux内核方面的深度优化(网络连接、IO、内存等)
- nginx加密传输优化
- 使用nginx cache
修改nginx.conf配置文件
1、隐藏版本信息
代码语言:javascript复制http模块中加如:
1 2 3 | http { server_tokens off; } |
---|
2、隐藏nginx版本号
需要修改nginx源码包:
代码语言:javascript复制1)、vim src/core/nginx.h
#define NGINX_VERSION “1.6.2" 修改为想要的版本号如2.4.3
#define NGINX_VER “nginx/" NGINX_VERSION 将nginx修改为想要修改的软件名称,如Apache。
2)、vim src/http/ngx_http_header_filter_module.c
<code>sed -i 's#Server:nginx#Server:Apache#g' ngx_http_header_filter_module.c</code>
3)、vim src/http/ngx_http_special_response.c
<code>sed -i "s#<center>nginx#<center>xs#g" src/http/ngx_http_special_response.c</code>
3、绑定不同的nginx进程到不同的CPU上
代码语言:javascript复制<code>worker_processes 4;</code>
<code>worker_cpu_affinity 0001 0010 0100 1000;</code>
4、nginx事件处理模型优化
nginx的连接处理机制在于不同的操作系统会采用不同的I/O模型,Linux下,nginx使用epoll的I/O多路复用模型
代码语言:javascript复制<code>use epoll;</code>
5、调整nginx单个进程允许的客户端最大连接数
代码语言:javascript复制```
enents { worker_connections 65535; #一个worker进程的并发 }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 总并发就是进程数与单个进程的最大连接数相乘 6、nginx worker进程的最大打开文件数 <code>worker_rlimit_nofile 65535</code> #可以和ulimit -n设置同一个值 7、开启高效文件传输模式 ``` http { sendfile on; #用于开启文件的高效传输模式 tcp_nopush on; #可以允许把httpresponse header和文件的开始放在一个文件里发布,减少网络报文段的数量(只有sendfile开启时生效) tcp_nodelay on; } |
---|
同时将tcp_nopush和tcp_nodelay设置为on,可防止网络及磁盘I/O阻塞,提升nginx工作效率
8、fastCGI优化
代码语言:javascript复制```
fastcgi_connect_timeout 300; #指定连接到后端FastCGI的超时时间 fastcgi_send_timeout 60; #指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间 fastcgi_read_timeout 60; #指定接收FastCGI应答的超时时间,这个值是已经完成两次握手接收FastCGI应答的超时时间 fastcgi_buffer_size 128k; #用于指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用一个128K的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小 fastcgi_buffers 4 128k; #指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16K” “4 64"等 fastcgi_busy_buffers_size 256k; #该值的默认值为fastcgi_buffers的两倍 fastcgi_temp_file_write_size 512k; #表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 9、压缩优化 ``` gzip on; gzip_min_length 1k; #表示允许压缩的页面最小字节数 gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; #压缩比率 gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml rss; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]."; |
---|
10、nginx expires功能
为用户访问网站的内容设定一个过期时间,当用户第一次访问到这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及之后继续访问网站,浏览器会检查本地是否有缓存,这样就不会向服务器请求,直到缓存内容过期或被清除为止
1 2 3 4 5 | location ^/(jpg|png|gif)$ { expires 30d; } expires off;是关闭缓存 expires -1d;永远过期 |
---|
11、nginx站点目录及文件URL访问控制
代码语言:javascript复制```
location ~ ^/images/.*.(php|php5|.sh|.pl|.py)$ { deny all; } 该location段需要放在处理php服务配置前面
1 2 3 4 5 6 7 8 9 | ### nginx.conf配置文件参考 |
---|
user www; worker_processes 8; #nginx进程数,建议按照cpu数目来指定,一般为它的倍数 worker_rlimit_nofile 65535; #指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n一致 error_log /var/log/nginx/error.log; pid /usr/local/nginx/run/nginx.pid;
include /usr/local/nginx/modules/*.conf;
events { use epoll; worker_connections 400000; #每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为 work_processes * worker_connections }
http { 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 /var/log/nginx/access.log main;
include /usr/local/nginx/conf/mime.types; default_type application/octet-stream;
server_names_hash_bucket_size 128; client_header_buffer_size 32k; #客户端请求头部缓冲区大小,可以根据系统的分页大小来设置(getconf PAGESIZE),如果分页大小在1~4K之间,建议设置4K,超过4K的可以设置分页大小的整倍数,不足1K的设置为1就好 large_client_header_buffers 4 32k; client_max_body_size 50m;
sendfile on; tcp_nopush on;
keepalive_timeout 60; #keepalive超时时间,不多说了
tcp_nodelay on;
fastcgi_connect_timeout 300; fastcgi_send_timeout 60; fastcgi_read_timeout 60; fastcgi_buffer_size 128k; fastcgi_buffers 4 128k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 512k;
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml rss; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable “MSIE [1-6].";
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; }