面向.NET开发人员的Dapr——服务调用

目录:

  • 面向.NET开发人员的Dapr——前言

  • 面向.NET开发人员的Dapr——分布式世界

  • 面向.NET开发人员的Dapr——俯瞰Dapr

  • 面向.NET开发人员的Dapr——入门

  • 面向.NET开发人员的Dapr——参考应用程序

  • 面向.NET开发人员的Dapr——状态管理

The Dapr service invocation building block

Dapr 服务调用构建块

Across a distributed system, one service often needs to communicate with another to complete a business operation. The Dapr service invocation building block can help streamline the communication between services.

在分布式系统中,一项服务通常需要与其他服务进行通信才能完成业务操作。 Dapr 服务调用构建块可帮助简化服务之间的通信。

What it solves

解决方法

Making calls between services in a distributed application may appear easy, but there are many challenges involved. For example:

  • Where the other services are located.

  • How to call a service securely, given the service address.

  • How to handle retries when short-lived transient errors occur.

在分布式应用程序中的服务之间进行调用可能会很简单,但会涉及到许多挑战。例如:

  • 其他服务的位置。

  • 在给定服务地址的情况下,如何安全地调用服务。

  • 在发生短暂的 暂时性错误 时如何处理重试。

Lastly, as distributed applications compose many different services, capturing insights across service call graphs are critical to diagnosing production issues.

最后,分布式应用程序由许多不同的服务构成,跨服务调用图洞察力对于诊断生产问题至关重要。

The service invocation building block addresses these challenges by using a Dapr sidecar as a reverse proxy for your service.

通过 Dapr 边车作为服务的 反向代理 ,使用服务调用构建块来解决这些难题。

How it works

工作原理

Let's start with an example. Consider two services, "Service A" and "Service B". Service A needs to call the catalog/items API on Service B. While Service A could take a dependency on Service B and make a direct call to it, Service A instead invokes the service invocation API on the Dapr sidecar. Figure 6-1 shows the operation.

让我们从一个示例开始。假设有两个服务:"服务 A" 和 "服务 B"。服务 A 需要在服务 B 上调用  catalog/items API。虽然服务 A 可能会依赖于服务 B 并直接对其进行调用,但此处服务 A 在 Dapr连车上调用服务调用 API。图6-1 显示了该操作。

Figure 6-1. How Dapr service invocation works.

图 6-1. Dapr 服务调用的工作方式。

Note the steps from the previous figure:

请注意上图中的步骤:

  1. Service A makes a call to the catalog/items endpoint in Service B by invoking the service invocation API on the Service A sidecar.      服务 A 通过调用其边车上的服务调用 API,来发出对服务B 终结点(catalog/items )的请求。

    Note      备注

    The sidecar uses a pluggable name resolution mechanism to resolve the address of Service B. In self-hosted mode, Dapr uses mDNS to find it. When running in Kubernetes mode, the Kubernetes DNS service determines the address.      边车使用可插接式名称解析机制来解析服务 B 的地址。在自承载模式下,Dapr 使用 mdn 来确定地址。在 Kubernetes 模式下运行时,Kubernetes DNS 服务将确定地址。

  2. The Service A sidecar forwards the request to the Service B sidecar.      服务 A 的边车将请求转发到服务 B 的边车。

  3. The Service B sidecar makes the actual catalog/items request against the Service B API.      服务 B 的边车对 服务 b 的终结点 catalog/items  发出实际请求。

  4. Service B executes the request and returns a response back to its sidecar.      服务 B 执行请求,并将响应返回给其边车。

  5. The Service B sidecar forwards the response back to the Service A sidecar.      服务 B 的边车将响应转发回服务A的边车。

  6. The Service A sidecar returns the response back to Service A.      服务 A 的连车将响应返回给服务 A。

Because the calls flow through sidecars, Dapr can inject some useful cross-cutting behaviors:

  • Automatically retry calls upon failure.

  • Make calls between services secure with mutual (mTLS) authentication, including automatic certificate rollover.

  • Control what operations clients can do using access control policies.

  • Capture traces and metrics for all calls between services to provide insights and diagnostics.

由于调用流过边车,Dapr 可以注入一些有用的横切(AOP思想)行为:

  • 失败时自动重试调用。

  • 服务器之间调用时使用相互 (mTLS) 身份验证(包括自动证书滚动更新)。

  • 使用访问控制策略控制客户端可以执行的操作。

  • 捕获服务间所有调用的跟踪和指标,以提供洞察和诊断。

Any application can invoke a Dapr sidecar by using the native invoke API built into Dapr. The API can be called with either HTTP or gRPC. Use the following URL to call the HTTP API:

任何应用程序都可以通过使用 Dapr 中内置的本机 调用 API 来调用 Dapr 边车。可以通过 HTTP 或 gRPC 调用 API。使用以下 URL 调用 HTTP API:

http://localhost:<dapr-port>/v1.0/invoke/<application-id>/method/<method-name>
  • <dapr-port> the HTTP port that Dapr is listening on.      Dapr 正在侦听的 HTTP 端口。

  • <application-id> application ID of the service to call.      要调用服务的应用程序 ID。

  • <method-name> name of the method to invoke on the remote service.      要在远程服务上调用的方法的名称。

In the following example, a curl call is made to the catalog/items 'GET' endpoint of Service B:

在下面的示例中, 对 Service B 的终结点 catalog/items 发出了一个"GET" 调用:

curl http://localhost:3500/v1.0/invoke/serviceb/method/catalog/items

Note

备注

The Dapr APIs enable any application stack that supports HTTP or gRPC to use Dapr building blocks. Therefore, the service invocation building block can act as a bridge between protocols. Services can communicate with each other using HTTP, gRPC or a combination of both.

Dapr Api允许支持 HTTP 或 gRPC 的任何应用程序堆栈以使用 Dapr 构建基块。因此,服务调用构建块可充当协议之间的桥梁。服务可以使用 HTTP、gRPC 或两者的组合互相通信。

In the next p, you'll learn how to use the .NET SDK to simplify service invocation calls.

在下一节中,你将了解如何使用 .NET SDK 来简化服务调用。

Use the Dapr .NET SDK

使用 Dapr .NET SDK

The Dapr .NET SDK provides .NET developers with an intuitive and language-specific way to interact with Dapr. The SDK offers developers three ways of making remote service invocation calls:

  1. Invoke HTTP services using HttpClient

  2. Invoke HTTP services using DaprClient

  3. Invoke gRPC services using DaprClient

Dapr .NET SDK 为 .net 开发人员提供了直观的、特定于语言的方式来与 Dapr 交互。SDK 为开发人员提供了三种建立远程服务调用的方式:

  1. 使用 HttpClient 调用 HTTP 服务

  2. 使用 DaprClient 调用 HTTP 服务

  3. 使用 DaprClient 调用 gRPC 服务

Invoke HTTP services using HttpClient

使用 HttpClient 调用 HTTP 服务

The preferred way to call an HTTP endpoint is to use Dapr's rich integration with HttpClient. The following example submits an order by calling the submit method of the orderservice application:

调用 HTTP 终结点的首选方法是使用 Dapr 与 HttpClient 的富集成 。下面的示例通过调用订单服务的 submit 方法来提交订单 :

var httpClient = DaprClient.CreateHttpClient();
await httpClient.PostAsJsonAsync("http://orderservice/submit", order);

In the example, DaprClient.CreateHttpClient returns an HttpClient instance that is used to perform Dapr service invocation. The returned HttpClient uses a special Dapr message handler that rewrites URIs of outgoing requests. The host name is interpreted as the application ID of the service to call. The rewritten request that's actually being called is:

在此示例中, DaprClient.CreateHttpClient 返回 HttpClient的实例, 用于执行 Dapr 服务调用。返回的 HttpClient 使用特殊的 Dapr 消息处理程序,该处理程序会重写传出请求的 uri。"http://orderservice/submit"中的主机名被解释为要调用的服务的应用程序 ID。实际调用的重写请求为:

http://127.0.0.1:3500/v1/invoke/orderservice/method/submit

This example uses the default value for the Dapr HTTP endpoint, which is http://127.0.0.1:<dapr-http-port>/. The value of dapr-http-port is taken from the DAPR_HTTP_PORT environment variable. If it's not set, the default port number 3500 is used.

此示例使用 Dapr HTTP 终结点的默认值,即 http://127.0.0.1:<dapr-http-port>/ 。 dapr-http-port 的值取自环境变量 DAPR_HTTP_PORT 。如果未设置,则使用默认端口号 3500 。

Alternatively, you can configure a custom endpoint in the call to DaprClient.CreateHttpClient:

或者,你可以在调用中配置自定义终结点 DaprClient.CreateHttpClient :

var httpClient = DaprClient.CreateHttpClient(daprEndpoint = "localhost:4000");

You can also directly set the base address by specifying the application ID. This makes it possible to use relative URIs when making a call:

还可以通过指定应用程序 ID 来直接设置基地址。这样就可以在进行调用方法时使用相对 Uri:

var httpClient = DaprClient.CreateHttpClient("orderservice");
await httpClient.PostAsJsonAsync("/submit");

The HttpClient object is intended to be long-lived. A single HttpClient instance can be reused for the lifetime of the application. The next scenario demonstrates how an OrderServiceClient class reuses a Dapr HttpClient instance:

HttpClient对象旨在长时间存在。可以在应用程序的生存期内重复使用单个 HttpClient 实例。下一个方案演示了 OrderServiceClient 类如何重用 Dapr HttpClient 实例:

public void ConfigureServices(IServiceCollection services)
{// ...services.AddSingleton<IOrderServiceClient, OrderServiceClient>(_ => new OrderServiceClient(DaprClient.CreateInvokeHttpClient("orderservice")));
}

