使用Lambda与EventBridge SDK向事件总线发事件丢失问题排查
问题描述
我需要通过AWS Lambda使用EventBridge SDK向事件总线发送事件,供后续流程调用。本地机器测试时功能正常,但部署到AWS后事件丢失,未被事件总线接收。
核心代码如下:
function _eventData(event: any): EventBusEvent { var eventData: BusEvent = { Source: 'events.mysource.update', DetailType: 'UpdateHasMade', Detail: JSON.stringify(event), EventBusName: 'arn:aws:events:ca-central-1:1111111111:event-bus/my-eventbus' }; return { Entries: [eventData], }; } // Create an Amazon EventBridge service client object. export const ebClient = new EventBridgeClient({ region: 'ca-central-1' }); export async function dispatchEvent(event: any) { const eventData = _eventData(event); await ebClient .send(new PutEventsCommand(eventData)) .then(data => { console.log(data); console.log('Success, event sent'); }) .catch(err => { console.log('Error'); console.log(err); }); }
已确认Lambda角色拥有EventBridge和EventBridgeSchemas的全部权限,且CloudWatch日志中未发现任何报错信息,请问问题出在哪里?
解决方案
将EventBridge客户端的实例化代码移至dispatchEvent函数内部后,问题得以解决。修改后的核心代码如下:
function _eventData(event: any): EventBusEvent { var eventData: BusEvent = { Source: 'events.mysource.update', DetailType: 'UpdateHasMade', Detail: JSON.stringify(event), EventBusName: 'arn:aws:events:ca-central-1:1111111111:event-bus/my-eventbus' }; return { Entries: [eventData], }; } export async function dispatchEvent(event: any) { // 将客户端实例化移至函数内部 const ebClient = new EventBridgeClient({ region: 'ca-central-1' }); const eventData = _eventData(event); await ebClient .send(new PutEventsCommand(eventData)) .then(data => { console.log(data); console.log('Success, event sent'); }) .catch(err => { console.log('Error'); console.log(err); }); }
原因分析
Lambda的执行环境会被复用,全局声明的ebClient会在多个调用请求之间共享。当执行环境长期闲置后复用,客户端可能存在连接超时、身份凭证过期等状态异常问题,导致事件发送失败但无明显报错(因为客户端内部的异常被静默处理,或者日志未捕获到深层错误)。将客户端实例化移至函数内部后,每次函数调用都会创建全新的客户端实例,避免了复用环境带来的状态异常问题。
内容的提问来源于stack exchange,提问作者Aniruddha32
相关产品推荐
相关产品推荐

