我们在使用函数计算的时候,往往会用它来处理异步请求,但是比较麻烦的是,异步调用期间报错后我们没有办法及时获取,从而影响对问题的修正。
当前的办法是定时轮询异步调用
查到调用状态是失败后再后根据requestId 等信息重新触发一个新的调度任务。
这样本身不是很及时,另外轮询任务会浪费资源。
有没有更好的办法解决呢?答案是使用 事件总线 EventBridge,其基本原理如下:
函数调用异常的信息投递到事先创建好的事件总线,总线根据事件规则将关联信息投递到另外一个处理的函数上,这个函数可以负责重新发起调度任务,接下来看看怎么做。
准备工作
异常函数
我们事先在函数计算上创建一个事件函数 fc-error,并且人工准备一个异常
'use strict'; /* To enable the initializer feature (https://help.aliyun.com/document_detail/156876.html) please implement the initializer function as below: exports.initializer = (context, callback) => { console.log('initializing'); callback(null, ''); }; */ exports.handler = (event, context, callback) => { console.log('hello world'); console.log(dddd); // 这里会报错 callback(null, 'hello world'); }
处理函数
创建事件函数error-handler 处理异常的请求
'use strict'; /* To enable the initializer feature (https://help.aliyun.com/document_detail/156876.html) please implement the initializer function as below: exports.initializer = (context, callback) => { console.log('initializing'); callback(null, ''); }; */ exports.handler = (event, context, callback) => { console.log('hello world'); console.log('事件来源', event.toString()); callback(null, 'hello world'); }
开通事件总线Eventbridge
开通Eventbridge ,创建一个自定义总线 fc-error-bridge, 同时在总线上创建好error-handler的事件规则,将事件目标指向error-handler
然后回到异常函数,设置失败的通知
准备好之后我们开始着手测试异常情况
测试异步调用函数异常
系统异常
回到错误函数我们先测试一下,非业务预期的异常,选择测试函数->异步调用,然后点击调用
之后查看调用日志,说明函数异常产生了。接下来我们查看eb,通过事件追踪
发现总线接收到了函数的异常,接下来看一下处理的函数
重新模拟异常后查看这个error-handler接收到了来自总线的事件,内容跟事件总线上一致,包含requestId和异常信息
业务异常
系统异常收取到之后,业务异常你也可以通过调用eb的sdk自行投递到 事件总线中。另外可以对整个业务try catch,通过throw 直接抛出去,这样总线依然可以接收并且处理