In the snippet above, the OrderServiceClient is registered as a singleton with the ASP.NET Core dependency injection system. An implementation factory creates a new HttpClient instance by calling DaprClient.CreateInvokeHttpClient. It then uses the newly created HttpClient to instantiate the OrderServiceClient object. By registering the OrderServiceClient as a singleton, it will be reused for the lifetime of the application.

在上面的代码片段中,使用 ASP.NET Core 依赖关系注入系统将 OrderServiceClient 注册为单一实例。服务工厂通过调用 DaprClient.CreateInvokeHttpClient 创建一个新的 HttpClient 实例。然后,它使用新创建的 HttpClient 来实例化 OrderServiceClient 对象。通过将OrderServiceClient 注册 为单一实例,它将在应用程序的生存期内重复使用。

The OrderServiceClient itself has no Dapr-specific code. Even though Dapr service invocation is used under the hood, you can treat the Dapr HttpClient like any other HttpClient:

OrderServiceClient本身没有特定于 Dapr 的代码。即使在后台使用 Dapr 服务调用,你也可以像处理任何其他 HttpClient 一样处理 Dapr HttpClient:

public class OrderServiceClient : IOrderServiceClient
{private readonly HttpClient _httpClient;public OrderServiceClient(HttpClient httpClient){_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));}public async Task SubmitOrder(Order order){var response = await _httpClient.PostAsJsonAsync("submit", order);response.EnsureSuccessStatusCode();}
}

Using the HttpClient class with Dapr service invocation has many benefits:

  • HttpClient is a well-known class that many developers already use in their code. Using HttpClient for Dapr service invocation allows developers to reuse their existing skills.

  • HttpClient supports advanced scenarios, such as custom headers, and full control over request and response messages.

  • In .NET 5, HttpClient supports automatic serialization and deserialization using System.Text.Json.

  • HttpClient integrates with many existing frameworks and libraries, such as Refit, RestSharp, and Polly.

通过HttpClient 类使用 Dapr 服务调用有很多好处:

  • HttpClient 是许多开发人员已在其代码中使用的众所周知的类。通过 HttpClient 使用 Dapr 服务调用,开发人员可重复使用其现有技能。

  • HttpClient 支持高级方案,如自定义标头,以及对请求和响应消息的完全控制。

  • 在 .NET 5 中,HttpClient 使用System.Text.Js 支持 自动序列化和反序列化。

  • HttpClient 集成了许多现有框架和库 ,如Refit、 RestSharp和 Polly。

Invoke HTTP services using DaprClient

使用 DaprClient 调用 HTTP 服务

While HttpClient is the preferred way to invoke services using HTTP semantics, you can also use the DaprClient.InvokeMethodAsync family of methods. The following example submits an order by calling the submit method of the orderservice application:

尽管 通过HttpClient 使用 HTTP 语义调用服务是首选方法,但也可以使用 DaprClient.InvokeMethodAsync 方法族。下面的示例通过调用 orderservice 应用的submit 方法来提交订单:

var daprClient = new DaprClientBuilder().Build();
try
{var confirmation =await daprClient.InvokeMethodAsync<Order, OrderConfirmation>("orderservice", "submit", order);
}
catch (InvocationException ex)
{// Handle error
}

The third argument, an order object, is serialized internally (with System.Text.JsonSerializer) and sent as the request payload. The .NET SDK takes care of the call to the sidecar. It also deserializes the response to an OrderConfirmation object. Because no HTTP method is specified, the request is executed as an HTTP POST.

第三个参数( order 对象)在内部序列化 (使用 System.Text.JsonSerializer) 并作为请求负载发送。.NET SDK 负责调用边车。它还会反序列化响应为 OrderConfirmation对象 。由于未指定 HTTP 方法,因此将以 HTTP POST 的形式执行请求。

The next example demonstrates how you can make an HTTP GET request by specifying the HttpMethod:

下一个示例演示如何通过指定http谓词来发出 HTTP GET 请求:

var catalogItems = await daprClient.InvokeMethodAsync<IEnumerable<CatalogItem>>(HttpMethod.Get, "catalogservice", "items");

For some scenarios, you may require more control over the request message. For example, when you need to specify request headers, or you want to use a custom serializer for the payload. DaprClient.CreateInvokeMethodRequest creates an HttpRequestMessage. The following example demonstrates how to add an HTTP authorization header to a request message:

在某些情况下,可能需要对请求消息进行更多的控制。例如,当你需要指定请求标头,或你想要有对负载使用自定义序列化时。 DaprClient.CreateInvokeMethodRequest 创建一个 HttpRequestMessage 。下面的示例演示如何在请求消息中增加 HTTP 授权标头:

var request = daprClient.CreateInvokeMethodRequest("orderservice", "submit", order);
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);

The HttpRequestMessage now has the following properties set:

  • Url = http://127.0.0.1:3500/v1.0/invoke/orderservice/method/submit

  • HttpMethod = POST

  • Content = JsonContent object containing the JSON-serialized order

  • Headers.Authorization = "bearer <token>"

