我在上一篇文章中,我谈到了微服务中涉及到的设计模式。现在,我想深更深入介绍微服务架构中最重要的设计模式:微服务之间的数据通讯。当我们用于开发独立应用程序时通讯是一个艰巨的任务。我们必须仔细设计数据库表之间的关系和对象模型映射。在微服务的世界,应用系统被拆分成单独的服务,需要创建一个网格网络来进行相互通信。让我们来谈谈迄今为止为解决这个问题而发展起来的所有通讯方式和模式。
通讯方式分为同步和异步交互。让我们把这些一个接一个。
当我们说同步的,这意味着客户端向服务器发出请求,并等待响应。线程将阻塞,直到它接收到通信。最相关的HTTP协议来实现同步通信。HTTP REST或SOAP实现。最近,REST的方式越来越流行,已经大大超过了SOAP的方式。对我来说,都是很好的方法。
现在让我们来谈谈不同的flows/use cases在同步风格,我们所面临的问题,以及如何解决它们。
这种情况带来了沟通的复杂性。让我们一个接一个进行讨论。
服务A将与每个服务B、C和D紧密耦合,它必须知道每个服务的端点和凭据。
解决方案:服务发现模式用于解决这类问题。它有助于解耦的消费者和生产者的应用提供了一个查找功能。服务B, C, D可以注册自己的服务。服务发现可以实现服务器端和客户端。对于服务器端,我们有AWS ALB和NGINX工具,它们接收来自客户端的请求,发现服务,并将请求路由到指定的位置。
对于客户端,我们有Spring Eureka discovery service。使用Eureka的真正好处是它在客户端缓存可用的服务信息,因此即使Eureka服务器宕机一段时间,它也不会成为一个单一的故障点。除了Eureka,其他服务发现工具如etcd和领事也被广泛使用。
如果服务B, C, D有多个实例,他们需要知道如何做负载均衡。
解决方案:负载均衡通常与服务发现相辅相成。对于服务器端负载平衡,可以使用AWS ALB,对于客户端,可以使用Ribbon或Eureka。
如果服务B, C, D需要保护,需要认证,我们需要透过只有某些要求这些服务,如果服务和其他服务的理解不同的协议。
解决方案:API网关模式有助于解决这些问题。它可以处理身份验证、过滤和转换协议从AMQP HTTP或他人。它还可以帮助使可观测性指标,如分布式日志、监测和分布式跟踪。Apigee Zuul,中国香港的一些工具可以使用。请注意,我建议这种模式如果服务B,C和D是管理API的一部分,否则它的杀伤力有API网关。深入阅读服务网格作为一个替代解决方案。
如果服务B, C, D,如果服务仍然可以服务客户机请求的功能,它必须是相应的设计。另一个问题:假设服务B是下来,所有的请求仍然在调用服务B和耗尽资源不回应。这可以使整个系统下降和服务将无法发送请求C和D。
解决办法,断路器和隔板模式有助于解决这些问题。断路器的模式识别如果下游服务是在一定的时间和旅行线路,以避免发送调用它。检查后再重试一段定义如果服务已经回来了,关闭电路继续调用它。这有助于避免网络堵塞和耗尽资源消耗。舱壁有助于隔离资源用于服务和避免级联故障。Spring Cloud Hystrix也做同样的工作。它适用于断路器和隔板模式。
API网关通常用于管理API,它处理来自UIs或其他用户的请求并将下游的调用传递给多个微服务并回应。但当microservice要调用另一个microservice在同一组,API网关是不必要的,不是目的。最终,个别microservice负责网络通信,做安全认证,处理超时,处理故障、负载平衡、服务发现、监控和日志记录。microservice开销太大。
解决方案:服务网格模式有助于处理这类NFRs。它可以减轻我们上面讨论的所有网络功能。,其他microservicse microservices不会直接调用,但通过这个服务网格,它将处理所有的通信功能。采用这种模式的好处是,现在您可以专注于编写业务逻辑,在任何语言,比如Java,NodeJS或Python——没有担心如果这些语言支持实现所有网络功能。Istio和Linkerd解决这些需求。我唯一不喜欢Istio是限于Kubernetes现在。
当我们讨论异步通信,这意味着客户机调用服务器,接收请求的确认,和忘记。服务器将处理请求并完成它。
现在让我们来谈谈当你需要异步的风格。如果您有一个应用程序包含大量读取操作,同步风格或许是不错的选择,特别是当它需要实时数据。然而,当您有大量的写事务并且您不能承担丢失数据记录的代价时,您可能希望选择异步,因为如果下游系统宕机,并且您继续向它发送同步调用,您将丢失请求和业务事务。经验法则是永不使用异步实时数据读取和从不使用同步的关键业务写事务,除非你需要数据后立即写。你需要选择的可用性数据记录和强大的数据的一致性。
我们有不同的方式可以实现异步风格:
在这种方法中,生产者将消息发送到消息代理和他消费者可以听消息代理接收消息,并相应地处理它。在重新有两种模式:一对一和一对多。我们谈论一些同步风格带来的复杂性,但一些默认取消的消息传递样式。例如,服务发现变得无关紧要的消费者和生产者都只谈论message broker。负载均衡是由扩大消息传递系统。故障处理是内置的,主要由message broker。RabbitMQ、ActiveMQ和Kafka是云平台中用于消息传递的最著名的解决方案。
事件驱动方法类似于消息,但它服务于不同的目的。而不是发送消息时,它将发送事件细节message broker随着负载。消费者将识别的事件是什么,如何应对它。这使得更多的松散耦合。有不同类型的负载,可以通过:
还有其他风格,喜欢编排风格,但是我个人不喜欢这样。太复杂的实现。这只能通过同步方式。