转眼间,距离Jerry最近一篇文章推送已经过去了一个多月的时间了。

公众号更新的频率降低,不是因为Jerry偷懒,而是由于从春节过后,我所在的SAP成都研究院数字创新空间整个团队,一直在忙一个5月份需要交付的项目上。

Jerry每天的工作量像下面这张图这样:

这个项目里Jerry负责的是后台开发工作,我用nodejs开发了若干微服务,每个微服务实现一个特定的业务逻辑。这些微服务由Jerry另外开发的一个编排器(Orchestra)统一调度。整套后台实现部署在亚马逊云平台(Amazon Web Service,以下简称AWS)上。

离交付日期越来越近了,我们的功能也赶得差不多了。本地测试运行得很好的场景,部署到AWS上运行后出现了一些bug。比如昨天就遇到一个棘手的bug,因此有了今天这篇文章。

2014年五一节的前一天,当时Jerry还在SAP CRM开发团队工作,负责处理SAP CRM中间件的一个bug。这个bug和代码执行时序有关,每执行一次只有40%的几率能重现,花了我整整一天(8个小时)的时间调试。因为重现bug的场景太复杂,需要调试的ABAP代码量太大,所以让我印象深刻。那个bug处理完之后,我也对自己花了8小时才搞定该bug的效率很不满意,因此写了一篇博客总结这次排错的经验教训:

My Tips about how to handle complex and tricky issues

https://blogs.sap.com/2014/05/01/my-tips-about-how-to-handle-complex-and-tricky-issues/

回到昨天我遇到的在AWS上出现的bug,根据问题的表象,一开始我和负责前端开发的同事,连这个问题出在前端还是后端都没办法判断。当微服务部署在本地并进行测试时一切正常,只有部署在AWS上进行集成测试时才会暴露,而运行在AWS上的nodejs应用,我昨天还不知道如何调试,因此只好采用我大二刚学C语言编程时用过的最笨的排查办法:打日志。

2001年,在结束了一年的计算机专业基础课学习后,Jerry开始了Unix环境下C语言编程的学习。当时我对gdb这种以命令提示行方式进行的调试风格很不适应,大多数时候的排错采用的还是在代码里添加printf语句打印变量内容的方式来进行,被寝室的同学鄙视了好久。

于是昨天我继续采用了这种自己18年前就曾经用过的排错方式:

1. 在可能引起bug的相关代码处逐一加上日志输出语句

2. 执行会出现bug的用户操作

3. 阅读AWS上生成的日志语句

上述三个步骤是一个不断迭代的过程。最开始我加了若干日志输出语句,执行操作后阅读生成的日志,发现没有任何异常。于是不断地增加新的日志打印代码,最后导致了执行一次操作,会生成1200行的日志输出。

我和负责前端开发的同事两人坐在显示器前,一行行检查这海量的日志输出。由于问题是用户第二次操作后才会暴露,每次操作会生成不同的会话,我们被迫不断的上下滑动屏幕来比较这两次会话的uuid和相关的WebSocket uuid等变量。Jerry很快发现,眼睛一眨不眨地盯着显示器逐条检查日志,时间一长眼睛就痛得受不了。无奈之下,只得把这些日志用打印机打印出来,用不同颜色的笔标注出两个会话对应的各种变量,在纸上来回比对。于是就有了下面这些纸张:

虽然最后用这种办法,成功排除了后台出错的可能性,使我们得以把精力花在前台代码的审查上,但是像我一个同事评价的,“这种方式太不环保了”,并且我自己也觉得,效率太低了

后来好几位热心的同事告诉Jerry,就算运行在SAP Cloud Platform或者AWS这些云平台上的nodejs应用,也是可以单步调试的,Jerry Google了一下,发现远程调试确实很简单,就两条命令而已。

Jerry用我们创新空间团队另外一位同事Haytham开发并部署在AWS上的一个nodejs应用为例来尝试如何在我的本地电脑上对其进行调试。

Haytham虽然是一个大四本科生,但是已经在SAP成都研究院Jerry所在团队实习将近十个月的时间了,最近三个月一直在SAP德国总部参与一个项目的开发。

等Haytham回到成都后,会将自己这十个月的工作感悟,从一个SAP新人的视角给大家分享出来,敬请期待。

Haytham之前写过的文章:

SAP成都研究院许聚龙:Hello, Coresystems!

Haytham写的这个nodejs应用实际上是Github Webhook的一部分。我们在本地进行微服务nodejs开发,本地git客户端推送代码到远端github仓库。然后需要在AWS上手动git pull把最新的代码拉下来,再用一个开源工具pm2进行微服务部署。Haytham写的这个nodejs应用,能实现本地git推送完毕后一切后续流程的完全自动化,节省了我们大量的部署时间。

下面就来对Haytham这个运行在AWS上的nodejs应用进行远程调试。

1. 用node --inspect-brk在AWS上以调试模式启动应用。

之后控制台上的输出表明有一个nodejs进程以WebSocket协议在127.0.0.1:9229这个地址上监听调试客户端的连接。

2. 我在我的本地电脑上,用如下命令行将我本地电脑的端口9221映射到AWS调试进程监听的9229端口上:

ssh -i C:\Users\i042416.ssh\KOI.pem -L 9221:localhost:9229 ubuntu@ec2-us-east-2.compute.amazonaws.com

