【问题标题】:Communication Between two microservices using ASP.Net Core WebApi使用 ASP.Net Core WebApi 在两个微服务之间进行通信
【发布时间】:2021-07-17 08:31:09
【问题描述】:

我有两个微服务。客户第一服务,发票服务第二服务。

在 Invoice MicroService 中,我将只保存 CustomerId。使用此 CustomerId,我想检索客户微服务的所有相关数据。但我不知道异步通信。

任何人请给我一些想法。

【问题讨论】:

  • 您的通信将在服务方法(控制器 - 服务模式)中进行,对吗?您可以将其设为异步并与其他服务通信 - 这很可能是一个 http 调用,或者如果您正在使用它,则为 gRPC。

标签: c# asp.net-core asp.net-core-mvc microservices asp.net-core-webapi


【解决方案1】:

您提出的建议——特别是一个服务直接对另一个服务进行 HTTP 调用——在服务之间被称为 tight coupling,并且是微服务中的一种反模式。它实质上会将您的应用程序变成distributed monolith - 应该避免。

一个示例(有很多选项)说明如何正确地异步执行此操作并使用良好、干净的松散耦合边界,如下所示:

  • 您的系统利用了message bus(我喜欢 AMQP,但还有其他选择)
  • 创建客户后,您的Customers Service 会生成customer_created 事件
  • 您的 Invoicing Service 订阅这些事件,并在收到时进行必要的内部 customer_id 更新(这是保持其本地数据存储更新 - eventual consistency
  • 当您的 Invoicing Service 创建需要来自 Customers Service 的信息的发票时,它会生成 cust_invoice_pending 事件
  • 您的Customers Service 订阅了这个事件,当它看到一个事件时,它会在总线上生成一条新消息,例如invoice_customer_detail_push(注意,我会在此消息的有效负载中使用invoice_id 来绑定它们一起)
  • 您的 Invoicing Service 订阅并查看了它需要的数据,从而可以填充发票的其余部分

这似乎需要大量额外的工作和复杂性,但确实如此。这是成功的微服务架构的“硬”部分。这需要更多的纪律和预先计划,但在这个简单的案例中,与您提出的分布式单体相比,以下是最终解决方案的优势:

  • 您可以将 Invoicing ServiceCustomers Service 换成完全不同的东西,而无需接触其他服务中的代码
  • 您已经为这两个服务抽象出了与 authz 相关的问题 - 它们共享消息总线,只要它们都可以访问/从那里访问,彼此都不知道对方
  • 您可以允许未来的服务监控此业务流程并与之交互(创建和详细说明发票),而无需更改这两个服务中的代码
  • 如果两个服务中的一个出现故障,另一个服务将继续完全响应,并且等待故障服务恢复联机的任何工作都会自动排队 - 它在调用/接收服务之外持续存在

因此,如果在您的情况下这些好处值得权衡取舍,那就去做吧。但是,每当您看到两个“微服务”直接通信时,您可能已经忽略了一点耦合,需要重新检查信息如何在您的系统中流动。

【讨论】:

    【解决方案2】:

    我认为您只需使用 CustomerId 作为查询参数(或帖子正文,但可能不是)向您的第二个服务发送一个 http 请求。

    您需要在您的应用程序中CreateClient,然后才能执行 http 请求。

    Make HTTP requests using IHttpClientFactory in ASP.NET Core

        var request = new HttpRequestMessage(HttpMethod.Get,
            "domain_second_service/controller/method?customerId=X");
        request.Headers.Add("Accept", "application/json");
        request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
    
        var client = _clientFactory.CreateClient();
    
        var response = await client.SendAsync(request);
    

    【讨论】:

    • 感谢您的回复。其实我想获取数据(GET方法)。
    猜你喜欢
    • 2016-08-10
    • 2018-09-07
    • 1970-01-01
    • 2020-07-15
    • 2017-07-15
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多