Tomcat 安全与优化-程序员宅基地

技术标签: ViewUI  java  运维  前端  

tomcat配置调优与安全总结

    作为运维,避免不了与tomcat打交道,然而作者发现网络上关于tomcat配置和调优安全的文章非常散,通过参考各位大神的相关技术文档,根据作者对tomcat的运维经验,总结了一些tomcat的基础运维注意事项,希望对广大技术兄弟们有些帮助。

    本篇文章只是对tomcat模板的基础调优,除了部署tomcat的各系统环境和配置,影响tomcat并发和性能的另一大重要因素,就是java的代码工程,而如何在生产中优化java工程,这个就需要运维与开发共同配合,尤其是运维需要有开发与运维是同一个团队的意识,只有双方配合默契才能发挥最大战力,要知道一个人的力量永远是有限的,只有团队合作才能爆发出真正力量!

     而包含了Java工程的整体优化就设计到整体的架构优化,这个更加是一个细致而有趣的过程,也是运维通向架构师的一个必经之路!

    

1      功能优化

1.1     硬件资源对tomcat的影响

    

    作者实测,在阿里云的不同区域部署相同系统应用配置的tomcat,在压测时会出现吞吐量差异达到1/4,经过对比发现,两个区域的cpu频率2.2GHz和2.6Ghz。系统硬件性能直接影响tomcat的并发量,起决定作用的是CPU和MEM,CPU运行速度提升,会带来tomcat响应时间的缩短,mem大小决定工程需要内存的大小和工程的并发数量。

1.2     Java虚拟机调优

   

1.2.1     JDK版本选择

    如果新手请选择SUN的JVM,在满足项目需要的前提下,尽量选用版本较高的JVM,一般来说高版本产品在速度和效率上比低版本会有改进。 JDK1.4比JDK1.3性能提高了近10%-20%,JDK1.5比JDK1.4性能提高25%-75%。 因此对性能要求较高的情况推荐使用 JDK1.6。

    这里需要补充的是,各位在打算升级JVM时,一定要先让开发先试用高版本的JVM,调试高版本JVM对工程的影响,经过测试后逐步部署到测试环境,经过一定时间的验证,发现没有问题后再谨慎的更换到生产。JVM版本不一致,很容易出现各类异常,对待生产,谨慎永远是第一原则!

   JVM调优参见:http://vekergu.blog.51cto.com/9966832/1626733

1.2.2     JDK参数优化

    Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置JAVA_OPTS参数。

1.   JAVA_OPTS参数说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-server 启用jdk 的 server 版; 
-Xms   java虚拟机初始化时的最小内存; 
-Xmx  java虚拟机可使用的最大内存; 
-XX:PermSize    内存永久保留区域 
-XX:MaxPermSize   内存最大永久保留区域 
-Xms=-Xmx=服务器内存*70%,如部署tomcat,jboss在同一台服务器-Xms=-Xmx=服务器内存*80%*1 /4 ,现公司服务器内存一般都可以加到最大4G,所以可以采取以下配置,把以下参数添加到catalina.sh里面,
  JAVA_OPTS= '-Xms1024m -Xmx4096m -XX:PermSize=256M -XX:MaxNewSize=256m-XX:MaxPermSize=256m'
  
#-Xmx6000m                        :设置JVM最大可用内存为6000MB
#-Xms6000m                        :设置JVM初始可用内存为6000MB
#-Xmn2g                              :设置年轻代大小为2G
#-Xss128k                             :设置每个线程的堆栈大小为128k
#-XX:NewRatio=4                 :设置年轻代与年老代的比值为4
#-XX:SurvivorRatio=4            :设置年轻代中Eden区与Survivor区的大小比值为4
#-XX:PermSize=512m                    :设置堆栈永久区起始大小为512m
#-XX:MaxPermSize=512m             :设置堆栈永久区最大大小为512m
#-XX:MaxTenuringThreshold=0     :设置垃圾最大年龄为0
#-XX:+UseParallelGC                     :选择垃圾收集器为并行收集器
#-XX:ParallelGCThreads=8             :配置并行收集器的线程数
#-XX:+UseParallelOldGC                :配置年老代垃圾收集方式为并行收集
#-XX:+UseAdaptiveSizePolicy     :并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时>间或者收集频率等,此值建议使用并行收集器时,一直打开。

 

 

