【微服务】springboot远程docker进行debug调试使用详解

目录

一、前言

二、线上问题常用解决方案

2.1 微服务线上运行中常见的问题

2.2 微服务线上问题解决方案

2.3 远程debug概述

2.3.1 远程debug原理

2.3.2 远程debug优势

三、实验环境准备

3.1 搭建springboot工程

3.1.1 工程结构

3.1.2 引入基础依赖

3.1.3 添加配置文件

3.1.4 添加Dockerfile文件

3.2 服务器环境准备

3.2.1 docker环境

3.2.2 docker-compose环境

3.2.3 java环境

3.2.4 maven环境

四、springboot远程debug操作过程

4.1 增加测试接口

4.2 本地构建jar包并启动服务

4.3 idea配置远程debug

4.3.1 调用接口模拟调试

4.4 配置服务器远程debug

4.4.1 启动服务

4.4.2 idea进行配置

4.4.3 模拟接口调试

五、springboot远程docker容器debug操作过程

5.1 修改Dockerfile文件

5.2 上传工程代码打包

5.3 使用docker-compose命令构建镜像

5.4 启动镜像

5.5 idea配置远程debug

5.6 接口模拟测试

六、写在文末


一、前言

在分布式微服务项目的部署模式下,通常来说,一个系统的运行往往是多个服务共同协作的结果,在这种模式下,系统的灵活性、扩展性、容错性得到了很大程度的提升,但是做过微服务开发的同学应该不陌生,在分布式开发模式中,一旦某个服务出现问题,不管是采用什么手段,问题的排查、分析和定位,以及到最终解决问题,这个过程一定是耗时耗力的,尽管到现在来说出现了很多链路追踪工具可用于排查问题,但是也很难说解决所有场景下的问题,本篇将介绍另一种方式,可用于比较快速的定位线上的问题,即代码的远程debug方式。

二、线上问题常用解决方案

2.1 微服务线上运行中常见的问题

结合实践经验,基于微服务架构模式,在线上运行的微服务可能有下面这些:

  • 服务间通信问题

    • 网络延迟:服务之间的请求响应时间过长,影响用户体验。

    • 超时与重试:服务间调用超时,或因网络不稳定等原因导致请求重试,增加了系统的复杂性和响应时间。

    • 断路器失效:当一个服务暂时不可用时,断路器未能及时打开,导致请求堆积

  • 性能问题

    • 资源争用:多个服务同时访问相同的资源(如数据库、缓存等),导致性能瓶颈。

    • 内存泄漏:服务运行过程中未能正确管理内存,导致内存消耗持续增长。

    • CPU 使用率高:服务处理请求时消耗过多 CPU 资源,导致系统响应缓慢。

  • 容错与恢复问题

    • 服务降级:当部分服务不可用时,未能正确地进行服务降级,影响系统整体可用性。

    • 自动恢复机制:服务故障后未能自动恢复,需要人工干预才能恢复正常运作。

  • 数据一致性问题

    • 分布式事务处理:在多个服务之间进行事务处理时,容易出现数据不一致的情况。

    • 最终一致性实现:在需要保证最终一致性的情况下,设计不当会导致数据状态混乱。

  • 监控与日志问题

    • 监控不足:缺乏足够的监控指标,无法及时发现服务问题。

    • 日志管理:日志格式不一致,或者日志量过大,使得问题排查变得困难。

  • 安全问题

    • 认证授权:服务间通信未正确实施认证授权机制,导致安全隐患。

    • 数据加密:敏感数据传输未加密,存在泄露风险。

    • 攻击防护:缺乏对常见攻击(如 DDoS、SQL 注入等)的有效防护措施。

  • 部署与更新问题

    • 版本兼容性:服务更新后与其他服务版本不兼容,导致功能异常。

    • 灰度发布:在进行灰度发布时出现问题,如流量切换不准确导致部分用户受到影响。

  • 故障隔离问题

    • 服务雪崩:一个服务故障导致连锁反应,引发系统整体崩溃。

    • 资源隔离不足:不同服务之间共享资源时未能有效隔离,导致相互干扰。

  • 扩展性问题

    • 水平扩展限制:服务在水平扩展时遇到瓶颈,如网络带宽限制。

    • 垂直扩展成本:增加单个节点的计算能力变得昂贵或不切实际。

  • 依赖管理问题

    • 依赖版本冲突:不同服务依赖的第三方库版本不一致,导致运行时错误。

    • 依赖升级滞后:未能及时更新依赖库,导致安全漏洞或功能缺失。

