转眼间,距离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. quartz.net 学习

    目录 简介  Quartz是什么?  Quartz的应用场景Quartz的安装  安装  源码Hello World范例API  核心API    Scheduler接口:    Job接口    J ...

  2. jmeter解决乱码

    在jmeter.properties 这个文件里面 找到sampleresult.default.encoding=xx 后面xx改成utf-8,然后取消注释 解决jmeterbody里面中文显示不出 ...

  3. Flutter磨砂玻璃效果制作

    Flutter的Fliter Widget 也是非常强大的,它可以制作出你想要的神奇滤镜效果.下面制作一个毛玻璃效果. 这个和以前的写法都一样,所以就直接贴代码了. import 'package:f ...

  4. [译]如何使用Python构建指数平滑模型:Simple Exponential Smoothing, Holt, and Holt-Winters

    原文连接:How to Build Exponential Smoothing Models Using Python: Simple Exponential Smoothing, Holt, and ...

  5. arduino系列文章

    arduino系列文章 1.Arduino基础入门篇-进入Arduino的世界 2.关于使用Arduino做开发的理解 3.详解Arduino Uno开发板的引脚分配图及定义(重要且基础) 4.Ard ...

  6. POJ 1840:Eqs

    Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53= The coe ...

  7. 第07组 Alpha冲刺(1/4)

    队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:完成人员分配,初步学习Android开发 Github签入记录 接下来的计划:继续完成Android开发的学习,带领团队进行前后端开 ...

  8. 解决redis运行期间key值过期但是内存memory依然占用过高

    要解决这个问题,首先要了解redis info信息中几个数据的意义:   used_memory:810575104 //数据占用了多少内存(字节)  used_memory_human:773.02 ...

  9. mysql非主键提示key2 检查索引是否设定为唯一

  10. redis通用命令

    1.keys pattern 含义:查找所有符合给定模式(pattern)的key keys * 遍历所有key keys he[h-l]* 遍历以he开头,第三个字符为h-l之间的所有key key ...