RPM*_*984 5 .net architecture rest azure microservices
目前我有一个设置,我的客户(网络应用程序,iOS应用程序等)通过REST调用与我的后端API .NET Web应用程序(Nancy)对话.没什么特别的.
我现在需要将此API拆分为微服务,其中每个服务都可以单独升级/部署.
我的主API(公共)将只执行身份验证,然后调用我的一个微服务,它将在我的专用网络中.
我可以在主API和其他微服务API之间进行通信的不同方式是什么?每种方法的优缺点?
通信需要是实时的 - 例如,请求来自浏览器/设备,主API执行auth,然后调用微服务API然后返回响应.所以我不能使用像队列或pub/sub这样的东西.它不一定需要使用HTTP,但它需要是实时通信(请求/响应).我还有其他需要与这些微服务交谈的服务(WebJobs,云服务等)(它们也在私有网络中).
想到的唯一方法是简单的基于REST的调用.完全没问题,但延迟是这里的主要问题.
谁能推荐任何其他解决方案来解决这个问题?Azure中有什么适合这个吗?
非常感谢
Mar*_*ett 14
首先 - 澄清你在"实时","同步/异步"和"单向/双向"之间的区别.你排除的东西(队列和pub/sub)当然可以用于双向请求/响应,但它们是异步的.
第二 - 澄清"效率" - 衡量标准的效率如何?带宽?潜伏?开发时间?客户支持?
第三 - 意识到微服务的成本(其中之一)是延迟.如果您在第一次整合时遇到问题,那么您可能需要走很长的路.
我可以在主API和其他微服务API之间进行通信的不同方式是什么?每种方法的优缺点?
脱离我的头顶:
你会注意到,当我们将多个应用程序绑在一起时,这是相同的列表...因为这就是你正在做的事情.只是因为你使应用程序更小并没有真正改变太多,只是让你的系统更加分散.期望解决"普通"分布式系统所有相同的问题,然后再解决一些与部署和版本控制相关的问题.
考虑来自用户的幂等GET请求,例如"给我问题1".该客户端期望问题1的JSON响应.简单.在我预期的架构中,客户端会点击api.myapp.com,然后它会通过REST将调用代理发送到question-api.myapp.com(微服务)以获取数据,然后返回给用户.我们怎么能在这里使用pub/sub?谁是发布者,谁是订阅者?这里没有事件要提出来.我对队列的理解:一个出版商,一个消费者.发布/子主题:一个发布者,许多消费者.谁是谁?
好的 - 首先,如果我们谈论微服务和延迟 - 我们将需要一个更具代表性的例子.假设我们的客户端是Netflix移动应用程序,要显示开始屏幕,它需要以下信息:
其中每一个都由不同的微服务提供(我们称之为M1-M5).来自客户端 - >数据中心的每次呼叫都有100ms的预期延迟; 服务之间的呼叫有20ms的延迟.
让我们比较一些方法:
正如预期的那样,这是最低延迟选项 - 但需要整体服务中的所有内容,我们认为由于操作问题我们不希望这样做.
那是500ms.使用代理w/this不会有帮助 - 它只会为每个请求增加20ms的延迟(使其达到600ms).我们有1 + 2和4,以及3和5之间的依赖关系,但可以做一些异步.让我们看看这有多大帮助.
我们降到200毫秒; 还不错 - 但我们的客户需要了解我们的微服务架构.如果我们用我们的代理抽象它,那么我们有:
低至140ms,因为我们正在利用减少的服务内延迟.
很棒 - 当事情顺利进行时,与单片(#1)相比,我们的延迟仅增加了40%.
但是,与任何分布式系统一样,我们也不得不担心事情进展顺利.
当M4的延迟增加到200ms时会发生什么?那么,在客户端 - >异步微服务路由(#3)中,我们在100ms(第一批请求)中有部分页面结果,在200ms内不可用,在400ms内有摘要.在代理案例(#4)中,我们没有任何东西,直到340ms.如果微服务完全不可用,则考虑类似因素.
队列是一种在空间和时间中抽象生产者/消费者的方式.让我们看看如果我们介绍一个会发生什么:
我们的客户,订阅了P2 - 接收到单个请求的部分结果,并从M1 + M2和M4以及M3和M5之间的工作流程中抽象出来.我们在最佳情况下的延迟是140ms,与#4相同,在最坏的情况下类似于直接客户端路由(#3)w /部分结果.
我们有一个更复杂的内部路由系统,但已经获得了微服务的灵活性,同时最大限度地减少了不可避免的延迟.我们的客户端代码也更复杂 - 因为它必须处理部分结果 - 但类似于异步微服务路由.我们的微服务通常彼此独立 - 它们可以独立扩展,并且没有中央协调权限(如代理案例中).我们可以根据需要添加新服务,只需订阅适当的渠道,让客户知道如何处理我们生成的响应(如果我们为客户端消费生成一个当然).
您可以使用网关进行变体聚合响应,同时仍在内部使用队列.外观看起来很像#4,内部看起来很#5.添加一个队列(是的,我一直在使用队列,发布/订阅,主题等可互换)仍然将网关与各个微服务分离,但从客户端抽象出部分结果问题(沿着它/但是好处.
但是,添加网关确实可以集中处理部分结果问题 - 如果它在多个平台上复杂,不断变化和/或重新实现,则非常有用.
例如,假设在M4(摘要服务)不可用的情况下 - 我们有一个M4b对缓存数据进行操作(例如,星级评定已过期).M4b可以立即应答R4a和R4b,然后我们的网关可以确定它是否应该等待M4应答或者仅仅基于超时来使用M4b.
有关如何Netflix的进一步信息实际上解决了这个问题,看看以下资源:
Apache Thrift旨在实现高效通信。它由 Facebook 开发(现已开源),并且可用于 C# 的实现。
Google 开发了高效的协议缓冲区序列化机制。协议缓冲区不包括 RPC(远程过程调用),但可用于通过各种传输机制发送数据。它也可用于 C#(由 SO 自己的 Marc Gravell 项目)。