2.2 微服务线上问题解决方案

在实际工作中,线上部署的微服务遇到的问题种类非常多,具体的解决方案也不一而足,下面就生产实践总结一些常用的解决方案。

  • 日志分析

    • 查看日志:首先查看服务的日志文件,特别是出问题的时间段的日志,寻找错误信息或异常堆栈。

    • 集中日志平台:使用集中化的日志管理平台(如 ELK Stack、Splunk、Graylog 等)来搜索和分析日志。

    • 结构化日志:确保日志结构化,便于解析和分析,例如使用 JSON 格式。

  • 监控与告警

    • 实时监控:使用监控工具(如 Prometheus、Grafana、Datadog 等)实时监控服务的运行状态,如 CPU、内存使用情况、网络延迟等指标。

    • 告警机制:设置合理的告警阈值,当关键指标超出正常范围时及时通知相关人员。

    • 异常检测:使用异常检测算法自动识别非正常行为。

  • 调用链追踪

    • 分布式追踪:引入分布式追踪系统(如 Zipkin、Jaeger、SkyWalking 等),追踪请求在整个服务间的调用链路。

    • 端到端追踪:确保每个请求都有唯一的追踪 ID,便于追踪请求在各个服务间的流转路径。

    • 异常追踪:关注异常调用链路,分析请求失败的原因。

  • 模拟复现

    • 模拟环境:尝试在测试或预生产环境中重现线上问题,以便更好地理解问题的具体表现。

    • 故障注入:使用混沌工程工具(如 Chaos Toolkit、Litmus 等)模拟故障场景,观察系统的行为。

  • 性能分析

    • 性能剖析:使用性能剖析工具(如 VisualVM、JProfiler、Pinpoint 等)来识别系统中的性能瓶颈。

    • 内存分析:检查是否有内存泄漏或频繁的垃圾回收导致性能下降。

    • CPU 分析:分析 CPU 使用情况,找出是否存在热点方法或死锁等问题。

  • 代码审查

    • 代码审计:检查最近的代码提交记录,寻找可能导致问题的代码变更。

    • 静态代码分析:使用静态代码分析工具(如 SonarQube、FindBugs 等)查找潜在的代码缺陷。

  • 状态检查

    • 健康检查:检查服务的健康状态,确认是否所有服务都在正常运行。

    • 依赖检查:确认外部依赖(如数据库、第三方 API 等)是否正常工作。

  • 数据分析

    • 流量分析:分析请求流量的变化趋势,判断是否由于流量激增导致的问题。

    • 错误率统计:统计错误请求的比例,了解服务的整体稳定性。

2.3 远程debug概述

Spring Boot 应用程序的远程调试是一项非常有用的技能,尤其是在开发阶段需要对部署在远程服务器上的应用程序进行调试时。远程调试允许你在本地开发环境中设置断点、查看变量值以及逐步执行代码,就好像应用程序就在本地一样。这对于诊断线上问题、理解和优化代码逻辑非常有帮助。

2.3.1 远程debug原理

远程调试的基本原理是通过配置应用程序使其能够监听一个特定的端口,然后使用本地的 IDE(如 IntelliJ IDEA 或 Eclipse)连接到该端口进行调试。这种方式可以跨越物理位置的限制,使开发者能够在本地开发环境中调试远程运行的应用程序。在进行远程debug之前,需要做好如下准备:

  • 确保远程服务器与本地计算机之间网络畅通:远程调试需要网络连接。

  • 安装 JDK 与 IDE:确保远程服务器上有 JDK,并且本地计算机上有支持远程调试的 IDE。

  • 代码一致:确保本地代码和待远程debug的服务器上面运行的代码一致。

  • 配置防火墙规则:确保远程服务器上的防火墙允许调试端口的流量通过。

2.3.2 远程debug优势

Spring Boot 应用程序的远程调试具有以下几方面的优势:

  1. 实时调试:远程调试允许开发者在应用程序运行时进行实时调试,这比离线分析日志或堆栈转储更为直接有效,特别是在处理复杂业务逻辑或性能问题时。

  2. 无需停止服务:当应用正在生产环境中运行时,通常不希望因为调试而停止服务。远程调试可以在不影响用户的情况下进行问题排查。

  3. 模拟真实环境:远程调试可以让开发者在一个与生产环境尽可能相似的环境下进行测试,这样可以更容易地发现和解决实际运行中可能遇到的问题。

  4. 节省时间和成本:当遇到线上问题时,如果能够在远程服务器上直接调试,就无需将问题复现到本地环境,从而节省了大量时间和资源。

  5. 提高效率:通过远程调试,开发者可以迅速定位问题所在,并且可以立即修改代码进行验证,提高了迭代的速度和开发效率。

  6. 团队协作:当多个开发者需要同时对同一份代码进行调试时,远程调试可以帮助他们更好地协作,特别是对于分布式团队来说,这是一个非常有用的工具。

  7. 减少错误引入的风险:直接在远程环境中调试可以减少因复制环境而导致的新问题出现的可能性。

  8. 便于理解线上数据:有时候,线上数据的状态和本地数据可能会有所不同,远程调试可以让开发者直接观察到线上数据的情况,有助于更准确地分析问题。

