全部产品

MNS主题触发器

更新时间:2019-06-20 16:11:52

MNS 主题触发器

阿里云消息服务(Message Service,简称 MNS) 是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。在消息服务中,主题是发布消息的目的地,发布者可以通过 PublishMessage 接口向主题发布消息, 主题的订阅者会接受到发布到主题上的消息,MNS 与阿里云函数计算(Function Compute,以下简称 FC)集成,将 MNS Topic 作为事件源接入 FC(即 Topic 的订阅者是函数),用户能仅通过实现函数就可以及时对发布在主题上的消息进行自定义处理。

mns-fc

如上图所示,对于 MNS 主题,可以支持特定的一些订阅者对象。但是不够灵活,比如:

  • 对消息进行一些高阶处理再发送给邮件或者短信。
  • http endpoint 需要有自建的服务。
  • 不能支持丰富的自定义处理,比如把消息发送给 slack 或者对于特定的消息进行持久化存储。

MNS 主题触发器就是解决上述痛点的利器,您首次使用 MNS Topic 触发器时请务必注意地域限制和注意事项。

地域限制

下面的地域是针对 MNS Topic 所在的地域,而不是函数计算所在的地域。

完全支持 MNS 主题触发器的地域

亚太东南 2(悉尼), 亚太南部 1(孟买), 华北 3(张家口),美国东部1(弗吉尼亚),亚太东南 5(雅加达), 华北 5(呼和浩特)

国内地域注意事项

华北 1(青岛), 华北 2(北京), 华东 1(杭州), 华东 2(上海), 华南 1(深圳)

目前 MNS 主题触发器处于 Beta 期间,您需要申请使用后才支持 MNS 主题触发器。

您可以在函数计算控制台,创建 MNS 主题触发器页面,选择 地域, 如果选中的地域不支持 MNS 主题触发器, 可以点击 MNS Trigger Beta 功能申请.

mnssq

暂不支持 MNS 主题触发器的地域有香港、亚太东北 1(东京)、亚太东南 1(新加坡)和 美国西部1(硅谷)。

注意事项

  • 强烈建议 MNS Topic 和 函数计算的函数在相同的地域:

    虽然 MNS Topic trigger 支持 topic 和 函数在不同的地域,但是在不同的地域会增加网络延时, 尤其是函数所在的地域和 MNS 主题所在的地域分别在国内外很大概率存在被墙的风险

  • 避免出现循环调用的情况:

    您编写函数时,注意不要出现以下逻辑: topic A 触发函数 B,函数 B 又 publish 新的 message 到 topic A,从而造成函数无限循环调用

MNS 主题触发器事件定义

发布在 MNS Topic 上的消息根据 notifyContentFormat 进行处理, 即为入口函数的 event

配置 MNS Topic 触发器

触发器示例:mns_topic_trigger.yml

  1. triggerConfig:
  2. notifyContentFormat: STREAM
  3. notifyStrategy: BACKOFF_RETRY
  4. filterTag: testTag

触发器参数说明

参数名称 约束 默认值 类型 描述
notifyContentFormat STREAM, JSON STREAM string Optional, 推送给函数入参event的格式
notifyStrategy BACKOFF_RETRY, EXPONENTIAL_DECAY_RETRY BACKOFF_RETRY string Optional, 详情参考 NotifyStrategy
filterTag 不超过16个字符的字符串 string Optional, 描述了该订阅中消息过滤的标签(标签一致的消息才会被推送), 如果不限制消息推送给函数,则不需要不设置tag

入口函数event示例

  • notifyContentFormat 为 STREAM, 消息有 attr 和没有 attr 的sample event

    1. 'hello topic'
    1. {
    2. "body": "hello topic",
    3. "attrs": {
    4. "Extend": "{\\"Context\\":\\"user custom info\\"}"
    5. }
    6. }
  • notifyContentFormat 为 JSON, 消息有 attr (具体表现 event 中的 Context ) 和没有 attr 的 sample event

    1. {
    2. "Context": "user custom info",
    3. "TopicOwner": "1186202104331798",
    4. "Message": "hello topic",
    5. "Subscriber": "1186202104331798",
    6. "PublishTime": 1550216302888,
    7. "SubscriptionName": "test-fc-subscibe",
    8. "MessageMD5": "BA4BA9B48AC81F0F9C66F6C909C39DBB",
    9. "TopicName": "test-topic",
    10. "MessageId": "2F5B3C281B283D4EAC694B7425288675"
    11. }
    1. {
    2. "TopicOwner": "1186202104331798",
    3. "Message": "hello topic",
    4. "Subscriber": "1186202104331798",
    5. "PublishTime": 1550216480040,
    6. "SubscriptionName": "test-fc-subscibe",
    7. "MessageMD5": "BA4BA9B48AC81F0F9C66F6C909C39DBB",
    8. "TopicName": "test-topic",
    9. "MessageId": "2F5B3C082B923D4EAC694B76D928B5B8"
    10. }
  • topic 发布消息的 go 版本 sample 代码

    1. ...
    2. client := ali_mns.NewAliMNSClient(conf.Url,conf.AccessKeyId,conf.AccessKeySecret)
    3. topic := ali_mns.NewMNSTopic("test-topic", client)
    4. msg := ali_mns.MessagePublishRequest{
    5. MessageBody: "hello topic",
    6. //MessageTag: "testTag",
    7. MessageAttributes: &ali_mns.MessageAttributes{
    8. ExtendAttributes: &ali_mns.ExtendAttributes{
    9. Context: "user custom info",
    10. },
    11. },
    12. }
    13. _, err := topic.PublishMessage(msg)
    14. if err != nil {
    15. fmt.Println(err)
    16. return
    17. }

