分布式系统组件的选型
这节我们来讲讲分布式相同类型的框架和组件该如何选型。
分布式、微服务和集群的定义
首先我们得了解什么是这三种东西分别代表的是什么意思。
分布式:
分布式官方给的名词解释是 “分布式系统(distributed system)是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。”简单点说分布式就是将一个业务拆分成多个子业务,部署在多台服务器上,从而分散服务器的压力,提升吞吐量。
集群
集群跟分布式正好相反,它是将一个业务同时部署在多个服务器中,当一个服务器因某种原因宕机时,可以及时切换到另一服务器,从而实现高可用。
微服务
微服务是一种架构思想,一个大型复杂软件应用由一个或多个微服务组成,系统中各个微服务可以独立部署,互不影响,每个微服务只关注完成一个任务,而这个任务一般指的是系统中的一个业务。
总结
分布式是微服务的一种实现,而在系统中分布式和集群之间一定是搭配使用的,每个子业务之间搭配集群,从而实现高并发与高可用。
CAP原则
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。
它的精髓在于它无法同时满足一致性、可用性和分区容错性,要么CA、要么CP、要么AP,无法满足CAP。
Springcloud和Dubbo
Springcloud是Spring公司开源的微服务框架,SpirngCloud 定位为微服务架构下的一站式解决方案。而Dubbo是阿里巴巴开源的RPC框架,Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。下面有张图列出的它们之间的区别:
从中可以看出Spring Cloud 的功能很明显比 Dubbo 更加强大,涵盖面更广,而且作为 Spring 的旗舰项目,它也能够与 Spring Framework、Spring Boot、Spring Data、Spring Batch 等其他 Spring 项目完美融合,这些对于微服务而言是至关重要的。
SpringCloud生态丰富,功能完善,更像是品牌机,Dubbo则相对灵活,可定制性强,更像是组装机。
Feign和Dubbo远程调用的差异
Feign是springcloud的远程调用方式,它是基于HTTP实现的,所有的接口都是restful风格,接口规范统一,实现接口的微服务可以采用任意语言或技术开发。但受限于http协议本身的特点,请求和响应格式臃肿,其通信效率相对会差一些。
Dubbo框架默认采用Dubbo自定义通信协议,与Http协议一样底层都是TCP通信。但是Dubbo协议自定义了Java数据序列化和反序列化方式、数据传输格式,因此Dubbo在数据传输性能上会比Http协议要好一些。
相关概念:
1)Rest风格
REST是一种架构风格,指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
Rest的风格可以完全通过HTTP协议实现,使用 HTTP 协议处理数据通信。REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
因此请求和想要过程只要遵循http协议即可,更加灵活
SpringCloud中的Feign就是Rest风格的调用方式。
2)RPC
Remote Procedure Call,远程过程调用,就是像调用本地方法一样调用远程方法。
RPC一般要确定下面几件事情:
数据传输方式:多数RPC框架选择TCP作为传输协议,性能比较好。
数据传输内容:请求方需要告知需要调用的函数的名称、参数、等信息。
序列化方式:客户端和服务端交互时将参数或结果转化为字节流在网络中传输,那么数据转化为字节流的或者将字节流转换成能读取的固定格式时就需要进行序列化和反序列化。因为有序列化和反序列化的需求,因此对数据传输格式有严格要求,不如Http灵活
Dubbo协议就是RPC的典型代表。
注册中心的选型
设计或者选型一个服务注册中心,首先要考虑的就是服务注册与发现机制。纵观当下各种主流的服务注册中心解决方案,大致可归为三类:
1,应用内:
直接集成到应用中,依赖于应用自身完成服务的注册与发现,最典型的是Netflix提供的Eureka。
2,应用外:
把应用当成黑盒,通过应用外的某种机制将服务注册到注册中心,最小化对应用的侵入性,比如Airbnb的SmartStack,HashiCorp的Consul。
3,DNS
将服务注册为DNS的SRV记录,严格来说,是一种特殊的应用外注册方式,SkyDNS是其中的代表。但此种模式存在缓存缺陷。
除了基本的服务注册与发现机制,从开发和运维角度,至少还要考虑如下五个方面:
测活:服务注册之后,如何对服务进行测活以保证服务的可用性?
负载均衡:当存在多个服务提供者时,如何均衡各个提供者的负载?
集成:在服务提供端或者调用端,如何集成注册中心?
运行时依赖:引入注册中心之后,对应用的运行时环境有何影响?
可用性:如何保证注册中心本身的可用性,特别是消除单点故障?
各注册中心区别:
API网关Gateway和Zuul
1、Zuul:
使用的是阻塞式的 API,不支持长连接,比如 websockets。
底层是servlet,Zuul处理的是http请求
没有提供异步支持,流控等均由hystrix支持。
依赖包spring-cloud-starter-netflix-zuul。
2、Gateway:
底层依然是servlet,但使用了webflux,多嵌套了一层框架
依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter。
总结
相同点:
底层都是servlet
两者均是web网关,处理的是http请求
不同点:
gateway对比zuul多依赖了spring-webflux,在spring的支持下,功能更强大,内部实现了限流、负载均衡等,扩展性也更强,但同时也限制了仅适合于Spring Cloud套件
zuul则可以扩展至其他微服务框架中,其内部没有实现限流、负载均衡等。
zuul仅支持同步
gateway支持异步。理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定
下面再介绍几个springcloud的组件:
cloud中最常见的就是netflix五大组件了:
Eureka:服务治理组件,包括服务端的注册中心和客户端的服务发现机制;
Ribbon:负载均衡的服务调用组件,具有多种负载均衡调用策略;
Hystrix:服务容错组件,实现了断路器模式,为依赖服务的出错和延迟提供了容错能力;
Feign:基于Ribbon和Hystrix的声明式服务调用组件;
Zuul:API网关组件,对请求提供路由及过滤功能。
其余SpringCloud中还有:
Spring Cloud Bus,用于传播集群状态变化的消息总线,使用轻量级消息代理链接分布式系统中的节点,可以用来动态刷新集群中的服务配置。
Spring Cloud Consul,基于Hashicorp Consul的服务治理组件。
Spring Cloud Security,安全工具包,对Zuul代理中的负载均衡OAuth2客户端及登录认证进行支持。
Spring Cloud Sleuth,Spring Cloud应用程序的分布式请求链路跟踪,支持使用Zipkin、HTrace和基于日志(例如ELK)的跟踪。
Spring Cloud Stream,轻量级事件驱动微服务框架,可以使用简单的声明式模型来发送及接收消息,主要实现为Apache Kafka及RabbitMQ。
Spring Cloud Task,用于快速构建短暂、有限数据处理任务的微服务框架,用于向应用中添加功能性和非功能性的特性。
Spring Cloud Zookeeper,基于Apache Zookeeper的服务治理组件。
Spring Cloud Gateway,API网关组件,对请求提供路由及过滤功能。
Spring Cloud OpenFeign,基于Ribbon和Hystrix的声明式服务调用组件,可以动态创建基于Spring MVC注解的接口实现用于服务调用,在Spring Cloud 2.0中已经取代Feign成为了一等公民。