需要注意的是,在进行远程调试时也要注意安全性,例如确保调试端口的安全性,防止未经授权的访问。此外,在生产环境中调试时,应该避免在用户活跃时段进行大规模的调试操作,以免影响用户体验。

三、实验环境准备

3.1 搭建springboot工程

3.1.1 工程结构

快速搭建一个springboot工程,工程目录结构如下

3.1.2 引入基础依赖

导入如下必要的依赖

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePath/></parent><properties><docker.image.prefix>dcloud</docker.image.prefix></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies><build><finalName>boot-docker</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

3.1.3 添加配置文件

在resources目录下添加配置文件,配置信息如下

server:port: 8081

3.1.4 添加Dockerfile文件

在工程根目录下添加一个Dockerfile文件,内容如下

  • 该文件用于在服务器上使用docker-compose的方式进行构建服务镜像的时候使用
#FROM java:8
FROM  openjdk:17-jdk-alpine
ADD target/boot-docker.jar boot-docker.jar
ENTRYPOINT ["java","-jar","/boot-docker.jar"]

3.2 服务器环境准备

3.2.1 docker环境

提前在服务器,或虚拟机上安装好docker环境,启动镜像时使用

3.2.2 docker-compose环境

提前安装docker-compose环境,用于构建服务镜像

3.2.3 java环境

提前在服务器安装jdk,运行jar包的时候需要依赖jdk环境

3.2.4 maven环境

对springboot工程进行打包时需要使用maven命令

四、springboot远程debug操作过程

基于上面准备的环境,首先介绍如何基于springboot的工程进行远程debug,在实际线上部署的时候,通过springboot打成jar包之后进行部署也是一种常用的方式,此时可以采用这种方式进行远程debug排查问题。

4.1 增加测试接口

在工程中添加如下测试接口用于测试

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DockerImageController {//localhost:8081/docker/v1@GetMapping("/docker/v1")public Object dockerTest1(){return "docker image test";}}

工程运行起来之后,调用一下接口确保功能正常

4.2 本地构建jar包并启动服务

在idea中使用maven命令构建jar包,然后在本地使用java -jar命令启动,最后测试一下效果

正常启动的时候,只需要使用 java -jar jar包名 即可,为了在后续部署到远程服务器上能够调试,需要额外添加监听端口,以这个jar为例,启动命令如下:

  • address后面的端口可以自己指定;
java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 boot-docker.jar

本地使用cmd启动,模拟远程服务器环境

再次访问,确保接口访问正常

4.3 idea配置远程debug

通过上面CMD启动窗口,可以看到5005端口准备就绪,然后再在idea做做如下配置

然后再在下面的配置框中填写信息,参考下面的配置

然后点击启动即可,正常启动后,可以看到控制台显示已经开始监听5005端口了

4.3.1 调用接口模拟调试

基于上面启动连接的状态下,再次调用一下接口,可以看到此时就进入代码中的断点了,就可以进行断点调试了

4.4 配置服务器远程debug

将上面的jar包上传到服务器,模拟真实的线上部署jar包进行debug调试

4.4.1 启动服务

使用下面的命令进行启动

java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 boot-docker.jar

启动后效果如下

4.4.2 idea进行配置

其他的配置保持不变,只需要修改下Host连接的IP地址为服务器IP地址

保存,然后连接即可,可以看到开始监听远程的5005端口

4.4.3 模拟接口调试

调用一下接口,可以看到也能正常进入到代码断点进行调试

五、springboot远程docker容器debug操作过程

springboot项目实际部署的时候,也可以通过docker的方式进行部署,在这种部署方式下,如果想要远程debug该怎么做呢,下面介绍详细的操作过程。

5.1 修改Dockerfile文件

在上面Dockerfile文件的基础上做一下调整,即在java -jar的启动参数配置中添加一行配置监听的参数信息,参考下面的配置

#FROM java:8
FROM  openjdk:17-jdk-alpine
ADD target/boot-docker.jar boot-docker.jar
#ENTRYPOINT ["java","-jar","/boot-docker.jar"]
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "/boot-docker.jar"]

