分类: 架构师之路 2012-07-01 23:30 1434人阅读 评论(2) 收藏 举报 javascript
在前两天的学习中咱们知道、了解并掌握了Web Server结合App Server实现单向Https的这样的一个架构。这个架构是一个很是基础的J2ee工程上线布署时的一种架构。在前两天的教程中,还讲述了Http服务器、App Server的最基本安全配置(包括单向https的实现), 它只是避免了用户能够经过浏览器侵入咱们的Web访问器或者可以经过Web浏览器来查询咱们的Web目录结构及其目录内的文件与相关内容,这种入侵咱们把它称为:php
Directory traversal,固然咱们只是实现了最基本的防范Directory traversal的手段,在往后的Security课程中将会详细地去擅述完整的Web Security的相关理论。css
从今天起咱们将继续在原有的这种Apache+Tomat的架构上,去论述如何在性能及Performance上优化这个架构,所以这两天的课程在有些人看来,可能会有些“枯燥”,因此我在此给你们打个招呼:html
这两天的课程论述的是如何在不改动代码与SQL语句的前提下,如何去改善和提升web server与app server的性能,千万不要小觑这一内容,它可让你在不改动代码的状况下获得10-20倍以上的性能提升,网上有其它的大牛们写过一篇文章叫“Tomcat如何支持到1000个用户”,经本人通过几个重大工程的实践,Opensource的Tomcat若是调优的好不仅能够支持者1000个用户,尤为当你的布署环境是64位操做系统的状况下,可能可以支持更大更高的并发性能,最后本节内容将会以Tomcat集群来作收场,在未来的课程中还会进一步详细讲述Weblogic的集群配置与IBM WASND的集群配置。前端
即压力测试,就是根据必定数量的VU(Virtual Users)我称为并发用户操做核心交易后,系统所能达到的最大瓶劲,以便于发现系统的极限、有没有Out of memory这样的问题存在以及相关的系统设置、配置是否搭挡的合理的一种测试。java
通常商业的比较好的用LoaderRunner,若是没钱的就用Opensource的Jmeter来模拟这个VU的操做。压力测试,存在几个误区,须要当心。web
1) 无限大的拼命增长VU的数量数据库
系统再完美,硬件配置再高,也经不住没有通过合理运算的VU的压力呀。apache
2) 偏执的用必定的数据量的VU,跑7*24小时浏览器
不是说这个不必,颇有必要,小日本的电视为何寿命敢说比中国人生产的电视机寿命长?由于它用一个机械臂就对着电视机的按钮不断的点点点。
咱们说的压力测试要测试多长时间,关键是要看通过科学计算的VU的数量以及核心交易数有多少,不是说我拿250个VU跑24*7若是没有问题我这个系统就没有问题了,这样的说法是不对的,错误的。随便举个例子就能把你推倒。
假设我有250个VU,同时跑上万笔交易,每一个VU都有上万笔交易,250个VU一次跑下来可能就要数个小时,你又怎么能判定250个VU对于这样的系统我跑24*7小时就能真的达到上万笔交易在250个VU的并发操做下可以真的跑完7天的所有交易?可能须要一周半或者两周呢?对吧?
我还看到过有人拿500个VU对着一条交易反复跑24*7小时。这样的测试有意义吗?你系统就仅仅只有一条交易?你怎么可以判断这条交易涉及到的数据量最大?更不用说交易是彼此间有依赖的,可能a+b+c+d的交易的一个混合组织就可以超出你单笔交易所涉及到的数据量了呢!
提供下面这个公式,以供你们在平时或者平常须要进行的性能测试中做为一个参考。
(1)计算平均的并发用户数:C = nL/T
公式(1)中,C是平均的并发用户数;n是login session的数量;L是login session的平均长度;T指考察的时间段长度。
(2)并发用户数峰值:C’ ≈ C+3根号C
公式(2)则给出了并发用户数峰值的计算方式中,其中,C’指并发用户数的峰值,C就是公式(1)中获得的平均的并发用户数。该公式的得出是假设用户的loginsession产生符合泊松分布而估算获得的。
实例:
假设有一个OA系统,该系统有3000个用户,平均天天大约有400个用户要访问该系统,对一个典型用户来讲,一天以内用户从登陆到退出该系统的平均时间为4小时,在一天的时间内,用户只在8小时内使用该系统。
则根据公式(1)和公式(2),能够获得:
C = 400*4/8 = 200
C’≈200+3*根号200 = 242
F=VU * R / T
其中F为吞吐量,VU表示虚拟用户个数,R表示每一个虚拟用户发出的请求数,T表示性能测试所用的时间
R = T / TS。
从上面的公式一节中咱们还获得了一个名词“吐吞量”。和吞吐量相关的有下面这些概念,记录下来以供参考。
2 吞吐量
指在一次性能测试过程当中网络上传输的数据量的总和。
对于交互式应用来讲,吞吐量指标反映的是服务器承受的压力,在容量规划的测试中,吞吐量是一个重点关注的指标,由于它可以说明系统级别的负载能力,另外,在性能调优过程当中,吞吐量指标也有重要的价值。
2 吞吐率
单位时间内网络上传输的数据量,也能够指单位时间内处理客户请求数量。它是衡量网络性能的重要指标,一般状况下,吞吐率用“字节数/秒”来衡量,固然,你能够用“请求数/秒”和“页面数/秒”来衡量。其实,无论是一个请求仍是一个页面,它的本质都是在网络上传输的数据,那么来表示数据的单位就是字节数。
2 事务
就是用户某一步或几步操做的集合。不过,咱们要保证它有一个完整意义。好比用户对某一个页面的一次请求,用户对某系统的一次登陆,淘宝用户对商品的一次确认支付过程。这些咱们均可以看做一个事务。那么如何衡量服务器对事务的处理能力。又引出一个概念----TPS
2 TPS (Transaction Per second)
每秒钟系统可以处理事务或交易的数量,它是衡量系统处理能力的重要指标。
2 点击率(Hit Per Second)
点击率能够看作是TPS的一种特定状况。点击率更能体现用户端对服务器的压力。TPS更能体现服务器对客户请求的处理能力。
每秒钟用户向web服务器提交的HTTP请求数。这个指标是web 应用特有的一个指标;web应用是“请求-响应”模式,用户发一个申请,服务器就要处理一次,因此点击是web应用可以处理的交易的最小单位。若是把每次点击定义为一个交易,点击率和TPS就是一个概念。容易看出,点击率越大。对服务器的压力也越大,点击率只是一个性能参考指标,重要的是分析点击时产生的影响。
须要注意的是,这里的点击不是指鼠标的一次“单击”操做,由于一次“单击”操做中,客户端可能向服务器发现多个HTTP请求。
2 吞吐量指标的做用:
用户协助设计性能测试场景,以及衡量性能测试场景是否达到了预期的设计目标:在设计性能测试场景时,吞吐量可被用户协助设计性能测试场景,根据估算的吞吐量数据,能够对应到测试场景的事务发生频率,事务发生次数等;另外,在测试完成后,根据实际的吞吐量能够衡量测试是否达到了预期的目标。
用于协助分析性能瓶颈:吞吐量的限制是性能瓶颈的一种重要表现形式,所以,有针对性地对吞吐量设计测试,能够协助尽快定位到性能冰晶所在位置。
2 平均相应时间
也称为系统响应时间,它通常指在指定数量的VU状况下,每笔交易从mouse 的click到IE的数据刷新与展现之间的间隔,好比说:250个VU下每笔交易的响应时间不超过2秒。
固然,响应时间也不能一律而论,对于实时交易若是银行柜台操做、超市收银员的操做、证交所交易员的操做来讲这些操做的响应时间固然是越快越好,而对于一些企业级的如:
与银行T+1交易间的数据跑批、延时交易、T+1报表等,你要求它在2秒内响应,它也作不到啊。就比如你有个1MB的带宽,你传的东西是超过4MB,你要它在2秒内跑完理论速度也作不到啊,对吧,因此有些报表或者数据,光前面传输时间就不止两秒了。一口咬死说我全部的交易平均相应时间要2秒,真的是不科学的!
2 VU数量的增长
一个合理的性能测试除了须要合理的计算VU的数量、合理的设置系统平均响应时间外还须要合理的在测试时去规划发起VU的时间,好比说,我看到有人喜欢这样作压力测试。
第一秒时间,500个并发用户所有发起了。结果致使系统没多久就崩了,而后说系统没有知足设计要求。
为何说上述这样的作法是不对的?咱们说不是彻底不对,只能说这样的测试已经超过了500个VU的并发的设计指标了。
合理的并发应该是以下这样的:
有25-50个VU开始起交易了,而后过一段时间又有25-50个用户,过一段时间又增长一些VU,当全部的设计VU都发起交易了,此时,再让压力测试跑一段时间好比说:24*7是比较合理的。因此VU数量不是一上手就500个在一秒内发起的,VU数量的增长应该以下面这张趋势图:
这是一个阶梯状的梯型图,能够看到VU的发起是逐渐逐渐增多的,如下两种状况若是发生须要检查你的系统是否在原有设置上存在问题:
VU数量上升阶段时崩溃
有时仅仅在VU数量上升阶段,系统就会了现各类各样的错误,甚至有崩溃者,这时就有从新考虑你的系统是否有设置不合理的地方了。
VU所有发起后没多久系统崩溃
VU在达到最高值时即全部的VU都已经发起了,此时它是以一条直的水平线随着系统运行而向前延伸着的,但过不了多久,好比说:运行24*7小时,运行了没1、两天,系统崩溃了,也须要作检查。
因此,理想的性能测试应该是VU数量上升到最终VU从发起开始到最后全部VU把交易作完后,VU数量落回零为止。
2 吞吐量的变化
从2.3节咱们能够知道,吞吐量是随着压力/性能测试的时间而逐渐增大的,所以你的吞吐量指示应该以下图所示:
确定是这样,你的吞吐量因该是积累的,若是你的吞吐量在上升了一段时间后忽然下落,而此时你的性能测试还在跑着,以下图所示:
那么,此时表明什么事情发生了?你能够查一下你的loaderrunner或者jmeter里对于这段吞吐量回落期间的交易的response的状态进行查看,你将会发现大量的error已经产生,由于产生了error,因此你的交易其实已经出错了,所以每次运行的数据量愈来愈小,这也就意味着你的压力测试没有过关,系统被你压崩了!
2 平均响应时间
平均响应时间如VU的数量增长趋势图同样,必定是一开始响应时间最短,而后一点点增高,当增高到必定的程度后,即全部的VU都发起交易时,你的响应时间应该维持在一个水平值,而后随着VU将交易都一笔笔作完后,这个响应时间就会落下来,这段时间内的平均值就是你的系统平均响应时间。看看它,有没有符合设计标准?
2 内存监控
咱们就来讲AppServer,咱们这边用的是Tomcat即SUN的JVM的内存变化,咱们就用两张图例来说解吧:
理想状态状况下的JVM内存使用趋势:
这是一个波浪型的(或者也能够说是锯齿型的)趋势图,随着VU数量的一点点增长,咱们的内存使用数会不断的增长,可是JVM的垃圾回收是自动回收机制的,所以若是你的JVM如上述样的趋势,内存上涨一段时间,随即会一点点下落,而后再上涨一点,涨到快到头了又开始下落,直到最后你的VU数量所有降低下来时,你的JVM的内存使用也会一点点的降低。
非理想状态状况下的JVM内存使用趋势:
嘿嘿嘿,看到了吗?
你的JVM随着VU 数量的上升,而直线上升,而后到了必定的点后,即到了java –Xmx后的那个值后,忽然直线回落,而此时你的交易还在进行,压力测试也还在进行,但是内存忽然回落了0。由于你的JVM已经crash了,即OUT OF MEMORY鸟。
2 CPU Load
咱们来看一份测试人员提交上来CPU得用率的报告:
Web Server |
App Server |
DB Server |
60% |
98% |
6% 囧 |
同时平均响应时间好慢啊。
拿过来看了一下代码与设计。。。Struts+Spring+JDBC的一个框架,没啥花头的,再仔细一看Service层。
大量的复杂业务逻辑甚至报表的产生所有用的是javaobject如:List, Hashmap等操做,甚至还有在Service层进行排序、复杂查询等操做。
一看DB层的CPU利用率才6%,将一部分最复杂的业务拿出去作成Store Procedure(存储过程后),再从新运行压力测试。
Web Server |
App Server |
DB Server |
60% |
57% |
26% 囧 |
同时平均响应时间比原来快了15-16倍。
为何?
看看第一份报告,咱们当时还查看了数据库服务器的配置,和APPServer的配置是一个级别的,而利用率才6%。
数据库,至因此是大型的商用的关系型数据库,你只拿它作一个存储介质,你这不是浪费吗?人家里面设置的这个StoreProcedure的处理能力,索引效率,数据分块等功能都没有去利用,而用你的代码去实现那么多复杂业务好比说多表关联、嵌套等操做,用必要吗?那要数据库干什么用呢?
是啊,我认可,原有这样的代码,跨平台能力强一点,可付出的代价是什么呢?
用户在意你所谓的跨平台的理论仍是在意的是你系统的效率?一个系统定好了用DB2或者是SQL SERVER,你以为过一年它会换成ORACLE或者MYSQL吗?若是1年一换,那你作的系统也只能让用户勉强使用一年,我劝你仍是不要去作了。在中国,有人统计过5年左右会有一次系统的更换,而一些银行、保险、金融行业的系统一旦采用了哪一个数据库,除非这个系统完全出了问题,不然是不会轻意换数据库的,所以不要拿所谓的纯JAVA代码或者说我用的是Hibernate,ejb实现能够跨数据库这套来讲事,效率低下的系统能够否认你所作的一切!
上面两节,讲了大量的理论与实际工做中碰到的相关案例,如今就来说一下在咱们第一天和次日中的ApacheHttp Server + Tomcat这样的架构,怎么来作优化吧。
Apache Http Server在刚安装完后是没有并发数的控制的,它采用一个默认的值,那么咱们的Web Server硬件很好,容许咱们撑到1000个并发即VU,而由于咱们没有去配置致使咱们的WebServer连300个并发都撑不到,这是谁的责任?
Apache Http服务器采用prefork或者是worker两种并发控制模式。
2 preforkMPM
使用多个子进程,每一个子进程只有一个线程。每一个进程在某个肯定的时间只能维持一个链接。在大多数平台上,PreforkMPM在效率上要比Worker MPM要高,可是内存使用大得多。prefork的无线程设计在某些状况下将比worker更有优点:它可使用那些没有处理好线程安全的第三方模块,而且对于那些线程调试困难的平台而言,它也更容易调试一些。
2 workerMPM 使用多个子进程,每一个子进程有多个线程。每一个线程在某个肯定的时间只能维持一个链接。一般来讲,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,由于Worker MPM的内存使用比PreforkMPM要低得多。但worker MPM也由不完善的地方,若是一个线程崩溃,整个进程就会连同其全部线程一块儿"死掉",这是因为线程共享内存空间,因此一个程序在运行时必须被系统识别为"每一个线程都是安全的"。
通常来讲咱们的ApacheHttp Server都是装在Unix/Linux下的,并且是采用源码编译的方式来安装的,咱们可以指定在编译时Apache就采用哪一种模式,为了明确咱们目前的Apache采用的是哪一种模式在工做,咱们还可使用httpd –l命令即在Apache的bin目录下执行httpd –l,来确认咱们使用的是哪一种模式。
这边,咱们使用Apache配置语言中的” IfModule”来自动选择模式的配置。
咱们的ApacheHttp Server在配完后通常是没有这样的配置的,是须要你手动的添加以下这样的一块内容的,咱们来看,在httpd.conf文件中定位到最后一行LoadModule,敲入回车,加入以下内容:
<IfModule prefork.c> ServerLimit 20000 StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 1000 MaxRequestsPerChild 0 </IfModule> |
上述参数解释:
ServerLimit 20000
默认的MaxClient最大是256个线程,若是想设置更大的值,就的加上ServerLimit这个参数。20000是ServerLimit这个参数的最大值。若是须要更大,则必须编译apache,此前都是不须要从新编译Apache。
生效前提:必须放在其余指令的前面
StartServers 5
指定服务器启动时创建的子进程数量,prefork默认为5。
MinSpareServers 5
指定空闲子进程的最小数量,默认为5。若是当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。
MaxSpareServers 10
设置空闲子进程的最大数量,默认为10。若是当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设的太大。若是你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改为"MinSpareServers+1"。
MaxClients 256
限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个连接被释放,队列中的请求将获得服务。要增大这个值,你必须同时增大ServerLimit。
MaxRequestsPerChild10000
每一个子进程在其生存期内容许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。若是MaxRequestsPerChild为"0",子进程将永远不会结束。
将MaxRequestsPerChild设置成非零值有两个好处:
1.能够防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候,减小活动进程的数量。
Prefork.c的工做方式:
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并做出应答。Apache老是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求,这样客户端就不须要在获得服务前等候子进程的产生。在Unix系统中,父进程一般以root身份运行以便绑定80端口,而Apache产生的子进程一般以一个低特权的用户运行。User和Group指令用于设置子进程的低特权用户。运行子进程的用户必需要对它所服务的内容有读取的权限,可是对服务内容以外的其余资源必须拥有尽量少的权限。
在上述的</IfModule>后再加入一个”<IfModule>”以下红色加粗(大又粗)内容:
<IfModule prefork.c> ServerLimit 20000 StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 1000 MaxRequestsPerChild 0 </IfModule> <IfModule worker.c> ServerLimit 50 ThreadLimit 200 StartServers 5 MaxClients 5000 MinSpareThreads 25 MaxSpareThreads 500 ThreadsPerChild 100 MaxRequestsPerChild 0 </IfModule> |
上述参数解释:
ServerLimit 50
服务器容许配置的进程数上限。这个指令和ThreadLimit结合使用设置了MaxClients最大容许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients的修改却会生效。
ThreadLimit 200
每一个子进程可配置的线程数上限。这个指令设置了每一个子进程可配置的线程数ThreadsPerChild上限。任何在重启期间对这个指令的改变都将被忽略,但对ThreadsPerChild的修改却会生效。默认值是"64".
StartServers 5
服务器启动时创建的子进程数,默认值是"3"。
MinSpareThreads 25
最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。若是服务器中总的空闲线程数太少,子进程将产生新的空闲线程。
MaxSpareThreads 250
设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。若是服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照以下限制自动修正你设置的值:worker要求其大于等于MinSpareThreads加上ThreadsPerChild的和
MaxClients400
容许同时伺服的最大接入请求数量(最大线程数量)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16(ServerLimit)乘以25(ThreadsPerChild)的结果。所以要增长MaxClients的时候,你必须同时增长ServerLimit的值。
ThreadsPerChild25
每一个子进程创建的常驻的执行线程数。默认值是25。子进程在启动时创建这些线程后就再也不创建新的线程了。
MaxRequestsPerChild 0
设置每一个子进程在其生存期内容许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。若是MaxRequestsPerChild为"0",子进程将永远不会结束。
将MaxRequestsPerChild设置成非零值有两个好处:
1.能够防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减小活动进程的数量。
注意
对于KeepAlive连接,只有第一个请求会被计数。事实上,它改变了每一个子进程限制最大连接数量的行为。
Worker.c的工做方式:
每一个进程能够拥有的线程数量是固定的。服务器会根据负载状况增长或减小进程数量。一个单独的控制进程(父进程)负责子进程的创建。每一个子进程能够创建ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。Apache老是试图维持一个备用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的创建便可获得处理。在Unix中,为了可以绑定80端口,父进程通常都是以root身份启动,随后,Apache以较低权限的用户创建子进程和线程。User和Group指令用于设置Apache子进程的权限。虽然子进程必须对其提供的内容拥有读权限,但应该尽量给予它较少的特权。另外,除非使用了suexec,不然,这些指令设置的权限将被CGI脚本所继承。
公式:
ThreadLimit>= ThreadsPerChild
MaxClients <= ServerLimit * ThreadsPerChild 必须是ThreadsPerChild的倍数
MaxSpareThreads>= MinSpareThreads+ThreadsPerChild
硬限制:
ServerLimi和ThreadLimit这两个指令决定了活动子进程数量和每一个子进程中线程数量的硬限制。要想改变这个硬限制必须彻底中止服务器而后再启动服务器(直接重启是不行的)。
Apache在编译ServerLimit时内部有一个硬性的限制,你不能超越这个限制。
preforkMPM最大为"ServerLimit200000"
其它MPM(包括work MPM)最大为"ServerLimit 20000
Apache在编译ThreadLimit时内部有一个硬性的限制,你不能超越这个限制。
mpm_winnt是"ThreadLimit 15000"
其它MPM(包括work prefork)为"ThreadLimit 20000
注意
使用ServerLimit和ThreadLimit时要特别小心。若是将ServerLimit和ThreadLimit设置成一个高出实际须要许多的值,将会有过多的共享内存被分配。当设置成超过系统的处理能力,Apache可能没法启动,或者系统将变得不稳定。
以上是Linux/Unix下的Apache的并发数优化配置,若是咱们打入了httpd –l以下显示:
怎么办?
步骤一
先修改/path/apache/conf/httpd.conf文件。
httpd.conf
将“#Includeconf/extra/httpd-mpm.conf”前面的 “#” 去掉,保存。
步骤二
再修改/apache安装目录/conf/extra/httpd-mpm.conf文件。
在mpm_winnt模式下,Apache不使用prefork也不使用work工做模式,切记!
所以,咱们只要找到原文件中:
<IfModule mpm_winnt_module> ThreadsPerChild 150 MaxRequestsPerChild 0 </IfModule> |
修改后
<IfModule mpm_winnt_module> ThreadsPerChild 500 MaxRequestsPerChild 5000 </IfModule> |
上述参数解释:
ThreadsPerChild
是指一个进程最多拥有的线程数(Windows版本,貌似不能够开启多个进程),通常100-500就能够,根据服务器的具体性能来决定。
MaxRequestsPerChild
是指一个线程最多能够接受的链接数,默认是0,就是不限制的意思,0极有可能会致使内存泄露。因此,能够根据实际状况,配置一个比较大的值。Apache会在几个线程之间进行轮询,找到负载最轻的一个线程来接受新的链接。
注意:
修改后,必定不要apacherestart,而是先 apache stop 而后再 apache start才能够。
对于静态的html 文件,在apache 可加载mod_deflate.so 模块,把内容压缩后输出,可节约大量的传输带宽。
打开httpd.conf文件,找到:
#LoadModule deflate_module modules/mod_deflate.so |
将前面的“#”去掉,变成:
LoadModule deflate_module modules/mod_deflate.so |
而后在最后一行的LoadModule处,加入以下的几行:
<IfModule mod_deflate.c> DeflateCompressionLevel 7 AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php AddOutputFilter DEFLATE css js </IfModule> |
注意:
默认等级是6,并且9级须要更多的CPU时间,用默认的6级就能够了。
要注意的是,在apache 2.2.15中,我用httpd -l看,竟然发现mod_deflat已经内置了,因此其实就不用再在httpd.conf中增长loadmodule了,不然会说出错的
咱们常常会在web页的一个超连接上点一个指向物理文件的文档,咱们通常会获得“保存,另存为,打开”,3个选项,当咱们打开的若是是一个MS文档,在选“打开”选项时IE会自动启用客户端上装有的word或者是excel等相关MS办公工具去打开,这个怎么作呢?很简单。
打开httpd.conf,找到:
AddType application/x-compress .Z AddType application/x-gzip .gz .tgz |
在其后敲入一个回车,加入:
AddType application/vnd.openxmlformats docx pptx xlsx doc xls ppt txt |
重启Apache服务便可。
DDOS攻击即采用自动点击机器人或者连续点击工具不断的刷新某一个网址或者网页上的按钮,形成网站在一时间收到大量的HTTP请求,进而阻塞网站正常的HTTP通道甚至形成网站瘫痪。
为了防止这一形式的攻击,咱们通常把在一个按钮或者是一个请求在一秒内连续执行如:100次,能够认为是一种攻击(好比说你打开一个网页,点一下提交按钮,而后按住F5键不松开)。
在Linux下的Apache HttpServer安装后会提供一个mod_evasive20的模块,用于防止这一形式的攻击,它的作法是:
若是认为是一个DDOS攻击,它的防范手段采用以下两种形势:
把这个请求相关联的IP,封锁30分钟
直接把相关的IP踢入黑名单,让其永不翻身
设置:
在你的Apache的httpd.conf文件中的最后一行“LoadModule”加入以下这句:
LoadModule evasive20_module /usr/lib/httpd/modules/mod_evasive20.so |
而后加入下面这几行
<IfModule mod_evasive20.c> DOSHashTableSize 3097 DOSPageCount 15 DOSSiteCount 100 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 36000 DOSEmailNotify 网站超级管理员@xxx.com DOSLogDir "logs/mod_evasive" </IfModule> |
核心参数解释:
DOSHashTableSize3097 记录黑名单的尺寸
DOSPageCount 每一个页面被判断为dos攻击的读取次数
DOSSiteCount 每一个站点被判断为dos攻击的读取部件(object)的个数
DOSPageInterval 读取页面间隔秒
DOSSiteInterval 读取站点间隔秒
DOSBlockingPeriod 被封时间间隔秒
注意:上述设置是针对Linux/Unix下的Apache Server,相关的Windows下的Apache见以下设置:
为Windows下的Apache加载mod_evasive模块
1. 下载附件中的压缩包,解压并拷贝mod_dosevasive22.dll到Apache安装目录下的modules目录(固然也能够是其余目录,须要本身修改路径)。
2. 修改Apache的配置文件http.conf。
添加如下内容
LoadModule dosevasive22_module modules/mod_dosevasive22.dll DOSHashTableSize 3097 DOSPageCount 3 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 |
这个话题颇有趣,原由是咱们在工程中碰到了客户这样的一个需求:
<a href=”xxx.xxx.xx/xx/xxx/轮胎损坏状况2007-05-05.jpg”>损坏部件</a>
看看好像没啥问题,一点这个超连接,应该是在IE中打开一个叫” 轮胎损坏状况2007-05-05.jpg”,嘿嘿,你们本身动手放一个带有中文名的这样的一个图片,看看可否被解析,解析不了。
因此咱们就说,真奇怪,咱们上传图片都是上传时的图片名经上传组件解析过之后变成一个UUID或者是GUID一类的文件名如:gb19070122abcxd.jpg这样一种英文加数字组合的文件名,这样的文件名,Apache固然是能够解析的,客户坚持必定我上传的图片是中文名(连中文描述都不行),由于,客户说:咱们是中国人,固然用中文图片名。。。
没办法,找了半天,找到一篇日文的教程,还好还好,N年前学过一点点日语,照着教程把它啃下来了。
这是一个日本人写的关于在Apache中支持以亚州文字命名文件名的一个“补丁”,叫“mod_encoding”。
相关配置:
1. 下载完后是一个这样的压缩包:mod_encoding-20021209.tar.gz
2. 解压后使用:
configure make make install |
在make这一行时,编译出错,报“make: *** [mod_encoding.so] Error 1”这样的错
缘由很明显,是regex.h未包含进来,解决办法也很简单:
ü 用vi打开mod_encoding.c,
ü 在#include <httpd.h>那一段的前面加上以下一行:
#include <regex.h>而后:
从新make再make install 搞定,CALL!!!
3. 编译后获得一个:mod_encoding.so的文件,而后在httpd.conf文件中加入下面这几行:
LoadModule encoding_module modules/mod_encoding.so Header add MS-Author-Via "DAV" <IfModule mod_encoding.c> EncodingEngine on NormalizeUsername on SetServerEncoding GBK DefaultClientEncoding UTF-8 GBK GB2312 AddClientEncoding "(Microsoft .* DAV $)" UTF-8 GBK GB2312 AddClientEncoding "Microsoft .* DAV" UTF-8 GBK GB2312 AddClientEncoding "Microsoft-WebDAV*" UTF-8 GBK GB2312 </IfModule> |
4. 重启Apache,搞定,在apache中咱们的url能够是中文名的附件了。
在Apache 服务器中,KeepAlive是一个布尔值,On 表明打开,Off 表明关闭,这个指令在其余众多的 HTTPD 服务器中都是存在的。KeepAlive 配置指令决定当处理完用户发起的 HTTP 请求后是否当即关闭 TCP 链接,若是 KeepAlive 设置为On,那么用户完成一次访问后,不会当即断开链接,若是还有请求,那么会继续在这一次 TCP 链接中完成,而不用重复创建新的 TCP 链接和关闭TCP 链接,能够提升用户访问速度。
那么咱们考虑3种状况:
1.用户浏览一个网页时,除了网页自己外,还引用了多个javascript 文件,多个css 文件,多个图片文件,而且这些文件都在同一个HTTP 服务器上。
2.用户浏览一个网页时,除了网页自己外,还引用一个javascript 文件,一个图片文件。
3.用户浏览的是一个动态网页,由程序即时生成内容,而且不引用其余内容。
对于上面3中状况,我认为:1 最适合打开 KeepAlive ,2 随意,3 最适合关闭 KeepAlive
下面我来分析一下缘由。
在 Apache 中,打开和关闭 KeepAlive 功能,服务器端会有什么异同呢?
先看看理论分析。
打开KeepAlive 后,意味着每次用户完成所有访问后,都要保持必定时间后才关闭会关闭TCP 链接,那么在关闭链接以前,必然会有一个Apache进程对应于该用户而不能处理其余用户,假设KeepAlive 的超时时间为10 秒种,服务器每秒处理 50个独立用户访问,那么系统中 Apache 的总进程数就是 10 * 50 = 500 个,若是一个进程占用 4M 内存,那么总共会消耗 2G内存,因此能够看出,在这种配置中,至关消耗内存,但好处是系统只处理了 50次 TCP 的握手和关闭操做。
若是关闭KeepAlive,若是仍是每秒50个用户访问,若是用户每次连续的请求数为3个,那么 Apache 的总进程数就是 50 * 3= 150 个,若是仍是每一个进程占用 4M 内存,那么总的内存消耗为 600M,这种配置能节省大量内存,可是,系统处理了 150 次 TCP的握手和关闭的操做,所以又会多消耗一些 CPU 资源。
再看看实践的观察。
我在一组大量处理动态网页内容的服务器中,起初打开KeepAlive功能,常常观察到用户访问量大时Apache进程数也很是多,系统频繁使用交换内存,系统不稳定,有时负载会出现较大波动。关闭了KeepAlive功能后,看到明显的变化是:Apache 的进程数减小了,空闲内存增长了,用于文件系统Cache的内存也增长了,CPU的开销增长了,可是服务更稳定了,系统负载也比较稳定,不多有负载大范围波动的状况,负载有必定程度的下降;变化不明显的是:访问量较少的时候,系统平均负载没有明显变化。
总结一下:
在内存很是充足的服务器上,无论是否关闭KeepAlive 功能,服务器性能不会有明显变化;
若是服务器内存较少,或者服务器有很是大量的文件系统访问时,或者主要处理动态网页服务,关闭KeepAlive 后能够节省不少内存,而节省出来的内存用于文件系统Cache,能够提升文件系统访问的性能,而且系统会更加稳定。
ü 补充1
关因而否应该关闭 KeepAlive 选项,我以为能够基于下面的一个公式来判断。
在理想的网络链接情况下,系统的Apache 进程数和内存使用能够用以下公式表达:
HttpdProcessNumber= KeepAliveTimeout * TotalRequestPerSecond / Average(KeepAliveRequests)
HttpdUsedMemory= HttpdProcessNumber * MemoryPerHttpdProcess
换成中文意思:
总Apache进程数 = KeepAliveTimeout * 每秒种HTTP请求数 / 平均KeepAlive请求
Apache占用内存 = 总Apache进程数 * 平均每进程占用内存数
须要特别说明的是:
[平均KeepAlive请求] 数,是指每一个用户链接上服务器后,持续发出的 HTTP 请求数。当 KeepAliveTimeout 等 0或者 KeepAlive 关闭时,KeepAliveTimeout 不参与乘的运算从上面的公式看,若是 [每秒用户请求]多,[KeepAliveTimeout] 的值大,[平均KeepAlive请求] 的值小,都会形成 [Apache进程数] 多和 [内存]多,可是当 [平均KeepAlive请求] 的值越大时,[Apache进程数] 和 [内存] 都是趋向于减小的。
基于上面的公式,咱们就能够推算出当 平均KeepAlive请求 <= KeepAliveTimeout 时,关闭 KeepAlive 选项是划算的,不然就能够考虑打开。
补充2
KeepAlive 该参数控制Apache是否容许在一个链接中有多个请求,默认打开。但对于大多数论坛类型站点来讲,一般设置为off以关闭该支持。
补充3
若是服务器前跑有应用squid服务,或者其它七层设备,KeepAlive On 设定要开启持续长链接
实际在 前端有squid 的状况下,KeepAlive 很关键。记得On。
Keeyalive不能为所欲为设置,而是须要根据实际状况,咱们来看一个真实的在我工做中发生的搞笑一次事件:
当时我已经离开该项目了,该项目的TeamLeader看到了keepalive的概念,他只看到了关闭keeyalive能够节省web服务器的内存,当时咱们的web服务器只有4gb内存,而并发请求的量很大,所以他就把这个keepalive设成了off。
而后直接致使脱机客户端(脱机客户端用的是.net而后webservice链接)的“login”每次都显示“出错”。
一查代码才知道,因为这个脱机客户端使用的是webservice访问,.net开发团队在login功能中设了一个超时,30秒,30秒timeout后就认为服务器没有开启,结果呢因为原来的apache设的是keeyalive和timeout 15秒,如今被改为了off,好家伙,根本就没有了这个timeout概念,所以每次.net登陆直接被apache弹回来,由于没有了这个timeout的接口了。
因而可知,学东西。。。不能只知其一;不知其二,务必求全面了解哈。
尽可能较少DNS查询的次数。若是你使用了任何”Allow fromdomain”或”Denyfrom domain”指令(也就是domain使用的是主机名而不是IP地址),则代价是要进行两次DNS查询(一次正向和一次反向,以确认没有做假)。因此,为了获得最高的性能,应该避免使用这些指令(不用域名而用IP地址也是能够的)。