使用示例概述

您可以通过 函数计算控制台命令行工具fcliSDK 三种方式设置函数的 MNS 主题触发器,本文对这三种方式分别进行介绍。

示例 1:控制台新建 MNS 主题触发器

本示例展示了使用控制台设置 MNS 主题触发器的方式。可以在创建函数的时候设置触发器,也可以在函数创建完成后再设置触发器。对触发器和创建触发器有困惑的同学可以参考文档使用事件源服务创建触发器

首先登录 函数计算管理控制台,选择相应的区域和服务。如果还未新建服务,请参考创建服务

在创建函数时设置触发器

  1. 单击 创建函数,进入创建函数页面,选择 空白函数,单击下一步

  2. 选择 MNS主题触发器,并按下图进行配置

    mnsse

  1. 创建函数,填写相应信息,选择 在线编辑,并粘贴以下 python runtime的函数示例代码,单击 下一步
  1. import logging
  2. def handler(event, context):
  3. # event is messages that posted on a topic
  4. logger = logging.getLogger()
  5. logger.info("mns topic trigger event = {}".format(event))
  6. return "OK"

4.(可选)配置权限,单击 下一步, 核对信息无误后,单击 创建

在函数创建完成后设置触发器

  1. 选中已有的函数,单击 触发器 > 创建触发器

  2. 在创建触发器页面,按下图配置 MNS主题触发器,单击 确定

    注: 如果不是考虑精确粒度的授权,可以直接使用 快捷授权

    mnsse

示例 2:Fun 新建 MNS 主题触发器

Fun 提供了 MNS 触发器 的支持,可以实现函数触发器的创建。下面,我们介绍使用 Fun 配置 MNS 触发器的步骤。

在项目根目录创建一个 template.yml 文件,并将内容填充为:

  1. ROSTemplateFormatVersion: '2015-09-01'
  2. Transform: 'Aliyun::Serverless-2018-04-03'
  3. Resources:
  4. FunDemo:
  5. Type: 'Aliyun::Serverless::Service'
  6. mnsdemo:
  7. Type: 'Aliyun::Serverless::Function'
  8. Properties:
  9. Handler: index.handler
  10. Runtime: python2.7
  11. CodeUri: './'
  12. Events:
  13. my-mns-trigger:
  14. Type: MNSTopic
  15. Properties:
  16. TopicName: test-topic
  17. NotifyContentFormat: JSON
  18. NotifyStrategy: EXPONENTIAL_DECAY_RETRY
  19. FilterTag : testTag

在项目根目录创建一个 index.js,然后编写相应的逻辑代码就可以了。代码编写完成,直接执行 fun deploy 即可实现部署。另外,Fun 也支持直接创建 MNS 服务,更完整的示例请参考

如果想在本地单步调试、运行函数,可以参考 开发函数计算的正确姿势 —— 使用 Fun Local 本地运行与调试

更多的配置规则 请参考

Fun 的更多教程 请参考

示例 3:fcli 新建 MNS 主题触发器

首先,创建一个包含 Trigger Config 的 yaml 文件,对应的 yaml 文件内容如下:

  1. triggerConfig:

在对应的fuction目录下创建触发器:

  1. mkt triggerName serviceName/functionName -t mns_topic -c TriggerConfig.yaml -r acs:ram::$accountId:role/aliyunmnsnotificationrole -s acs:mns:cn-hangzhou:$accountId:/topics/$topicName
  • -r —invocation-role string设置触发角色。
  • -s —source-arn string事件源的资源符号,例如acs:mns:cn-hangzhou:123456:/topics/test-topic。
  • -c —trigger-config string设置trigger配置文件。
  • -t —type string 触发器类型。

更多fcli使用,请参考 fcli 开发指南

示例 4:SDK编程新建 MNS 主题触发器

fc-python-sdk为例演示如何通过 SDK 新建 MNS 主题触发器。函数计算还提供fc-nodejs-sdkfc-java-sdkfc-php-sdk.

新建触发器代码

  1. client = fc2.Client(
  2. endpoint='<Your Endpoint>',
  3. accessKeyID='<Your AccessKeyID>',
  4. accessKeySecret='<Your AccessKeySecret>')
  5. service_name = 'serviceName'
  6. function_name = 'functionName'
  7. trigger_name = 'triggerName'
  8. trigger_type = 'mns_topic'
  9. source_arn = 'acs:mns:cn-hangzhou:<Your Account ID>:/topics/<Your topicName>'
  10. invocation_role = 'acs:ram::<Your Account ID>:role/<Your Invocation Role>'
  11. trigger_config = {}
  12. client.create_trigger(service_name, function_name, trigger_name, trigger_type, trigger_config, source_arn, invocation_role)

函数代码

  1. import logging
  2. def handler(event, context):
  3. # event is messages that posted on a topic
  4. logger = logging.getLogger()
  5. logger.info("mns topic trigger event = {}".format(event))
  6. # to do anything, for example, record event to tablestore
  7. return "OK"

如有疑问可留言,或加入函数计算官方客户群(钉钉群号:11721331)。