1.2.3     生产案例

    根据作者本人的经验,生产环境需要确定对JVM的设置,还是需要根据java的运行状态,通过监控后,不断的调试的一个过程,没有那个配置一上来就可以适应所有的场景。以下就举列作者常用的一个JVM配置方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
JAVA_OPTS="
-server 
-Xms1024m
-Xmx1024m
-Xmn384m
-XX:PermSize=64m
-XX:MaxPermSize=128m
-XX:+UseParallelOldGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc: /opt/tomcat/log/gc .log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath= /opt/tomcat/heap .bin"
说明:

 

1.   Xms与Xmx普遍选择配置相同的大小,实际大小根据实际情况调整,由小向大增加,没必要一开始就增加到很大的内存。
2.   XX:PermSize设置堆栈永久区起始大小,XX:MaxPermSize设置堆栈永久区最大大,其实设置比默认值大写即可,或者默认也可以。作者这个这两个值,是因为出现过永久区内存溢出,才进行设定的。
3.   UseParallelOldGC、PrintGCDateStamps、PrintGCDetails、Xloggc:/opt/tomcat/log/gc.log设置GClog日志,这个对分析tomcat中JVM内存使用情况非常有效。
4.   XX:+HeapDumpOnOutOfMemoryError、XX:HeapDumpPath=/opt/tomcat/heap.bin"设置内存溢出时,输出HeapDump,具体如何使用分析HeapDump文件,请参考:http://vekergu.blog.51cto.com/9966832/1619640
5.   作者对JVM参数设置的做法,调整合适的JVM内存大小,开启GClog和HeapDump即可。

1.3     tomcat集群之session共享

1.3.1     基于tomcat集群的session共享

 在{TOMCST_HOME}/conf/server.xml取消下面代码注释即可:

1
<ClusterclassName= "org.apache.catalina.ha.tcp.SimpleTcpCluster" />

 

1.3.2     基于memcached存储session共享

 具体配置方法见:http://vekergu.blog.51cto.com/9966832/1672833

1.4     站点的默认网页、自定义错误页面、禁止列目录等功能

    这些功能开发会在工程的WEB-INF目录下的web.xml中设置,运维了解下就好,者遇到类似问题可以找到解决思路。

1.4.1     默认主页

1
2
3
4
5
    <welcome- file -list>
        <welcome- file >index.html< /welcome-file >
        <welcome- file >index.htm< /welcome-file >
        <welcome- file >index.jsp< /welcome-file >
    < /welcome-file-list >

1.4.2     自定义错误页面

1
2
3
4
<error-page> 
<error-code> 404 </error-code> 
<location>/ 404 .htm</location> 
</error-page>

 

1.4.3     定义会话超时时间

1
2
3
    <session-config>
        <session-timeout> 30 </session-timeout>
    </session-config>

1.4.4     禁止列目录

1
2
3
4
        <init-param>
            <param-name>listings</param-name>
            <param-value> false </param-value>
        </init-param>

1.5     管理AJP端口

    AJP是为 Tomcat 与 HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。由于我们公司前端是由nginx做的反向代理,因此不使用此连接器,因此需要注销掉该连接器。在{TOMCST_HOME}/conf/server.xml中找到下列代码,注释即可

1
2
3
          <!--
    <Connector port= "8009"  protocol= "AJP/1.3" redirectPort= "8443"  />
-->

1.6     取消默认gc监听

    如果开启了GClog,再开启GC监听,会影响GClog输出,功能重复,可以选择取消。

1
2
  <!-- 内存泄露侦测,对于垃圾回收不能处理的对像,它就会做日志,开启gcc后,不需要这个功能-->
  <!-- ListenerclassName= "org.apache.catalina.core.JreMemoryLeakPreventionListener" gcDaemonProtection= "false" / -->

 

