Goland 对容器中的 Go 程序断点远程调试

1,针对 golang 程序打断点有哪几种情况

  • 临时进程:针对临时运行一次的 Golang 脚本,比如定时统计脚本,定时推送脚本。
  • 常驻进程:针对一直在后台运行的 Golang 程序,比如 HTTP 或者 GRPC 服务。

我们现在假设不管是上面的临时进程还是常驻进程都是运行的容器中。(因为不在容器中的大家可以直接在 Goland 中进行断点 debug)

2,临时进程断点 debug?

1,首先我们需要在一个 含有 Golang 程序的容器中安装 delve(简称dlv)(debug 工具,类似 PHP 的 xdebug)

第一种安装方式:go install github.com/go-delve/delve/cmd/dlv@latest

第二种安装方式(推荐):针对我们使用的 golang 镜像,进行二次定制,直接将 delve 打包进行,dockerfile 如下

FROM golang:1.20.2 AS builderWORKDIR /build# 这里他的 main.go 没有直接在项目主目录,不同于其他 golang 开源项目。
RUN git clone --depth 1 --branch v1.20.2 https://github.com/go-delve/delve.git && \cd /build/delve/cmd/dlv && \go build -o /build/delve/bin/dlvFROM golang:1.20.2COPY --from=builder /build/delve/bin/dlv /usr/local/bin/dlv
  • 执行命令进行编译(双版本):docker buildx build --platform linux/amd64,linux/arm64 -t golang:1.20.2-debug .

备注:使用 FROM golang:1.20.2 AS builder 的语法是 Dockerfile 中的多阶段构建(Multi-stage build)功能,旨在帮助优化镜像的大小和构建过程

2,在下载好dlv的容器中的程序主目录,运行dlv的命令

dlv debug --headless --listen=:40000 --api-version=2 --accept-multiclient

如下图代表启动成功,并且监听 40000 端口,等待远程的 debug 工具(Goland/vscode等)连接。

image.png

3,配置 goland 连接第二步运行的dlv

image.png

image.png

image.png

image.png

4,使用 goland 打断点并触发 debug

image.png

3,常驻进程断点 debug?

如果你只调试一个常驻进程也可以像临时进程进行一样 debug,不过当你有多个微服务用 docker-compose 部署起来以后,一般都是启动 docker 就启动对应的 golang 程序。这个时候要去杀死这个进程再用dlv进行启动,会发现比较麻烦

这里提供一个方便的方法。就是原来的微服务配置全部不动。然后

  • 通过一个 shell 脚本,获取到容器里面运行微服务的pid。
  • 通过 dlv的 attach 操作直接入侵正在运行的goalng程序 同时暴露 40000 端口。
  • 通过 goland 的 go remote 连接暴露的 40000 端口。

细化操作如下: 1, 在容器内,编译并运行(或者直接修改 docker-compose 中的 command)一个 golang web 服务 编译并且运行:

go build -gcflags="-N -l" -o demo
./demo

这里先 build 是因为需要添加 -gcflags="-N -l" 这个参数,因为当使用go run命令运行Go代码时,无法直接添加编译器标志(例如-gcflags="-N -l"),而只有加了这个参数才可以避免 golang 在做编译时把一些代码进行忽略,导致goland无法再某一行代码上打断点且会报错:could not find statement at /usr/local/go/src/cmd/ go/main.go:24, please use a line with a statement

2,通过一个shell 脚本(dlv_debug.sh)启动 dlv

#!/bin/bash# 配置这个程序的名字
#program_name="/data/golang_breakpoint_debug/tmp/main"
program_name="/demo"# 获取所有程序
program_list=$(ps -ef | grep -v "air" | grep -v "/bin/sh")# 获取包含 program_name 的程序的PID
go_app_pid=$(echo "$program_list" | awk -v pname="$program_name" '$0 ~ pname {print $2}')echo "====== get golang program,name:$program_name pid: $go_app_pid ======"# 运行dlv命令
dlv attach "$go_app_pid" --headless --listen=:40000 --api-version=2 --accept-multiclient

可以在容器内运行上面的 shell 脚本:

image.png

也可以在容器外面执行这个命令:

docker exec -t golang_breakpoint_debug /bin/sh -c "chmod +x /data/golang_breakpoint_debug/dlv_debug.sh && /data/golang_breakpoint_debug/dlv_debug.sh"

3,按照临时程序的debug流程一样配置goland,启动 debug

image.png

以上就是怎么在不停止golang 的常驻进程(比如 HTTP或者 GRPC 的服务)的情况下,对这个 golang 的常驻进程进行 debug。

4,全自动一键 debug(不想折腾可以跳到第五小节)

上面每次停止 debug 或者 代码更新以后都需要再去手动启动一下dlv,但是程序员是最讨厌手动的。所以得想办法解决这两个手动操作。

4.1 解决代码更新自动重启

安装一个工具包:go install http://github.com/cosmtrek/air@latest 将 app 启动命令替换为 air 启动的命令:air --build.cmd 'go build -gcflags="all=-N -l" -o demo' --build.bin="./demo"

备注:这里 air 会监听 golang 代码,当代码发生变动的时候,会自动重启。

4.2 解决每次都要手动启动dlv

配置一下before launch 来每次自动启动dlv 在go remote 里面增加一个 before launch 命令如下图

image.png

dlv_debug_out_start.sh 的 shell 脚本内容如下:

#!/bin/bashdocker exec -t golang_breakpoint_debug /bin/sh -c "chmod +x /data/golang_breakpoint_debug/dlv_debug.sh && /data/golang_breakpoint_debug/dlv_debug.sh" &sleep 0.5

注意的第一点: 报错:the input device is not a TTY 因为一般docker 命令里面是用的 exec -it ,而如果您在命令中使用了 -t 或 --tty 选项,它会要求终端交互性,并且如果当前的输入设备不是一个 TTY,则会出现该错误。

注意的第二点: shell 脚本中需要 sleep 0.5 ,是因为这个是顺序执行,因为 shell 里面最后加了 & 所以不会阻塞,有可能 shell 运行完了,Goland 启动 debug, 但是shell 那里异步启动还没完成,会导致启动失败。

注意的第三点: 我们配置 go remote 的时候需要配置停止 debug 以后自动停止远程的dlv。

image.png

4.3 整个流程的一个回顾

完成上面的配置,基本就可以做到一键 debug 运行在 docker 中的常驻微服务。最后我们再整体回顾一下,看下这个流程是怎么走通的,假设现在有一个常驻 web 服务大体的流程是

1,docker-compose 启动所有容器,此时容器中有一个 web 服务。

2,这个时候你在 Goalnd里面打好断点,同时点击Goland 中的debug按钮。

3,点击 debug 按钮后,触发 before launch,在宿主机运行 shell 脚本(dlv_debug_out_start.sh)启动 web 服务容器内 shell 脚本(dlv_debug.sh)。

4,web 容器里面的 shell 脚本(dlv_debug.sh)获取正在运行的web服务pid,然后启动dlv劫持这个pid,同时暴露 40000 端口。

5,此时 before launch 运行完毕,Goalnd的debug客户端连接上 web 容器的40000端口,此时可以进行 debug 操作。

6,debug 完毕以后,我们关闭 debug,这个时候自动触发关闭远程dlv

7,我们修改我们需要修改的 Golang 文件,此时触发 air,重启了 web 服务

8,我们再次尝试 debug(循环 3-8)

按照以上的流程,其实我们可以给其他任何语言(PHP/jave)运行在 docker 里面的服务做添加类似的debug配置。

5,Goland 断点 debug 的基础操作教程

最后提供一个 Goland 断点 debug 页面中简单调试会用到的基础按钮的作用,具体可看下图。红色框起来的的几的按钮以及后面对这几个按钮的解释。

image.png

  • Show Execution Point (Alt + F10):如果你的光标在其它行或其它页面,点击这个按钮可跳转到当前代码执行的行。
  • Step Over (F8):步过,一行一行地往下走,如果这一行上有方法不会进入方法。
  • Step Into (F7):步入,如果当前行有方法,可以进入方法内部,一般用于进入自定义方法内,不会进入官方类库的方法。
  • Force Step Into (Alt + Shift + F7):强制步入,能进入任何方法,查看底层源码的时候可以用这个进入官方类库的方法。
  • Step Out (Shift + F8):步出,从步入的方法内退出到方法调用处,此时方法已执行完毕,只是还没有完成赋值。
  • Run to Cursor (Alt + F9):运行到光标处,你可以将光标定位到你需要查看的那一行,然后使用这个功能,代码会运行至光标行,而不需要打断点。
  • Evaluate Expression (Alt + F8):计算表达式。

