54、云发布/订阅:托管事件发布全解析

云发布/订阅:托管事件发布全解析

1. 订阅概述

订阅在其他消息传递系统中有时被称为队列,它代表了监听或消费特定主题消息的需求或意图。订阅还承担了大部分与消费者接收消息配置相关的责任,根据特定配置,可实现一些有趣的消费模式。

1.1 订阅的重要特性

  • 消息副本独立 :每个订阅都会收到发送到其主题的每条消息的不同副本,消费者可以访问主题中的消息,而不会影响其他对该主题消息感兴趣的人。一个消费者从一个订阅中读取消息,对其他订阅没有任何影响。
  • 消息全量可见 :每个订阅都能看到你在主题上发送的所有消息。如果更多消费者为该主题创建订阅,你就可以将消息广播给更广泛的受众。
  • 多消费者共享 :多个消费者可以从同一个订阅中消费消息,因此可以使用订阅将主题中的消息分发给多个消费者。一旦一个消费者从订阅中消费了一条消息,该消息就不再在同一主题上可用,下一个消费者将获得不同的消息。这种安排确保了同一订阅的两个消费者不会处理相同的消息。

1.2 订阅类型

订阅有两种类型:拉取(pull)和推送(push),这与消费者获取消息的方式有关。区别在于订阅是等待消费者请求消息(拉取),还是在新消息到达时主动向特定 URL 发送请求(推送)。

1.3 消息确认截止时间

在消息被视为已送达之前,你必须确认已收到消息。每个订阅除了推送或拉取配置外,还必须指定一个确认截止时间。这个截止时间以秒为单位,作为一个计时器,用于在假设消费者出现问题之前等待的时间。

下面是确认截止时间过期的流程图:

graph LR
    A[Consumer 1 从订阅中拉取消息] --> B[Consumer 1 在确认消息接收前异常退出]
    B --> C[确认截止时间到期]
    C --> D[消息放回订阅队列]
    D --> E[Consumer 2 拉取消息]
    E --> F[Consumer 2 确认消息接收]

2. 示例配置

假设有一个生产者向两个主题(主题 1 和主题 2)发送三条消息(消息 A、消息 B 和消息 C),有四个不同的消费者(消费者 1、消费者 2、消费者 3 和消费者 4)最终接收这些消息。

2.1 主题 1 的消息处理

生产者向主题 1 发送消息 A,消费者 1 和消费者 2 各自有自己的订阅。由于订阅会收到发送到主题的所有消息的副本,因此消费者 1 和消费者 2 都会收到消息 A 的通知。

2.2 主题 2 的消息处理

生产者向主题 2 发送消息 B 和消息 C,消费者 3 和消费者 4 使用相同的订阅(订阅 3)来消费主题 2 的消息。由于订阅每个消息只有一个副本,且消息一旦被消费者消费就不再可用,因此消息 B 和消息 C 很可能会被拆分。可能的情况是,其中一个消息(例如消息 B)会发送给消费者 3,另一个消息(例如消息 C)会发送给消费者 4。多个消费者使用同一订阅的最终结果是他们会分担工作,各自获得发送的所有消息的一部分。

不过要注意,这只是可能的情况,并非绝对。消息也可能会互换(消费者 3 收到消息 C,消费者 4 收到消息 B),或者一个消费者可能会收到消息 B 和消息 C(例如,如果其中一个消费者被其他工作压得喘不过气来)。

主题 消息 消费者 订阅情况 消息分配
主题 1 消息 A 消费者 1、消费者 2 各自有订阅 消费者 1 和消费者 2 都收到消息 A
主题 2 消息 B、消息 C 消费者 3、消费者 4 共同使用订阅 3 可能消费者 3 收到消息 B,消费者 4 收到消息 C,但不绝对

3. 实践操作

3.1 启用 API

在开始编写与云发布/订阅交互的代码之前,你必须启用 API。操作步骤如下:
1. 在浏览器中访问云控制台。
2. 在顶部的主搜索框中输入“Cloud Pub/Sub API”(记得包含斜杠)。
3. 搜索结果应该只有一个,点击它会进入一个带有大“启用”按钮的页面,点击该按钮即可启用 API。

3.2 发送第一条消息