1.7   自定义tomcat代码路径(2015-7-21新增)

1
<Context docBase= "/code_path/code_file" path= "/code_file "  reloadable= "false"  />

其中:

docBase这个是你代码的路径

path这个是你访问网站的URL路径,要区别path的意义,请看下面的举例

 

举例:

1
2
3
4
5
访问www.aaa.com
<Context docBase= "/code_path/code_file" path= " "  reloadable= "false"  />
  
访问www.aaa.com /code_file
<Context docBase= "/code_path/code_file" path= "/code_file "  reloadable= "fasle"  />

reloadable如果为true,会自动加载变化的动态文件,看起来挺智能的,但是,在tomcat加载变化代码的时候有可能会出现内存溢出,tomcat服务不正常等异常,建议还是false掉,更新完代码脚本重启tomcat才是王道。

     此前看到一些文章,在讲解自定义tomcat代码路径时,reloadable全部是true,可能能多小伙伴都设置为true,建议对这个参数认真对待,否则一不小心就是一个坑。。。。

 

2      性能优化

2.1     屏蔽DNS查询

    Web应用程序可以通过Web容器提供的getRemoteHost()方法获得访问Web应用客户的IP地址和名称,但是这样会消耗Web容器的资源,并且还需要通过IP地址和DNS服务器反查用户的名字。因此当系统上线时,可以将这个属性关闭,从而减少资源消耗,那么Web应用也就只能记录下IP地址。修改的属性是enableLoopups="false"。

2.2     调整线程数

    Tomcat通过线程池来为用户访问提供响应,对于上线的系统初步估计用户并发数量后,再调整线程池容量。例如,用户并发数量在100左右时,可以设置minProcessors="100",maxProcessors="100"。将最大和最小设置为一样后,线程池不会再释放空闲的线程,当用户访问突然增加时,不需要再消耗系统资源去创建新的线程。

2.3     调整最大连接数

   这个其实最复杂,即使用户并发量大,但是系统反应速度快,也没必要把这个值设置太高,高了系统需要消耗大量的资源去切换线程,但是如果设置太低也会造成应用无法满足用户并发需要。因此设置这个最好能够结合整个系统的跟踪与调优,使系统达到最好的平稳状态,一般设置为maxProcessors的1.5倍即可。

2.4     调整网络超时

    主要是HTTP协议也有个连接过程,客户端连接到服务器上后,如果长时间没有得到处理就会被释放。如果服务器处理速度较慢,但是希望每个用户都能得到有效处理,或者网络环境不好,需要保证用户不会因为超时中断,也可以把时间加长。但是一般设置成connectionTimeout="30000"即可。太长对系统来说价值不大,反而会浪费系统资源在无谓的长连接上。

2.5     压缩管理

    tomcat作为一个应用服务器,也是支持 gzip 压缩功能的。我们可以在 server.xml 配置文件中的Connector 节点中配置如下参数,来实现对指定资源类型进行压缩。

 

1
2
3
4
   compression= "on"             # 打开压缩功能
   compressionMinSize= "50"      # 启用压缩的输出内容大小,默认为2KB
   noCompressionUserAgents= "gozilla, traviata"       # 对于以下的浏览器,不启用压缩
   compressableMimeType= "text/html,text/xml,text/javascript,text/css,text/plain" # 哪些资源类型需要压缩

如果使用apache/nginx代理,所以tomcat自身不需要进行压缩,会给服务器增加压力

2.6     tomcat的三种运行模式选择

2.6.1     Bio

默认的模式,性能非常低下,没有经过任何优化处理和支持。

2.6.2     Nio

利用java的异步io护理技术,no blocking IO技术.

 

想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol为

 

1
2
3
4
5
6
  <Connector port= "80"  protocol= "org.apache.coyote.http11.Http11NioProtocol"
          connectionTimeout= "20000"
          URIEncoding= "UTF-8"
          useBodyEncodingForURI= "true"
          enableLookups= "false"
          redirectPort= "8443" />

启动后,就可以生效。

