实现高效的消息传递与队列管理:深入解析Google Cloud Pub/Sub
1. 系统设置
在现代分布式系统中,消息传递和队列管理是确保系统各部分高效协作的关键。Google Cloud Pub/Sub 是一种强大的服务,它提供了安全、持久、可扩展的消息传递能力,用于连接云中的独立系统。要开始使用 Google Cloud Pub/Sub,首先要进行系统设置。
启用 Cloud Pub/Sub API
在发布第一条消息之前,您需要先启用 Cloud Pub/Sub API。以下是具体步骤:
- 访问 Google Developers Console 。
- 选择一个项目或创建一个新项目。
- 导航到 APIs & Auth > APIs 。
- 如果未看到 Cloud Pub/Sub,请使用搜索框查找“Pub/Sub API”并启用它。
获取访问权限
Cloud Pub/Sub API 仅限授权账户使用。您需要使用服务账户进行授权。对于 Google App Engine 和 Google Compute Engine 应用程序,默认服务账户可以直接使用。如果您从其他地方调用 API,则需要创建服务账户并下载密钥文件。以下是如何创建服务账户的步骤:
- 进入 APIs & Auth > Credentials 。
- 点击 Create New Client ID ,选择 Service Account 。
- 选择 JSON 密钥并创建账户。将 JSON 文件保存在服务器的安全位置。
- 设置环境变量
GOOGLE_APPLICATION_CREDENTIALS指向密钥文件路径。
2. 主题
主题(Topic)是发布消息的地方。每个主题可以有多个订阅者,订阅者可以根据主题接收消息。以下是创建和管理主题的具体步骤:
- 创建主题:
```python
from google.cloud import pubsub_v1
project_id = ‘your-project-id’
topic_name = ‘your-topic-name’
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project_id, topic_name)
topic = publisher.create_topic(request={“name”: topic_path})
print(f”Created topic: {topic.name}”)
```
- 列出所有主题:
python topics = publisher.list_topics(project=f"projects/{project_id}") for topic in topics: print(topic.name)
3. 订阅
订阅(Subscription)是接收消息的方式。有两种类型的订阅:推送订阅和拉取订阅。
推送订阅
推送订阅会将消息发送到指定的 HTTP 端点。以下是创建推送订阅的步骤:
- 创建推送订阅:
```python
from google.cloud import pubsub_v1
project_id = ‘your-project-id’
topic_name = ‘your-topic-name’
subscription_name = ‘your-subscription-name’
push_endpoint = ‘https://your-verified-endpoint.com/push’
subscriber = pubsub_v1.SubscriberClient()
topic_path = subscriber.topic_path(project_id, topic_name)
subscription_path = subscriber.subscription_path(project_id, subscription_name)
push_config = pubsub_v1.types.PushConfig(push_endpoint=push_endpoint)
subscription = subscriber.create_subscription(
request={
“name”: subscription_path,
“topic”: topic_path,
“push_config”: push_config,
}
)
print(f”Created subscription: {subscription.name}”)
```
拉取订阅
拉取订阅允许客户端主动从服务器拉取消息。以下是创建拉取订阅的步骤:
- 创建拉取订阅:
```python
from google.cloud import pubsub_v1
project_id = ‘your-project-id’
topic_name = ‘your-topic-name’
subscription_name = ‘your-subscription-name’
subscriber = pubsub_v1.SubscriberClient()
topic_path = subscriber.topic_path(project_id, topic_name)
subscription_path = subscriber.subscription_path(project_id, subscription_name)
subscription = subscriber.create_subscription(
request={
“name”: subscription_path,
“topic”: topic_path,
}
)
print(f”Created subscription: {subscription.name}”)
```
| 类型 | 描述 |
|---|---|
| 推送订阅 | 将消息发送到指定的 HTTP 端点 |
| 拉取订阅 | 客户端主动从服务器拉取消息 |
4. 消息结构
消息是通过 Cloud Pub/Sub 传递的数据单元。每条消息都有一个唯一的 messageId ,并且可以包含以下字段:
-
data: 消息的有效负载,必须以 Base64 编码。 -
attributes: 可选属性,用于传递附加信息。 -
messageId: 消息的唯一标识符。
以下是发布消息的示例:
import base64
project_id = 'your-project-id'
topic_name = 'your-topic-name'
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project_id, topic_name)
message_data = base64.b64encode('Hello, World!'.encode('utf-8'))
attributes = {'key1': 'value1'}
future = publisher.publish(
topic_path,
data=message_data,
**attributes
)
print(future.result())
5. 处理消息
处理消息的方式取决于您使用的订阅类型。推送订阅由 Cloud Pub/Sub 自动将消息发送到指定端点,而拉取订阅则需要客户端主动拉取消息。
拉取订阅的消息处理
以下是拉取订阅处理消息的示例:
import base64
project_id = 'your-project-id'
subscription_name = 'your-subscription-name'
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
def callback(message):
print(f"Received message: {message.data.decode('utf-8')}")
print(f"Attributes: {message.attributes}")
message.ack()
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}..\n")
try:
streaming_pull_future.result(timeout=timeout)
except Exception as e:
streaming_pull_future.cancel()
streaming_pull_future.result()
以下是拉取消息的流程图:
sequenceDiagram
participant Client
participant Cloud Pub/Sub
Client->>Cloud Pub/Sub: Pull Request
Cloud Pub/Sub-->>Client: Message Batch
Client->>Cloud Pub/Sub: Acknowledge
通过以上步骤,您可以有效地设置和使用 Google Cloud Pub/Sub 进行消息传递和队列管理。继续阅读以了解更多关于确认截止期限和消息处理的最佳实践。
6. 确认截止期限
在消息传递过程中,确保消息在合理的时间内被正确处理是非常重要的。Cloud Pub/Sub 提供了确认截止期限(Acknowledgement Deadline)的功能,以防止消息在处理过程中丢失或重复处理。默认情况下,确认截止期限为60秒,但您可以根据需要调整这个时间。
修改确认截止期限
您可以为每个订阅设置不同的确认截止期限。以下是如何修改确认截止期限的示例:
from google.cloud import pubsub_v1
project_id = 'your-project-id'
subscription_name = 'your-subscription-name'
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
# 修改确认截止期限为599秒
subscriber.modify_ack_deadline(
subscription=subscription_path,
ack_ids=['ack_id_1', 'ack_id_2'],
ack_deadline_seconds=599
)
延长特定消息的确认截止期限
有时,您可能需要延长特定消息的确认截止期限。以下是如何延长特定消息确认截止期限的示例:
from google.cloud import pubsub_v1
project_id = 'your-project-id'
subscription_name = 'your-subscription-name'
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
# 延长特定消息的确认截止期限
subscriber.modify_ack_deadline(
subscription=subscription_path,
ack_ids=['ack_id_1'],
ack_deadline_seconds=600
)
| 参数 | 描述 |
|---|---|
ack_ids | 消息的确认标识符 |
ack_deadline_seconds | 新的确认截止时间(秒) |
7. 消息处理的最佳实践
在处理消息时,确保系统的健壮性和可靠性至关重要。以下是一些最佳实践:
幂等性
由于消息传递系统可能存在重复消息的情况,确保消息处理逻辑是幂等的非常重要。幂等操作意味着即使同一消息被处理多次,最终结果也不会受到影响。
消息顺序
Cloud Pub/Sub 不保证消息传递的顺序。如果您需要保持消息的顺序,可以在消息的 attributes 中添加时间戳或其他排序信息。
错误处理
处理消息时,确保有适当的错误处理机制。如果处理失败,消息将被重新加入队列,以便稍后重试。
以下是处理推送订阅消息的示例:
import base64
import json
from google.cloud import pubsub_v1
def process_push_message(request):
envelope = json.loads(request.data.decode('utf-8'))
message_data = base64.b64decode(envelope['message']['data']).decode('utf-8')
attributes = envelope['message'].get('attributes', {})
print(f"Received message: {message_data}")
print(f"Attributes: {attributes}")
# 处理消息的逻辑
# ...
return 'OK', 200
以下是处理拉取订阅消息的示例:
import base64
from google.cloud import pubsub_v1
def process_pull_message():
project_id = 'your-project-id'
subscription_name = 'your-subscription-name'
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
def callback(message):
print(f"Received message: {message.data.decode('utf-8')}")
print(f"Attributes: {message.attributes}")
# 处理消息的逻辑
# ...
message.ack()
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}..\n")
try:
streaming_pull_future.result(timeout=timeout)
except Exception as e:
streaming_pull_future.cancel()
streaming_pull_future.result()
以下是处理消息的流程图:
sequenceDiagram
participant Client
participant Cloud Pub/Sub
Client->>Cloud Pub/Sub: Pull Request
Cloud Pub/Sub-->>Client: Message Batch
Client->>Cloud Pub/Sub: Process Messages
Client->>Cloud Pub/Sub: Acknowledge
8. 示例应用:LunchMates
为了更好地理解如何在实际应用中使用 Google Cloud Pub/Sub,我们来看一个名为 LunchMates 的示例应用。LunchMates 帮助用户组织小型聚会,如午餐、饮品、咖啡等。一个关键的需求是让用户在活动结束后立即对其体验进行评分。
使用推送订阅进行通知
假设 LunchMates 与一家支付公司合作,当用户支付账单时,触发一个 Cloud Pub/Sub 消息。该消息将被发送到一个配置好的 HTTP 端点,该端点负责向用户发送评分请求。
以下是创建推送订阅并处理消息的示例代码:
import base64
import json
from google.appengine.api import mail
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class MeetingsTaskHandler(webapp.RequestHandler):
def meetingFinished(self):
sender_address = 'Lunch Mate <lunchmates@lunch--mates.appspotmail.com>'
subject = 'How was your meeting?'
body = 'Rate your last meeting!'
message = json.loads(base64.b64decode(self.request.body))
message_data = base64.b64decode(message['message']['data'])
attributes = message['message']['attributes']
if attributes:
meeting_id = int(attributes['meeting_id'])
query = MeetingRequest.for_meeting(meeting_id, 'accepted')
for request in query:
attendee = request.key.parent().get()
if attendee and mail.is_email_valid(attendee.email):
mail.send_mail(sender_address, attendee.email, subject, body)
application = webapp.WSGIApplication([('/meeting_finished', MeetingsTaskHandler)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
通过以上代码,您可以实现一个完整的消息传递和处理流程,确保用户在活动结束后立即收到评分请求。
9. 总结
通过本篇文章,我们深入了解了 Google Cloud Pub/Sub 的核心概念和使用方法,包括系统设置、主题和订阅的创建与管理、消息结构、确认截止期限以及消息处理的最佳实践。此外,我们还通过一个实际应用案例展示了如何在实际项目中使用 Cloud Pub/Sub。
Cloud Pub/Sub 是一个强大且灵活的服务,适用于各种需要高效消息传递和队列管理的场景。通过合理配置和使用,您可以显著提升应用程序的性能和可靠性。希望本文能为您提供有价值的参考,帮助您更好地理解和使用 Google Cloud Pub/Sub。
超级会员免费看
1485

被折叠的 条评论
为什么被折叠?



