gpt4 book ai didi

.net - 在多个.NET应用之间进行通信的最有效方法

转载 作者:行者123 更新时间:2023-12-02 09:41:29 25 4
gpt4 key购买 nike

目前,我有一个设置,其中我的客户端(Web应用程序,iOS应用程序等)通过REST调用与我的后端API .NET Web应用程序(Nancy)对话。没什么特别的。

现在,我需要将此API拆分为微服务,在微服务中,每个服务都可以单独升级/部署。

我的主要API(公共(public))将只执行身份验证,然后调用我的一个微服务,该微服务将在我的专用网络中。

我可以在主要API和其他微服务API之间进行通信的方式有哪些?每种方法的优缺点?

通信需要是实时的-例如,请求来自浏览器/设备,主API执行身份验证,然后调用微服务API,然后返回响应。所以我不能使用队列或发布/订阅之类的东西。它不一定需要使用HTTP,但必须是实时通信(请求/响应)。我还有其他服务(WebJobs,云服务等)需要与这些微服务通信(它们也在专用网络中)。

想到的唯一方法是简单的基于REST的调用。完全可以,但是延迟是这里的主要问题。

有人可以推荐其他解决方案吗? Azure中是否有适合此的东西?

非常感谢

最佳答案

首先-明确您在“实时”,“同步/异步”和“单向/双向”之间的区别。您排除的内容(队列和pub/sub)当然可以用于双向请求/响应,但它们是异步的。

第二-阐明“效率”-效率采用什么度量标准?带宽?潜伏?开发时间?客户支持?

第三-意识到微服务的成本之一是等待时间。如果这是您初次集成时遇到的问题,那么您可能还有很长的路要走。

What's the different ways i could communicate between my main API and other microservice API's? Pros/cons of each approach?