2.6.3     Apr

安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能.。必须要安装apr和native,直接启动就支持apr。

 

安装APR

1
2
3
4
5
6
sudo  yum -y  install  apr  apr-devel
tar  zxvf tomcat-native. tar .gz  // 该文件在tomcat的bin目录下面
cd  tomcat-native-1.1.24-src /jni/native
. /configure--with-apr = /usr/bin/apr-1-config
make
make  install

 

安装完成之后 会出现如下提示信息

Libraries have been installed in:

/usr/local/apr/lib

 

安装成功后还需要对tomcat设置环境变量,方法是在catalina.sh文件中增加一 行:

1
2
3
CATALINA_OPTS= "-Djava.library.path=/usr/local/apr/lib"
修改8080端对应的
protocol= "org.apache.coyote.http11.Http11AprProtocol"

2.7     Tomcat连接相关参数总结

在Tomcat 配置文件 server.xml 中的 <Connector ... /> 配置中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
maxThreads 客户请求最大线程数
minSpareThreads    Tomcat初始化时创建的 socket 线程数
maxSpareThreads   Tomcat连接器的最大空闲 socket 线程数
enableLookups      若设为 true , 则支持域名解析,可把 ip 地址解析为主机名
redirectPort        在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort端口
acceptAccount       监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )
connectionTimeout   连接超时
minProcessors         服务器创建时的最小处理线程数
maxProcessors        服务器同时最大处理线程数
URIEncoding    URL统一编码
compression 打开压缩功能  
compressionMinSize   启用压缩的输出内容大小,这里面默认为2KB
compressableMimeType 压缩类型
connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间

 

 

2.8     生产配置实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Connector port= "8080"  protocol= "org.apache.coyote.http11.Http11NioProtocol"    #nio  利用java的异步io护理技术,noblocking IO技术.
         URIEncoding= "UTF-8"     #设置编码
         minSpareThreads= "25"   #Tomcat初始化时创建的 socket线程数
         maxSpareThreads= "75"   #Tomcat连接器的最大空闲socket 线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值50
         enableLookups= "false"   #屏蔽DNS查询
         disableUploadTimeout= "true"   #该标志位表明当执行servlet时,是否允许servlet容器使用一个不同的、更长的连接超时。启用该标志位将导致在上传数据时,要么使用更长的时间完成上传,要么出现更长的超时。如果不指定,该属性为“false”。       
         connectionTimeout= "20000"    #网络超时时间
         acceptCount= "300"      #容许的最大连接数,一般设置为maxProcessors的1.5倍即可,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )
         maxThreads= "300"      #客户请求最大线程数,默认值为“200”
         maxProcessors= "1000"    #最大连接线程数,即:并发处理的最大请求数,默认值为75 ,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程
         minProcessors= "5"       #最小空闲连接线程数,用于提高系统处理性能,默认值为10
         useURIValidationHack= "false"
         <!--   前端使用nginx作为反向代理,不需要启用tomcat压缩功能。
         compression= "on"    #打开压缩功能
         compressionMinSize= "2048"  #启用压缩的输出内容大小,这里面默认为2KB
         compressableMimeType= "text/html,text/xml,text/javascript,text/css,text/plain"    #压缩类型
         -->
         redirectPort= "8443" />

             

3      安全优化

3.1     tomcat影藏版本信息

Tomcat 安装目录下的lib目录下,名称为 catalina.jar,直接修改catalina.jar中的文件,org/apache/catalina/util/ServerInfo.properties

server.info=Apache Tomcat/7.0.53

3.2     禁用 Tomcat 管理页面

    我们线上是不使用 Tomcat 默认提供的管理页面的,因此都会在初始化的时候就把这些页面删掉。这些页面是存放在 Tomcat 安装目录下的webapps目录下的。我们只需要删除该目录下的所有文件即可。当然,还有涉及管理页面的2个配置文件host-manager.xml 和 manager.xml 也需要一并删掉。这两个文件存放在 Tomcat 安装目录下的conf/Catalina/localhost目录下。