要使用云发布/订阅广播消息,首先需要一个主题。发送消息时,使用主题对消息进行分类。可以在代码中创建主题,也可以先在云控制台中创建。

3.2.1 在云控制台创建主题
  1. 在左侧导航栏中,在“大数据”下方找到“Pub/Sub”条目并点击。
  2. 你会看到一个空页面,上面有一个按钮提示你创建主题,点击该按钮。
  3. 在出现的输入框中输入主题名称,主题的完全限定名称是一个以“projects/”开头的长路径,这可以在云发布/订阅中唯一标识你的主题。为第一个主题选择一个简单的名称,例如“first - topic”,然后点击“创建”。
3.2.2 安装 Node.js 客户端库

在编写代码之前,需要安装云发布/订阅的 Node.js 客户端库。可以使用 npm 运行以下命令进行安装:

npm install @google - cloud/pubsub@0.13.1
3.2.3 编写发布消息的代码
const pubsub = require('@google - cloud/pubsub')({    
    projectId: 'your - project - id'
});
const topic = pubsub.topic('first - topic');               
topic.publish('Hello world!').then((data) => {       
    const messageId = data[0][0];                      
    console.log('Message was published with ID', messageId);
});

运行这段代码,你会看到类似以下的输出:

> Message was published with ID 105836352786463

这里看到的消息 ID 是在该主题内保证唯一的标识符。

3.3 接收第一条消息

要从云发布/订阅接收消息,首先需要创建一个订阅。订阅是从主题消费消息的方式,主题上的每个订阅都会收到发送到该主题的每条消息的副本。

3.3.1 在云控制台创建订阅
  1. 回到 Pub/Sub 部分的主题列表,点击之前创建的主题名称。
  2. 主题展开后,会显示当前没有订阅,但右上角会有一个“新建订阅”按钮,点击该按钮。
  3. 在接下来的页面中,将订阅命名为“first - subscription”,“交付类型”暂时选择“拉取”。
  4. 点击“创建”,你会回到主题列表页面。点击你创建的主题,应该会在列表中看到你创建的订阅。
3.3.2 编写消费消息的代码
const pubsub = require('@google - cloud/pubsub')({
    projectId: 'your - project - id'
});
const topic = pubsub.topic('first - topic');          
const subscription = topic.subscription('first - subscription');                              
subscription.pull().then((data) => {            
    const message = data[0][0];
    console.log('Got message', message.id, 'saying', message.data);
});

运行上述代码,你会看到类似以下的输出:

> Got message 105838342611690 saying Hello world!

不过,这里遗漏了一个重要步骤:确认消息。如果在大约 10 秒后再次运行相同的代码,你会再次得到相同的消息。这是因为订阅知道已经将消息提供给了消费者,但消费者从未确认收到该消息。

3.3.3 编写消费并确认消息的代码
const pubsub = require('@google - cloud/pubsub')({
    projectId: 'your - project - id'
});
const topic = pubsub.topic('first - topic');
const subscription = topic.subscription('first - subscription');
subscription.pull().then((data) => {
    const message = data[0][0];
    console.log('Got message', message.id, 'saying', message.data);
    message.ack().then(() => {                           
        console.log('Acknowledged message ID', message.id,
        'with ackId', message.ackId);              
    });
});

运行这段代码,你会看到消费者向云发布/订阅发送确认消息,表明已收到该消息。再次尝试拉取消息时,会发现该消息已消失,因为云发布/订阅认为该消息已从该订阅中消费,不会再次发送给同一订阅。

4. 推送订阅

到目前为止,你接收的所有消息都是从订阅中拉取的,即你明确要求订阅提供可用的消息。不过,还有另一种消费消息的方式,不需要你主动请求,而是云发布/订阅在新消息到达时将其推送给你。

4.1 推送订阅的配置

这种类型的订阅需要你配置当新消息到达时,云发布/订阅应将推送通知发送到哪里。通常,发布/订阅会向你指定的端点进行 HTTP 调用,其中包含与使用常规拉取订阅时相同的消息数据。

4.2 处理推送通知

