相关概念
EdgeRoutine (以下简称er)阿里云边缘程序,是阿里云CDN推出的边缘Serverless计算环境。针对CDN场景,通过ER可在CDN边缘节点执行您自行编写的JavaScript代码。您无需关心代码部署的机器硬件配置、部署region、调度和弹性扩容。ER代码一经上传,即可完成全球阿里云CDN节点的部署,在全球边缘执行,根据您的代码逻辑个性化处理全球各地的请求。
事件总线 EventBridge (以下简称eb)是阿里云提供的一款无服务器事件总线服务,支持阿里云服务、自定义应用、SaaS应用以标准化、中心化的方式接入,并能够以标准化的 CloudEvents 1.0 协议在这些应用之间路由事件,帮助您轻松构建松耦合、分布式的事件驱动架构。
日志服务SLS(以下简称sls) 是云原生观测分析平台,为Log/Metric/Trace等数据提供大规模、低成本、实时平台化服务。一站式提供数据采集、加工、分析、告警可视化与投递功能,全面提升研发、运维、运营和安全等场景数字化能力。
一图说明
简单来说,我们只需要在eb程序中用原生fetch方法, 向由eb创建的endpoint发起请求即可,其余的都交给eb转发给sls。
操作步骤
- 开通EB并且创建一条自定义总线
- 在自定义总线中创建 HTTP/HTTPS触发的事件源
- 创建一个可以处理这个http事件源的事件规则
- 选择“日志服务”的事件目标,(需要提前准备好相同region 下的sls project 和logstore)
需要特别注意的是,刚eb需要你提供一个授权角色来对sls进行操作,这里可以点击“授权创建新角色”进入阿里云RAM界面创建Eventbridge的授信角色,RAM创建授信角色的教程放到附录。之后点击角色配置右边的刷新按钮,就可以看到创建好的角色,选中即可
5.查看事件源中的 HTTP/HTTPS触发信息,复制公网请求URL
6.在ER应用程序中增加访问eb的代码(下方代码59行)
constinit= { headers: { "content-type": "text/html;charset=UTF-8", }, } constAPI_ROUTER_REG=/^\/(prod-api|api)/g; constUPLOAD_ROUTER_REG=/^\/(uploads)\/?/g; constADMIN_OR_PORTAL_ROUTER_REG=/^\/(admin|portal)\/?/g; constAPI_PATH='/api'; constGET_TYPE= { type: "text" }; asyncfunctiongatherResponse(response) { constheaders=response.headersconstcontentType=headers.get("content-type") ||""if (contentType.includes("application/json")) { returnJSON.stringify(awaitresponse.json()) } elseif (contentType.includes("application/text")) { returnresponse.text() } elseif (contentType.includes("text/html;charset=UTF-8")) { returnresponse.text() } else { returnresponse.blob() } } asyncfunctionhandleRequest(request) { try { constrequestHeaders=request.headers||init; constedgeKv=newEdgeKV({ namespace: "myweb"}); conststaticUrl=awaitedgeKv.get('staticUrl', GET_TYPE); constapiUrl=awaitedgeKv.get('apiUrl', GET_TYPE); constportalUrl=awaitedgeKv.get('portalUrl', GET_TYPE); constebUrl=awaitedgeKv.get('ebUrl', GET_TYPE); constbody=request.body; constmethod=request.method; consturl=newURL(request.url) const { pathname, search } =url; letresponse= {}; if (pathname.match(API_ROUTER_REG)) { constmatchedData=pathname.match(API_ROUTER_REG)[0]; letfinalurl= (apiUrl+pathname+search).replace(matchedData, API_PATH); response=awaitfetch(finalurl, { headers: requestHeaders, method,body }); } elseif (pathname.match(UPLOAD_ROUTER_REG)) { letfinalurl=apiUrl+pathname+search; response=awaitfetch(finalurl, { headers: requestHeaders, method ,body}) } elseif(pathname.match(ADMIN_OR_PORTAL_ROUTER_REG)){ letfinalurl=staticUrl+pathname+search; response=awaitfetch(finalurl, { headers: requestHeaders, method }); } else { letfinalurl=portalUrl+pathname+search; response=awaitfetch(finalurl, init); } constresults=awaitgatherResponse(response) constfinalResponse=newResponse(results, response.headers); try { // 这里开始插入访问eb的代码awaitfetch(ebUrl, {method,body:JSON.stringify({path: pathname}) }); }catch(e){} returnfinalResponse; } catch (e) { returnnewResponse(JSON.stringify({ message: e.message }), { headers: { "content-type": "application/json;charset=UTF-8" } }) } } addEventListener("fetch", event=> { returnevent.respondWith(handleRequest(event.request)) })
上面实例代码没有明文显示请求地址,而是将eb的请求地址存放到了边缘存储,这样做好处是,将配置部分跟逻辑代码分离,方便做替换变更。同时避免重要信息在源代码中泄露
数据测试
可以在两个地方查看数据信息
第一个地方在eventbridge的事件追踪部分,导航目录是自定义事件->事件追踪,你可以在这里查看所有发送过来的事件信息,以及投递情况
你可以访问一下使用ER的站点,然后查询最近5分钟访问事件
可以看到事件已经投递过来,查看一下啊事件轨迹,目标投递到sls已经ready,再查看一下事件体的内容,body部分有我们传入的path属性。接下来去sls日志的控制台查看一下
第二个地方查看sls日志控制台
同样的,你得到了相关的日志信息。
更多处理
eventbridge 也可以以sls日志写入作为触发的事件源,这就意味着我们可以处理这样的场景。我们对自己关注的日志数据,比如错误访问信息,或者重要商机功能访问信息做“精确的”事件通知,所谓精确就是将事件目标用函数计算处理,可以做到@钉群的具体人员,他的访问架构如下
更多的能力集成等你发掘
附录
创建Eventbridge授信服务角色,并给其授权操作日志服务的策略
1.访问阿里云RAM控制台 ,进入角色页面,点击“创建角色”
2.选择 “阿里云服务”
输入角色名称, 选择授信服务选中“事件总线”
4 为角色授权,如果你不清楚具体应该选择哪种权限策略可以先选择“AdminstratorAccess”进行测试,之后确认操作权限后以最小权限为原则替换 AdminstratorAccess确保安全