3.3     用普通用户启动 Tomcat

    为了进一步安全,我们不建议使用 root 来启动 Tomcat。这边建议使用专用用户 tomcat 或者 nobody 用户来启动 Tomcat。在启动之前,需要对我们的tomcat 安装目录下所有文件的属主和属组都设置为指定用户。

3.4     分离 Tomcat 和项目的用户

为了防止 Tomcat 被植入 web shell 程序后,可以修改项目文件。因此我们要将 Tomcat 和项目的属主做分离,这样子,即便被搞,他也无法创建和编辑项目文件。

3.5     关闭war自动部署

默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。

修改实例:

1
2
3
  
      <Host name= "localhost"  appBase= ""
            unpackWARs= "false"  autoDeploy= "false" >

3.6     更改关闭 Tomcat 实例的指令

    server.xml中定义了可以直接关闭 Tomcat 实例的管理端口。我们通过 telnet 连接上该端口之后,输入SHUTDOWN (此为默认关闭指令)即可关闭 Tomcat 实例(注意,此时虽然实例关闭了,但是进程还是存在的)。由于默认关闭Tomcat 的端口和指令都很简单。默认端口为8005,指令为SHUTDOWN 。因此我们需要将关闭指令修改复杂一点。

    当然,在新版的 Tomcat 中该端口仅监听在127.0.0.1上,因此大家也不必担心。除非黑客登陆到tomcat本机去执行关闭操作。

      修改实例:

1
<Server port= "8005" shutdown= "9SDfjsd29jf24sdff0LSDdfJKS9DKkjsd" >

4      内核优化

   在修改内核参数的时候,建议大家逐个设置,然后反复试验,切勿图方便直接拿上就用,一次全部替换。

优化网络参数

修改/etc/sysctl.cnf文件,在最后追加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 65536

 

保存退出,执行sysctl-p生效

内核参数详细作用,可以参考:http://blog.chinaunix.net/uid-21505614-id-2181210.html

 

5      tomcat监控

5.1     配置tomcat的status状态页

步骤1:修改%tomcat安装路径%\conf \tomcat-users文件,配置admin设置权限。在<tomcat-users>中增加部分内容。具体如下:

1
2
  <role rolename= "manager-gui" />
  <user username= "manager" password= "1234"  roles= "manager-gui" />

  注:用户名:manager,密码:1234

步骤2:完成后,启动tomcat,输入:http://localhost:8080  --(IP,端口号,可远程访问)

点击status,输入账号,密码(manager,1234),进入status,时时刷新页面,查看当前tomcat状态。 或者直接访问:http://localhost:8080/manager/status页面。

备注1:若希望整个服务器的性能数据以一个单行的xml文件形式表示,则进入如下界面:http://localhost:8080/manager/status?XML=true

备注2:若服务器中存在几个项目,单独对某个项目进行监控,则需要另行增加代码。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Free memory: 304.84 MB Total memory: 903.00MB Max memory: 7273.00 MB
Free memory:空闲内存大小。
Total memory:总内存大小。
Max memory:最大内存大小。
  
Max threads: 200 Current thread count: 10Current thread busy: 1 Keeped alive sockets count: 1Max processing  time : 187 msProcessing  time : 0.281 s Request count: 32 Error count: 3 Bytes received: 0.00MB Bytes sent: 0.12 MB
Max threads:最大线程数。
Current thread count:最近运行的线程数。
Max processing  time :最大CPU时间。
Processing  time :CPU消耗总时间
Request count:请求总数。
Error count:错误的请求数。
Bytes received:接收字节数。
Bytes sent:发送字节数。

 

 

访问地址:

curl --user manager:1234   http://you_tomcat_ip:port/manager/status?XML=true

 