HttpRequestMessage现在具有以下属性集:

  • Url = http://127.0.0.1:3500/v1.0/invoke/orderservice/method/submit

  • HttpMethod = POST

  • Content = JsonContent 包含 order对象的json字符串

  • 授权标头= "bearer <token> "

Once you've got the request set up the way you want, use DaprClient.InvokeMethodAsync to send it:

按所需方式设置请求后,请使用 DaprClient.InvokeMethodAsync 发送此请求:

var orderConfirmation = await daprClient.InvokeMethodAsync<OrderConfirmation>(request);

DaprClient.InvokeMethodAsync deserializes the response to an OrderConfirmation object if the request is successful. Alternatively, you can use DaprClient.InvokeMethodWithResponseAsync to get full access to the underlying HttpResponseMessage:

如果请求成功,DaprClient.InvokeMethodAsync 会反序列化响应 为OrderConfirmation 对象。或者,您可以使用 DaprClient.InvokeMethodWithResponseAsync 来获取对HttpResponseMessage 底层的完全访问权限 :

var response = await daprClient.InvokeMethodWithResponseAsync(request);
response.EnsureSuccessStatusCode();var orderConfirmation = response.Content.ReadFromJsonAsync<OrderConfirmation>();

Note

For service invocation calls using HTTP, it's worth considering using the Dapr HttpClient integration presented in the previous p. Using HttpClient gives you additional benefits such as integration with existing frameworks and libraries.

备注

对于使用 HTTP 的服务调用,有必要考虑使用上一节中介绍的 Dapr HttpClient 集成。使用 HttpClient 为你提供了更多好处,例如与现有框架和库集成。

Invoke gRPC services using DaprClient

使用 DaprClient 调用 gRPC 服务

DaprClient provides a family of InvokeMethodGrpcAsync methods for calling gRPC endpoints. The main difference with the HTTP methods is the use of a Protobuf serializer instead of JSON. The following example invokes the submitOrder method of the orderservice over gRPC.

DaprClient 提供了一系列 InvokeMethodGrpcAsync 方法来调用 gRPC 终结点。与 HTTP 方法的主要区别是使用 Protobuf 序列化,而不是 JSON。下面的示例使用gRPC 调用订单服务(orderservice)的 submitOrder 方法 。

var daprClient = new DaprClientBuilder().Build();
try
{var confirmation = await daprClient.InvokeMethodGrpcAsync<Order, OrderConfirmation>("orderservice", "submitOrder", order);
}
catch (InvocationException ex)
{// Handle error
}

In the example above, DaprClient serializes the given order object using Protobuf and uses the result as the gRPC request body. Likewise, the response body is Protobuf deserialized and returned to the caller. Protobuf typically provides better performance than the JSON payloads used in HTTP service invocation.

在上面的示例中,DaprClient 使用 Protobuf 序列化给定order 对象,并使用序列化结果作为 gRPC 请求正文。同样,响应正文使用 Protobuf 反序列化并返回给调用方。与 HTTP 服务调用中使用的 JSON 负载相比,Protobuf 通常提供更好的性能。

Reference application: eShopOnDapr

参考应用:eShopOnDapr

The original eShopOnContainers microservice reference architecture from Microsoft used a mix of HTTP/REST and gRPC services. The use of gRPC was limited to communication between an aggregator service and core back-end services. Figure 6-2 show the architecture:

Microsoft 的原始 eShopOnContainers 微服务参考架构混合使用了 HTTP/REST 和 gRPC 服务。gRPC的使用 仅限于 聚合器服务 与核心后端服务之间的通信。图6-2 显示了该架构:

Figure 6-2. gRPC and HTTP/REST calls in eShopOnContainers.

图 6-2. eShopOnContainers 中的 gRPC 和 HTTP/REST 调用。

Note the steps from the previous figure:

  1. The front end calls the API gateway using HTTP/REST.

  2. The API gateway forwards simple CRUD (Create, Read, Update, Delete) requests directly to a core back-end service using HTTP/REST.

  3. The API gateway forwards complex requests that involve coordinated calls to multiple back-end services to the web shopping aggregator service.

  4. The aggregator service uses gRPC to call core back-end services.

请注意上图中的步骤:

  1. 前端使用 HTTP/REST 调用 API 网关 。

  2. API 网关直接转发简单的 CRUD (使用 HTTP/REST 将) 请求到核心后端服务。

  3. API 网关将涉及多个后端服务的协调调用的复杂请求转发到 web 购物聚合器服务。

  4. 聚合器服务使用 gRPC 来调用核心后端服务。

In the recently updated eShopOnDapr implementation, Dapr sidecars are added to the services and API gateway. Figure 6-3 show the updated architecture:

在最近更新的 eShopOnDapr 实现中,Dapr 边车被添加到各个服务和 API 网关。图6-3 显示了更新后的架构:

Figure 6-3. Updated eShop architecture using Dapr.

