Skip to main content
消息机制为运行在同一个内核中的服务提供同步的点对点通信。发送方服务指定一个目标服务,发送一个主题(topic)和一段字节负载,然后等待目标服务返回一个回复。 当一个服务需要另一个服务执行某项操作或返回数据时,请使用消息机制。当数据应该作为状态共享、而不是作为一次请求投递时,请改用 KV 存储

消息信封

该消息就是协议中描述的 ServiceMessage 目标服务会收到一个 ServiceMessageReply 内核不会解释 topicpayloadmessage 的内容,它们的格式由参与通信的服务之间自行定义。您可以使用 JSON、某种生成的消息类型、文本,或其他编码方式,但发送方和目标方必须就此达成一致。

发送一条消息

要发送一条消息:
  1. 选择目标服务已注册的名称;
  2. 选择一个稳定的主题名称;
  3. 将请求编码进 payload;以及
  4. 通过您所用运行时对应的生成的 host 绑定发送该信封。
发送方会一直等待,直到内核把该消息分派给目标服务的消息处理程序。成功的回复中包含目标服务的 message 值。发送方服务无法自行选择或覆盖自己的身份;内核会将 source 字段替换为调用方经过身份验证的名称。

接收一条消息

目标服务收到的是同一个信封,其中包含由内核提供的 source。它应当:
  1. 验证该来源服务是否被允许请求该操作;
  2. 根据 topic 对消息进行路由;
  3. 解码并校验 payload;以及
  4. 返回一个结果或一个错误。
内核不在服务内部提供主题订阅或自动分派机制。目标服务的消息处理程序会接收发给该服务的消息,并负责解释其中的主题。只有 wasmgrpc 服务可以以这种方式接收消息——static 服务没有可供分派的处理程序。

错误与投递

消息只会被投递给当前正在运行的目标服务。以下情况会导致发送失败:
  • target 为空;
  • 目标服务未在运行;
  • 目标处理程序返回了传输或执行错误;或者
  • 目标的回复中包含非空的 error 字段。
目标返回的 error 值会作为错误返回给发送方。当目标不可用时,消息不会被投递给另一个服务。 消息不会被排队、重试、广播或持久化,没有持久化投递保证。如果目标在消息处理过程中停止,调用上下文会随着目标服务的生命周期一起被取消。

后端行为

两种服务运行时的消息语义是完全相同的:
  • WASM 服务通过生成的 host 绑定发送;以及
  • gRPC 服务通过内核的 host 回调通道发送。
内核随后会通过目标服务所用的运行时调用该服务,并将目标的回复转换回发送方对应运行时的响应类型。

身份与授权

内核会在 host 边界处对来源服务进行身份验证。服务无法通过在发送请求中写入不同的 source 值来冒充另一个服务。 内核层面不存在针对单个主题的访问策略。任何正在运行的服务都可以按名称寻址另一个正在运行的服务,因此当某个主题或负载代表一项特权操作时,目标必须在自己的处理程序中强制执行授权检查。请将 topic 视为路由信息,而不是一种访问控制机制。

设计一份消息契约

请让消息契约保持明确、且可版本化:
请为每个主题编写文档,说明负载的 schema、必需字段、响应格式以及错误含义。在使用之前校验不受信任的负载,并针对未知或格式错误的主题返回明确的错误。 请使用稳定的目标名称和主题命名空间。如果某个请求可以被安全地重复执行,请将该操作设计为幂等的,因为发送方在目标出现临时故障后,可能需要在应用层重试该请求。