远程调试jar
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xmx8G -Xms8G -server -Dserver.port=8899 -Djava.security.egd=file:/dev/./urandom -XX:+UseG1GC -XX:MaxGCPauseMillis=30 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true -Dspring.profiles.active=test -Dfile.encoding=utf-8 -jar xxx.jar
idea实现远程调试
1.项目开启远程调试
在-jar 后面配置 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8327 (8327是远程调试的端口号,注意不要和项目端口号冲突)
nohup java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8327 newsell-0.0.1-SNAPSHOT.jar >/dev/null 2>&1 &
注意,在服务器上开放自己的调试端口
2.配置idea
3.开启设置
现在在上一步选择”Edit Configurations…”的下拉框的位置选择上一步创建的newsell-debugging,然后点击右边的debug按钮(长的像臭虫那个),看控制台日志,如果出现类似“Connected to the target VM, address: ‘xx.xx.xx.xx:5555’, transport: ‘socket’”的字样,就表示连接成功过了。我这里实际显示的内容如下:
Connected to the target VM, address: '10.185.0.192:15555', transport: 'socket'
假如出现Connecteing,那基本上凉凉送你,再检查一下自己的配置,项目的发布是否开启了远程调试,服务器的调试端口是否开放,以及自己的本地代码和远程代码是否一致
一、背景
在日常系统开发中,常常需要将程序部署到指定内部网络环境下,维护人员会通过堡垒机(跳板机)来访问内网的系统。此景下,当系统需要联机DEBUG时会受堡垒机的影响。不过依靠ssh的隧道功能,可以很方便的避开此问题。
二、实操
假设网络拓扑环境如下:
1、在服务器A上开启远程调试端口
假设我们在服务器A上可通过如下命令开启程序调试端口:
-
java -Xms2457m -Xmx2457m -Xmn921m -server \
-
-Dsun.net.inetaddr.ttl=60 \
-
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=29776 \
-
-jar /usr/lib/demo/demo-server-1.0.0-SNAPSHOT.jar
2、在堡垒机X上通过ssh在本地开启29776端口并映射到服务器A的29776端口上
在堡垒机器X上使用如下命令开启本地到服务器A的29776端口映射:
ssh -fCNg -L 29776:172.26.5.40:29776 root@172.26.5.40
对于ssh各个参数的说明大致如下:
-L <local-port>:<remote-host>:<remote-port> : 本地端口与远程主机端口的映射配置
-f : 请求 ssh 在执行命令之前转到后台
-C : 请求压缩所有数据(包括 stdin、stdout、stderr 和用于转发的 X11、TCP 和 UNIX 域连接的数据)
-N : 不执行远程命令。此选项用于只需要端口转发功能时
-g: 允许远程主机连接到本地转发端口。如果用于多路复用连接,则必须在主进程上指定此选项
详细参数可参考:利用SSH隧道技术穿越内网访问远程设备
3、使用IDEA启动到堡垒机的DEBUG操作
(1)点击 + 号找到 Remote JVM Debug
(2) 添加一个Remote JVM Debug
(3)配置堡垒机X的IP地址和做了映射的29776端口;
至此,就完成了远程DEBUG的相关配置,打上断点,启动debug程序吧。
前言
断点调试
对IT从业者不是一个陌生的概念,我认为它是每个
程序猿(媛)从业者都避不开的
且非常重要的技能之一。
那它到底有多重要呢?为了体现本文的重要性,我引用几个大佬的话来表述断点调试
的重要性:
神秘大佬A
:调试技巧比编码技巧更为重要,因为花费在调试上的时间往往比编码还多,学到的东西比编码中学到的更丰富神秘大佬B
:调试技能重要性甚⾄超过学习⼀门语⾔神秘大佬C
:不会调试的程序员,肯定编制不出任何好的软件
大佬都这么认为了,so我们需要有一个共识:调试能力是一个程序员最最最基础的技能。本文主要发力讲述调试的相关技能、技巧,希望对你的职业生涯能有所帮助。
说明:本文讲解是基于IntelliJ IDEA
而非eclipse
,因此我们从它的断点对话框开始:
弹出此对话框默认快捷键是:Ctrl + Shift +F8
,在这里你可以管理
你所有的断点(增删改)。
鼠标方式可以这样开启:Action-view breakpoints / 菜单run-view breakpoints
断点的基本概念
断点你可能天天都在使用,但是若真要你对它下定义,估计一时间还有点懵逼呢有木有?
断点
:是一种附加在源代码上面的特殊标记,在调试模式(debug模式)
下可以触发特定的动作
,比如打印线程调用栈信息、计算值、打印指定表达式的值等等。Tips:断点一但设置就会一直保存在工程中直到手动删除~
断点若想生效,必须是调试模式(debug模式)下才行~
断点参数(断点属性)
断点并不是仅仅是孤立的存在的,它也可以通过参数
进行定制化,这些叫断点参数
。
不同类型的断点支持的断点参数也不尽相同,在下面具体介绍时会详细说明~
开胃小菜:比如最常用的
条件断点
,它就是断点参数的一个典型应用
断点的种类
据我粗略调查,80%
的小伙伴打断点只会采用代码行左边鼠标单击这种最基础的方式打断点然后调试。其实在现实场景中,有非常非常多的情况下,这种方式将很难快速定位
到问题所在,因此了解断点分类、调试技巧就显得有点必须了~
殊不知,IDEA
给我们提供了丰富的断点类型,让我们能够在不同的调试场景下,使用不同的断点类型来大大提高我们的调试效率,毕竟效率就是时间
,而时间就是生命
。
从idea断点对话框里也能够看出断点是分类的。然后下面我对断点的分类讲解不是完全按此分类,我的分类会更加详细如下:
Line breakpoint(行断点)
:在指定代码行设置断点,属于行级别的断点Temporary line breakpoint(临时行断点)
:与行断点类似,不同之处在于该类型的断点在被激活之后会被立即删除Field watchpoint(属性断点)
:读取
或者修改
属性时会激活属性断点Method breakpoint(方法断点)
:它是标记在方法那一行的断点,有自己特有的属性参数Exception breakpoint(异常断点)
:当程序抛出指定异常时会激活异常断点。与行断点不同,异常断点不需要与源代码映射(不需要打在具体某一行代码上),因为异常断点应用程序级别的
Line breakpoint(行断点)
这是使用得最为广泛的一种断点。示例操作“视频“:
断点参数
作为第一个介绍的断点类型,这里有必要全面的解释一下上面行断点操作的断点参数:
Suspend
:有没有让你诧异到,它竟然是个复选框并且还可以不被选中。若它不被选中的话断点的相关动作依然激活执行,只是线程不会被组塞了而已。它的两种阻塞策略如下:
-All
:阻塞该程序内所有线程(默认)
-Thread
:只阻塞当前断点所在线程(在多线程调试、远程调试中强烈建议使用这种方式)Condition
:这就是所谓的条件断点,只有书写的表达式返回true时候断点才会被激活Log
:
- 勾选"Breakpoint hit message":断点激活时输出提示日志
- 勾选"Stack trace":断点激活时输出程序调用栈信息
- 勾选"Evaluate and log":并在下面的输入框中输入"args",断点激活时会计算并输出变量 args 的值
-他哥三是可以同时被勾选的(因为都是复选框~)
这里其实已经把绝大多数共用的断点参数都讲述了,这样下面就会稍微简单点了~~
Temporary line breakpoint(临时行断点)
创建方法不说了,同上。和上面的唯一区别是:把Remove once hit
这个复选框给勾选上(此类型断点其实使用较少)。
Field watchpoint(属性断点)
创建的方式和上无差异。
断点参数
由于绝大多数参数第一个已经讲述了,so这里只剩一个它独有的参数:
Watch
:选中"Filed Access" 读取的时候都会断住。选中"Filed madification"表示修改的时候都会断住
Method breakpoint(方法断点)
打断点方式同上,只是它是必须把断点打在方法那一行上。
它也有一个自己独有的参数:
参数
Watch
:
- “Method entry”:进入方法时激活断点
- “Method exit”:出去方法时激活断点
- “Emulated”:目前发现没啥卵用(求小伙伴不要喷我~)
Exception breakpoint(异常断点)
异常断点属于非常特殊的一种断点类型,它不对应任何一行代码
,因为它属于程序级别的断点。
它不能像上面在代码处直接创建,只能通过上面的断点对话框来创建。
此处注意:异常断点中很多选项就是不能使用的(灰色)如下图示:
断点参数
但是同理,它也提供一个特有的断点参数:
Notification
:
- “Catch excetion”:程序在捕获(Try Catch)这个异常时激活断点
- “Uncatch excetion”:不catch捕获异常时激活断点
小细节:对于不同类型的断点,打桩后我们看到的图标也是有差异的,如图:
关于IDEA
的远程调试(远程Debug)
远程调试
是调试分布式系统的一个利器。因为现在都以微服务部署,你不可能在本地同时启动N个服务来做本地调试。
更重要的是如果测试时候测出发现你的bug,这时候你若想定位问题,通过远程调试
直接连接到测试服务(甚至是线上服务
)不失为一种最为高效的解决方案,并且它还能有非常好的保护现场的辅助能力~
启动远程调试主要分两步:
- 第一步:要让远程服务器运行的代码支持远程调试,也就是启动的时候必须加上特定的
JVM参数
:
1.java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${debug_port} demo.jar
(适用于JDK8以上)
2.java -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=${debug_port} demo.jar
(适用于JDK8以下) - 第二步:idea使用remote链接远程端口(注意
ip:port
要对应上):”Edit Configurations” -> “Remote” 配置好后debug启动
~~~
当你看到控制台这样的字样,就证明你链接成功了,进而你可以像调试本地代码一样随意的打各种类型的断点进行调试了~
需要注意的是:远程调试时请确保你本地的代码和远程的一模一样。
Java平台调试体系架构(JPDA)和JDWP(Java Debug Wire Protocol):参考权威文档 JPDA 体系概览
以及 JDWP 远程命令执行漏洞
JDWP
协议是个标准协议,我们的Tomcat是支持的,其实tomcat它的catalina.sh文件里有告诉你怎么开启这个端口:
对上面变量的解析代码如下(注意有些默认值):
传统Tomcat怎么开启呢?
找到入口文件startup.sh
,最后一句改为的start前面加上 jpda
如下:
exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"
或者在catalina.sh中进行配置:
JPDA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005’
这样根据上面的脚本可知,判断第一个参数等于jpda,所以调试端口开放了。
嵌入式Tomcat怎么开启呢?(重要)
这里主要指的SpringBoot
环境下如何开启呢?答案见上~
如果想深入了解Java调试,强烈给你推荐去这里看看:深入Java调试体系
总结
本文并没有介绍所有的断点参数,如对话框的右半部分的Catch class filter
等等各种filter的参数,因为我觉得没太大的用~~~有兴趣的自行研究哈
另外本文讲述使用的IDE是IntelliJ IDEA
,使用Eclipse的用户可以仿照着执行~
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
2020-08-26 通俗易懂告诉你CPU/GPU/TPU/NPU...XPU都是些什么鬼?