5.2 上传工程代码打包

将代码上传到服务器指定目录,或者通过git下载代码到服务器指定目录

在当前目录下,执行mvn clean package 进行打包,打完包之后,确保在target目录下能够看到构建出来的工程jar包

5.3 使用docker-compose命令构建镜像

使用docker-compose命令,通过Dockerfile文件对上一步的jar包进行镜像的构建,需要进入到Dockerfile所在的目录进行命令执行

docker build -t boot-docker:1.0 .

执行完成后,通过docker images检查确保镜像正常生成

5.4 启动镜像

使用下面的命令启动容器

docker run -d -it -p 8081:8081 -p 5005:5005 --name=boot-k8s boot-docker:1.0

然后使用docker ps 检查下确保镜像正常启动

5.5 idea配置远程debug

和上面对jar包进行debug配置类似,在idea中启动参数中做下面的配置

然后远程连接一下

5.6 接口模拟测试

在浏览器调用一下测试接口,可以看到断点已经可以正常进入到工程接口代码中了

六、写在文末

本文通过实际操作详细演示了如何对springboot项目进行远程debug的过程,希望对看到的同学有用哦,本篇到此结束,感谢观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/446185.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux之如何找回 root 密码?

1、启动系统&#xff0c;进入开界面&#xff0c;在界面中按“e"进入编辑界面 2、进入编辑界面&#xff0c;使用键盘上的上下键把光标往下移动&#xff0c;找到以”Linux16“开通内容所在的行数&#xff0c;在行的最后面输入&#xff1a;init/bin/sh 3、输入完成后&…

麒麟信安CentOS安全加固案例获评中国信通院第三届“鼎新杯”数字化转型应用奖

“鼎新杯”数字化转型应用大赛&#xff0c;由中国通信标准化协会主办、中国信息通信研究院承办&#xff0c;以落实国家“十四五”规划关于“加快数字化发展&#xff0c;建设数字中国”的总体要求为目标&#xff0c;意在打造一批具有产业引领与推广应用效应的企业数字化转型应用…

JavaEE-进程与线程

1.进程 1.1什么是进程 每个应⽤程序运⾏于现代操作系统之上时&#xff0c;操作系统会提供⼀种抽象&#xff0c;好像系统上只有这个程序在运 ⾏&#xff0c;所有的硬件资源都被这个程序在使⽤。这种假象是通过抽象了⼀个进程的概念来完成的&#xff0c;进程可 以说是计算机科学…

C#源码安装ZedGraph曲线显示组件

在软件开发里,数据的显示,已经是软件开发的大头。 如果让数据更加漂亮地、智能地显示,就是软件的核心价值了。 因为不管数据千万条,关键在于用户看到图。因为一个图表,就可以表示整个数据的趋势, 或者整个数据的走向,数据频度和密码。所以图表显示是软件的核心功能,比如…

STM32 -- USB CDC 虚拟串口通信

本篇操作: 通过CubeMX Keil&#xff0c;配置STM32作为USB设备端&#xff0c;与电脑上位机进行通信&#xff08;CDC&#xff09;&#xff1b;通用带USB功能的 STM32 芯片 &#xff08;如F1、F4等&#xff0c;系统时钟配置不同&#xff0c;代码通用&#xff09;。 目录 一、 S…

python中双引号和单引号的区别是什么

python3中的单引号‘’和双引号“”的作用一样。 3个单引号的作用&#xff1a; 1、表示注释 #3个单引号表示注释多行gf_of_archerzon "Wang" print("archerzon的女盆友是",gf_of_archerzon) print("archerzon的女盆友是%s"%gf_of_archerzon)2…

Vue基础(三)

生命周期 又名生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子 是什么&#xff1a;Vue在关键时刻帮我们调用的一些特殊名称的函数 生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根据需求编写的 生命周期函数中的this指向是vm或者组件实…

Leetcode - 周赛418

目录 一&#xff0c;3309. 连接二进制表示可形成的最大数值 二&#xff0c;3310. 移除可疑的方法 三&#xff0c;3311. 构造符合图结构的二维矩阵 四&#xff0c;3312. 查询排序后的最大公约数 一&#xff0c;3309. 连接二进制表示可形成的最大数值 本题数据范围较小&#…

鼓组编写:SsdSample鼓映射 GM Map 自动保存 互换midi位置 风格模板 逻辑编辑器

