1.优化维度
优化目的
提高网站访问速度。网站架构的稳定性。用户体验。
优化实践
应用层面,架构层面,代码层面,硬件层面。
安全
监控
日志
流程制度
故障排查
2.硬件层选型
WEB服务器:硬盘不需要太大。因为要水平扩展。
CPU、内存、硬盘、RAID:提高硬盘读取速度,提高冗余。
JAVA项目占内存大,处理业务逻辑都在内存中。工作效率高。
PHP项目占内存少。
数据库服务器
硬盘、RAID:提高硬盘读取速度,提高冗余。 RAID5 RAID10
机械硬盘:300M/s IOPS INNODB
缓存服务器
内存要求高:64G 128G
负载均衡服务器
CPU配置要高。磁盘不用太大。
3.系统层优化
磁盘IO调度算法选择
cat /sys/block/sda/queue/scheduler 配置某个磁盘的io算法路径。
noop [deadline] cfq 三种调度算法
centos7默认:deadline
deadline:此算法适合mysql服务器。一个时间内处理一个事件。一个时间内持续mysql读写IO
cfq:平均分配。
noop:维护一个队列。先进先出。 SID硬盘
修改调度方式:
echo cfq > /sys/block/sda/queue/scheduler
减少SWAP分区使用
echo 0 > /proc/sys/vm/swappiness
会导致磁盘IO速度慢几十倍。
增大打开文件描述数量
每个用户访问一次index.html就是打开一个index.html文件。
调整ulimit -n 数值。
ulimit -SHn 10240 设置为10240.对当前登录的系统用户生效。
全部配置
vi /etc/security/limits.conf
在最后增加
* soft nofile 65535 软限制,最大打开文件数65535
* hard nofile 65535 硬限制,最大打开文件数65535
内核参数调优
sysctl -a |wc -l 查看部分内核参数。
sysctl -a |grep tcp
net.ipv4.tcp_max_syn_backlog = 4096 最大的syn队列长度。设置为4096
TCP建立连接的时候,第一次发的请求。
net.ipv4.tcp_syncookies = 1 需要开启。
如果不开启,当syn请求数量大于最大值时,会拒绝syn请求。
开启后会将syn超出最大值的请求连接缓存起来。
net.ipv4.tcp_fin_timeout = 30 默认60秒,设置小一点。
建立TCP连接时用户端的超时时间。如果不断开,就会占用TCP资源。
mysql和nginx静态服务器中打开。lvs和负载均衡不建议开启。
net.ipv4.tcp_tw_recycle = 1 1为开启。
netstat -anutp 的State中状态TIME的快速回收连接资源。
net.ipv4.tcp_tw_reuse = 1 1为开启。
如果有新的TIME连接请求,会用上次为断开的TIME请求连接。
保存在:vi /etc/sysctl.conf
加在最后,保存。
刷新:sysctl -p
4.软件层调优
4.1Nginx基本调优
vi /etc/nginx/nginx.conf
user nginx;
worker_processes 1; 设置为cpu核心数
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
use epoll; 默认是epoll模型。
worker_connections 4096; 设置为最大连接数。
}
http {
include /etc/nginx/mime.types; 引入的默认传输类型。
default_type application/octet-stream; 如果默认的传输类型中没有的,就使用此文档流方式传输。
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;
sendfile on; 提高处理IO的性能。
传统读取:用户->进程(socket buffer)->用户态->内核缓冲区->内核->磁盘
Sendfile: 用户->进程(socket buffer)->内核缓冲区->内核->磁盘
#tcp_nopush on;
keepalive_timeout 30; 长连接超时时间。设置为30秒,减少tcp连接
#gzip on; 压缩文件,提高传输速度。但增加服务器CPU开销。
include /etc/nginx/conf.d/*.conf;
}
七层代理层调优:代理缓存
vi /etc/nginx/nginx.conf #nginx全局文档配置。
http {
...
keepalive_timeout 65;
#gzip on;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=proxy_cache_zone:128m inactive=5m max_size=10g;
# 缓存目录 目录层级 缓存区名称和大小 移除多长时间未访问的缓存数据 最大占用磁盘空间
proxy_buffering on; # 默认on,是否缓存后端服务器响应
proxy_buffer_size 64k; # 缓存区大小
proxy_buffers 8 32k; # 指定多少与多大缓存区来缓存后端服务器响应
proxy_ignore_headers Set-Cookie; # 忽略缓存cookie
proxy_set_header Host $host; # 添加请求头Host字段值为本机IP地址
proxy_set_header X-Real-IP $remote_addr; # 添加请求头X-Real-IP值为客户端IP
proxy_set_header X-Forwarded-For $http_x_forwarded_for; #前面所经过的代理ip都存起来。
proxy_connect_timeout 60s; # 默认60s,与后端服务器建立连接超时时间
proxy_read_timeout 300s; # 默认60s,读取后端服务器响应超时时间
proxy_send_timeout 300s; # 默认60s,发送请求到后端服务器超时时间
}
vi /etc/nginx/conf.d/wp.aliangedu.com.conf #PHP-FPM项目代理缓存
server {
listen 80;
server_name wp.aliangedu.com;
location / {
fastcgi_pass dynamic.wp;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
location ~ \.(html|css|js|jpg|png|gif)$ {
proxy_pass http://static.wp;
proxy_cache proxy_cache_zone; # 指定缓存区名称 http{keys_zone=proxy_cache_zone}使用此处指定的名称
proxy_cache_key $host$request_uri; # 定义缓存的key,根据md5值为缓存文件名
proxy_cache_valid 200 302 10m; # 为不同状态码设置缓存时间
proxy_cache_valid 301 1d;
proxy_cache_valid any 1m;
add_header X-Cache $upstream_cache_status; # 添加响应头,测试是否命中
expires 30d;
}
}
vi /etc/nginx/conf.d/solo.aliangedu.com.conf #java项目代理缓存
server {
listen 80;
server_name solo.aliangedu.com;
access_log /var/log/nginx/solo.access.log main;
location / {
proxy_pass http://dynamic.solo;
}
location ~ \.(html|css|js|jpg|png|gif)$ {
proxy_pass http://static.solo;
proxy_cache proxy_cache_zone;
proxy_cache_key $host$request_uri;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1d;
proxy_cache_valid any 1m;
add_header X-Cache $upstream_cache_status;
expires 30d;
}
}
查看缓存目录
ls /usr/local/nginx/proxy_cache #缓存目录根据自己情况创建
4.2PHP项目
每访问一次.php文件,php就会编译一次。
PHP缓冲器:将编译的缓存起来,二次访问直接从缓存中读取。
打开后能提高2-3倍的速度。
ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
vi /usr/local/php/etc/php.ini
opcache.enable=1 1表示启用,启用
opcache.memory_consumption=512 代码缓存内存大小。修改大小。
; extension=/path/to/extension/msql.so
zend_extension=opcache.so 添加。
PHP-FPM
pm.start_servers 固定进程数量。相当于nginx中的work_proccess
vi /usr/local/php/etc/php-fpm.conf
pm.max_children = 5 默认最大5个进程。根据cpu数量调整。
pm.start_servers = 2 启动时,最小启动2个进程。
pm.min_spare_servers = 1 最小空闲数
pm.max_spare_servers = 3 最大空闲数。
pm.process_idle_timeout = 10s;去掉注释。 空闲进程多长时间没有处理请求被kaill掉
pm.max_requests = 500去掉注释,一个子进程处理完500个请求后,自动重启进程。为的是释放资源。
4.3JAVA项目
https://blog.51cto.com/lizhenliang/1763866 java调优
1、增加最大连接数 2、调整工作模式 3、启用gzip压缩 4、调整JVM内存大小
5、作为Web服务器时,与Apache整合或Nginx 6、合理选择垃圾回收算法
7、尽量使用较新JDK版本
Tomcat
vi /root/apache-tomcat-8.5.51/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="1000"
minSpareThreads="20"
maxSpareThreads="100"
acceptCount="900"
disableUploadTimeout="true"
connectionTimeout="20000"
URIEncoding="UTF-8"
enableLookups="false"
redirectPort="8443"
compression="on" #启用压缩
compressionMinSize="1024"
compressableMimeType="text/html,text/xml,text/css,text/javascript" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
JVM堆内存
vi /root/apache-tomcat-8.5.51/bin/catalina.sh
JAVA_OPTS="-server -Xms256m -Xmx1024m -XX:+UseConcMarkSweepGC -XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps
-Xloggc:../logs/gc.log"
说明:
-Xms256:最小256, -Xmx1024m:最大根据项目程序需求反复实验出来。
不是越大越好,3072m, 3G差不多就能跑所有项目了。
根据进程查看堆内存
ps -ef |grep tomcat
jmap -heap 2356
Heap Configurateion:看此项。
5.电商网站大并发优化思路
5.1 CDN :解决南北通信问题。提高全局链路访问速度。(Squid,varnish)。
5.2 OSPF+LVS(FULLNAT实现跨机房负载均衡)。
5.3 增加Nginx七层集群量。
5.4 Redis Cluster 增加缓存系统。
5.5 数据库IO瓶颈,一主多从数据库读写分离,使用固态硬盘,多主多从来分担压力。
5.6 业务项目拆分,分而治之。多集群。