1、Apache worker/prefwork模式说明
在linux中,我们可以用httpd-l 查看安装的模块是prefork模式还是worker模式
[root@LAMP ~]# /application/apache/bin/apachectl -l|egrep "worker|prefoker"
worker.c
[root@LAMP ~]#
或者
[root@LAMP ~]# /application/apache/bin/apachectl -l |sed -n '/worker\|prefork/p'
worker.c
[root@LAMP ~]#
prefork模式(默认):
prefork使用的是多个子进程,而每个子进程只有一个线程,每个进程在某个确定的时间只能维持一个连接。
工作原理:
控制进程最初建立若干个子进程,为了不在请求到来时再生成子进程,所以要根据需求不断的创建新的子进程,最大可以达到每秒32个知道满足需求为止。
简单表示为:
安装方法:
在编译的时候,加入参数--with-mpm=prefork 如果不加也可以,因为默认的话,会采用prefork模式
优点:效率高,稳定,安全。对于线程调试困难的平台来说,调试更加容易一些。
缺点:和worker模式相比消耗的资源多
配置参数说明:
StartServers 5 #--->最初建立的子进程
MinSpareServers 5 #--->最小空闲进程数,如果空闲的进程小于设定值,Apache会自动建立进程,如果服务器并发及负载大的话,可以考虑加大。
MaxSpareServers 10 #--->最大空闲进程数,如果空闲的进程大于设定值,Apache会自动kill掉多余的进程,如果服务器负载大的话,可以考虑加大
MaxClients 150 #--->设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数,就是Apache可以同时处理的请求数,就是说如果有150个用户在访问,那么151个用户就要等之前的访问结束后才能访问
MaxRequestPerChild 0 #---->每个子进程可以处理的请求数。每个子进程在处理了"maxrequestsperchild"个请求后将自动销毁,0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零页有两点好处(1)防止意外的内存泄露(2)在服务器负载下降的时候回自动减少子进程数
提示:在设置参数值的时候,MinSpareServers 与StartServers尽量保持一致,在prefork模式下,MaxClients被认为是Apache的最大并发数
常用配置参考:
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1000
MaxRequestsPerChild 5000
prefork模式环境下,如何查看Apache的并发连接数(进程数):
具体方法如下:
[root@LAMP ~]# ps -ef|grep http|wc -l
6
[root@LAMP ~]#
worker模式:
worker模式是Apache2.x新引进的模式,是线程与进程的结合,在worker模式下会有多个子进程,每个子进程又会有多个线程。每个线程在某个确定时间只能维持一个连接。
简单表示为:
工作原理:
由主控制进程生成若干个子进程,而每个子进程中又包含固定的线程数,各个线程独立处理请求,同样为了不在请求到来时再生成线程,在配置文件中设置了最小和最大空闲线程数及所有子进程的线程总数,如果现有子进程中的线程总数不能满足并发负载,控制进程将派生新的子进程。
安装方法:
在配置编译的过程中,加入参数--with-mpm=worker,如果不加的话系统会采用默认的prefork模式
优点:内存占用比prefork模式低,适合高并发高流量的HTTPD服务
缺点:假如一个线程崩溃,整个进程积极会连同其任何线程一起“死掉”。由于线程共享内存空间,所以一个程序在运行时必须被系统识别为“每个线程都是安全的”。服务稳定性不如prefork模式。
配置说明(prefork模式):
[root@LAMP ~]# sed -n '43,58p' /application/apache/conf/extra/httpd-mpm.conf
# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
生产场景配置4:
StartServers 3
MaxClients 1600
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 64
MaxRequestsPerChild 0
worker模式下所能同时处理的请求总数是由子进程总数乘以Threadsperchild值决定的,应该大于等于maxclients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。
提示: 默认最大的子进程总数为16,如需加大时也需要明显的申明serverlimit的值(最大值时20000)
查看Apache的worker下并发连接数:
[root@LAMP ~]# pstree -a|grep httpd|wc -l
84
[root@LAMP ~]#
2、web防盗链技术
简单的说,就是某些不法的网站,通过在其自身网站程序里未经许可非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,达到了填充自身网站显示的效果,但是浪费了调用资源网站的网络流量,造成其他网站的带宽及服务压力吃紧,甚至宕机。
网站被盗链的解决方案:
1、根据http referer实现防盗链
在HTTP协议中,有一个表头字段叫referer,使用URL格式来表示从哪里来的链接到当前网页的资源,通过referer可以检测到目标访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一单检测出来源不是本站进行阻止或返回指定页面。 目前Apache,nginx,lighttpd三者都支持根据http referer实现防盗链
2、根据cookie处理
3、通过加密变换访问路径实现防盗链lighttpd有类似的插件mod_secdownload
Apache web服务实现防盗链实战
ServerAdmin [email protected]
DocumentRoot "/var/html/bbs"
ServerName ucode.blog.51cto.com
ServerAlias www.dummy-host.example.com
ErrorLog "logs/bbs-error_log"
CustomLog "|/usr/local/sbin/cronolog /app/logs/access_bbs_%Y%m%d.log" combined
RewriteEngine On #开启防盗链
RewriteCond %{HTTP_REFERER}!^http://ucode.blog.51cto.com/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://ucode.blog.51cto.com/$ [NC]
RewriteCond %{HTTP_REFERER}!^http://ucode.blog.51cto.com/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://ucode.blog.51cto.com$ [NC]
RewriteCond .*\.(gif|jpg|swf)$ http://ucode.blog.51cto.com/img/nolink.jpg [ R,NC]
满足以上的黑体部分的就会返回:http://ucode.blog.51cto.com/img/nolink.jpg图片
原理流程图:
利用referer和rewrite实现Apache防盗链小结
通过判断referer变量的值,来判断图片或资源的引用是否合法,只有在根据配置符合设定需求范围内的referer,这样的网站内容,才能调用访问指定的资源内容,从而实现了资源被网站盗链的目的。需要注意的是:是所有的用户代理(浏览器)都会设置referer变量,而且有的还可以手工修改erferer,referer是可以被伪造的,上面的配置只是一种简单的防护手段。应付一般的盗链足矣。
当网站被盗链,一般可以采取以下措施:
a、对本站的图片、视频、音频等文件标上自己的站名品牌或者相关水印;
b、设置防火墙,从源头IP进行控制
c、设置防盗链(根据referer机制)
网站被非法盗链使用,会导致网站带宽成本加大以及服务器压力加大,严重时会导致巨额的网站及正常用户访问受到影响。
##############基于LAMP(LNMP)问架构深度优化---配置文文件#################
3、修改配置文件参数实现隐藏版本号
a、nginx隐藏版本号
syntax server_tokens on|off;
在nginx配置文件中加入“server_token off;”
http
{
.........
server_tokens off;
.........
}
b、Apache隐藏版本号
[root@LAMP ~]# egrep "Server|ServerS" /application/apache/conf/extra/httpd-default.conf
# This configuration file reflects default settings for Apache HTTP Server.
# ServerName directive.
# ServerTokens
# This directive configures what you return as the Server HTTP response
ServerTokens Full
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
ServerSignature On
[root@LAMP ~]#
其中黑体部分改分别改为如下:
ServerTokens Prod
ServerSignature Off
4、修改nginx/Apache的默认用户及用户组nobody
a、启动nginx服务,使用的默认用户为nobody:
为了防止***猜到这个用户,我们需要更改下特殊的用户名,提供nginx服务用。
b、更改默认用户的方法有两种,第一种为:
user:nginx nginx;
设置Nginx Worker进程运行的用户以及用户组
useradd nginx -s /sbin/nologin -M <==不需要有系统登录权限,应该禁止其登录,相当于Apache里的用户一样
c、更改默认用户的方法有两种,第一种如上面所说,第二种为:
./configure --user=nginx --group=nginx --prefix=/application/nginx1.6.2 --with-http_stub_status_module --with-http_ssl_module
提示:其实在前面编译nginx服务时,我们就这样带着参数编译的。
d、Apache默认用直接修改配置文件内容:
[root@LAMP ~]# egrep "User|Group" /application/apache/conf/httpd.conf
# User/Group: The name (or #number) of the user/group to run httpd as.
User www
Group www
补充知识:
配置nginx worker进程个数
在高并发场景,我们需要事先启动更多的nginx进程以保证快速响应并处理用户的请求。具体的配置参数如下:
worker_processes 8 <===指定了Nginx需要开启的进程数,建议指定和CPU的数量相等或者乘2的进程数
work_processes 参数开始的设置可以等于cpu的个数或者核数(work_cpu_affinity参数中的配置可以指定第一个到最后一个进程分别使用的哪个cpu),进程多一些,其实提供服务就不会临时启动新进程提供服务,减少了系统开销,提升了服务速度。特殊场合也可以考虑提高至CPU*2 的进程数,具体情况要跟根据实际的业务来选择,因为这个参数,除了CPU核数的影响外,和硬盘存储的数据以及负载也有关。
查看linux服务器的核数的方法:
[root@LNMP application]# grep "physical id" /proc/cpuinfo
physical id : 0
physical id : 0
physical id : 1
physical id : 1
[root@LNMP application]#
可以按照physical数量设置,或者将目前数量*2
5、事件处理模型优化
nginx的连接处理机制在于不同的操作系统采用不同的IO模型,在linux使用epoll的IO多路复用模型,在FreeBSD使用kqueue的IO多路复用模型,在Solaris使用/dev/poll方式的IO多路复用模型,在Windows中使用的是icop等等。
根据系统类型不同选择不同use[kqueue|rtsig|epoll|/dev/poll|select|poll];该参数结合系统使用,不同系统使用参数不同,我们使用的是Centos6.5,因此我们调整为epoll模型
具体参数配置如下:
events <====envents指令是设定nginx的工作模式及连接数上限
{
use epoll;
}
6、调整单个进程允许客户端最大连接数
这个值根据根据具体服务器性能和程序的内存使用量来制定(一个进程启动使用的内存根据程序确定)
events <====指令设定Nginx的工作模式及连接数上限
{
worker_connections 20480;
}
worker_connections也是个模块指令,用于定义Nginx每个进程的最大连接数,默认是1024,客户端最大连接数由worker_processes和worker_connections决定,即Max_client=worker_processes * worker_connections,进程的最大连接数受linux系统进程的最大打开文件数限制,在执行操作系统命令“umilited -HSn 65535”或者配置相应的文件后,worker_connections的设置才生效
7、配置每个进程最大文件打开数
worker_rlimit_nofile 65536;
该参数的意思为每个进程打开的最大文件数,可以设置为系统优化受的ulimit -HSn的结果,在第一章系统安装时调整文件描述符和这个处理的一个问题。
详细查阅:http://nginx.org/en/docs/ngx_core_module.html
8、优化服务器名字的hash表大小
确切名字和通配符名字存储在哈希表中。哈希表和监听端口关联,每个端口都最多关联三张表:确切的名字的哈希表,以星号(*)起始的通配符名字的哈希表和以星号结束的通配符名字的哈希表。哈希表的尺寸在配置阶段进行了优化,可以以最小的CPU缓存命中失败来找到名字。nginx首先搜索切确名字的的哈希表,如果没有找到,则搜索以星号(*)其实的通配符名字的哈希表,如果还是没有找到,继续搜索以星号结束的通配符名字的哈希表。因为名字是按照域名的节点来搜索的。所以搜索通配符名字的哈希表比搜索确切名字的哈希表慢。注意:nginx.org存储在通配符名字的哈希表中,而不在确切名字的哈希表中。正则表达式是一个一个串行的测试,所以是最慢的,而且不可扩展。由于上述原因,我们一般尽可能的使用确切的名字。比如如果使用nginx.org和www.nignx.org来访问服务器是最频繁的,那么我们明确的定义出来对访问搜索域名的速度效率来说更有效:
如果定义了大量名字,或者定义了非常长的名字,那就需要在php配置模块中调整server_names_hash_max_size和server_names_hash_bucket_size的值。
server_names_hash_bucket_size的默认值可能是32,或者是64,或者是其他值,取决于CPU的缓存行的长度。如果这个值是32,那么定义“too.long.server.name.nginx.org”作为虚拟机主机名就会失败,显示如下错误信息:
could not build the server_names_hash,
you should increase server_names_hash_bucket_size;32
出现这种情况,那就需要设置值扩大一倍:
http{
server_names_hash_bucket_size 64;
}
9、开启高效的文件传输模式
sendfile on; <====sendfile参数用户开启文件高效传输模式,同时将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞。
10、设置连接的超时时间
php服务,建议希望短连接;java建议长连接
keepalive_timeout 60;
<==设置客户端保持会话的超时时间,超过这个时间,服务器会关闭连接。
tcp_nodelay on;
<==打开tcp_nodelay,包含了keepalive参数才有效
client_header_timeout 15;
<==设置客户端请求读取超时时间,如果超过这个时间,客户端还没发送任何数据,Nginx将返回“Rquest timeout (408)”错误.
client_body_timeout 15;
<==设置客户端请求主体读取超时时间,如果超过这个时间,客户端还没发送任何数据,Nginx将返回“Request time out(408)”错误,默认值是60.
send_timeout 15;
<==指定响应客户端的超时时间,这个超时时间仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。
11、上传文件大小限制(动态应用)
主配置文件里加入如下参数,具体大小根据你自己的业务做调整。
client_max_body_size 10m;
12、fastcgi调优(配合PHP引擎动态服务)
fastcgi_connect_timeout 300;
<==指定连接到后端FastCGI的超时时间
fastcgi_send_timeout 300;
<==向Fastcgi传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。
fastcgi_read_timeout 300;
<==指定接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间
fastcgi_buffer_size 64k;
<==指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64k的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers 选项指定的缓冲区大小。
fastcgi_buffers 4 64k;
<==指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个PHP脚本产生的页面大小为256K,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到Fastcgi_temp指定的路径中,但是这并不是好方法;因为内存中的数据处理速度要快于硬盘,一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本产生的页面大小为256KB,那么可以把这个值设置为“16 16K”、“4 64K”等。
fastcgi_busy_buffers_size 128k;
<==建议为fastcgi_buffers 的两倍
fastcgi_temp_file_write_size 128k;
<==在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,设置上述数值设置太小时若负载上来时能报 502 Bad Gateway
fastcgi_cache ucode_nginx;
<==表示开启FastCGI缓存并为其指定一个名称,开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也可能会引起其他问题,要根据具体情况选择。
fastcgi_cache_valid 200 302 1h;
<==用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时。
fastcgi_cache_valid 301 1d;
<==将301应答缓存1天
fastcgi_cache_valid any 1m;
<==将其他应答缓存为1分钟
fastcgi_cache_min_uses 1;
<==缓存在fastcgi_cache_path指令inactive参数时间内的最少使用次数
13、修改nginx源码文件进行优化:具体优化避免显示header为nginx和错误提示显示nginx关键字和版本号
a、隐藏nginx作为header头
修改nginx源码文件中的vim src/http/ngx_http_header_filter_module.c
光标分别移动到以下两行(49、50)修改红色部分关键字为其他内容:
这里改为Web SERVER和Web Server test
即修改如下字段:
"Server: nginx" CRLF;
"Server: NGINX_VER"
修改为:
"Server: Web Server" CRLF;
"Server: Web Server test"
重新编译安装nginx,然后启动,通过curl -I 10.0.0.10 查看结果:
b、隐藏错误信息避免爆出关键字nginx及其版本号
修改错误页面信息修改文件路径为:
vim nginx-1.7.10/src/http/ngx_http_special_response.c
修改为:
然后重新编译、安装、启动nginx
提示:目前测试nginx版本是nginx-1.7.10,对于nginx其他版本可以根据需要修改对应参数,一般修改参数为:
static u_char ngx_http_error_full_tail[] =
"
"