转眼间,距离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. 整理了一份比较全面的PHP开发编码规范.

    这些年来多从事Linux下PHP和C相关的开发,带过很多项目和团队,下面是根据经验整理的PHP编码规范,可以用作给大家的范例和参考,根据需要进行取舍和修改! (可能最新的一些php5的规范不够完整,今 ...

  2. java dom4j 解析xml使用实践

    参考:https://dom4j.github.io/ http://www.cnblogs.com/liuling/archive/2013/02/05/dom4jxml.html 常用api: 1 ...

  3. 使用badusb“烧鹅”制作“百度U盘”

    HID攻击:USB HID攻击技术是一种利用USB接口伪造用户击键行为实施是攻击的方式.通过恶意USB HID设备连接主机后发送伪造的按键命令,篡改系统设置.运行恶意功能.这种技术区别于传统的USB攻 ...

  4. pip install staty

    ERROR: Complete output from command python setup.py egg_info:ERROR: Traceback (most recent call last ...

  5. Linux-文件系统的简单操作

    文件系统的简单操作 磁盘与目录的容量:df.du df [option] [目录或文件名] 参数: -a:列出所有的文件系统,包括系统特有的/proc等系统 -k:以KB的容量显示各文件系统 -m:以 ...

  6. Ideal常用 快捷键

    IntelliJ Idea 常用快捷键列表   Alt+回车 导入包,自动修正Ctrl+N   查找类Ctrl+Shift+N 查找文件Ctrl+Alt+L  格式化代码 Ctrl+Alt+O 优化导 ...

  7. HBase管理与监控——Dead Region Servers

    [问题描述] 在持续批量写入HBase的情况下,出现了Dead Region Servers的情况.集群会把dead掉节点上的region自动分发到另外2个节点上,集群还能继续运行,只是少了1个节点. ...

  8. 使用super函数----增量重写普通方法和构造方法

    使用super函数----增量重写普通方法和构造方法 在子类中如果重写了超类的方法,通常需要在子类方法中调用超类的同名方法,也就是说,重写超类的方法,实际上应该是一种增量的重写方式,子类方法会在超类的 ...

  9. PHP 调用C# WebService

    在VS2010中新建WebService:Finance.asmx 代码如下: using System.Web.Services; namespace WebTest.WebService { // ...

  10. opengl鼠标键盘控制相机漫游

    键盘wsad控制相机位移,鼠标左键按下控制相机旋转 效果如下 代码如下 #include <stdio.h> #include <string.h> #include < ...