另外贴一个 PHP 的 断点 debug 教程,我记得好像很多是 PHP 转 Golang:

以上,基本就是全部的利用 Goland 对 运行在 docker 里面的 goland 程序进行 debug 的配置和基本操作了,创作不易,欢迎点赞收藏,以及如果有疑问或者改进意见,欢迎在评论区留言。

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

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

相关文章

QT学习之QT概述

1.1 什么是QT? Qt是一个跨平台的C图形用户界面应用程序框架。 QT特点: 跨平台,几乎支持所有的平台接口简单,容易上手,学习QT框架对学习其他框架有参考意义。一定程度上简化了内存回收机制开发效率高,能够…

react+canvas实现横跨整个页面的动态的波浪线(贝塞尔曲线)

本来写这个特效 我打算用css实现的,结果是一波三折,我太难了,最终没能用css实现,转战了canvas来实现。来吧先看效果图 当然这个图的波浪高度、频率、位置、速度都是可调的,请根据自己的需求调整,如果你讲波…

【Nginx38】Nginx学习:SSL模块(二)错误状态码、变量及宝塔配置分析

Nginx学习:SSL模块(二)错误状态码、变量及宝塔配置分析 继续我们的 SSL 模块的学习。上回其实我们已经搭建起了一个 HTTPS 服务器了,只用了三个配置,其中一个是 listen 的参数,另外两个是指定密钥文件的地址…

Rust语言和curl库编写程序

这是一个使用Rust语言和curl库编写的爬虫程序&#xff0c;用于爬取视频。 use std::env; use std::net::TcpStream; use std::io::{BufReader, BufWriter}; ​ fn main() {// 获取命令行参数let args: Vec<String> env::args().collect();let proxy_host args[1].clon…

MobaXterm使用VNC远程显示和控制ubuntu桌面

目录 1 在ubuntu中安装vnc 2 设置ubuntu远程连接 3 MobaXterm中连接ubuntu的vnc 1 在ubuntu中安装vnc 参考&#xff1a;Ubuntu18.04~Ubuntu22.04安装并配置VNC_ubuntu安装vnc-CSDN博客 大体流程就是在ubuntu中安装vnc&#xff0c;设置密码&#xff0c;然后配置服务&#x…

linux+python3.6.8+uwsgi+postgresql+django部署web服务器

linuxpython3.6.8uwsgipostgresqldjango部署web服务器 1.查看系统信息2.配置postgresql数据库2-1.安装postgresql数据库2-2.设置密码2-3.修改postgresql数据库配置文件 3.Python虚拟环境激活虚拟环境 4.Django4-1.Python 安装Django4-2.创建Django项目4-3.配置Django 5.uwsgi5-…

基于python+django+vue开发的酒店预订管理系统 - 毕业设计 - 课程设计

文章目录 源码下载地址项目介绍项目功能界面预览项目备注毕设定制&#xff0c;咨询 源码下载地址 点击这里下载源码 项目介绍 该系统是基于pythondjango开发的酒店预定管理系统。适用场景&#xff1a;大学生、课程作业、毕业设计。学习过程中&#xff0c;如遇问题可在github…

CSS3设计动画样式

CSS3动画包括过渡动画和关键帧动画&#xff0c;它们主要通过改变CSS属性值来模拟实现。我将详细介绍Transform、Transitions和Animations 3大功能模块&#xff0c;其中Transform实现对网页对象的变形操作&#xff0c;Transitions实现CSS属性过渡变化&#xff0c;Animations实现…

ChatGPT 实际上是如何工作的?

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; ChatGPT 操作的两个主要阶段 我们再用谷歌来打个比方。当你要求谷歌查找某些内容时&#xff0c;你可能知道它不会——在你提出要求的那一刻——出去搜索整个网络来寻找答案。相反&#xff0c;谷歌会在其数…

