JAVA運維總結篇

寫這篇文章主要目的是完成本身多年來運維JAVA應用的一個總結,至關於我的知識庫,之後工做中遇到問題便於臨時查閱並不斷完善本身的知識體系。

 
 

上圖,就知道Tomcat在JAVA容器界是多麼重要。html

Tomcat是一個開箱即用的軟件,配置java環境變量便可把Tomcat進程運行起來,但要投入生產環境,有哪些須要注意的呢?前端

(1)、性能,默認的Tomcat配置能夠正常提供服務,但對於高負載的應用就至關吃力。

  1. 調JVMjava

    • 調整爲server模式,默認爲client模式,針對生產環境有作優化,啓動速度慢,運行速度快(官方說的);
    • 爲了減小JVM垃圾回收和從新分配內存的頻率能夠把Xms和Xmx設置一樣的值,從而tomcat提供更多的服務;
    • JVM有幾種垃圾回收算法:【閱讀一篇文章:建議開發不要主動去調用System.gc(),這會致使stop-the-world,讓JVM本身去解決垃圾回收吧】
      • 垃圾標識算法:引用計數法、根搜索算法;
      • 垃圾收集算法:標記-清除算法,複製算法,標記-整理算法,分代收集算法(Generational Garbage Collection);
      • 垃圾收集器對比與應用場景:web


         
         
    • 進程啓動參數選擇【能夠進入網站自助生成配置:http://jvmmemory.com/
       
       
    • 總結GC 調優目標基本有三個思路:
      • 下降 GC 頻率,能夠經過增大堆空間,減小沒必要要對象生成;
      • 下降 GC 暫停時間,能夠經過減小堆空間,使用 CMS GC 算法實現;
      • 避免 Full GC,調整 CMS 觸發比例,避免 Promotion Failure 和 Concurrent mode failure(老年代分配更多空間,增長 GC 線程數加快回收速度),減小大對象生成等。
  2. 配置鏈接器(有三種鏈接器供選擇)redis

    • 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」
    • 下面是三者之間對比:算法


       
       
    • 配置模版:sql


       
       

(2)、性能監控

推薦使用JavaMelody 可以監測Java或Java EE應用程序服務器,並以圖表的方式顯示:Java內存和Java CPU使用狀況,用戶Session數量,JDBC鏈接數, 和http請求、sql請求、jsp頁面與業務接口方法(EJB三、Spring、 Guice)的執行數量,平均執行時間,錯誤百分比等。圖表能夠按天,周,月,年或自定義時間段查看。數據庫

  1. 下載地址:
    https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/javamelody/javamelody-1.48.0.jar apache

  2. 配置web.xml:segmentfault

<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> 
  1. 重啓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" connectionTimeout="20000" Server =" " redirectPort="8443" /> 
  1. 安全啓動進程,試想有人在請求中加<% System.exit(1); %>,後果是很嚴重的。
    官方建議tomcat正確啓動姿式,
    ./startup.sh -security
    參考連接:https://tomcat.apache.org/tomcat-6.0-doc/security-manager-howto.html

  2. 推薦使用HTTPS協議,若是tomcat直接對外訪問就加一個HTTPS吧,若是前端有負載均衡器,負載均衡器使用HTTPS,tomcat放在一個安全的內網使用http也可;

  3. 爲Cookie設置HttpOnly屬性


     
     
  4. 推薦tomcat啓動使用單獨的普通用戶,避免黑客攻擊後致使整個服務器淪陷;

  5. 在部署生產環境時,去除tomcat默認的應用和頁面,避免存在安全風險,刪除$tomcat/webapps目錄下全部文件便可;

  6. 改變Tomcat的shutdown端口和命令,假如默認的8005端口對外網訪問,能夠直接經過遠程將運行的tomcat關閉,很危險,建議修改server.xml
    <Server port="8867" shutdown="NOTGONNAGUESS">

  7. 替換默認的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一次。

  1. 具體的線程分析內容比較多,能夠參考下面連接:
    https://dzone.com/articles/how-analyze-java-thread-dumps
    https://dzone.com/articles/how-to-read-a-thread-dump

(6)、JVM dump

Head dump是JVM某個時刻的內存快照,能夠幫助咱們分析內存泄露和分析java應用的內存使用狀況。Heap dump一般市存儲2進程hprof文件,咱們打開和分析須要用jhat 或者JVisualVM等其餘工具。

  1. 獲取Heap dump
    jmap -F -dump:live,format=b,file=/tmp/dump.hprof 12587 #dump時間比較長
  2. 查看heap dump 【不建議在生產環境分析,建議在本地找一臺內存大的機器啓動】
    jhat /tmp/dump.hprof 12587
  3. 訪問:http://ip:7000/
  4. 具體分析內容比較多,給兩個連接詳細研究。
    https://www.baeldung.com/java-heap-dump-capture
    https://www.javatang.com/archives/2017/10/30/53562102.html

(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累計消耗時間

詳細的能夠見下面:
https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html

(8)、java實用命令【java命令集很強大】

  • java:啓動java應用,引導main()方法;
  • jps:主要是列出目標機器上運行的JVM;
  • jstat:列出JVM性能統計數據;
  • jstack:打印指定進程的java堆棧信息;
  • jcmd:發送一些診斷命令給運行的JVM;
  • jmap: 打印指定進程、核心文件或遠程調試服務器的共享對象內存映射或堆內存細節。
  • jhat:命令行工具解析Heap dump文件並啓動一個web服務;
  • jdb:針對java class,簡單的命令行debug工具;
  • jinfo:打印指定java進程的配置信息;
  • keytool:是一個密鑰和證書的管理工具,java使用https須要用到;
  • jar:主要是給java應用的打包和解壓工具;
  • javac:將java源碼編譯爲二進制class文件;
  • jconsole:開啓一個圖形界面,讓你監控和管理java應用;
  • jvisualvm:很好的heap dump分析工具;

做者:連接:https://www.jianshu.com/p/355ee06c3d2b

相關文章
相關標籤/搜索