SsdSample音源的键位映射 方便编写鼓的技巧 可以这样去设置键位关系的面板和钢琴卷帘窗的面板&#xff0c;方便去写鼓。 可以先按GM的midi标准去写鼓&#xff0c;然后比对下鼓的键位映射的关系&#xff0c;去调整鼓。 可以边看自己发b站等处的图文笔记&#xff0c;然后边用电…

网络初识基本概念总结

网络发展背景 经历了 单机阶段 -> 局域网阶段 -> 广域网阶段 -> 移动互联网阶段 (简单介绍一下) 其他一些小概念 局域网LAN: 是把一些设备通过交换机 / 路由器连接, 形成的私有网络广域网WAN: 是把更多的局域网相互连接起来,当规模足够大时形成广域网交换机和路由器…

STM32F103ZET6 FREERTOS 双UART 多任务多串口输出(配置教程)

基本的stm32cubemx使用就不细说了&#xff0c;要想配置freertos&#xff0c;用这个工具配置那是相当方便和简单 1、系统晶振配置 使用外部时钟晶振&#xff0c;配置如图 2、系统定时器设置 serial wire 保证下次可以程序下载 SysTick 是 Cortex-M 内核中的一个系统定时器&a…

用C++编写信息管理系统(歌单信息管理)

C语言是面向过程的编程语言&#xff0c;而C是面向对象的编程语言&#xff0c;在书写代码时风格有所不同&#xff08;也存在很多共性&#xff09;。 程序说明 本次系统程序使用的是C语言进行编写&#xff0c;主要考虑怎么实现面向对象的问题。 因为本次程序属于小型系统程序&…

C语言 | 第十六章 | 共用体 家庭收支软件-1

P 151 结构体定义三种形式 2023/3/15 一、创建结构体和结构体变量 方式1-先定义结构体&#xff0c;然后再创建结构体变量。 struct Stu{ char *name; //姓名 int num; //学号 int age; //年龄 char group; //所在学习小组 float score; //成绩 }; struct Stu stu1, stu2; //…

从二维到三维,电商行业有哪些变化?

从二维到三维&#xff0c;电商行业经历了一系列显著的变化&#xff0c;这些变化不仅体现在商品展示的方式上&#xff0c;还深刻影响了消费者的购物体验、电商平台的运营策略以及整个电商行业的竞争格局。 一、商品展示方式的变革 二维展示阶段&#xff1a; 在电商行业的早期&…

【黑苹果】记录MacOS升级Sonoma的过程

【黑苹果】记录MacOS升级Sonoma的过程 一、硬件二、提前说明三、准备OC四、选择驱动五、选择ACPI六、下载内核扩展七、其他问题 一、硬件 设备是神舟zx6-ct5da 具体参照下图 二、提前说明 本机器已经安装过 macOS Monterey 12.6&#xff0c;这次是升级到 macOS Sonoma 14。 …

Java后端面试题(day16)

目录 java常见的引用类型java中深拷贝和浅拷贝如何设计一个秒杀系统?谈一下对高并发的理解&#xff0c;平时怎么处理高并发问题?Comparable和Comparator区别&#xff1f;解决hash冲突有哪些方法&#xff1f;Synchronized锁的升级过程 java常见的引用类型 java的引用类型一般分…

图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)

图论day56|广度优先搜索理论基础 、bfs与dfs的对比&#xff08;思维导图&#xff09;、 99.岛屿数量&#xff08;卡码网&#xff09;、100.岛屿的最大面积&#xff08;卡码网&#xff09;&#xff09; 广度优先搜索理论基础bfs与dfs的对比&#xff08;思维导图&#xff09;&…

C++调试方法(Vscode)(一) ——本地调试

初学者在调试一段代码的时候&#xff0c;经常出于不明原因&#xff0c;写出bug&#xff0c;导致程序崩溃。但是定位崩溃的地方时&#xff0c;往往采用简单而朴素的方法&#xff1a;即采用cout或者printf进行输出。这种方式既原始&#xff0c;又低效。一个合格的工程师应该是通过…

RabbitMQ简介及安装类

RabbitMQ概述-MQ介绍 RabbitMQ是一个开源的消息代理和队列服务器&#xff0c;它支持多种消息协议&#xff0c;并且可以轻松地与多种编程语言和框架集成。RabbitMQ是使用Erlang语言编写的&#xff0c;因此它具有高并发和高可用性的特点。以下是RabbitMQ的一些关键特性和概念 消息…

华为OD机试 - 区间交叠问题 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…