5.2     tomcat监控脚本

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
#auther:gushao
#time:2015-5-4
#========================DefaultSettings===============================
# address of status page
STATUS_ADDR= "http://localhost:8080/manager/status?XML=true"
USER= "manager"
PASS= "1234"
# sample rate, default: 5seconds
SAMPLE_RATE=5
# if press "Ctrl+c", stop monitor
EXIT_SIGNAL=2
# connector to monitor
CONNECTOR= "http-8080"
# result directory to store data
RESULT_DIR= "/tmp"
# perf data file
PERF_DATA= "perf_data"
# jvm data file
JVM_DATA= "jvm_data"
# connector data file
CONNECTOR_DATA= "connector_data"
# thread data file
THREAD_DATA= "thread_data"
# request data file
REQUEST_DATA= "request_data"
  
# ===========================Output ErrorMessage========================
# Show Error Message and exit, get oneparameter
errorMsg()
{
        if  [[ $ # -eq 1 ]]; then
                 echo  "Runtime Error:$1"
                 exit  1
        else
                echo  "Function Error:errorMsg"
                 exit  127
        fi
}
  
# =========================Get DataFunction=============================
# Get performance data, no parameter wanted
getPerfData()
{
        cd  $RESULT_DIR
        wget --http-user= "$USER"  --http-password= "$PASS" "$STATUS_ADDR"  -O  "$PERF_DATA"  || errorMsg  "Failed toget data, please check the connection"
        # JVM data
        sed  's/.*<jvm>//g;s/<\/jvm>.*//g'  $PERF_DATA |  awk  -F \ ' ' {print $2, $4, $6 }' >> $JVM_DATA
        # 'Connector data
        sed  's/.*' $CONNECTOR '.>//g;s/<\/connector>.*//g'  $PERF_DATA>> $CONNECTOR_DATA
        # Thread data
        sed  's/.*<threadInfo//g;s/\/>.*//g'  $CONNECTOR_DATA |  awk  -F\"  '{ print $2, $4, $6 }'  >> $THREAD_DATA
        # " Request data
        sed  's/.*<requestInfo//g;s/\/>.*//g'  $CONNECTOR_DATA |  awk  -F\"  '{ print $2, $4, $6, $8, $10, $12 }'  >> $REQUEST_DATA
  
}
  
# ========================Build ChartFunction==========================
# "according the data, build the chart(use gnuplot)
buildChart()
{   
        TITLE= ""
        OUTPUT= ""
        PLOT= ""
        YRANGE= "[0:]"
        case  "$1"  in
                 "jvm"  )
                 TITLE= "JVM"
                OUTPUT= "jvm_graph.png"
                 PLOT="plot  'jvm_data' using 1 title  'free'  w linespoints, \
                 'jvm_data'  using 2 title 'total'  w linespoints,\
                 'jvm_data'  using 3 title  'max' w linespoints"
                 ;;
  
                 "thread"  )
                 TITLE= "Thread"
                OUTPUT= "thread_graph.png"
                 PLOT="plot  'thread_data' using 1 title  'max threads'  w linespoints,\
                 'thread_data'  using 2 title 'current thread count'  w linespoints,\
                 'thread_data'  using 3 title 'current thread busy'  w linespoints"
                 ;;
  
                 "request"  )
                 TITLE= "Request"
                 YRANGE= "[-1:]"
                OUTPUT= "request_graph.png"
                 PLOT="plot  'request_data' using 1 title  'max time'  w linespoints,\
                 'request_data'  using 2 title 'processing time'  w linespoints,\
                 'request_data'  using 3 title 'request count'  w linespoints,\
                 'request_data'  using 4 title 'error count'  w linespoints,\
                 'request_data'  using 5 title 'bytes received'  w linespoints,\
                 'request_data'  using 6 title 'bytes sent'  w linespoints"
                 ;;
        esac
  
        # build graph
        gnuplot <<EOF
        set  terminal png small size 480,360
        set  title  "$TITLE"
        set  yrange $YRANGE
        set  grid
        set  xlabel  "timeline (s)"
        set  output  "$OUTPUT"
        $PLOT
EOF
}
  
# ========================Build ReportFunction=========================
# include data and chart, give a readablehtml report
buildReport()
{
        # build graph jvm, request,thread
        buildChart  "jvm"  || errorMsg  "Function Error: build jvmgraph"
        buildChart  "thread"  || errorMsg  "Function Error: buildthread graph"
        buildChart  "request"  || errorMsg  "Function Error: buildrequest graph"
        # build html report
}
  
