httpd2.2+mod_proxy+jetty7.2.0配置
<IfModule mod_proxy.c>?? ProxyRequests Off?? ProxyPreserveHost On? ProxyPassMatch ^/(blog|user|mo)/(.*)$ http://localhost:8080 min=5 smax=16 max=64 ttl=300 timeout=20</IfModule>
?
ProxyPassMatch ^/(blog|user|mo)/(.*)$ http://localhost:8080:
与另外两种配置比较
1. 所有的apache请求都代理给后端服务器
ProxyPass / ?http://localhost:8080/
缺点:后端服务器接受太多非法url,比如用户访问/admin/index.htm,apache也会乖乖的把请求代理给后端,后端服务器消耗一些cpu计算能力后,返回404。另外也不安全,此类探测性的请求在生产环境还是挺多的,这些请求在apache端就应该过滤掉。
2. 和mod_jk的jmount配置类似,每个模块需要一行
ProxyPass /blog http://localhost:8080/blog ??min=5 smax=16 max=64 ttl=300 timeout=20
ProxyPass /user http://localhost:8080/user ??min=5 smax=16 max=64 ttl=300 timeout=20
ProxyPass /mo http://localhost:8080/mo? min=5 smax=16 max=64 ttl=300 timeout=20
缺点:连接池没有共用,如上面的配置每行都会创建自己的连接池。可以把apache日志调到debug来查看。
由于我们使用Worker MPM,每个workor都有自己的连接池,连接池最大值同ThreadsPerChild,如配置<IfModule worker.c> ServerLimit 16 StartServers 5 MaxClients 1024 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 64</IfModule>
?
理论上最多有16个连接池,如果用第2种配置方式,连接池数就是16*3=48, 每个池最大64,就是最多有48*64=4096个连接到后端服务器。
而采用ProxyPassMatch,不会出现同一个workor创建多个连接池的问题,最多有16*64=1024 连接到后端服务器。
?
?
注意ttl和timeout区别
?
jetty配置相关====================================================
<Set name="ThreadPool">??????? <New /></Set><Set name="port"><Property name="jetty.port" default="8080"/></Set><Set name="maxIdleTime">300000</Set><Set name="Acceptors">2</Set><Set name="acceptQueueSize">256</Set><Set name="statsOn">false</Set><Set name="confidentialPort">8443</Set><Set name="lowResourcesConnections">20000</Set><Set name="lowResourcesMaxIdleTime">5000</Set> </New> </Arg></Call>
?
线程池:
线程池初始大小minThreads为10,最大maxThreads为200,
而任务队列初始大小为10,如果任务队列大小不够,每次增加10(同minThreads)
?
maxIdleTime=300000:单位毫秒,maxIdleTime值要和ttl的值一致,否则连接的关闭时间以min(maxIdleTime,ttl)为准
?
Accpetors=2:从线程池划分2个线程用于监听连接端口
?
lowResourcesConnections=20000 lowResourcesMaxIdleTime=5000:当连接数大于20000,表示jetty运行在低资源状态,此时的lowResourcesMaxIdleTime作为连接最长的空闲时间,目的在加快连接的回收。20000非精确值,jetty拿“selector.keys.size()“,既当selector的keys大小超过20000时,用lowResourcesMaxIdleTime的值作为maxIdleTime。
?
?
apache worker配置===========================================================
# 服务器在断定请求失败前等待的秒数
# TimeOut指令用于设置Apache等待以下三种事件的时间长度:
# ??1. 接受一个GET请求耗费的总时间。
# ??2. POST或PUT请求时,接受两个TCP包之间的时间。
# ??3. 应答时TCP包传输中两个ACK包之间的时间。
#?? default 300
Timeout 15
KeepAlive On
# 一个持久链接中允许的最大请求数量
# default 100
MaxKeepAliveRequests 200?
# 持久链接中服务器在两次请求之间等待的秒数
# Apache在关闭持久连接前等待下一个请求的秒数。一旦收到一个请求,超时值将会被设置为Timeout指令指定的秒数。
# default 5
KeepAliveTimeout 10
?
# 每个子进程在其生存期内允许伺服的最大请求数量,到达MaxRequestsPerChild的限制后,子进程将会结束
# 对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。
MaxRequestsPerChild 20000
?
<IfModule worker.c>
# ServerLimit & ThreadLimit 需要配置其它worker指令前面
# default 16
??? ServerLimit ???? 16???
# 每个子进程可配置的线程数上限, ThreadsPerChild的配值不能超过ThreadLimit,否则启动报警告并自动调整ThreadPerChild
# default 64
??? ThreadLimit ???? 64???
# 服务器启动时建立的子进程数, 子进程在启动时建立这些线程后就不再建立新的线程了
# default 3
??? StartServers ??? 5 ???
# MaxClients指令设置了允许同时伺服的最大接入请求数量
# 对于混合型的MPM默认值是16(ServerLimit)乘以64(ThreadsPerChild)的结果
??? MaxClients ????? 1024
# worker的默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。
# default 75
??? MinSpareThreads ?25???
# Apache将按照"其大于等于MinSpareThreads加上ThreadsPerChild的和"自动修正你设置的值
# 75<64+25,所以MaxSpareThreads被重新设置为64+25=89
# default 250
??? MaxSpareThreads ?75
# 每个子进程建立的线程数,要设在超过64,需求相应配置ThreadLimit
# default 25
??? ThreadsPerChild ?64??
</IfModule>
??? ThreadLimit实际是用来限制ThreadsPerChild的取值,即ThreadsPerChild必须不能大于ThreadLimit。ThreadLimit的默认值是64,所以如果你的ThreadsPerChild=128,启动apache就给你一个“WARNING: ThreadsPerChild of 128 exceeds ThreadLimit value of 64 threads, lowering ThreadsPerChild to 64. To increase, please see the ThreadLimit directive.“ ,自动把ThreadsPerChild降级为64。如果你非要ThreadsPerChild=128,必须添加ThreadLimit=N(N大于等于128),ThreadLimit还必须配在其他指令前面,否则无效。
??? 另外MaxClient的值必须<=ThreadsPerChild*ServerLimit,且能被ThreadsPerChild整除,默认值是ThreadsPerChild*ServerLimit? (ThreadsPerChild表示实际使用值,可能被lowering了)
??? MPM混合模式下,每个子进程根据实际ThreadsPerChild值一次性创建好所有线程,且在子进程活动期间不会再创建或销毁线程,线程要么工作要么空闲。
如果线程数不够,apache创建一个子进程批量增加可用线程。
?
???? 上面配置MaxSpareThreads=75是有问题的,因为MinSpareThreads=25, ThreadsPerChild=64,当一个进程下的 64线程中,有超过ThreadsPerChild-MinSpareThreads=64-25=39已经投入工作,此时空闲线程数小于 MinSpareThreads,是必要创建更多的空闲线程以保持空闲线程在[MinSpareThreads, MaxSpareThreads]范围内。新进程会创建ThreadsPerChild个线程。那么此时就有 MinSpareThreads+ThreadsPerChild = 25+64 = 89 个空闲线程,如果MaxSpareThreads < 89,就需要销毁空闲线程,刚创建又销毁显然是不合理的。?所以apache启动时会把MaxSpareThreads调整为>= MinSpareThreads+ThreadsPerChild的值。
??? 另外StartServers被设置为5,启动初始创建6个进程,1个主进程(控制进程)和5个子进程,每个子进程初始化64个线程,5*64=320空闲线程,大于MaxSpareThreads(89),所以有4个子进程很快被杀掉,启动apache时可以用“ps -ux“观察到,
?
比较合理的worker配置
?
<IfModule worker.c># 配置都采用默认值,可以去掉ServerLimit 16ThreadLimit 64StartServers 3MinSpareThreads? 25MaxSpareThreads 250# 应用特殊配置值MaxClients 1024ThreadsPerChild 64</IfModule>?
worker MPM:混合的多线程多进程
由于使用线程来处理请求,可以处理海量请求,而系统资源的开销小于基于进程的MPM。但是,它也使用了多进程,每个进程又有多个线程,以获得基于进程的MPM的稳定性。