首先,你需要编写一个处理程序,该处理程序接受带有消息体的传入 HTTP 请求。处理程序收到消息后,负责确认消息,但确认推送消息的方式与拉取订阅有所不同。使用拉取订阅时,你需要单独调用云发布/订阅,告知其你已收到并处理了消息;而使用推送订阅时,你将依靠 HTTP 响应代码来进行通信。在这种情况下,HTTP 代码 204(无内容)表示你已成功接收并处理了消息,任何其他代码(例如 500 服务器错误或 404 未找到)则表示出现了某种故障。

以下是一个使用 Express.js 编写的简单处理程序示例:

const express = require('express');
const app = express();
app.post('/message', (req, res) => {
    console.log('Got message:', req.message);    
    res.status(204).send()                         
});

4.3 创建推送订阅

要指示云发布/订阅将消息发送到这个处理程序,你可以通过创建一个配置了 URL 的新订阅来实现。以下是使用云控制台创建推送订阅的步骤:
1. 在控制台的 Pub/Sub 区域,你可以重用之前创建的主题(first - topic),直接创建新订阅。
2. 假设你已将带有基本处理程序的简单 Express.js 应用部署到自己的域名(例如 your - domain.com)。浏览到该主题并点击顶部的“创建订阅”按钮,你会看到一个表单,在其中可以指定订阅名称和推送消息的 URL。例如,将订阅名称设为“push - subscription”,URL 设为“https://your - domain.com/message”(注意代码中的路径是“/message”)。
3. 点击“创建”后,云发布/订阅会将该主题的传入消息路由到你的处理程序,无需进行拉取或确认操作。

注意 :你可能会收到关于是否拥有该域名的错误提示,这是正常现象,这是 Google 确保消息仅发送到你拥有的域名的方式。要了解如何将你的域名列入白名单以用作 Pub/Sub 推送端点,请查看 https://cloud.google.com/pubsub/docs/push#other - endpoints。

下面是一个 mermaid 流程图,展示了推送订阅的处理流程:

graph LR
    A[新消息到达主题] --> B[Pub/Sub 向指定 URL 发送 HTTP 请求]
    B --> C[处理程序接收消息]
    C --> D{处理是否成功?}
    D -- 是 --> E[返回 204 状态码]
    D -- 否 --> F[返回其他状态码]
    E --> G[Pub/Sub 认为消息处理成功]
    F --> H[Pub/Sub 认为消息处理失败]

5. 了解定价

与许多 Google Cloud API 一样,云发布/订阅仅根据你实际使用的资源和计算量收费。发布/订阅根据你通过系统广播的数据量进行计费,最高费率为每千兆字节数据 0.06 美元。虽然这大致与消息数量相关,但具体费用还取决于你发送的消息大小。例如,与其通过消息发送整个视频文件的内容,不如发送视频的链接,这样不仅因为发布/订阅并非专门设计用于发送大视频文件,而且发送链接的成本要低得多,从其他地方(如 Google Cloud Storage)下载视频文件可能会便宜得多。

5.1 具体示例分析

假设你的系统每秒发送五条消息,有 100 个消费者对这些消息感兴趣,且这些消息非常小。下面来计算一下一个月的费用:
- 计算消息总数
- 每天有 86400 秒,为了简化计算,假设一个月平均有 30 天,那么一个月共有 2592000 秒。
- 由于每秒发送五条消息,所以一个月总共发送的消息数为 12960000 条。
- 计算请求总数
- 每条消息需要进行一次发布请求,这是发送消息的必要操作。
- 每个消费者需要对每条消息进行一次拉取请求(或通过推送订阅接收消息),即每个消息对应 100 个额外请求。
- 一个月发送 12960000 条消息,100 个消费者总共会进行 1296000000 次拉取(或推送)请求。

5.2 费用总结

虽然这里没有给出具体的费用数值,但可以看出,消息的大小和请求的数量都会影响最终的费用。在使用云发布/订阅时,需要根据实际情况合理设计消息内容和消费方式,以控制成本。

项目 数量
每秒发送消息数 5 条
一个月的秒数 2592000 秒
一个月发送的消息总数 12960000 条
消费者数量 100 个
一个月的拉取(或推送)请求总数 1296000000 次

通过以上内容,你应该对云发布/订阅的使用方式、推送订阅的处理以及定价有了较为全面的了解,可以根据实际需求合理运用云发布/订阅服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值