# ========================Stop MonitorFunction
# call buildReport function
stopMonitor()
{
    echo  "Monitor stopped, and we are building the report ..."
    buildReport || errorMsg  "Function Error: buildReport"
    exit
}
  
# =============================MainFunction=============================
trap  "stopMonitor"  $EXIT_SIGNAL
#收到stopMonitor信号,则中断退出
while  :
do
        getPerfData || errorMsg  "Failed to get performance data"
        sleep  $SAMPLE_RATE
done

 

转载至:http://vekergu.blog.51cto.com/9966832/1672931

 

转载于:https://www.cnblogs.com/onone/articles/7760967.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aicyo8644/article/details/102064025

智能推荐

c# 调用非托管代码_c# 声明kernel32 函数-程序员宅基地

文章浏览阅读956次,点赞3次,收藏5次。编程过程中,一般c#调用非托管的代码有两种方式:1.直接调用从DLL中导出的函数。2.调用COM对象上的接口方法。首先说明第1种方式,基本步骤如下:1.使用关键字static,extern声明需要导出的函数。2.把DllImport 属性附加到函数上。3.掌握常用的数据类型传递的对应关系。4.如果需要,为函数的参数和返回值指定自定义数据封送处理信息,这将重写.net framework默认的封送处理。简单举例如下:托管函数原型:DWORD GetShortPathName(LPCTST_c# 声明kernel32 函数

高频交易及化资策与区_hudson river trading-程序员宅基地

文章浏览阅读406次。转 高频交易及量化投资的策略与误区一、高频交易公司和量化投资公司的区别一般来说,高频交易公司和量化投资公司既有联系,又有区别。在美国,人们常说的高频交易公司一般都是自营交易公司,这些公司主要有Getco、Tower Research、Hudson River Trading、SIG、Virtu Financial、Jump Trading、RGM Advisor、Chopper Tradi..._hudson river trading

C语言文件操作相关的函数_c语言与文件处理有关的函数-程序员宅基地

文章浏览阅读865次。文件的打开和关闭文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件 的关系。ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。FILE * fopen ( const char * filename, const char * mode ); int fcl..._c语言与文件处理有关的函数

java 无法读取文件_java 读取文件,无法显示文件内容,如何解决? 谢谢。-程序员宅基地

文章浏览阅读1.1k次。从来没见过进行文件读取写入时,在写入中需要随机数的,你读取文件就是从一个地方获取输入流,然后将这个输入流写到别的地方,根本不要随机数。给你一个示例://copyafiletoanotherfilebyusingFileReader/FileWriterimportjava.io.*;publicclassTFileRead{publicstaticvoidmain(S..._java复制文件文件没有内容显示

vue引入原生高德地图_前端引入原生地图-程序员宅基地

文章浏览阅读556次,点赞2次,收藏3次。由于工作上的需要,今天捣鼓了半天高德地图。如果定制化开发需求不太高的话,可以用vue-amap,这个我就不多说了,详细就看官网 https://elemefe.github.io/vue-amap/#/zh-cn/introduction/install然而我们公司需要英文版的高德,我看vue-amap中好像没有这方面的配置,而且还有一些其他的定制化开发需求,然后就只用原生的高德。其实原生的引入也不复杂,但是有几个坑要填一下。1. index.html注意,引入的高德js一定要放在头部而_前端引入原生地图

ViewGroup重写大法 (一)-程序员宅基地

文章浏览阅读104次。本文介绍ViewGroup重写,我们所熟知的LinearLayout,RelativeLayout,FrameLayout等等,所有的容器类都是ViewGroup的子类,ViewGroup又继承View。我们在熟练应用这些现成的系统布局的时候可能有时候就不能满足我们自己的需求了,这是我们就要自己重写一个容器来实现效果。ViewGroup重写可以达到各种效果,下面写一个简单的重写一个Vi..._viewgroup 重写