从我的头顶上:
  • 单节点和IPC上的主机:优点:性能;缺点:与部署拓扑紧密耦合;到其他节点的可达性;客户支持;失败模式
  • REST/SOAP/等。端点:优点:广泛的客户端和服务器支持;调试; Web缓存,缺点:性能;失败模式
  • 二进制协议(protocol):优点:性能;缺点:版本控制;客户端和服务器支持;调试;失败模式
  • 消息队列:优点:异步性;缺点:复杂度
  • ESB:优点:异步性;客户支持;缺点:复杂度
  • 平面文件:优点:带宽;简单;客户支持;缺点:延迟,一般的PITA

  • 您会注意到,当我们将多个应用程序绑定(bind)在一起时,这就是相同的列表...因为这就是您要做的。仅仅是因为您使应用程序变小,除了使您的系统更加分散之外,并没有太大的改变。期望解决“正常”分布式系统所具有的所有相同问题,然后再解决一些与部署和版本控制有关的问题。

    Consider an idempotent GET request from a user like "Get me question 1". That client expects a JSON response of question 1. Simple. In my expected architecture, the client would hit api.myapp.com, which would then proxy a call via REST to question-api.myapp.com (microservice) to get the data, then return to user. How could we use pub/sub here? Who is the publisher, who is the subscriber? There's no event here to raise. My understanding of queues: one publisher, one consumer. Pub/sub topic: one publisher, many consumers. Who is who here?



    好的-首先,如果我们谈论微服务和延迟-我们将需要一个更具代表性的示例。假设我们的客户是Netflix移动应用,要显示打开屏幕,它需要以下信息:
  • 热门电影ID列表
  • 最近看过的电影ID列表
  • 帐户状态
  • 对于引用的每个电影ID:名称,星星数,摘要文字
  • 您所在地区不可用的电影ID列表(将被过滤掉以免被趋势/最近观看)

  • 其中的每一个都由不同的微服务提供(我们将其称为M1-M5)。客户端->数据中心的每次调用均具有100毫秒的预期延迟;服务之间的调用有20毫秒的延迟。

    让我们比较一些方法:

    1:整体服务
  • T0 + 100ms:客户端发送对/API//StartScreen的请求;收到响应

  • 不出所料,这是最低的延迟选项-但需要单片服务中的所有内容,出于运营方面的考虑,我们决定不希望这样做。

    2:微服务
  • T0 + 100ms:客户端向M1/API/Trending
  • 发送请求
  • T1 + 100ms:客户端向M2/API//最近的
  • 发送请求
  • T2 + 100ms:客户端向M3/API//帐户发送请求
  • T3 + 100毫秒:客户端将请求发送到M4/API/Summary?movieids = []
  • T4 + 100ms:客户端将请求发送到M5/API//不可用

  • 那是500毫秒。使用带有此功能的代理无济于事-它只会为每个请求增加20毫秒的延迟(使其变为600毫秒)。我们的依赖关系在1 + 2和4之间,以及3和5之间,但是可以执行一些异步操作。让我们看看有什么帮助。

    3:微服务-异步
  • T0:客户端向M1/API/Trending
  • 发送请求
  • T0:客户端向M2/API//最近的
  • 发送请求
  • T0:客户端向M3/API//帐户发送请求
  • T0 + 200ms :(从1 + 2响应)客户端将请求发送到M4/API/Summary?movieids = []
  • T0 + 200ms :(响应3)客户端将请求发送到M5/API//不可用

  • 我们到了200毫秒;不错-但是我们的客户需要了解我们的微服务架构。如果我们通过代理抽象它,那么我们有:

    4:微服务-带网关的异步
  • T0 + 100ms:客户端向G1/API/StartScreen发送请求
  • T1:G1向M1/API/Trending
  • 发送请求
  • T1:G1向M2/API//最近的
  • 发送请求
  • T1:G1向M3/API//帐户发送请求
  • T1 + 40ms :(从1 + 2响应)G1向M4发送请求/API/Summary?movieids = []
  • T1 + 40ms :(响应3)G1将请求发送到M5/API//不可用

  • 缩短至140毫秒,因为我们正在利用减少的服务内延迟。

    太好了-当一切顺利进行时,与单片式(#1)相比,我们仅将延迟增加了40%。

    但是,与任何分布式系统一样,我们还必须担心事情进展不顺利。

    当M4的延迟增加到200ms时会发生什么?好吧,在客户端->异步微服务路由(#3)中,那么我们在100ms(第一批请求)中有部分页面结果,在200ms中不可用,在400ms中有摘要。在代理服务器情况下(#4),直到340毫秒我们什么都没有。如果微服务完全不可用,则类似的考虑。

    队列是一种抽象生产者/消费者在时间和空间上的方式。让我们看看如果引入一个会发生什么:

    5:具有异步发布/订阅的微服务
  • T0 + 100ms:客户端将请求Q0发布到P1 StartScreen,回复 channel 为P2
  • T1 + 20ms:M1看到Q0,将响应R1放在P2趋势/Q0上
  • T1 + 20ms:M2看到Q0,将响应R2放到P2最近/Q0
  • T1 + 20ms:M3看到Q0,将响应R3放在P2帐户/Q0上
  • T2 + 40ms:M4看到R1,将响应R4a放到P2摘要/Q0
  • T2 + 40ms:M4看到R2,将响应R4b放到P2摘要/Q0
  • T2 + 40ms:M5看到R3,将响应R5放在P2上不可用/Q0

  • 订阅了P2的客户-收到带有单个请求的部分结果,并从M1 + M2和M4与M3和M5之间的工作流中抽象出来。最好的情况下,我们的延迟时间为140毫秒,与#4相同,最坏的情况下,它与带有部分结果的直接客户端路由(#3)相似。

    我们涉及的内部路由系统要复杂得多,但是在增加微服务的灵活性的同时最大程度地减少了不可避免的延迟。我们的客户端代码也更复杂-因为它必须处理部分结果-但类似于异步微服务路由。我们的微服务通常彼此独立-它们可以独立扩展,并且没有中央协调机构(例如在代理案例中)。我们可以通过简单地订阅适当的 channel ,并让客户知道如何处理我们生成的响应(如果我们为客户使用而生成一个响应),来根据需要添加新的服务。

    6种微服务-带队列的网关

    您可以使用网关来汇总响应,同时仍在内部使用队列,这可以做一些变化。外部看起来很像#4,但是内部看起来很像#5。队列的添加(是的,我一直在交替使用队列,发布/订阅,主题等)仍然使网关与各个微服务脱钩,但是从客户端(连同它的客户端)中提取了部分结果问题。好处)。

    但是,添加网关确实可以使您集中处理部分结果问题-如果它很复杂,不断变化和/或在多个平台上重新实现,则很有用。

    例如,假设M4(摘要服务)不可用-我们有一个M4b对缓存的数据进行操作(例如,星级已过时)。 M4b可以立即回答R4a和R4b,然后我们的网关可以根据超时来确定它是应该等待M4回答还是只是继续使用M4b。

    有关Netflix如何实际解决此问题的更多信息,请查看以下资源:
  • 他们的API Gateway
  • fault-tolerance layer
  • 基础的消息传递模式
  • 更多about IPC in microservices
  • 关于.net - 在多个.NET应用之间进行通信的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35613841/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com