网络编程套接字(二)

目录 简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求单执行流服务器的弊端 多进程版TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务多线程版的TCP网络程序客户端创建套接字客户端链接服务器客户端发起请求 线程池版的TCP网络程序 简单的T…

IntelliJ IDEA 2023 最新版如何试用?IntelliJ IDEA 2023最新版试用方法及验证ja-netfilter配置成功提示

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Rocky9 上安装 redis-dump 和redis-load 命令

一、安装依赖环境 1、依赖包 dnf -y install perl gcc gcc-c zlib-devel2、编译openssl 1.X ### 下载编译 wget https://www.openssl.org/source/openssl-1.1.1t.tar.gz tar xf openssl-1.1.1t.tar.gz cd openssl-1.1.1t ./config --prefix/usr/local/openssl make make ins…

Ubuntu重启后进入initramfs导致无法开机解决方案

今天&#xff0c;我的电脑意外关机&#xff0c;重新开机后打开了虚拟机。该虚拟机使用的是 Ubuntu 22.04 系统。但重启后&#xff0c;系统一直显示(initramfs):&#xff0c;导致无法正常启动。最后&#xff0c;在网上查找了一些解决方案&#xff0c;成功解决了这个开机问题。在…

Java配置47-Spring Eureka 未授权访问漏洞修复

文章目录 1. 背景2. 方法2.1 Eureka Server 添加安全组件2.2 Eureka Server 添加参数2.3 重启 Eureka Server2.4 Eureka Server 升级版本2.5 Eureka Client 配置2.6 Eureka Server 添加代码2.7 其他问题 1. 背景 项目组使用的 Spring Boot 比较老&#xff0c;是 1.5.4.RELEASE…

Minium:专业的小程序自动化工具

小程序架构上分为渲染层和逻辑层&#xff0c;尽管各平台的运行环境十分相似&#xff0c;但是还是有些许的区别&#xff08;如下图&#xff09;&#xff0c;比如说JavaScript 语法和 API 支持不一致&#xff0c;WXSS 渲染表现也有不同&#xff0c;所以不论是手工测试&#xff0c…

腾讯云双十一云服务器活动:88元1年的云服务器难道不香吗?

腾讯云双十一活动中&#xff0c;有三款轻量应用服务器可享受特惠优惠。这三款服务器分别是2核2G、2核4G和4核8G&#xff0c;价格分别为88元/年、166.6元/年和529元/15个月。对于需要低成本而又高性能的服务器需求&#xff0c;轻量应用服务器是一个理想的选择。 轻量应用服务器特…

【错误解决方案】matplotlib绘图中文标签不显示

1. 错误提示 Matplotlib 中文标签不显示的问题通常是由于中文字符在图形中的编码问题导致的。例如&#xff1a; import numpy import matplotlib.pyplot as pltz numpy.arange(-5, 5, .1) sigma_fn numpy.vectorize(lambda z: 1/(1numpy.exp(-z))) sigma sigma_fn(z)fig …

中国等28个国家发布《布莱切利宣言》,鼓励AI以安全方式发展

英国时间11月1日&#xff0c;中国、美国、英国、法国、德国等28个国家和欧盟&#xff0c;在英国的布莱切利庄园签署了&#xff0c;首个全球性人工智能&#xff08;AI&#xff09;声明——《布莱切利宣言》。 该宣言明确指出了AI对人类社会的巨大机遇&#xff0c;但AI需要以人为…

【C语法学习】11 - fprintf()函数

文章目录 1 函数原型2 参数3 返回值4 比较5 示例 1 函数原型 fprintf()&#xff1a;将格式化输出发送至指定流stream&#xff0c;函数原型如下&#xff1a; int fprintf(FILE *stream, const char *format, ...)2 参数 fprintf()函数参数包括三部分&#xff1a; 参数stream…

【数据结构】归并排序 的递归实现与非递归实现

归并排序 前言一、归并排序递归实现&#xff08;1&#xff09;归并排序的核心思路&#xff08;2&#xff09;归并排序实现的核心步骤&#xff08;3&#xff09;归并排序码源详解&#xff08;4&#xff09;归并排序效率分析1&#xff09;时间复杂度 O&#xff08;N*logN&#xf…