首页 > 编程语言 >JAVA运维总结篇

JAVA运维总结篇

时间:2024-09-11 21:22:47浏览次数:11  
标签:总结 JAVA 运维 tomcat java 线程 gc 日志 GC

写这篇文章主要目的是完成自己多年来运维JAVA应用的一个总结,相当于个人知识库,以后工作中遇到问题便于临时查阅并不断完善自己的知识体系。

 

JAVA运维总结篇_java


Tomcat是一个开箱即用的软件,配置java环境变量即可把Tomcat进程运行起来,但要投入生产环境,有哪些需要注意的呢?

(1)、性能,默认的Tomcat配置可以正常提供服务,但对于高负载的应用就相当吃力。

调JVM

  • 调整为server模式,默认为client模式,针对生产环境有做优化,启动速度慢,运行速度快(官方说的);
  • 为了减少JVM垃圾回收和重新分配内存的频率可以把Xms和Xmx设置同样的值,从而tomcat提供更多的服务;

JVM有几种垃圾回收算法:【阅读一篇文章:建议开发不要主动去调用System.gc(),这会导致stop-the-world,让JVM自己去解决垃圾回收吧】

  • 垃圾标识算法:引用计数法、根搜索算法;
  • 垃圾收集算法:标记-清除算法,复制算法,标记-整理算法,分代收集算法(Generational Garbage Collection);

垃圾收集器对比与应用场景:


 

进程启动参数选择【可以进入网站自助生成配置:http://jvmmemory.com/

 

  • 总结GC 调优目标基本有三个思路:
  • 降低 GC 频率,可以通过增大堆空间,减少不必要对象生成;
  • 降低 GC 暂停时间,可以通过减少堆空间,使用 CMS GC 算法实现;
  • 避免 Full GC,调整 CMS 触发比例,避免 Promotion Failure 和 Concurrent mode failure(老年代分配更多空间,增加 GC 线程数加快回收速度),减少大对象生成等。

配置连接器(有三种连接器供选择)

  • BIO全称blocking I/O,配置参数
    protocol=”HTTP/1.1”
  • NIO全称Non-blocking I/O,配置
    protocol=”org.apache.coyote.http11.Http11NioProtocol”
  • APR全称Apache Portable Runtime,配置
    protocol=”org.apache.coyote.http11.Http11AprProtocol”

 

(2)、性能监控

推荐使用JavaMelody 能够监测Java或Java EE应用程序服务器,并以图表的方式显示:Java内存和Java CPU使用情况,用户Session数量,JDBC连接数, 和http请求、sql请求、jsp页面与业务接口方法(EJB3、Spring、 Guice)的执行数量,平均执行时间,错误百分比等。图表可以按天,周,月,年或自定义时间段查看。

