默认情况下,我们使用的都是 jre 版本的 openjdk,当容器启动卡住不动的时候,看不出来任何问题。

此时如果能 dump 就能知道线程在干啥,也能找到一些大概的问题。

此时 jre 版本的镜像就不够用了。

切换 jre 为 jdk 版本

只切换为 jdk 还不够,还会遇到 Unable to get pid of LinuxThreads manager thread 的错误。

创建可以 dump 用的基础镜像

参考前面文章,创建如下镜像:

FROM openjdk:8u191-jdk-alpine3.9
RUN apk add --no-cache tini
ENTRYPOINT ["tini"]

修改项目使用的镜像和启动方式

假设上面创建的镜像名为 openjdk:8u191-jdk-alpine3.9-tini

FROM openjdk:8u191-jdk-alpine3.9-tini
COPY app.jar /opt/dubbo-app/app.jar
WORKDIR /opt/dubbo-app
EXPOSE 20880
ENTRYPOINT ["/sbin/tini", "--", "java", "-jar", "app.jar"]

启动镜像后进入容器

  1. jps 查看 pid
  2. jstack -l pid 查看线程信息

关于此次 BUG

经过查看堆栈和代码,发现是 Dubbo 连接 zookeeper 时,用了 CountDownLatch ,由于通过环境变量配置的 ZOOKEEPER 地址中,环境变量名竟然配错了,导致 zookeeper 一直连接不上,因此锁死了主线程。

实际上这里没有添加 timeout 也是 Dubbo 2.7.1 的一大 BUG。

dubbo 2.7.1 有很多严重 BUG,而且修复和发布的周期特别的长,一定要慎用。

主线程堆栈信息:

"main" #1 prio=5 os_prio=0 tid=0x00005592eb0f1000 nid=0x9 waiting on condition [0x00007fda15afd000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f885dac0> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration.<init>(ZookeeperDynamicConfiguration.java:64)
at org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory.createDynamicConfiguration(ZookeeperDynamicConfigurationFactory.java:38)
at org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory.getDynamicConfiguration(AbstractDynamicConfigurationFactory.java:33)
- locked <0x00000000f885db68> (a org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory)
at org.apache.dubbo.config.AbstractInterfaceConfig.getDynamicConfiguration(AbstractInterfaceConfig.java:275)
at org.apache.dubbo.config.AbstractInterfaceConfig.prepareEnvironment(AbstractInterfaceConfig.java:250)
at org.apache.dubbo.config.AbstractInterfaceConfig.startConfigCenter(AbstractInterfaceConfig.java:240)
at org.apache.dubbo.config.AbstractInterfaceConfig.lambda$null$7(AbstractInterfaceConfig.java:584)
at org.apache.dubbo.config.AbstractInterfaceConfig$$Lambda$218/1961945640.get(Unknown Source)
at java.util.Optional.orElseGet(Optional.java:267)

对应代码截图如下:

获取资料

本次给大家推荐一个免费的学习群,里面概括Java架构/分布式/微服务/docker/高性能高并发以及面试资源等。
对Java架构感兴趣的程序猿,欢迎加入Q群:790047143,不管你是刚入行得还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
最后,祝大家早日学有所成。