图 6-3。使用 Dapr 的 eShop 架构。

Note the updated steps from the previous figure:

  1. The front end still uses HTTP/REST to call the API gateway.

  2. The API gateway forwards HTTP requests to its Dapr sidecar.

  3. The API gateway sidecar sends the request to the sidecar of the aggregator or back-end service.

  4. The aggregator service uses the Dapr .NET SDK to call back-end services through their sidecar architecture.

请注意上图中更新了的步骤:

  1. 前端仍使用 HTTP/REST 调用 API 网关。

  2. API 网关将 HTTP 请求转发到其 Dapr 边车。

  3. API 网关边车将请求发送到聚合器或后端服务的边车。

  4. 聚合器服务使用 Dapr .NET SDK 通过其边车调用后端服务。

Dapr implements calls between sidecars with gRPC. So even if you're invoking a remote service with HTTP/REST semantics, a part of the transport is still implemented using gRPC.

Dapr 使用 gRPC 实现连车之间的调用。因此,即使你使用 HTTP/REST 语义调用远程服务,也仍然会在微服务间使用 gRPC 来交互。

The eShopOnDapr reference application benefits from the Dapr service invocation building block. The benefits include service discovery, automatic mTLS, and observability.

Dapr 服务调用构建块为eSheopOnDapr参考应用带来的优点包括服务发现、自动 mTLS 和可观察性。

Forward HTTP requests using Envoy and Dapr

使用 Envoy 和 Dapr 转发 HTTP 请求

Both the original and updated eShop application leverage the Envoy proxy as an API gateway. Envoy is an open-source proxy and communication bus that is popular across modern distributed applications. Originating from Lyft, Envoy is owned and maintained by the Cloud-Native Computing Foundation.

eShopOnContainers和eShopOnDapr都将 Envoy Proxy 用作 API 网关。Envoy 是一个 开放源代码和跨现代分布式应用程序常用的通信总线。源自 Lyft,Envoy 由 云原生计算基础拥有和维护。

In the original eShopOnContainers implementation, the Envoy API gateway forwarded incoming HTTP requests directly to aggregator or back-end services. In the new eShopOnDapr, the Envoy proxy forwards the request to a Dapr sidecar. The sidecar provides service invocation, mTLS, and observability.

在原始 eShopOnContainers 实现中,Envoy API 网关会将传入的 HTTP 请求直接转发到聚合器或后端服务。在 新的eShopOnDapr 中,Envoy 代理将请求转发到 Dapr 边车。边车提供服务调用、mTLS 和可观察性。

Envoy is configured using a YAML definition file to control the proxy's behavior. To enable Envoy to forward HTTP requests to a Dapr sidecar container, a dapr cluster is added to the configuration. The cluster configuration contains a host that points to the HTTP port on which the Dapr sidecar is listening:

使用 YAML 定义文件对 Envoy 进行配置,以控制代理的行为。为了使 Envoy 能够将 HTTP 请求转发到 Dapr 边车容器,会将一个 dapr 集群添加到配置中。集群配置包含一个主机,该主机指向 Dapr 边车正在侦听的 HTTP 端口:

clusters:
- name: daprconnect_timeout: 0.25stype: strict_dnshosts:- socket_address:address: 127.0.0.1port_value: 3500

The Envoy routes configuration is updated to rewrite incoming requests as calls to the Dapr sidecar (pay close attention to the prefix_rewrite key/value pair):

更新 Envoy 路由配置,以将传入请求重写为对 Dapr 边车的调用, (请注意 prefix_rewrite 键/值对) :

- name: "c-short"match:prefix: "/c/"route:auto_host_rewrite: trueprefix_rewrite: "/v1.0/invoke/catalog-api/method/"cluster: dapr

Consider a scenario where the front-end client wants to retrieve a list of catalog items. The Catalog API provides an endpoint for getting the catalog items:

假设前端客户端要检索目录项。Catalog API  提供用于获取目录项的终结点:

[Route("api/v1/[controller]")]
[ApiController]
public class CatalogController : ControllerBase
{[HttpGet("items")]public async Task<IActionResult> ItemsAsync([FromQuery] int pageSize = 10,[FromQuery] int pageIndex = 0){// ...}

First, the front end makes a direct HTTP call to the Envoy API gateway.

首先,前端直接使用http调用 Envoy API 网关。

GET http://<api-gateway>/c/api/v1/catalog/items?pageSize=20

The Envoy proxy matches the route, rewrites the HTTP request, and forwards it to the invoke API of its Dapr sidecar:

 Envoy 代理匹配路由,重写 HTTP 请求,并将请求转发到其Dapr 边车的服务调用API:

GET http://127.0.0.1:3500/v1.0/invoke/catalog-api/method/api/v1/catalog/items?pageSize=20

The sidecar handles service discovery and routes the request to the Catalog API sidecar. Finally, the sidecar calls the Catalog API to execute the request, fetch catalog items, and return a response:

 网关Envoy 的边车进行服务发现并将请求路由到Catalog API 的边车。最后,Catalog API 的边车调用Catalog API 来执行请求、提取目录项并返回响应:

GET http://localhost/api/v1/catalog/items?pageSize=20

Make aggregated service calls using the .NET SDK

使用 .NET SDK 进行聚合服务调用

Most calls from the eShop front end are simple CRUD calls. The API gateway forwards them to a single service for processing. Some scenarios, however, require multiple back-end services to work together to complete a request. For these more complex calls, eShop uses the web shopping aggregator service to mediate the workflow across multiple services. Figure 6-4 show the processing sequence of adding an item to your shopping basket:

EShop 前端的大多数调用都是简单的 CRUD 调用。API 网关将它们转发给单个服务进行处理。但在某些情况下,需要多个后端服务协调工作来完成请求。对于更复杂的调用,eShop 使用 web 购物聚合器服务来跨多个服务协调工作流。图6-4 显示了将商品添加到购物篮的序列图:

Figure 6-4. Update shopping basket sequence.

图 6-4 。更新购物篮序列图。

The aggregator service first retrieves catalog items from the Catalog API. It then validates item availability and pricing. Finally, the aggregator service saves the updated shopping basket by calling the Basket API.

聚合器服务首先从Catalog  API 中检索目录项。然后,它将验证商品的是否可用(是否有效)和价格。最后,聚合器服务通过调用Basket  API 来保存更新后的购物车。

The aggregator service contains a BasketController that provides an endpoint for updating the shopping basket:

聚合器服务包含一个 BasketController ,它提供用于更新购物篮的终结点:

[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class BasketController : ControllerBase
{private readonly ICatalogService _catalog;private readonly IBasketService _basket;[HttpPost][HttpPut]public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data, [FromHeader] string authorization){// Get the item details from the catalog API.var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));// Check item availability and prices; store results in basket object.var basket = CreateValidatedBasket(data, catalogItems);// Save the shopping basket.await _basket.UpdateAsync(basket, authorization);return basket;}// ...
}

The UpdateAllBasketAsync method gets the Authorization header of the incoming request using a FromHeader attribute. The Authorization header contains the access token that is needed to call protected back-end services.

UpdateAllBasketAsync方法使用FromHeader 特性获取传入请求的 Authorization 标头 。 Authorization 标头包含调用受保护的后端服务所需的访问令牌。

After receiving a request to update the basket, the aggregator service calls the Catalog API to get the item details. The Basket controller uses an injected ICatalogService object to make that call and communicate with the Catalog API. The original implementation of the interface used gRPC to make the call. The updated implementation uses Dapr service invocation with HttpClient support:

收到更新购物篮的请求后,聚合器服务将调用Catalog API 以获取商品详细信息。购物篮控制器使用注入的 ICatalogService 对象与Catalog API 通信。 ICatalogService 接口的原始实现使用 gRPC 进行调用。更新了的实现结合使用 Dapr 服务调用与 HttpClient 支持:

public class CatalogService : ICatalogService
{private readonly HttpClient _httpClient;public CatalogService(HttpClient httpClient){_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));}public Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids){var requestUri = $"api/v1/catalog/items?ids={string.Join(",", ids)}";return _httpClient.GetFromJsonAsync<IEnumerable<CatalogItem>>(requestUri);}// ...
}

Notice how no Dapr specific code is required to make the service invocation call. All communication is done using the standard HttpClient object.

请注意,不需要 Dapr 特定的代码就可以调用服务调用。所有通信都是使用标准 HttpClient 对象完成的。

The Dapr HttpClient is injected into the CatalogService class in the Startup.ConfigureServices method:

在 Startup.ConfigureServices 方法中将 Dapr HttpClient 注入 CatalogService 类:

services.AddSingleton<ICatalogService, CatalogService>(_ => new CatalogService(DaprClient.CreateInvokeHttpClient("catalog-api")));

The other call made by the aggregator service is to the Basket API. It only allows authorized requests. The access token is passed along in an Authorization request header to ensure the call succeeds:

聚合器服务还调用Basket API。它只允许授权的请求。在 授权 请求标头中传递访问令牌,以确保调用成功:

public class BasketService : IBasketService
{public Task UpdateAsync(BasketData currentBasket, string accessToken){var request = new HttpRequestMessage(HttpMethod.Post, "api/v1/basket"){Content = JsonContent.Create(currentBasket)};request.Headers.Authorization = new AuthenticationHeaderValue(accessToken);var response = await _httpClient.SendAsync(request);response.EnsureSuccessStatusCode();}// ...
}

In this example too, only standard HttpClient functionality is used to call the service. This allows developers who are already familiar with HttpClient to reuse their existing skills. It even enables existing HttpClient code to use Dapr service invocation without making any changes.

在此示例中,仅使用标准 HttpClient 功能来调用服务。这样,已经熟悉 HttpClient 的开发人员就可以重复使用其现有技能。甚至现有的 HttpClient 代码可以用于 Dapr 服务调用,而无需进行任何更改。

