一,LAMP 和 LNMP的优化 主要是对PHP引擎的优化(纯PHP的并发就500~1000个左右)
1,并发慢的原因:
1)PHP程序每次请求都会进行编译解析
解决:操作码缓存,将PHP程序编译为opcode二进制的操作码缓存
php5.5已经自带性能最好的opcache模块,只需编译安装PHP5.5的时候加上–enable-opcache即可
补充知识:
查看Linux安装的软件包(rpm安装方式无法查看):yum grouplist
查看Nginx编译参数:/application/nginx/bin/nginx -V
查看Apache编译参数:cat /application/apache/build/config.nice
查看Mysql编译参数: grep CONFIGURE_LINE/application/mysql/bin/mysqlbug
查看PHP编译参数:/application/php/bin/php -i|grep configure
2)数据库查询慢
解决:加memcache , redis等
Memcache分为服务器端软件和客户端插件两部分:
服务器软件的名字如:memcached-1.4.3.tar.gz
客户端软件的名字为:memcache-2.2.5.tgz
3)存储慢:
解决:加CDN,squid,vanish等
二,企业级web Nignx服务优化(值钱)
1,配置文件:( nginx.conf , httpd.conf , my.cnf , php.ini , php-fpm.conf , httpd-vhost.conf , httpd-mpm.conf )
1.1 nginx.conf配置文件基本参数优化
1.1.1 隐藏nginx header内版本号信息
Apache隐藏版本号,httpd.conf中添加 :
ServerTokens Prod
ServerSignature Off
nginx隐藏版本号,nginx.conf中添加:
server_tokens off; #默认是 on
放 http, server , location 标签中
1.1.2 更改nginx的默认用户及用户组nobody
nginx服务启动使用默认的用户nobody和用户组nobody
方法一:在nginx.conf中修改:
user nginx nginx;
方法二:编译时指定 --user=nginx --group=nginx
(思考:nginx主进程不要用root来执行,延伸到linux的服务都不要用root来执行,减少被攻击的破坏性)
1.1.3 配置nginx worker进程个数(初始值,后面根据负载,硬件等来逐步调整)
worker_processes 8 ; # 建议按照CPU的个数或核数 X 2
(查看服务器物理CPU信息:grep "physical id" /proc/cpuinfo)
1.1.4 根据CPU核数进行nginx进程优化
分配不同的进程给不同的CPU,
例如四核CPU:
worker_cpu_affinity 0001 0010 0100 1000;
(额外知识点:压力测试,看请求失败数的临界点,则可以统计并发数)
(额外知识点 taskset 命令: 设置cpu 的 affinity,比如设置apache服务的cpu亲和度)
1.1.5 事件处理模型优化:
use epoll; # 放在events标签中,高并发软件都支持epoll模型
1.1.6 调整单个进程允许的客户端最大连接数
worker_connections 20480; # 定义nginx每个进程(worker)的最大连接数,默认512;nginx最大客户端连接数=worker_connections * worker_processes;
ulimit -HSn 65535 #配置linux最大文件打开数
1.1.7 配置每个进程(worker)最大文件打开数:
worker_rlimit_nofile 65535;
1.1.8 优化服务器名字的hash表大小
server_name 中,把最明确访问的域名放在前面;
如果定义了大量名字,或者定义了非常长的名字,那就需要在http配置块中调整
server_names_hash_max_size(默认512kb)和server_names_hash_bucket_size(默认16或32,与CPU有关)的值。
1.1.9 开启高效文件传输模式(非必须)
#开启文件高效模式,打开linux下TCP_CORK才有效,做减少报文端的数量使用
sendfile on;
#防止网络阻塞
tcp_nopush on;
tcp_nodelay on;
1.1.10 设置连接超时的时间
(一般php服务都希望短连接,java为长连接)
#设置客户端连接保持会话的超时时间,超过这个时间,服务器会关闭连接;默认75秒
keepalive_timeout 60:
#打开tcp_nodelay,在包含了keepalive参数才有效
tcp_nodelay on;
#设置客户端请求头读取超时时间,如超过这个时间,客户端还没发送任何数据,Nginx将返回“Request timeout (408)”错误。
client_header_timeout 15;
#设置客户端请求主体读取超时时间,如超过这个时间,客户端还没发送任何数据,Nginx将返回“Request timeout (408)”错误,默认是60。
client_body_timeout 15;
#指定响应客户端的超时时间,这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接
send_timeout 15;
1.1.11 客户端最大请求大小限制
#设置客户端最大请求内容(content-length)大小
client_max_body_size 10m
1.1.12 fastcgi 调优(配合PHP引擎动态服务)
#指定连接到后端FastCgi的超时时间
fastcgi_connect_timeout 300;
#向FastCgi传送请求的超时时间,这个值是指已经完成两次握手后向FastCgi传送请求的超时时间
fastcgi_send_timeout 300;
#指定接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间
fastcgi_read_timeout 300;
#指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64kb的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小。
fastcgi_buffer_size 64k;
#指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个PHP脚本所产生的页面大小为256kb,那么会为其分配4个64kb的缓冲区来缓存;如果页面大小大于256kb,那么大于256kb的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256kb,那么可以把这个值设置为 “16 16k” , “4 64k”等
fastcgi_buffers 4 64k;
#建议为fastcgi_buffers的两倍
fastcgi_busy_buffers_size 128k
#在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,设置上述数值设置太小时,若负载上来时可能报 502 Bad Gateway错误
fastcgi_temp_file_write_size 128k;
#表示开启FastCGI缓存,并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也可能会引起其他问题,要根据具体情况选择
fastcgi_cache oldboy_nginx
#用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存1个小时
fastcgi_cache_valid 200 302 1h;
#将301应答缓存1天
fastcgi_cache_valid 301 1d;
#将其他应答缓存1分钟
fastcgi_cache_valid any 1m;
#缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数
fastcgi_cache_min_uses 1;
1.1.13 配置nginx gzip压缩功能,可以放到http或server标签中
gzip压缩模块允许nginx服务器将输出的内容在发送到客户端之前根据具体的策略进行压缩,以节约网站宽带,同时提升用户访问体验
此功能同apache的mod_deflate压缩功能,依赖ngx_http_gzip_module模块,默认已经安装
可以压缩的内容:所有的文本程序文件(js , css , html );不要压缩的二进制内容:图片、视频、flash、小文件(1、2kb)
#开启gzip压缩功能
gzip on;
#设置允许压缩的页面最小字节数,页面字节数从header头的Content-Lenth中获取,默认值是0,不管页面多大都进行压缩。建议设置成大于1k。如果小于1k可能会越压越大
gzip_min_length 1k;
#压缩缓冲区大小。表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来压缩gzip压缩结果
gzip_buffers 4 16k;
#压缩版本(默认1.1,前端为squid2.5时使用1.0)用于设置设别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可
gzip_http_version 1.0;
#压缩比率。用来指定GZIP压缩比,1压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源。
gzip_comp_level 2;
#用来指定压缩的类型, "text/html"类型总是会被压缩
gzip_types text/css application/javascript text/xml;
#vary header支持,该选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据,到真实的客户浏览时才解压
gzip_vary on;
apache压缩补充:编译apache时,加入--enable-deflate模块
在httpd.conf 配置中配置如下:
<ifmodule mod_deflate.c>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE
AddoutputFilgerByType DEFLATE text/html text/plain text/xml
AddoutputFilgerByType DEFLATE application/javascript
AddoutputFilgerByType DEFLATE text/css
</ifmodule>
1.1.14 配置 Nginx expires缓存功能(重要)
1.2 最小化 apache / Nginx目录及文件权限设置
1.2.1 不安全的权限例子
1)chown -R 777 /sitedir (最不安全的)
2)chown -R apache.apache /sitedir (不安全的)
1.2.2 安全的权限:
1)所有站点目录的用户和组都应该为root
2)所有目录权限是默认的755
3)所有文件权限是默认的644
4)网站服务的用户不能用root
以上设置可以访问黑客上传木马,但是合理的上传也被拒绝了,解决方法:
前端访问把动态、静态服务进行分离、隔离;合理的上传就连接到另外一台上传upload集群(这台上传权限可以设置为网站服务用户);
访问图片通过图片集群(只安装Nginx,不安装PHP);
1.3 Nginx日志相关优化与安全
1.3.1 编写脚本实现 Nginx access日志轮询
通过信号控制和reload重新加载实现,然后利用crontab定时执行脚本
cat cut_nginx.sh
/bin/mv www_access.log www_access_$(date +%F -d -1day).log
/application/ngnix/sbin/nginx -s reload
1.3.2 不记录不需要的访问日志:健康检查或某些图片,js,css的日志
location ~.*\.(js|jpg|JPG|jpeg|JPEG|css/bmp|gif|GIF)$ {
access_log off;
}
apache配置方法:
httpd.conf配置文件中
<FileMatch "\.(css|js|gif|jpg|ico|swf)">
SetEnv IMAG 1
</FileMatch>
日志配置:
CustomLog "|/usr/local/sbin/cronolog /app/logs/%Y/%m/%d/access_%Y%m%d.log" combined env=!IMAG
1.3.3 访问日志的权限(访问日志通常不需要给web用户)
假如日志目录为/app/logs,则授权方法
chown -R root.root /app.logs
chown -R 700 /app/logs
1. 4 nginx站点目录及文件URL访问控制
1.4.1 根据扩展名限制程序和文件访问
范例1:nginx配置限制指定目录下的php程序被解析
location ~ ^/images/.*\.(php|php5)$ {
deny all;
}
1.4.2 禁止访问指定目录下所有的文件和目录
location ~ ^/static {
deny all;
}
1.4.3 禁止static目录被外界访问,但允许某个IP访问该目录,且支持PHP解析
location ~ ^/static/ {
allow 202.111.12.211;
deny all;
}
1.6 错误访问显示优雅页面
error_page 404 /404.html
1.7 使用tmpfs文件系统替代频繁访问的目录
php图片上传服务异常最终解决方案 mount tmpfs
1)cat /etc/rc.local
mount -t tmpfs -o size=16m tmpfs /tmp
2)定时清理临时文件
#!/bin/bash
find /tmp -cmin +15 -exec rm -f {} \;
1.8 apache两种常用运行模式
1)prefork(默认):一个主进程,下面多个子进程,每个子进程只开一个线程进程处理
稳定,比较占用资源;可以通过httpd-mpm.conf配置默认进程数、最大进程数等
查看并发数:ps -ef | grep httpd | wc -l
2)worker:一个主进程,下面多个子进程,每个子进程开多个子线程进行处理
并发高,稳定性差一点;,可以通过httpd-mpm.conf配置默认进程数、每个进程最大线程数等
查看并发数:pstree -a | grep httpd | wc -l
1.9 web防止盗链接的解决办法:(思想比实现更重要,做领导、架构师)
1)图片、视频上打水印、品牌等
2)防火墙控制,根据IP控制
3)放盗链(根据referer机制)
1.9.1 网站资源被盗链接带来的问题
影响网络宽带占用加大了,监控系统等报警频繁
如何能够及时发现:
1)对IDC及CDN带宽做监控报警
2)作为高级运维或运维经理,每天上班第一个主要任务就是查看网站流量图,关注流量变化,关注异常流量
3)对访问日志做分析,对异常流量能迅速定位,并且和公司市场推广等有比较好的默契沟通交流,以便调度带宽和服务器资源
案例:IDC机房流量暴涨
http://oldboy.blog.51cto.com/2561410/909696
1.9.2 常见防盗链接解决方案的基本原理
1)根据http referer实现
可以检测到文件是否被其他域名或页面使用,一旦检测出来源不是本站就进行阻止
Apache , nginx , lighttpd 三者都支持根据http referer实现防盗链接
apache实现:在httpd.conf 或 httpd-vhost.conf中配置
<VirtualHost *:80>
.............
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://xxxxx.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://xxxxx.com$ [NC]
RewriteRule .*\.(gif|jpg|swf)$ http://xxxx.com/img/nolink.jpg [R,NC]
</VirtualHost>
Nginx实现:在 nginx.conf配置
location ~* \.(jpg|gif|swf)${
valid_referers none blocked xxxx.com xxxx1.com; #自己网站域名,合作网站域名等
if($invalid_referer){
# return 403;
rewrite ^/ http://xxxxx.com/nolink.jpg;
}
}
如果不怕麻烦,有条件实现的话,推荐:NignxHttpAccessKeyModule实现防盗链接介绍
2)根据cookie处理(工作中少用)
3)通过加密变换访问路径实现防盗链接:lighttpd有类似的插件 mod_secdownload
1.1,打开php的安全模式
php的安全模式是个非常重要的php内嵌的安全机制,能够控制一些php中的函数执行,比如system()
safe_mode = On;(默认是关闭的)
1.2 用户组安全
当safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,且相同组的用户也能够对文件进行访问,建议设置为:
safe_mode_gid = off (php5.3.27默认为Off)
1.3 关闭危险函数
disable_functions = system,passthru,exec,shell_exec,popen,phpinfo 。。。(根据业务)
1.4 关闭PHP版本信息在http头中的泄露
expose_php = Off
1.5 关闭注册全局变量
register_globals = Off
1.6 打开magic_quotes_gpc 来防止SQL注入
magic_quotes_gpc = On
1.7 错误信息控制
display_errors = Off
1.8 打开log_error日志记录
log_errors = On
日志文件应该开发给apache用户写入的权限
1.9 部分资源限制参数优化
max_execution_time
memory_limit
max_input_time
upload_max_filesize
allow_url_fopen = Off
cgi.fix_pathinfo = 0:防止Nginx文件类型错误解析漏洞
2.1 php-fpm.conf 参数优化
pm = dynamic #动态模式
pm.max_children #最大子进程数量
pm.start_servers
pm.min_spare_servers
pm.max_spare_servers
.............