Docker 镜像,dump openjdk-alpine 镜像容器中的 jvm的更多相关文章

  1. Docker学习笔记:Alpine镜像+Python3安装+http服务器

    编写Dockerfile文件使用最新的Alpine镜像并安装Python3环境,如下: 因为python高于3.4则不会默认安装pip,需要手动安装. 试了很多其他办法都没安装上,唯有下载get-pi ...

  2. 【原创】大叔经验分享(71)docker容器中使用jvm工具

    java应用中经常需要用到jvm工具来进行一些操作,如果java应用部署在docker容器中,如何使用jvm工具? 首先要看使用的docker镜像, 比如常用的openjdk镜像分为jdk和jre,只 ...

  3. 将Docker主机数据挂在到容器中

    dcoker 提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts, tmpfs.volumes: Docker管理宿主机文件系统的一部分(/var/lib/docke ...

  4. docker挂载war包到tomcat容器中的注意点和坑

    刚开始用docker,难免会遇到很多坑,这里分享一下: 一 挂载最好挂载目录 我刚开始挂载war包,结果发现容器里把挂载的war包当成目录了 二 本地路径必须是绝对路径,否则不管用 三 容器中使用vi ...

  5. 容器中的JVM资源该如何被安全的限制?

    前言 Java与Docker的结合,虽然更好的解决了application的封装问题.但也存在着不兼容,比如Java并不能自动的发现Docker设置的内存限制,CPU限制. 这将导致JVM不能稳定服务 ...

  6. 创建新镜像-从已创建的容器中更新镜像并提交镜像(以Nginx为例)

    目标:现在我们主要是修改nginx的index.html,然后做一个新镜像 1.基于nginx:1.12运行一个容器 docker run -d -p 8080:80 --name nginx ngi ...

  7. Dockerfile 自动制作 Docker 镜像(三)—— 镜像的分层与 Dockerfile 的优化

    Dockerfile 自动制作 Docker 镜像(三)-- 镜像的分层与 Dockerfile 的优化 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 CentOS 7.0 云 ...

  8. 在 Docker 容器中运行应用程序

    案例说明 运行 3 个容器,实现对网站的监控. 三个容器的说明: 容器 web: 创建自 nginx 映像,使用 80 端口,运行于后台,实现 web 服务. 容器 mailer: 该容器中运行一个 ...

  9. 无需安装 vsftpd , 直接使用 FTP 来管理 docker 容器中的文件

    无图无真相,先放个效果图:     背景 使用 docker 来跑一些服务很方便,但是有的时候想管理容器里面的文件却很麻烦 -- 一般常规做法有3种: 通过数据卷或数据卷容器的方式 启动容器的时候时候 ...

随机推荐

  1. flask实战-个人博客-表单

    表单 下面我们来编写所有表单类,personalBlog中主要包含下面这些表单: 登录表单: 文章表单: 评论表单: 博客设置表单: 这里仅介绍登录表单.文章表单.分类表单和评论表单,其他的表单在实现 ...

  2. views视图

    1.request.POST.get('.......')    --radio       单选框 get()方法  从HTML中提取发过来的数据 1. 2. 3. 4. 2.request.POS ...

  3. JavaScript的深克隆与浅克隆

    JS数据类型分为两类: 基本类型(Number.Boolean.Undefined.Null.String.Symbol(ES6新加,此处不讨论))与引用类型(Object).原始类型存储的是对象的实 ...

  4. 写入Txt文本信息

    public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { L ...

  5. Io 异常: Invalid number format for port number

    报错信息: Caused by: java.sql.SQLException: Io 异常: Invalid number format for port number    at oracle.jd ...

  6. javascript中 encodeURIComponent() 与 encodeURI() 的区别

    前言:js 中仅有的几个全局函数中,有两个全局函数可以用来编码url 字符串. 一.encodeURIComponent() 将转义用于分隔 URI 各个部分的标点符号 ,也就是可以编码 " ...

  7. js如何遍历map类型

    1.forEach遍历: map.forEach(function(value,key){ console.log(value,key); }); 函数中第一个参数是属性值,第二个参数是属性 2.fo ...

  8. 简要说明盒子模型和flex布局

    盒子模型:可以看做是一个盒子,包括外边距.边框.内边距.实际内容. flex布局:弹性布局,灵活性好. 当给元素设置display:flex时,它就是flex容器,它的所有子元素自动成为容器成员,称为 ...

  9. 【luoguP1533】可怜的狗狗

    题目链接 发现区间按左端点排序后右端点也是单调的,所以扫一遍就行了,用权值线段树维护第\(k\)大 #include<algorithm> #include<iostream> ...

  10. Math的round方法

    代码如下,后面的注释是输出的结果 public static void main(String[] args) { System.out.println(Math.round(0.399)); Sys ...