服务调用概述
服务调用构建块概述
介绍
通过服务调用,应用程序可以使用 gRPC 或 HTTP 这样的标准协议来发现并可靠地与其他应用程序通信。
在许多具有多个需要相互通信的服务的环境中,开发者经常会问自己以下问题:
- 我如何发现和调用不同服务上的方法?
- 我如何安全地调用其他服务?
- 我如何处理重试和瞬态错误?
- 我如何使用分布式跟踪来查看调用图来诊断生产中的问题?
Dapr 通过提供服务调用 API 来应对这些问题,这种调用 API 作为反向代理与内置的服务发现相结合, 同时利用内置分布式跟踪、计量、错误处理、加密等功能。
Dapr 采用边车(Sidecar)、去中心化的架构。 要使用 Dapr 来调用应用程序,请在任意 Dapr 实例上使用 invoke
这个API。 sidecar 编程模型鼓励每个应用程序与自己的 Dapr 实例对话。 Dapr 实例会相互发现并进行通信。
调用逻辑
下图是 Dapr的服务调用如何工作的总览图
服务 A 对服务 B 发起HTTP/gRPC的调用。
Dapr discovers Service B’s location using the name resolution component which is running on the given hosting platform.
Dapr 将消息转发至服务 B的 Dapr 边车
注: Dapr 边车之间的所有调用考虑到性能都优先使用 gRPC。 仅服务与 Dapr 边车之间的调用可以是 HTTP 或 gRPC
服务 B的 Dapr 边车将请求转发至服务 B 上的特定端点 (或方法) 。 服务 B 随后运行其业务逻辑代码。
服务 B 发送响应给服务 A。 响应将转至服务 B 的边车。
Dapr 将消息转发至服务 A 的 Dapr 边车。
服务 A 接收响应。
特性
服务调用提供了一系列特性,使您可以方便地调用远程应用程序上的方法。
命名空间作用域
服务调用支持跨命名空间调用。 在所有受支持的托管平台上, Dapr 应用程序标识(ID)遵循包含了目标命名空间的有效 FQDN 格式。
例如,以下字符串包含应用程序标识 nodeapp
以及应用程序在 production
中运行的名称空间。
localhost:3500/v1.0/invoke/nodeapp.production/method/neworder
这在 Kubernetes 集群中进行跨命名空间调用特别有用。 观看此演示视频以获取有关如何使用具有命名空间的服务调用。
服务间安全性
Dapr 应用程序之间的所有调用都可以通过托管平台上的相互(mTLS) 身份验证来安全,包括通过 Dapr 哨兵服务来自动证书翻转(certificate rollover)。 下面的图表显示了自托管的应用程序。
For more information read the service-to-service security article.
重试
应用程序可以控制哪些其他应用程序允许调用它们,以及通过访问策略授权它们做什么。 这使您能够限制敏感应用,也就是说有人员信息的应用被未经授权的应用访问。 与服务间安全通信相结合,提供软多租户部署。
For more information read the access control allow lists for service invocation article.
服务调用安全示例
下图是 Kubernetes 集群上的一个部署示例,使用 Dapr 化的Ingress
服务,该服务调用Service A
,使用mTLS加密服务调用,并应用访问控制策略。 Service A
接下来调用 Service B
并也使用服务调用和 mTLS。 每个服务都在不同的名称空间中运行,以增加隔离。
重试
在发生调用失败和瞬态错误的情况下,服务调用会在回退(backoff)时间段内执行自动重试。
导致重试的错误有:
- 网络错误,包括端点不可用和拒绝连接
- 因续订主调/被调方Dapr边车上的证书而导致的身份验证错误
每次调用重试的回退间隔是 1 秒,最多重试三次。 通过 gRPC 连接目标 sidecar 的超时时间为5秒。
可插拔的服务发现
Dapr can run on any hosting platform. 对于支持的托管平台,这意味着他们有一个能够发现服务的 名称解析组件。 例如,Kubernetes 名称解析组件使用 Kubernetes DNS 服务来解析在集群中运行的其他应用程序的位置。 对于本地和多个物理机器,这将使用 mDNS 协议。
Note: For local and physical machines, ensure mDNS is functioning properly.
使用 mDNS 轮询负载均衡
Dapr 使用 mDNS 协议提供轮询负载均衡的服务调用请求,例如用于本地或多个联网的物理机器。
下面的图表显示了如何运作的一个例子。 如果您有一个应用程序实例,其中包含 app ID 为 FrontEnd
和 3 个 app ID 为 Cart
的应用程序实例,并且您从 FrontEnd
应用程序到 Cart
应用程序的3个实例之间的进行轮询。 这些实例可以在同一机器上或不同的机器上。 .
注意:您可以有 N 个相同app ID的实例,对于每个应用程序来说 app ID 都是唯一的。 而且您可以有多个此应用程序的实例,其中所有这些实例都有相同的 app ID。
具有可观测性的追踪和指标
默认情况下,所有应用程序之间的调用都会被追踪,也会收集到度量(metrics),以便为应用程序提供洞察力(insights)和诊断。 这在生产场景中尤其重要。 这给您的服务之间的调用提供了调用链图和度量(metrics)。 For more information read about observability.
服务调用 API
The API for service invocation can be found in the service invocation API reference which describes how to invoke a method on another service.
Example
按照上述调用顺序,假定您有 Hello World 快速入门中描述的应用程序,在 python 应用程序调用一个 node.js 应用的地方。 这种情况下,python应用将是“service A”,Node.js应用将是“service B”。
下面的图表展示本地机器上 API 调用的顺序 1-7:
- Node.js 应用程序有一个 app ID 为
nodeapp
的 Dapr 应用程序。 当 python 应用程序通过 POSThttp://localhost:3500/v1.0/invoke/nodeapp/method/neworder
调用 Node.js 应用程序的neworder
方法时, 首先会到达 python app 的本地 dapr sidecar。 - Dapr 使用本地机器运行的名称解析组件(在这种情况下自动运行的 mDNS),发现 Node.js 应用的位置。
- Dapr 使用刚刚收到的位置将请求转发到 Node.js 应用的 sidecar。
- Node.js 应用的 sidecar 将请求转发到 Node.js 应用程序。 Node.js 应用执行其业务逻辑,记录收到的消息,然后将订单 ID 存储到 Redis (未在图表中显示)中
- Node.js应 用程序通过 Node.js sidecar 向 Python 应用程序发送一个响应。
- Dapr 转发响应到 Python 的 Dapr sidecar
- Python 应用程序收到响应。
下一步
- 遵循这些指南:
- Try out the hello world quickstart which shows how to use HTTP service invocation or try the samples in the Dapr SDKs
- Read the service invocation API specification
- Understand the service invocation performance numbers