Summary

总结

In this chapter, you learned about the service invocation building block. You saw how to invoke remote methods both by making direct HTTP calls to the Dapr sidecar, and by using the Dapr .NET SDK.

本章介绍了服务调用构建块。你已了解如何通过直接 HTTP 调用 Dapr 边车并使用 Dapr .NET SDK 调用远程方法。

The Dapr .NET SDK provides multiple ways to invoke remote methods. HttpClient support is great for developers wanting to reuse existing skills and is compatible with many existing frameworks and libraries. DaprClient offers support for directly using the Dapr service invocation API using either HTTP or gRPC semantics.

Dapr .NET SDK 提供了多种方法来调用远程方法。HttpClient 支持对于需要重复使用现有技能的开发人员非常有用,并且与许多现有框架和库兼容。DaprClient 提供通过 HTTP 或 gRPC 语义直接使用 Dapr 服务调用 API 的支持。

The eShopOnDapr reference architecture shows how the original eShopOnContainers solution is modernized by using Dapr service invocation. Adding Dapr to eShop provides benefits such as automatic retries, message encryption using mTLS, and improved observability.

EShopOnDapr 参考架构显示了如何使用 Dapr 服务调用优化原始 eShopOnContainers 解决方案。将 Dapr 添加到 eShop 提供了一些优点,例如自动重试、使用 mTLS 进行消息加密,以及改进的可观察性。

目录:

  • 面向.NET开发人员的Dapr——前言

  • 面向.NET开发人员的Dapr——分布式世界

  • 面向.NET开发人员的Dapr——俯瞰Dapr

  • 面向.NET开发人员的Dapr——入门

  • 面向.NET开发人员的Dapr——参考应用程序

  • 面向.NET开发人员的Dapr——状态管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速入门深度学习,其实并不难!

深度学习的概念源于人工神经网络的研究&#xff0c;而深度学习的过程就是使用多个处理层对数据进行高层抽象&#xff0c;得到多重非线性变换函数的过程。虽然深度学习的概念看似高大上&#xff0c;让人有种莫名的距离感&#xff0c;实际上它在日常生活中随处可见&#xff0c;比…

插入始终是1_插入式电磁流量计特点与应用

一、本文引言首先&#xff0c;插入式电磁流量计是电磁流量计中的一种安装类型&#xff0c;电磁流量计的安装方式有多种&#xff0c;包括法兰式安装&#xff0c;螺纹安装&#xff0c;卡箍式安装&#xff0c;插入式安装等四种类型&#xff0c;法兰式安装是常见普遍都在使用的安装…

面向.NET开发人员的Dapr——发布和订阅

目录&#xff1a;面向.NET开发人员的Dapr——前言面向.NET开发人员的Dapr——分布式世界面向.NET开发人员的Dapr——俯瞰Dapr面向.NET开发人员的Dapr——入门面向.NET开发人员的Dapr——参考应用程序面向.NET开发人员的Dapr——状态管理面向.NET开发人员的Dapr——服务调用The …

bootstrap的表单验证 vue_第45天:Web表单

在了解了 Flask Bootstrap 基本框架之后&#xff0c;我们来了解一下 Flask 框架的 表单( form )&#xff0c;以帮助我们创建交互式的 Web 应用&#xff0c;最后会有个提交个人信息的例子。Flask-WTF 是 Flask 框架的一个扩展&#xff0c;用来做表单的交互&#xff0c;是对 WTFo…

超火GitHub项目!一夜获得5000星,竟是微软开源的计算器

全世界只有3.14 % 的人关注了数据与算法之美昨天&#xff0c;微软在 MIT License 下开源了一个 GitHub 项目——Windows 计算器&#xff0c;短短 24 小时内就获得了接近 5000 颗星&#xff0c;并引发大量讨论。这个项目爆红的速度可能连微软自己都始料未及。科技媒体 The Verge…

面向.NET开发人员的Dapr——目录

今天上午的主题就是Dapr&#xff0c;别错过了哦。本系列部分翻译自 .NET团队编写的Dapr for .NET Developers | Microsoft Docs(https://docs.microsoft.com/en-us/dotnet/architecture/dapr-for-net-developers/)&#xff0c;大部内容复制于面向 .NET 开发人员的 Dapr | Micro…

人体工学腰垫,保腰神器,改善久坐腰酸背痛

▲数据汪特别推荐点击上图进入玩酷屋之前小木推荐“德国MINICUTE人体工学腰垫”受到了大家一致的好评和争相购买。小木为什么推荐这一款原因是&#xff1a;据统计&#xff0c;我国腰椎病患者已经突破2亿人。30~40岁人群中&#xff0c;患有颈腰椎病的占比59.1%&#xff01;而且有…

和flag_不怕立Flag,就怕没有Flag

