Pepper Metrics是我與同事開發的一個開源工具(github.com/zrbcool/pep…),其經過收集jedis/mybatis/httpservlet/dubbo/motan的運行性能統計,並暴露成prometheus等主流時序數據庫兼容數據,經過grafana展現趨勢。其插件化的架構也很是方便使用者擴展並集成其餘開源組件。
請你們給個star,同時歡迎你們成爲開發者提交PR一塊兒完善項目。html
容器化後,在應用發佈時,某個服務重啓,致使該服務調用方大量報錯,直到服務重啓完成。報錯的內容是RPC調用失敗,咱們的RPC這塊是有優雅關閉的,也就是說,在進程收到SIGTERM信號後,咱們經過JVM的ShutdownHook機制,註冊了RPC服務的反註冊鉤子,在進程收到SIGTERM時應用會主動從註冊中心摘除自身防止調用方大量報錯。可是爲何容器化後會致使這個問題呢?java
應用正常啓動 git
查看容器內進程# yum install psmisc
# pstree -p
bash(1)───java(22)─┬─{java}(23)
├─{java}(24)
├─{java}(25)
├─{java}(26)
├─{java}(27)
├─{java}(28)
├─{java}(29)
├─{java}(30)
...
# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:50 ? 00:00:00 /bin/bash run.sh start
root 22 1 15 09:50 ? 00:01:20 /app/3rd/jdk/default/bin/java -Xmx512m -Xms512m ...
root 49 0 0 09:51 pts/0 00:00:00 bash
root 263 49 0 09:59 pts/0 00:00:00 ps -ef
複製代碼
在容器內正常kill 22子進程,可見咱們應用的shutdown鉤子能夠正確處理善後工做 github
可是,在實際生產中,咱們的deploy滾動更新時,經過查看被刪除pod的日誌,發現pod被terminate的時候,應用進程並未正確處理SIGTERM信號,問題產生。根據對Kubernetes機制的調研,如圖: kubernetes.io/docs/concep… docker
由於咱們的容器是經過run.sh腳本啓動,這個在前面截圖能夠看到,java進程是1號run.sh進程的子進程,對應Kubernetes原理,可知22號java進程在POD刪除時不必定會收到SIGTERM,因此致使了咱們的shutdown hook不生效。既然已經定位問題,那麼解決問題的方法就有了思路,run.sh執行java進程後,將進程上下文讓給java進程,java進程接管,java進程變爲容器內的1號進程。 咱們參考了這篇文章受到啓發 yeasy.gitbooks.io/docker_prac… 在run.sh執行java前面增長exec命令便可 數據庫
而後,從新build鏡像,發佈,查看進程,發現咱們的java進程已是1號進程 而後重啓,再查看重啓前POD留下的日誌 問題解決!