随便推点

台式计算机有没有无线连接模块,台式机能不能连接wifi_台式机怎么连接wifi-程序员宅基地

文章浏览阅读1.2k次。2016-12-30 09:54:26你好!很高兴为你解答,先将无线路由器接通电源,然后插上网线,将另一端插到你电脑上,等网络通了之后,你在IE浏览器上输入:192.168.1.1(这是一般无线路由器的IP,如果有特殊...2016-12-16 11:44:30手机系统问题,可能系统出现了问题,导致连接上了WiFi却无法上网。重启一下路由器试试,或者将路由器恢复一下出厂设置,然后重新拨号上网,并根..._计算机无线模块怎么看

OpenGLES编程思想-程序员宅基地

文章浏览阅读4.8k次。最近在看gles的reference,想多了解一下gles的底层,gles是opengl在khronos在嵌入式设备上的图形硬件的软件访问接口,很多东西和opengl似曾相似,但是和opengl又有很大的不同,最新的标准是gles3.2,标准文档非常长,如果不是写引擎没必要对每个接口烂熟于心,但是为了能够了解他,我对他的编程思想做个总结,最重要的是理解gles的设计思路,然后在使用的时候也必将容易找到相关接口。所以本文基本不会列出gles的每个接口,不会记录讲解每个接口,而是希望能够通过总结gles的设计思_gles

linux命令行去掉滴滴声_linux一直叮叮叮-程序员宅基地

文章浏览阅读2.6k次,点赞2次,收藏2次。在CentOS中,我们常用Tab键进行命令补全,但是系统总是提示滴滴声,让人很烦躁。 即使把音频设备关掉,或者虚拟机的音频设备也关掉,还是有这个声音。 如果不喜欢这个声音,可以通过修改配置去掉它。用vi 编辑 /etc/inputrc 文件,在vi的命令模式下,用键盘方向键进行定位, 找到“#set bell-style none”,用X 删除语句前方的#号,就可以了。“: wq_linux一直叮叮叮

Java从零开始 第10.5讲 面向对象的习题课_编写一个测试类booktest,创建几个book对象,并打印它们的字符串表示,同时判断-程序员宅基地

文章浏览阅读197次。面向对象的习题课类的定义员工类Employee求和类Sum类与对象书籍类BookBook类的测试类BookTest异常能扩容的MyList类剪刀石头布转载请注明出处在这一讲中我会给出一些关于面向对象部分的习题,同样希望在不看答案的情况下自己编写,即使看过了答案,也要能够在不看答案的情况下写出来。类的定义员工类Employee定义在同一个公司工作的Employee类,要求其中含有属性:员工的名字,员工的年龄,员工的爱好,员工的公司名(注意当公司更名时,所有员工的公司名都需要更名),工作地点默认为中国(_编写一个测试类booktest,创建几个book对象,并打印它们的字符串表示,同时判断

Spark伪分布安装(依赖Hadoop)_下载spark的hadoop依赖-程序员宅基地

文章浏览阅读6.7k次,点赞7次,收藏14次。一、伪分布安装Spark安装环境:Ubuntu 14.04 LTS 64位+Hadoop2.7.2+Spark2.0.0+jdk1.7.0_761、安装jdk1.7(1)下载jdk-7u76-linux-x64.tar.gz;(2)解压jdk-7u76-linux-x64.tar.gz,并将其移动到/opt/java/jdk路径下(自建);命令:tar -zxvf jdk-_下载spark的hadoop依赖

TCP/IP 是用于因特网 (Internet) 的通信协议_广泛应用在internet中的tcp/ip的网络管理主要使用的是 ____协议。 (填空题)-程序员宅基地

文章浏览阅读6.7k次。计算机通信协议计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述。什么是 TCP/IP?TCP/IP 是供已连接因特网的计算机进行通信的通信协议。TCP/IP 指传输控制协议/网际协议 (Transmission Control Protocol / Internet Protocol)。TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准..._广泛应用在internet中的tcp/ip的网络管理主要使用的是 ____协议。 (填空题)