为什么需要远程调试

最近在二次开发一个分布式系统,几个组件互相依赖。由于本地环境(windows系统)限制,无法像Linux环境那样,快速搭建目标程序所依赖的分布式环境。
而在远端SIT环境已经部署好了整套分布式系统,因此想到,是否可以用本地IDE上远程调试部署在远端的目标程序?

Luckily,对于go程序来说,可以借助Goland这款开发利器完成远程调试,VS Code也可以,但Goland提供的界面化配置更直观。

通过Goland远程调试

1.为本地代码创建远程服务器的部署策略

首先确保Goland已经安装了“Remote Hosts Access”插件,并且保持启用状态:

通过菜单栏Tools–>Deployment–>Configuration添加新的部署配置:

点击➕号,创建一个SFTP配置,下面是我的配置,目标机器是一台局域网Ubuntu机器,在“Connection”页面一般需要填入:

  • “Host”和“Port”
  • “User name”
  • “Authentication”,是指选择连接远端机器的方式,可以通过密码、私钥或openssh agent,注意这里的私钥只支持SSH-2协议和ppk形式

在“Mappings”页面一般只需要填入“Deployment path”,指定远端机器的部署路径,如果你的local path是一个GOPATH路径,那么“Deployment path”也是一个GOPATH路径:

remotedebug-addmappingconf

以上完成了创建对远端机器部署的策略,可以通过Tools->Deployment->Upload to <remote-server>,点击执行部署操作:

成功部署后Goland会显示相关信息,可以看到“部署”的本质就是把本地文件上传到远端服务器上:

查看远端ubuntu服务器上已经有同样的code base:

2.远端服务器上以debug模式启动程序

根据上一篇中阶文章使用dlv debug命令启动程序,具体步骤如下:

# 启动调试应用部署的docker容器,注意加上 
--security-opt seccomp:unconfined ,--cap-add=SYS_PTRACE 两个高级选项。
前者用来关闭容器访问资源限制,后者是允许容器使用ptrace能力

> docker run -ti --rm --security-opt seccomp:unconfined --cap-add=SYS_PTRACE --net=host -v /home/davidli/gopp:/root/go robolwq/golang-debug:1.10.3 bash

# 进入容器后,运行dlv debug启动程序

> dlv debug --headless --api-version=2 --listen=:80 ./src/github.com/nevermosby/godebug/main.go

这里有几个陌生的delve启动参数:

  • --headless: run debug server only, in headless mode
    只启动服务端,使用非交互模式
  • --api-version: selects API version when headless. (default 1),如果是headless模式,就需要指定一个大于1的版本
  • --listen: debugging server listen address. (default "localhost:0"),监听程序启动时使用的端口

命令成功执行后反馈如下:

3.为本地项目添加远程调试策略

在远端服务器通过dlv debug启动程序后,剩下就是为本地项目创建远程调试策略,即如何连接远端服务器上应用程序,利器Goland为此提供了非常方便的界面操作方式。

通过菜单栏Run–>Edit Configurations 添加新的调试配置:

点击➕号,创建一个Go Remote配置,在“Configuration”页面需要填入Host,就是远端服务器的可以联通的IP地址或机器名;Port,就是刚刚dlv debug启动时指定的监听端口,如下图所示。完成后点击OK保存。

接下来一步非常重要,为本地项目指定GOPATH路径。很多情况下,本地安装GO SDK后默认GOPATH是安装目录,不是本地项目开发时使用的GOPATH路径。通过Goland菜单栏File->Settings,打开项目配置界面,在左边导航栏找到GOPATH选项,点击 ➕ 添加Project GOPATH,指定当前本地项目的GOPATH,如下图所示:

Finally,万事俱备,准备开始我们的表演。

  • 点击目标代码行设置断点
  • 在工具栏选择刚刚配置的调试选项(我这里是remote-ubuntu
  • 点击右边小虫子按钮(是不是隐喻调试的本质就是为了找出bug)启动本地调试

remotedebug-startdebug

调试开始后,本地Goland会根据remote-ubuntu配置的远程服务器和端口,尝试连接delve服务,连接成功后会显示connected

remotedebug-debugconnected

这时,在远端服务器上的程序也输出一条新的日志“Started!!!”,表明当前web服务正式启动,可以接受用户请求了。

remotedebug-appendlog

模拟用户在本地浏览器端或直接curl远端程序:

curl http://192.168.56.101/davidli

Bingo,本地Goland上设置的断点命中了!

remotedebug-hitbp

接下来就跟在本地开发一样,顺滑地开始你的找虫子之旅吧!

再给大家贴一张动图,把上面几个重要步骤串联起来recap一把:

发表评论

电子邮件地址不会被公开。 必填项已用*标注