基于Docker的微服务架构-企业级服务集群实践(二)

来源:互联网 发布:mac os 10.13.1 重装 编辑:程序博客网 时间:2024/06/06 18:23

服务间的IPC机制

按照微服务的架构体系,解决了服务发现的问题之后。就需要选择合适的服务间通信的机制。如果是在Springboot应用中,使用基于Http协议的REST API是一种同步的解决方案。而且Restful风格的API可以使每个微服务应用更加趋于资源化,服务化的松耦合思想靠近。
如果每个微服务是使用DDD的思想的话,那么需要每个微服务尽量不使用同步的RPC机制。异步的基于消息的方式比如AMQP或者STOMP,来松耦合微服务间的依赖会是很好的选择。目前基于消息的点对点的pub/sub的框架选择也比较多。下面具体介绍下两种IPC的一些方案。

同步

对于同步的请求/响应模式的通信方式。可以选择基于Restful风格的Http协议进行服务间通信,或者跨语言性很好的Thrift协议。如果是使用纯Java语言的微服务,也可以使用Dubbo。如果是Springboot集成的微服务的架构体系,建议选择跨语言性好,Spring社区支持比较好的RPC。

Dubbo

Dubbo是由阿里巴巴开发的开源的Java客户端的RPC框架。Dubbo基于TCP协议的长连接进行数据传输。传输格式是使用Hessian二进制序列化。其服务注册中心可以通过zookeeper实现。

ApacheThrift

Thrift是由Facebook开发的RPC框架。其代码生成引擎可以在多种语言中,如C++, Java, Python, PHP, Ruby, Erlang, Perl等创建高效的服务。传输数据采用二进制格式,其数据包要比使用Json或者XML格式的http协议小。高并发,大数据场景下更有优势。

REST

Rest Api基于Http协议,Http协议本身具有语义的丰富性。随着Springboot被广泛使用,越来越多的基于Restful风格的API流行起来。REST是基于http协议的,所以。并且大多数开发者也是熟知http的。
这里另外提一点,很多公司或者团队也是使用Springboot的,也在说自己是基于Restful风格的。但是事实其实往往是实施得并不到位。对于你的Restful是否是真的Restful,可以参考这篇文章,对于Restful风格API的成熟度进行了四个层次的分析: Richardson Maturity Model steps toward the glory of REST。

如果使用Springboot的话,无论使用什么服务发现机制,都可以通过Spring的RestTemplate来做基础的Http请求封装。
如果使用的前文提到的Netflix-Eureka的话,可以使用Netflix-FeignFeign是一个声明式Web Service客户端。客户端的负载均衡使用Netflix-Ribbon

异步

在微服务架构中,排除纯粹的“事件驱动架构”,使用消息队列的场景一般是为了进行微服务之间的解耦。服务之间不需要了解是由哪个服务实例来消费或者发布消息。只要处理好自己领域范围的逻辑,然后通过消息通道来发布,或者订阅自己关注的消息就可以。目前开源的消息队列技术也很多。比如Apache Kafka,RabbitMQ,Apache ActiveMQ,以及阿里巴巴的RocketMQ。目前已经成为Apache项目之一。
消息队列的模型中,主要的三个组成就是:

  • Producer: 消息生产者,将消息写入channel。
  • Message Broker:消息代理,将写入channel的消息按队列的结构进行管理。负责存储/转发消息。Broker一般是需要单独的搭建,配置的集群,而且必须是高可用的。
  • Consumer:消息的消费者。目前大多数的消息队列都是保证消息至少被消费一次。所以根据使用的消息队列设施不同,消费者要做好幂等。

不同的消息队列的实现,消息模型不同。各个框架的独有的特性也不同:

RabbitMQ

RabbitMQ是AMQP协议的开源实现,由以高性能、可伸缩性出名的Erlang写成。目前客户端支持Java、.Net/C#和Erlang。在AMQP(Advanced Message Queuing Protocol)的组件中,Broker中可以包含多个Exchange(交换机)组件。Exchange可以绑定多个Queue以及其他Exchange。消息会按照Exchange中设置的Routing规则,发送到相应的Message Queue。在Consumer消费了这个消息之后,会跟Broker建立连接。发送消费消息的通知。则Message Queue才会将这个消息移除。

Kafka

Kafka是一个高性能跨语言分布式,基于发布/订阅的消息系统。Kafka开发语言为Scala。其特性是:

  • 以时间复杂度为O(1)的方式快速消息持久化;
  • 高吞吐率;
  • 支持服务间的消息分区,及分布式消费,同时保证消息顺序传输;
  • 支持在线水平扩展,自带负载均衡;
  • 支持只消费且仅消费一次(Exactly Once)模式等等。
  • 说个缺点: 管理界面是个比较鸡肋的点,可以使用开源的kafka-manager

其高吞吐的特性,除了可以作为微服务之间的消息队列,也可以用于日志收集, 离线分析, 实时分析等。
Kafka官方提供了Java版本的客户端API, Kafka社区目前也支持多种语言, 包括PHP, Python, Go, C/C++, Ruby, NodeJS等。

ActiveMQ

ActiveMQ是基于JMS(Java Messaging Service)实现的JMSProvider。JMS主要提供了两种类型的消息:点对点(Point-to-Point)以及发布/订阅(Publish/Subscribe)。目前客户端支持 Java, C, C++, C#, Ruby, Perl, Python, PHP。而且ActiveMQ支持多种协议:Stomp,AMQP,MQTT 以及OpenWire。

RocketMQ/ONS

RocketMQ是由阿里巴巴研发开源的高可用分布式消息队列。ONS是提供商业版的高可用集群。ONS支持pull/push。可支持主动推送,百亿级别消息堆积。ONS支持全局的顺序消息,以及有友好的管理页面,可以很好的监控消息队列的消费情况,并且支持手动触发消息多次重发。

小结

通过上篇的微服务的服务发现机制,加上Restful API,可以解决微服务间的同步的进程间通信。当然,既然使用了微服务,就希望所有的微服务能有合理的限界上下文(系统边界)。微服务之间的同步通信应尽量避免,以防止服务间的领域模型互相侵入。为了避免这种情况,就可以在微服务的架构中使用一层API gateway(会在下一篇介绍)。所有的微服务通过API gateway进行统一的请求的转发,合成。并且API gateway需要同时支持同步,以及NIO的异步的请求(可以提高请求合并的效率以及性能)。
消息队列可以用于微服务间的解耦。在基于Docker的微服务的服务集群环境下,网络环境会比一般的分布式集群复杂。选择一种高可用的分布式消息队列实现即可。如果自己搭建诸如Kafka,RabbitMQ集群环境的话,那对于Broker设施的高可用性会要求很高。基于Springboot的微服务的话,比较推荐使用Kafka,或者ONS。虽然ONS是商用的,但是易于管理以及稳定性高,尤其对于必要场景才依赖于消息队列进行通信的微服务架构来说,会更适合。如果考虑到会存在日志收集,实时分析等场景,也可以搭建Kafka集群。目前阿里云也有了基于Kafka的商用集群设施。
下一篇会总结一下在微服务中使用API gateway,以及服务请求的熔断机制的解决方案。

后记

后面几篇会持续总结一下:

  • 使用API Gateway 进行请求转发,合成,协议。此时再谈谈DDD
  • 怎样持续集成部署微服务
  • 服务集群的解决方案(负载均衡, 分布式缓存, 搜索技术,消息队列, 安全技术, 持久化技术)
阅读全文
1 0
原创粉丝点击