Fabric 技巧 --- 通过 Fabric 无法启动 Tomcat

最近有一个需求是调整 tomcat 的参数,因为服务器比较多,就使用 fabric 来批量处理了。

tomcat 需要调整的参数为 acceptCount

 <Connector port="8080"
               protocol="org.apache.coyote.http11.Http11NioProtocol"  
               connectionTimeout="20000"
               redirectPort="8444" 
               URIEncoding="UTF-8"
               useBodyEncodingForURI="true"
               maxThreads="1024"
               minSpareThreads="200"
               maxSpareThreads="600"
               acceptCount="800"
               enableLookups="false"
               compression="on"
               compressionMinSize="2048"
               noCompressionUserAgents="gozilla,traviata"

  • maxThreads:tomcat 启动的最大线程数,即同时处理的任务个数,默认值为200
  • acceptCount:当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100

该参数值的作用的讲解请参照 baibaluo 博文 tomcat的maxThreads、acceptCount(最大线程数、最大排队数)

为了自己看方便,我直接贴出来

这两个值如何起作用,请看下面三种情况

情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。

情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。

情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused

maxThreads如何配置

一般的服务器操作都包括量方面:
1、计算(主要消耗cpu)
2、等待(io、数据库等)

第一种极端情况,如果我们的操作是纯粹的计算,那么系统响应时间的主要限制就是 cpu 的运算能力,此时 maxThreads 应该尽量设的小,降低同一时间内争抢 cpu 的线程个数,可以提高计算效率,提高系统的整体处理能力。

第二种极端情况,如果我们的操作纯粹是IO或者数据库,那么响应时间的主要限制就变为等待外部资源,此时 maxThreads 应该尽量设的大,这样才能提高同时处理请求的个数,从而提高系统整体的处理能力。此情况下因为 tomcat 同时处理的请求量会比较大,所以需要关注一下 tomcat 的虚拟机内存设置和 linux 的 open file 限制。

我在测试时遇到一个问题,maxThreads  我设置的比较大比如 3000,当服务的线程数大到一定程度时,一般是2000出头,单次请求的响应时间就会急剧的增加,

百思不得其解这是为什么,四处寻求答案无果,最后我总结的原因可能是cpu在线程切换时消耗的时间随着线程数量的增加越来越大,

cpu 把大多数时间都用来在这 2000 多个线程直接切换上了,当然 cpu 就没有时间来处理我们的程序了。

以前一直简单的认为多线程=高效率。。其实多线程本身并不能提高cpu效率,线程过多反而会降低cpu效率。

当 "cpu核心数<线程数" 时,cpu就需要在多个线程直接来回切换,以保证每个线程都会获得cpu时间,即通常我们说的并发执行。

所以 maxThreads 的配置绝对不是越大越好。

现实应用中,我们的操作都会包含以上两种类型(计算、等待),所以 maxThreads 的配置并没有一个最优值,一定要根据具体情况来配置。

最好的做法是:在不断测试的基础上,不断调整、优化,才能得到最合理的配置。

acceptCount 的配置,我一般是设置的跟 maxThreads 一样大,这个值应该是主要根据应用的访问峰值与平均值来权衡配置的。

如果设的较小,可以保证接受的请求较快相应,但是超出的请求可能就直接被拒绝

如果设的较大,可能就会出现大量的请求超时的情况,因为我们系统的处理能力是一定的。

Fabric 的脚本编写

@roles('user-api')
def bacup_tomcat_server_xml():
    run('cp -av /opt/apps/tomcat/conf/server.xml /opt/apps/tomcat/conf/server.xml.2014-07-31')

@roles('user-api')
def rollback_tomcat_server_xml():
    run('cp -av /opt/apps/tomcat/conf/server.xml.2014-07-31 /opt/apps/tomcat/conf/server.xml')


@roles('user-api')
def modify_tomcat_server_xml():
    run("sed -i '/acceptCount/s/800/1024/' /opt/apps/tomcat/conf/server.xml")

#@roles('user-api')
def stop_tomcat():
    run("ps -ef |grep tomcat |grep -v grep   |awk -F\" \" '{print $2}' |xargs kill -9 ")

@roles('user-api')
def start_tomcat():
    with cd('/opt/sh'):
        run("./tomcat start")

@roles('user-api')
def reload_tomcat_nginx():
    run('sudo /opt/nginx/sbin/nginx -s quit')
    run("ps -ef |grep tomcat |grep -v grep   |awk -F\" \" '{print $2}' |xargs kill -9 && sleep 5")
    run('/opt/sh/tomcat.sh start')
    run("sudo /opt/sh/nginx.sh start")



@parallel
def execute_modify_tomcat_conf():
    execute(bacup_tomcat_server_xml)
    execute(modify_tomcat_server_xml)

然后执行命令,为了安全稳妥起见,先执行其中一台

fab reload_tomcat_nginx -H 192.168.0.1

执行后,发现出现问题一个问题,在启动 tomcat 的时候出现问题,启动不起来,最后 google ,在 stackoverflow 上发现一个解答 how-to-start-tomcat-by-fabric-with-sudo-as-another-user

因此按照这个修改下,主要修改了 run('/opt/sh/tomcat.sh start') 这个步骤,

run('set -m;/apps/sh/tomcat.sh start')

只需要加一个 set -m 即可,该命令的作用是

"set -m" turns on job control, you can run processes in a separate process group.

我的理解是在一个独立的进程组里面运行我们的进程。

修改完毕后,再次测试,成功。

    原文作者:yexiaobai
    原文地址: https://segmentfault.com/a/1190000000624187
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