转眼间就已经是今年的最后一天了&#xff0c;回想去年给自己立下的flag&#xff0c;看着自己手机上的减肥计划和体测成绩上的超重&#xff0c;我陷入了沉思&#xff0c;到底是哪个环节出问题了呢&#xff1f;我慢悠悠地在宿舍里转圈&#xff0c;看见舍友递过来的薯片&#xff0…

面向.NET开发人员的Dapr——状态管理

目录&#xff1a;面向.NET开发人员的Dapr——前言面向.NET开发人员的Dapr——分布式世界面向.NET开发人员的Dapr——俯瞰Dapr面向.NET开发人员的Dapr——入门面向.NET开发人员的Dapr——参考应用程序The Dapr state management building blockDapr 状态管理构建基块Distributed…

为什么网易云音乐总能知道你喜欢听什么歌?背后的原理竟然如此简单!

全世界只有3.14 % 的人关注了数据与算法之美无处不在的数据分析谷歌的数据分析可以预测一个地区即将爆发的流感&#xff0c;从而进行针对性的预防&#xff1b;淘宝可以根据你浏览和消费的数据进行分析&#xff0c;为你精准推荐商品&#xff1b;口碑极好的网易云音乐&#xff0c…

判断小数是否相等_五年级上册数学综合练习题(填空、判断、选择、文字题),覆盖全册知识点!...

五年级上册判断题练习1、整数乘法的运算定律对小数乘法同样适用 .( )2、小数不一定比整数小。( )3、两个小数相除 ,如果商大于被除数 ,那么除数一定大于.( )4、两个数相除 ,商是 .8,如果除数缩小10倍,被除数不变 ,商是 0.8。( )5、小数乘法的意义与整数乘法的意义完全相…

次优二叉树

在有序序列的查找中&#xff0c;如果各个元素的查找概率都是一样的&#xff0c;那么二分查找是最快的查找算法&#xff0c;但是如果查找元素的查找概率是不一样的&#xff0c;那么用二分查找就不一定是最快的查找方法了&#xff0c;可以通过计算ASL来得知。所以基于这种查找元素…

每日一笑 | 老板,黑凤梨真的能吃吗?

全世界只有3.14 % 的人关注了数据与算法之美&#xff08;图片来源于网络&#xff0c;侵权删&#xff09;

crontab执行shell脚本日志中出现乱码

使用nutch开源的搜索引擎抓取网页信息&#xff0c;通过计划任务crontab执行shell脚本&#xff0c;并将启动信息记录进日志文件&#xff0c;但是每次都会出现乱码&#xff0c;如图所示经过反复测试&#xff0c;排除了java程序问题&#xff0c;文件权限问题&#xff0c;系统字符集…

学好数学建模,走哪买菜都不怕!

随着新学期的开始&#xff0c;数学建模的热度也在逐步回温&#xff08;据说大家开始了数学建模知识储备&#xff09;&#xff0c;常有小伙伴私聊小天咨询关于数学建模的事情。大大小小的数学建模比赛如火如荼开展着&#xff0c;而如何快速掌握数学建模&#xff0c;做好充足的准…

[翻译]Go与C#的比较,第二篇:垃圾回收

Go vs C#, part 2: Garbage Collection | by Alex Yakunin | ServiceTitan — Titan Tech | Medium目录译者注什么是垃圾回收&#xff1f;什么是GCBurn&#xff1f;峰值分配吞吐量&#xff08;"速度测试"&#xff09;GCBurn 测试GC Burn测试结果结论.NET CoreGo两者…

写在《ASP.NET MVC 4 Web 编程》即将出版之际!献给有节操的程序员!

《Programming ASP.NET MVC 4》中文版即将上市了&#xff01;非常荣幸我可以再次参与一本不错的技术书籍的翻译工作。 这也是在《WCF技术内幕》与《WCF服务编程》第三版之后&#xff0c;翻译的第三本书。此书由世界上最著名的计算机出版社Oreilly出版&#xff0c;中文版本由华中…

日本码农为了萝莉,竟然在GitHub上做这种事,“警察,快来抓我啊!”

全世界只有3.14 % 的人关注了数据与算法之美近日&#xff0c;日本刈谷市警方抓了一名13岁的小女孩&#xff0c;原因是“她将一段恶意代码的链接放到了网上&#xff0c;导致一千多台电脑系统崩溃。”其实&#xff0c;这就是一个入门级的恶作剧无限弹窗而已&#xff0c;只要你点了…

带老弟做个实时排行榜

阿巴可懂的实时排行榜设计和实现思路。大家好&#xff0c;我是鱼皮&#xff0c;暑假快到了&#xff0c;我的老弟小阿巴听说我家有很多好康的&#xff0c;就跑来找我玩。结果我摆出了几个以前开发过的小系统&#xff0c;准备在这段时间带着小阿巴多做些作品&#xff0c;学习编程…

每日一笑 | 在托运行李时,怎样才能不会因为超重被罚钱?

全世界只有3.14 % 的人关注了数据与算法之美&#xff08;图片来源于网络&#xff0c;侵权删&#xff09;