开发函数计算的正确姿势 —— 排查超时问题
2019独角兽企业重金招聘Python工程师标准>>>
写不尽的 code,查不完的 bug
通常我们写 bug,哦,不对,写代码时总不会一帆风顺,往往各种 bug 充斥其中,即使测试有较高的代码覆盖率往往也会有漏网之鱼。能写出一些比较隐蔽或者看起来像 feature 的 bug,并且经过了测试、code review 等层层的考验,最终 merge 到主干,这也算的上是一种本事。
这次,我们讨论的场景是,当你制造的 bug 被别人发现或者不小心把自己坑了,而不得不去 fix,且你自己也忘了这个 bug 是怎么写的了,在这种情况下,如何排查问题?
一气呵成,bug 侧漏
var request = require('request');exports.handler = function(event, context, callback) {console.log("event: " + event);console.log('context: ', JSON.stringify(context));const options = {url: 'https://saweather.market.alicloudapi.com/spot-to-weather?area=%E6%B3%B0%E5%B1%B1&need3HourForcast=0&needAlarm=0&needHourData=0&needIndex=0&needMoreDay=0',headers: {Authorization: 'APPCODE 5d9129e294fc4f518793ae9f9a15dbff'}}request(options, function (error, response, body) {if (error || response.statusCode != 200) {console.log("error " + error);return } console.log(body.day_weether);});
};
很简单的一个 nodejs 函数,刚刚接触函数计算往往会意气风发的一口气抒写出这样一段代码,通常是为了简单测试一下函数的使用流程。但是发布到上去后,却出现了调用超时的问题。
大胆猜测,小心求证
首先,在无从下手的情况下,你大胆猜测如下:
- 函数入口写错了
- 代码中的逻辑有问题
- 函数计算服务有问题
为了排除其中的 3 选项,首先通过 fun local,在本地运行测试:
fun local invoke nodejs_timeout
得到结果:
可以看到,程序也被卡在这里了。由此,可以排除掉 3 的可能性。
接着,可以通过加一些日志,或者单步调试来进一步缩小排查的范围,这里选用单步调试,因为这种方法往往更简单。
首先,利用 VSCode 在侧边栏下一个断点:
然后使用以下命令将函数以调试的方式运行起来(调试基本用法 参考,这里不再过多阐述):
fun local invoke -d 3000 nodejs_timeout
然后单击 VSCode 的开始调试按钮进行调试:
可以看到,函数被正确的调用了,且进入到了入口函数。到此为止,可以排除掉 1 的可能性。
接下来,就要确认 2 可能性中存在的问题。
在 request 处的代码设置断点,continue 到里面,然后在 Local 可以看到运行到此处时的变量的值。
可以看到,http 请求返回的 resposne 的 statusCode 为 200,符合预期。body 也是有数据的,这个也符合预期。
把 body.weakday
放到 watch 里面执行一下,看下结果。
这个就不是预期中的值了。
仔细看下 body 这个对象,发现其显示格式不对,通过 typeof 将 body 的类型打印出来:
这货竟然是个 string
!
刚想破口大骂,但一想这代码是自己写的,赶紧闭嘴。
那就转成 json 吧。
但转完后,发现事情更不对了,day_weether 并不直接在 body 下,而是隐藏的很深。
而且名字不叫 day_weether,这里有个拼写错误。正确的写法应该是:
JSON.parse(body).showapi_res_body.f1.day_weather
What the.... 脏话都到嘴边了,但一想代码自己写的,总不能骂自己吧,赶紧修吧。
把正确的表达式贴到 Watch 里面,查看,果然能够取到正确的值:
验证完毕后,将正确的值粘贴到代码中,心想,总算解决了。
重新运行一下函数,发现果然能够取到数据了:
但函数依旧卡在这里,并没有继续往下走————超时的问题依旧存在!
现在,愤怒的心情已经没有了,取而代之的是蓝瘦,香菇。站起身,望望窗外,让冷风肆虐你的脸庞。许久,心里平静一些了。
山穷水尽,柳暗花明
冷静下来,理一理线索:
从刚才的调试结果来看,函数已经运行,且获得了正确的结果,但是函数却没有结束,直到超时。突然,一个隐约的答案在你身边徘徊,你拼命想要抓住,来回踱步,蓦地,像是出现了救命稻草一般,打开了函数计算 Nodejs 的 文档,你用尽力气摆动眼球,快速阅读文档,并在心里恳求那根救命稻草的出现。恍然间,你如同穿越了一道厚重的铁门,身边的光线突然由暗变亮,你被这明亮的光线刺的睁不开眼睛。但你知道,答案就在这刺眼的光芒里。眼泪,没能止住,顺着你的脸庞缓慢地流了下来。终于,你松开了紧握的拳头,弯下了一直挺直的腰板,眼泪鼻涕突然倾泻而出,你————失声痛哭。所有的委屈从内心经过喉咙、鼻子、眼睛发泄出来,伴随着这一阵阵渐渐衰弱的回荡声,远去。
哭罢,擦干眼泪,平复下自己的心情,将那一段你追寻许久的答案缓慢但却有力的敲击出来:
callback(null, JSON.parse(body).showapi_res_body.f1.day_weather);
终于,这段代码就如同你家叛逆的孩子,脱去叛逆的伪装,显现出它乖巧的样子:
欲善其事,先利其器
经过这一次事件,你总结出三条经验:
- 写代码要耐心、细心,每一段代码都要经过思考。一口气将功能写完,往往是看上去写的快,但实际上会埋很多坑,坑到别人还好,往往不小心会把自己坑了。
- 要多读文档。使用语言,要读语言文档,使用第三方库,要读库的文档,使用产品,要读产品文档。如果不仔细阅读仅凭自己的猜测去写,写出的代码往往漏洞百出。男人千万不要硬撑,别对自己这么很。累了要休息,可以读读文档放松下。俗话说得好,磨刀不误砍柴工!
- Fun 工具的熟练使用重中之重。 在前两点都没做到的情况下,却能最终将问题排查出来,Fun 工具功不可没!但与之功劳成反比的是,对 Fun 工具的学习尤其是本地调试功能,花的时间反而是最少的,如此巨大的收益比,使自己下定决心,一定要再花些时间,把 Fun 工具 吃透!
总结完,你又用心的看着自己写下的代码,就如同看向自己的孩子,宠溺、疼爱、气愤各种心情夹杂在一起。突然,你一皱眉,呵斥道:这样不对,异常的时候,也要返回!
于是,你纠正了代码的错误行为:
if (error || response.statusCode != 200) {console.log("error " + error);callback(error, null) ;
}
就如同,训斥完与人打架的孩子,看到孩子听话了,你露出了欣慰的微笑。
阅读原文
更多技术干货 请关注阿里云云栖社区微信号 :yunqiinsight
转载于:https://my.oschina.net/u/3827390/blog/2988004
开发函数计算的正确姿势 —— 排查超时问题相关推荐
- 开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试
前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...
- 开发函数计算的正确姿势——支持 ES6 语法和 webpack 压缩
为什么80%的码农都做不了架构师?>>> 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算 ...
- 开发函数计算的正确姿势——轻松解决大依赖部署
前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...
- 开发函数计算的正确姿势 —— 移植 next.js 服务端渲染框架
为什么80%的码农都做不了架构师?>>> 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算 ...
- aptitude安装出现依赖_开发函数计算的正确姿势——依赖安装方法一览
1. 前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函 ...
- 开发函数计算的正确姿势 —— 爬虫
2019独角兽企业重金招聘Python工程师标准>>> 在 <函数计算本地运行与调试 - Fun Local 基本用法> 中,我们介绍了利用 Fun Local 本地运行 ...
- 开发函数计算的正确姿势———为 PHP 运行时添加自定义扩展
PHP 语言提供了一种扩展机制(Extension),通过 PHP 扩展可以增强语法.调用 C/C++ 实现的库函数以及优化执行性能.PHP 扩展是与平台相关的动态链接库,在 Linux 和 Mac ...
- 开发函数计算的正确姿势——运行 Selenium Java
前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...
- 开发函数计算的正确姿势——使用交互模式安装依赖
前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...
最新文章
- python中io.textio_Python文件读写概述(IO操作、文件读写、stringiobytesio、序列化),python,的,小,总结,StringIOBytesIO...
- django mysql 表单_Python Django 表单提交数据到mysql并展示
- django自定义模板标签,通过键获取字典的值,屏蔽姓名等隐蔽信息并调用展示到页面上
- OpenCV学习笔记:绘图指令(矩形、圆、线、文本标注)
- 速修复!CISA警告称 Zoho 服务器0day已遭在野利用
- 头脑仅仅是一个实验室
- 系统学习数字图像处理之频域滤波
- Matlab简单教程:条件分支
- 定义一个内核panic问题
- Unix编程艺术之第一部分
- QCC频率校准工具定频
- TapTap Android电话面经
- ffmpeg -progress读取进度
- 怎么做gif?一分钟帮你搞定gif制作
- TriangleCount三角形计数
- 2022年最新版Android安卓面试题+答案精选(每日20题,持续更新中)【八】
- Storm - 事务管理
- 【封面】数字经济引领中国产业改革
- 制作简易的牛顿摆锤模型
- 金力股份冲刺科创板:拟募资13亿 比亚迪小米复星是股东