目录
- 前言
- 现象
- 分析原因
- 解决方法
- 思考感悟
前言
jvm启动参数应该非常熟悉了,但是最近在测试环境想要远程debug的时候发现怎么也连不上,接下来记录一下整个排查过程
现象
版本(抛开版本就是耍流氓~)
jdk8
远程debug参数添加之后一直没有生效, 报如图1所示的错误。环境为k8s的service部署模式
图一:
分析原因
首先,因为环境是k8s的service模式部署的,所以刚开始我查看了我的debug端口是否打开了8999,发现是kubeProxy监听的所有主机。
tips:其实这里给大家一个提示,如果端口没有被监听,我们的客户端报的应该是connect timeout,所以如果是拒绝链接,那么可以肯定的是一定有进程监听你访问的端口
其次,查看自己的pod容器是否成功的进行了端口映射,命令 kubeclt describe pod <PodName>
在容器的地方我们发现了三个tcp协议的端口映射,其中8999是我的debug端口,到这里基本上可以排除端口映射的问题了。
tips:后面会写一篇yaml文件配置端口映射的文章,这里不解释如何进行端口映射的方法了,这里给大家解释一下过程,首先远程机器连接到宿主机(k8s中称为node)的8999端口,被kube-proxy进程监听到,然后通过映射将报文发送给对应的pod(该pod是一个独立的网络栈,详情搜pause)的8999端口,pod再通过映射将报文发送给其下的docker容器(docker也是一个独立的网络栈)的8999端口,而监听docker端口的才是我们的程序。然后,接下来思路定位才定位到自己的程序是否出现问题,其实刚开始docker中没有netstat命令导致我没办法查看是否我的程序在监听端口,我其实很早就怀疑自己的程序了,但是没有完全怀疑,然后一直找办法判断是否自己的程序能够监听8999端口,最后,我找到curl可以在docker中使用,所以看了看help发现可以当telnet使用!于是使用了 curl -v <ip>:<port>
tips:尝试了几个没有监听的端口发现,curl中没有被监听的端口是会被拒绝的,而监听的端口不会拒绝,会是其他信息,比如
到这里基本就判定自己的程序有问题,然后,通过苦苦搜索才发现,原来有一个惊天大秘密,自己从来没有注意过的。。。
java命令语法:
我们注意到 其实下面的options全都应该放在 -jar 的前面才能生效,如此问题解决。。。
包括help中的所有options都适用
解决方法
将所有options都放到-jar前面才会生效
思考感悟
其实这个问题我问过之前一起工作过的前同事,因为之前一起开发成熟的项目,所以开发流水线化导致我们都没有注意过这种问题,后来我问过他发现他也不知道,但是配置确实是在前面,他也不知道为什么在前面。。。。作为初学者的我们,其实这些细节和坑确实需要我们自己去踩过才能知道为什么。而这种排查问题的经验恰恰是书本给不了我们的宝贵财产。