现在,本地电脑上Chrome浏览器地址栏chrome://inspect里指定监听地址为localhost:9221, 

通过第二步建立的SSH tunnel,

我就可以用本地电脑连接到AWS上的nodejs应用并进行调试了。

现在终于可以在Chrome开发者工具里进行愉快的调试了:

因为我平时本地做nodejs开发和调试时,更喜欢用Visual Studio Code,所以下一步我准备试试用Visual Studio Code进行远程调试。

说到Visual Studio Code,Jerry突然想起今天在网上看到的一个关于这个IDE的有意思的扩展,名为"超越鼓励师"。

Jerry试着在自己的Visual Studio Code扩展安装栏里搜索了一下,这个扩展还真的可以下载。不过扩展里出现的"杨超越",Jerry又孤陋寡闻了,咨询了老婆后才知道她是谁。

至于实际效果如何,Jerry不做评价,欢迎Visual Studio Code爱好者自行下载体验。

最后,祝各位程序猿/程序媛们每天即使没有程序员鼓励师的陪伴,仍然可以愉快地编程。感谢阅读。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

如何提高后台服务应用问题的排查效率?日志 VS 远程调试的更多相关文章

  1. 记在Linux上定位后台服务偶发崩溃的问题

    问题描述 在最近的后台服务中,新增将某个指令的请求数据落盘保存的功能.在具体实现时,采用成员变量来保存请求消息代理头,在接收响应以及消息管理类释放时进行销毁.测试反馈,该服务偶发崩溃. 问题分析 测试 ...

  2. Linux(2)---记录一次线上服务 CPU 100%的排查过程

    Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...

  3. Java后台服务慢优化杂谈

    Java后台服务慢优化杂谈 前言 你是否遇到过这样的场景,当我们点击页面某个按钮后,页面一直loading,要等待好几分钟才出结果的画面,有时直接502或504,作为一个后台开发,看到自己开发的系统是 ...

  4. iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法

    问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...

  5. 带后台服务配置的tomcat使用

    tomcat服务启动,将不需要手动启动startup.bat,避免cmd窗口的出现,因为隐藏到后台服务执行: 1,下载. 官网:http://tomcat.apache.org/download-70 ...

  6. Android 三级联动选择城市+后台服务加载数据库

    技术渣,大家将就着看 首先我们需要一个xml数据保存到数据库,这里我从QQ下面找到一个loclist.xml文件 <CountryRegion Name="中国" Code= ...

  7. highchart访问一次后台服务返回多张图表数据

    本文承接上一篇,我们制作动态图表的时候,往往需要的不止一张图表,如果每张图表都与服务接口做一次交互的话未免太过频繁,这无论对前后还是后台都是一种压力,本文介绍一种一次访问返回多组数据的方式来减少前台与 ...

  8. linux/windows下启用和停止VMware后台服务的脚本

    linux/windows下启用和停止VMware后台服务的脚本 linux/windows下启用和停止VMware后台服务的脚本 linux平台 windows平台 本文由乌合之众 lym瞎编,欢迎 ...

  9. mongodb启动后台服务

    将MongoDB部署在服务器机子上时mongodb的实例应为后台服务进行的方式运行,而非前台进程,否则远程会话一关闭mongodb也跟着关闭了.本文介绍mongodb后台服务进程开启和关闭的操作. 开 ...

随机推荐

  1. 003-log-jul,jdk自带日志服务

    一.简介 java官方日志jul,位于java.util.logging包下. 1.1.POM依赖 无依赖 1.2.配置 JUL的默认配置文件是logging.properties ,在 $JAVA_ ...

  2. C++ STL copy copy_backward

    #include <iostream>#include <algorithm>#include <vector>#include <functional> ...

  3. Qt编写自定义控件31-面板仪表盘控件

    一.前言 在Qt自定义控件中,仪表盘控件是数量最多的,写仪表盘都写到快要吐血,可能是因为各种工业控制领域用的比较多吧,而且仪表盘又是比较生动直观的,这次看到百度的echart中有这个控件,所以也来模仿 ...

  4. []how to use caffe model with TensorRT c++

    //IHostMemory *gieModelStream {nullptr}; //const char* prototxt = "./googlenet/test_20181010.pr ...

  5. paramiko实现putty功能

    paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. context:python3.5 执行命令 1.基于用户名和密码方 ...

  6. 如何解决滚动条scrollbar出现造成的页面宽度被挤压的问题

    参考如下: https://www.ucloud.cn/yun/114228.html

  7. MySQL之LEFT JOIN中使用ON和WHRERE对表数据

    背景 left join在我们使用mysql查询的过程中可谓非常常见,比如博客里一篇文章有多少条评论.商城里一个货物有多少评论.一条评论有多少个赞等等.但是由于对join.on.where等关键字的不 ...

  8. 51nod1050 循环数组最大子段和

    思路: 分两种情况讨论. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; ; ll sum[ ...

  9. CentOS7.3安装Python3.6

    安装python3.6可能使用的依赖 # yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sql ...

  10. 洛谷 题解 P2502 【[HAOI2006]旅行】

    由于此题边数比较小,所以可以先给边排个序,然后跑m遍最小生成树,每跑一次删除一条边,找最优解. 防TLE技巧 把边按从小到大的顺序排好,那么只要当前无法联通,那么后面也无法联通 最优解找法 doubl ...