openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题
基于openjdk:8u171-alpine构建的java镜像,使用jstack命令打印线程的时候会提示以下错误:
/opt # ps -ef
PID USER TIME COMMAND
1 root 0:28 /usr/lib/jvm/java-1.8-openjdk/bin/java -jar /test/lib/test.jar
66 root 0:00 /bin/sh
70 root 0:00 ps /opt # jstack 1
1: Unable to get pid of LinuxThreads manager thread
使用jmap命令尝试了一下,也是一样的错误。
换了一种启动方式,使用/bin/sh启动docker,然后进入docker手动启动java进程,然后再用jstack命令,就能正常打印。
换了一个centos镜像,手动安装openjdk,在启动docker的时候直接启动java进程,然后进入docker,使用jstack命令,也可以正常打印。
通过这几种尝试,得出的结论是:
使用centos+java镜像,可以正常打印线程堆栈,但是这种方式的缺陷就是镜像太大,大约600M左右;
使用alpine+java镜像,以/bin/sh方式启动docker,然后手动启动java进程,这时java进程的PID不为1,这种方式能够正常打印线程堆栈。这种方式缺点就是java进程如果异常退出了,docker不会检测到,所以无法做自动重启等操作;
使用alpine+java镜像,如果是以直接运行java进程的方式启动docker,也就是说java进程的PID为1,这种方式无法正常打印线程堆栈。
查看了一下github上openjdk官方的问题答复,确实是存在这种情况,并且openjdk的维护成员看上去也无法解决这个问题。
但是有一个曲线解决方法,就是在启动docker的时候先运行一个tini进程,然后通过tini进程去运行java进程。
这种方式java进程的PID不为1,能够打印堆栈,同时如果java进程退出,tini也能检测到,并通知到docker,docker来做相关的处理,完美的解决了这个问题。
参考Dockerfile如下:
FROM openjdk:8u171-alpine
RUN apk add tini
ENTRYPOINT ["tini"]
这里的RUN命令指定在制作镜像的时候通过apk管理工具安装了tini程序。ENTRYPOINT命令指定在运行docker的时候要运行tini程序,具体的java程序作为参数传给tini。
我们有多个java微服务,所以不能把tini装在每个java微服务镜像中,而是装在我们自己的基础镜像中。
具体服务的Dockerfile如下:
FROM java
ADD build/bootScripts /test/bin
ADD build/libs /test/lib
WORKDIR /test
EXPOSE 8080
CMD /test/bin/test
这里的/test/bin/test就是传给tini的实际要执行的启动命令。
参考资料:
https://github.com/docker-library/openjdk/issues/76
https://github.com/krallin/tini/issues/8
openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题的更多相关文章
- 程序中打印当前进程的调用堆栈(backtrace)
为了方便调式程序,产品中需要在程序崩溃或遇到问题时打印出当前的调用堆栈.由于是基于Linux的ARM嵌入式系统,没有足够的空间来存放coredump文件. 实现方法,首先用__builtin_fram ...
- alpine 镜像 java 日志中文问号乱码
0x00 前言 吾使用 alpine 作为基础镜像构建了 jdk8 镜像,为线上业务的 java 微服务架构提供支持,但是有容器运行的 java 服务中打印的日志中一旦出现中文,就会出现诸如以下的 ? ...
- JVM 找出最耗 cpu的线程 并打印线程栈
监控JVM中最占cpu的线程 top -Hp pid JVM中最占cpu的线程ID -o THREAD,tid,time | awk 'BEGIN {count=0; } { if($2>0.3 ...
- sh: /etc/init.d/sshd: not found Docker中的Alpine镜像安装sshd无法启动
问题描述 在Alpine镜像中安装了openssh-server和openssh之后,无法执行ssh localhost.发现未启动服务,开启服务时报以下错误 / # ls /etc/init.d/s ...
- 一个带bash,带glibc,中国时区,非root用户可运行crond命令的基于alpine镜像的Dockerfile
这个镜像现在说起来简单, 带bash(增加执行脚本的兼容性,带GLIBC,中国时区,非root用户可运行crond命令-安全) 但让我开始陷入时,真的让我有段时间有点爆了. 比如,将filebeat文 ...
- 编译一个支持django及mysqlclient连接的alpine镜像
一切都不难,难的就是在alpine镜像里. 最后,使用了网上编译好mysqlclient的镜像,才搞定. 记录一下. 一,基础镜像Dockerfile https://github.com/tnir/ ...
- Docker学习笔记:Alpine镜像+Python3安装+http服务器
编写Dockerfile文件使用最新的Alpine镜像并安装Python3环境,如下: 因为python高于3.4则不会默认安装pip,需要手动安装. 试了很多其他办法都没安装上,唯有下载get-pi ...
- 一个神奇的bug:OOM?优雅终止线程?系统内存占用较高?
摘要:该项目是DAYU平台的数据开发(DLF),数据开发中一个重要的功能就是ETL(数据清洗).ETL由源端到目的端,中间的业务逻辑一般由用户自己编写的SQL模板实现,velocity是其中涉及的一种 ...
- linux信号机制 - 用户堆栈和内核堆栈的变化【转】
转自:http://itindex.net/detail/16418-linux-%E4%BF%A1%E5%8F%B7-%E5%A0%86%E6%A0%88 此文只简单分析发送信号给用户程序后,用户堆 ...
随机推荐
- HDOJ4857【拓扑排序】
首先 CLJ ORZ 这道题做了两次,第一次瞎搞... 第二次,好吧,骄傲地说水过... 题意:不说了: 思路: 题目默认是小的在前面,那么就是反向建图,每次排序拿大的出来: 第一次做的时候,我记得我 ...
- JAVA多线程(一) Thread & Runnable
githut代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service/ ...
- NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925
题目传送门 $Sol$ $50pts$:我们考虑$q==0$的情况,每次在所有的蚯蚓中找到一只长度最大的,这非常二叉堆.所以我们可以用一个优先队列,随便水一下就有50分.($NOIp$的分真这么好拿? ...
- STL<queue>的使用
队列是一种基本的线性数据结构.它满足先进先出(First In ,First Out)的原则. 我们可以应用这种数据结构实现很多复杂的问题.但每次要手写队列的相关函数并不省事,我们便可以应用STL中的 ...
- 轻松搞定JSONP跨域请求【转】,文章非常好!
http://blog.csdn.net/u014607184/article/details/52027879
- Throwing Dice LightOJ - 1064 || (勉强能用的)分数类
Throwing Dice LightOJ - 1064 方法: 设ans[i][j]表示i个骰子点数恰好为j的概率.那么ans[1][1]到ans[1][6]都为1/6. 显然,$ans[i][j] ...
- find missing conjunction, why?
find . -name *.c find: missing conjunction, why? SHELL会把*.c直接扩展成当前工作目录的多个.c文件,所以必须用单引号'*.c'或者/*.c进行转 ...
- SpringCloud开发学习总结(七)—— 声明式服务调用Feign(二)
参数绑定 在上一章的示例中,我们使用Spring Cloud Feign实现的是一个不带参数的REST服务绑定.然而现实系统中的各种业务接口要比它复杂得多,我们有时会在HTTP的各个位置传入各种不同类 ...
- 127 Word Ladder 单词接龙
给出两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列,转换需遵循如下规则: 每次只能改变一个字母. 变换过程中的 ...
- 三色灯渐变DIY制作
小编前几天查资料,怎么使用12864屏幕的用法,突然发觉微博是个好东西,随着自己的成长,学习了很多的知识,没有做笔记的习惯,只是习惯把用到的硬件,传感器,资料写到程序的备注内,但感觉,用到时不是那么方 ...