<filter>  
             <filter-name>monitoring</filter-name>  
                <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>  
        </filter>  
        <filter-mapping>  
                <filter-name>monitoring</filter-name>  
                <url-pattern>/*</url-pattern>  
        </filter-mapping>  
        <listener>  
                <listener-class>net.bull.javamelody.SessionListener</listener-class>  
        </listener>

重启Tomcat应用,访问地址:

http://host/context/monitoring

 

(3)、高可用
  • Tomcat的高可用官方目前是3种方案:

    • Session持久化并把session保存在共享存储;
    • Session持久化并把session保存的共享数据库(JDBC连接);
    • 通过SimpleTcpCluster ,每个tomcat节点都保存所有tomcat节点的数据,这个也是集群模式的基础;
    • 另外,第三方有支持redis共享session从而实现高可用,比较推荐,但是模块稳定性可能需要考虑下。
  • 官方给的集群方案。


     

  • 高可用涉及面比较广,需要根据自己业务情况设计对应的方案,推荐两个链接可以详细研究:
    https://tomcat.apache.org/tomcat-8.0-doc/cluster-howto.html
    https://segmentfault.com/a/1190000009591087

  • (4)、安全
    1. 移除容器版本信息,很容易根据容器版本号找到对应的漏掉做针对性的;
      修改文件server.xml,如下
    <Connector port="8080" protocol="HTTP/1.1"  cnotallow="20000" Server =" "
    redirectPort="8443" />
  • 安全启动进程,试想有人在请求中加<% System.exit(1); %>,后果是很严重的。
    官方建议tomcat正确启动姿势,
    ./startup.sh -security
    参考链接:https://tomcat.apache.org/tomcat-6.0-doc/security-manager-howto.html

  • 推荐使用HTTPS协议,如果tomcat直接对外访问就加一个HTTPS吧,如果前端有负载均衡器,负载均衡器使用HTTPS,tomcat放在一个安全的内网使用http也可;

  • 为Cookie设置HttpOnly属性


     

  • 推荐tomcat启动使用单独的普通用户,避后导致整个服务器沦陷;

  • 在部署生产环境时,去除tomcat默认的应用和页面,避免存在安全风险,删除$tomcat/webapps目录下所有文件即可;

  • 改变Tomcat的shutdown端口和命令,假如默认的8005端口对外网访问,可以直接通过远程将运行的tomcat关闭,很危险,建议修改server.xml
    <Server port="8867" shutdown="NOTGONNAGUESS">

  • 替换默认的404,403,500页面,和避免异常报错暴露在页面
    在web.xml文件下添加到</web-app>之前

  • <error-page>
       <error-code>404</error-code>
       <location>/error.jsp</location>
    </error-page>
    <error-page>
       <error-code>403</error-code>
       <location>/error.jsp</location>
    </error-page>
    <error-page>
       <error-code>500</error-code>
       <location>/error.jsp</location>
    </error-page>
    <error-page>
       <exception-type>java.lang.Exception</exception-type>
       <location>/error.jsp</location>
    </error-page>
    (5)、线程dump

    当我们的java应用比我们预期的要慢的时候,我们就需要用到thread dumps,然后分析它们并知道他们的瓶颈或阻塞的线程等信息,然后针对性的优化从而提示整个系统的性能。

    1. 首先我们了解2个概念;

      • Thread contention(线程竞争):线程竞争是一个状态,等待锁被释放,这个锁正好被其他线程占用。在web网站中,不同的线程频繁的访问共享资源。比如记录日志,线程要记录日志必须要获得锁然后才能记录日志。
      • Deadlock(死锁):死锁是一种特殊的线程竞争,2个或者更多的线程为了完成自己的任务必须等待其他线程完成他们的任务。比较典型案例,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。
    2. 了解java线程背景信息

      • 线程同步:
        为了解决同时访问资源,一个线程需要在访问共享资源时使用线程同步。Java中使用monitor作为线程同步,每个对象都有一个monitor,一个monitor只能被一个线程拥有。假如其他线程获得这个monitor需要进入等待队列,等待释放;

      • 线程状态:

        • NEW:线程刚刚启动还没有开始处理任务;
        • RUNNABLE:线程正在占用CPU并且处理任务;
        • BLOCKED:线程是阻塞的,等待获取monitor,一般是等待共享对象、资源;
        • WAITING:线程无限时间等待另外一个线程,为了执行特定的任务;
        • TIMED_WAITING:线程有限时间等待另外一个线程,为了执行特定的任务;
        • TERMINATED:线程已经结束生命;
      • 线程类型:

        • daemon thread:守护线程,
        • non-daemon threads:非守护线程
    3. 获取Java堆栈

    jps -v #获取java进程PID
    jstack -F 31336 > dump.log #强制dump出线程堆栈(不同版本,获取方式不一样)

    【注】:线程堆栈是某一时刻的堆栈快照,为了分析线程状态改变,需要提取5-10次,每5秒dump一次。

    (6)、JVM dump

    Head dump是JVM某个时刻的内存快照,可以帮助我们分析内存泄露和分析java应用的内存使用情况。Heap dump通常市存储2进程hprof文件,我们打开和分析需要用jhat 或者JVisualVM等其他工具。

    (7)、GC日志

    GC叫做垃圾收集,正常的垃圾回收是对整个JVM健康起着重要作用,如果回收不及时,会导致GC频繁,GC时间过长,严重情况可能导致OOM,严重影响业务正常。下面介绍怎么开启gc日志,命令行查看gc,常用gc的含义。

    • 开启gc日志
    -XX:+PrintGCDetails -Xloggc:/opt/tmp/myapp-gc.log         #这个支持java 8
    -Xlog:gc*:file=/opt/tmp/myapp-gc.log                                  #这个支持java 9

    gclog-analysis

    有下面的参数适合于java 8可以选择性开启:

    -XX:+DisableExplicitGC                             #开发想自己调用垃圾回收,在生产环境中不建议开发调用:System.gc() or Runtime.getRuntime().gc()
    -XX:+PrintGCDetails                                 #默认是禁用的,可以打印更加详细的垃圾回收信息
    -XX:+PrintGCApplicationStoppedTime     #默认是禁用的,这个选项代表在GC过程中,应用pause时间
    -XX:+PrintGCApplicationConcurrentTime #默认是禁用的,这个选项代表在GC过程中,应用running时间
    -XX:+PrintGCDateStamps                         #打印每个gc的日期和时间
    -Xloggc:gclog.log                                       #gclog.log是gc日志的具体路径,所有gc日志记录在这个文件
    -XX:+UseGCLogFileRotation                    #假如gc日志达到指定的大小,会开启自动轮换
    -XX:NumberOfGCLogFiles=5                   #默认是1,轮换日志的数目
    -XX:GCLogFileSize=2000k                      #指定gc日志的大小,当达到这个大小后会轮换一次
    • 命令行开启gc
    jps -v #获取java进程PID
    jstat –gc  PID 1000      #PID是jvm的进程号

    输出内容解释:
    S0C #显示当前Survivor 0区的大小
    S1C #显示当前Survivor 1区的大小
    S0U #显示当前使用Survivor 0区的大小
    S1U #显示当前使用Survivor 1区的大小
    EC #显示E区的大小
    EU #显示已使用E区的大小
    OC #显示old区的大小
    OU #显示已经使用的old区
    PC #显示permanent区的大小
    PU #显示已经使用的permanent区大小
    YGC #young区发生gc的次数
    YGCT #在young区累计的时间
    FGC #full gc发生的次数
    FGCT #full gc累计占有时间
    GCT #gc累计消耗时间





    标签:总结,JAVA,运维,tomcat,java,线程,gc,日志,GC
    From: https://blog.51cto.com/u_15854462/11983948

    相关文章

    • Java:类和对象(2)
      一对象的构建和初始化1.对象构建(ObjectConstruction)Studentstudent1=newStudent("zhangsan",12,"123456");Studentstudent2=newStudent("lisi",10,"15236");2.构造函数(Constructor)构造函数的特性:名字与类名相同。没有返回类型。可以重载(多个构造函数可以具有不......
    • Java——多态
      什么是多态:        多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。可能不太懂是什么意思,那首先来简单实现一个:(看效果!!)     classAnamals{Stringname;Stringcolor;public......
    • Day07.Java方法
      Java方法方法的定义和调用Java方法是语句的集合,它们在一起执行一个功能方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的......
    • 22年国内最牛的Java面试八股文合集,不接受反驳
      又是一年金三银四面试季!纵观今年的技术招聘市场, Java依旧是当仁不让的霸主 !即便遭受Go等新兴语言不断冲击,依旧岿然不动。究其原因:Java有着极其成熟的生态,这个不用我多说;Java在运维、可观测性、可监控性方面都有着非常优秀的表现;Java也在积极应对容器化、云原生......
    • Java方法
      方法类似其它语言的函数形参:定义实参:实际调用传递的参数方法的重载重载就是在一个类中,有相同的函数名称,但是形参不同的函数可变参数/不定向参数packagemethod;publicclassDemo02{publicstaticvoidmain(String[]args){Demo02demo02=newDemo02......
    • Java数据库轮询
      在Java中,数据库轮询(DatabasePolling)通常指的是定期查询数据库以检查是否有新的数据或者数据状态的变化。这种方式在某些场景下是有用的,比如在需要实时监控数据库变化的应用中。不过,轮询并不是一种高效的解决方案,因为它可能会导致不必要的资源消耗,特别是在没有变化发生的时候。以......
    • 力扣49 字母异位词分组 Java版本
      文章目录题目描述题解注意事项题目描述给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。字母异位词是由重新排列源单词的所有字母得到的一个新单词。示例1:输入:strs=[“eat”,“tea”,“tan”,“ate”,“nat”,“bat”......
    • 20240911 模拟赛总结
      期望得分:100+0+30=130实际得分:100+20+30=150T1感觉没有大样例也还是可以猜到那么一点的结论。k=0无解。当k≠0时,考虑交换不含1的两项,一定能使这两个位置都符合gcd(i,ai)=1,如果最后长度为奇数剩一个位置出来怎么办?那就O(n)枚举一遍找到可行的位置和它换一下即可,易......
    • java计算机毕业设计民宿出租管理系统(开题+程序+论文)
      本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景:随着旅游业的蓬勃发展和人们对个性化旅行体验的追求,民宿作为一种新兴的住宿方式,在全球范围内迅速崛起。它以其独特的文化氛围、灵活的租赁方式及亲民......
    • Java中数学类的学习
      数学类目录数学类Math类math的floor,round和ceil方法实例比较Math类Java的Math包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。Math的方法都被定义为static形式,通过Math类可以在主函数中直接调用。publicclassTest{publicst......