Vscode debug GoLang micro-services in Docker

栏目: Go · 发布时间: 5年前

内容简介:查一般的 bug,我更习惯直接加打印,能快速定位问题,远比断点调试方便的多。但遇到一些复杂、或是涉及第三方类库时,却不得不需要添加断点逐步跟踪逻辑。使用 golang 开发的微服务,全部是直接运行在 docker 容器里的,想要调试并不是一件简单的事情,这时候我们就需要 Remote Debug (远程调试)

English

查一般的 bug,我更习惯直接加打印,能快速定位问题,远比断点调试方便的多。但遇到一些复杂、或是涉及第三方类库时,却不得不需要添加断点逐步跟踪逻辑。

使用 golang 开发的微服务,全部是直接运行在 docker 容器里的,想要调试并不是一件简单的事情,这时候我们就需要 Remote Debug (远程调试)

  • vscode - 代码编辑器
  • ms-vscode.go - vscode 支持 Go 语言的插件
  • delve - Golang 调试工具,支持远程调试
  • Makefile - 封装指令的合集
  • alpine - 迷你 Docker 系统镜像,只有 5MB

启动容器

通过 MakefileDockerfile 编译镜像和运行 Docker 容器,我的方式是在本地(MacOS)上编译好 Linux 的可执行文件,拷贝到用 alpine 小镜像创建的容器里。也可以选择用 golang 镜像,拷贝源码进去。

  1. 配置 Makefile
-gcflags "all=-N -l"
-security-opt="seccomp=unconfined" --cap-add=SYS_PTRACE
-p 20000:20000
NAME := account
IMAGE := $(NAME)-service

# 编译镜像
build-debug:
    # 清理废弃的image (按需开启)
    docker image prune -f

    # 编译Linux版 dlv可执行文件
    GOOS=linux GOARCH=amd64 go build github.com/go-delve/delve/cmd/dlv

    # 编译Linux版 应用可执行文件
    GOOS=linux GOARCH=amd64 go build -gcflags "all=-N -l"

    # 指定Dockerfile 生成镜像
    docker build -f Dockerfile.debug -t $(IMAGE) .

    # 清理掉生成的可执行文件
    rm -f $(NAME) dlv

# 运行容器
run-debug:
    # my-docker-network 是我的Docker network,所有的微服务都在这个网络里,可以直接互连
    docker run --rm --name $(IMAGE) \
    --network my-docker-network \
    --security-opt="seccomp=unconfined" --cap-add=SYS_PTRACE \
    -p 20000:20000 \
    $(IMAGE)


debug: build-debug run-debug
  1. 配置 Dockerfile.debug

容器启动入口为 ./dlv --listen=:20000 --headless=true --api-version=2 --log=true exec ./account

  • ./ 代表 WORKDIR 的 /app 目录,dlv、account 可执行文件我们通过 Dockerfile 都已经添加到这个目录里了
  • --listen=:20000 dlv 服务绑定的端口
  • --headless=true 调试服务器,无 ui 模式
  • --api-version=2 服务提供的 API 版本
  • --log=true 开启日志,否则只能看到应用日志,没有 dlv 自身的日志
  • exec ./account 准备执行的程序,这个程序必须支持 Debug

exec 对应的还有另外一个指令: debug ,直接调试源码可以用

FROM alpine:3.9

# 应用程序需要这个组件来支持请求HTTPS的网址
RUN apk add ca-certificates

RUN mkdir /app
WORKDIR /app

ADD dlv account config.yml ./

ENTRYPOINT ["./dlv", "--listen=:20000", "--headless=true", "--api-version=2", "--log=true", "exec", "./account"]
  1. 运行容器

会发现没有应用启动日志,是因为微服务在此时还未被拉起,只是关联好了

$ make debug
...
2019-05-08T13:03:23Z info layer=debugger launching process with args: [./account]
API server listening at: [::]:20000

Vscode 配置及断点调试

  1. 配置启动文件
  • mode remote 开启远程模式

  • hostport 配置成 dlv 暴露出的服务器地址

  • program 配置成本地对应的源码 main 文件

  • launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Remote Debug",
      "type": "go",
      "request": "launch",
      "mode": "remote",
      "remotePath": "",
      "port": 10001,
      "host": "127.0.0.1",
      "program": "${workspaceRoot}/cmd/account/main.go",
      "showLog": true,
      "env": {},
      "args": []
    }
  ]
}
  1. 点击开始调试,应用才开始运行,所以可以看出是 vscode 客户端通知 dlv 服务器启动应用的
  2. 这时候我们在 vscode 里创建一个断点,服务器会出现对应的日志。
2019-05-08T13:06:03Z debug layer=debugger halting
2019-05-08T13:06:03Z info layer=debugger created breakpoint: ...
2019-05-08T13:06:03Z debug layer=debugger continuing
  1. 接下来就和在本地调试程序是一样的了。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ACM国际大学生程序设计竞赛

ACM国际大学生程序设计竞赛

俞勇 编 / 2012-12 / 29.00元

《ACM国际大学生程序设计竞赛:知识与入门》适用于参加ACM国际大学生程序设计竞赛的本科生和研究生,对参加青少年信息学奥林匹克竞赛的中学生也很有指导价值。同时,作为程序设计、数据结构、算法等相关课程的拓展与提升,《ACM国际大学生程序设计竞赛:知识与入门》也是难得的教学辅助读物。一起来看看 《ACM国际大学生程序设计竞赛》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具