SpringCloud和Dubbo都是现在主流的微服务架构
从技术维度上,其实SpringCloud远远的超过Dubbo,Dubbo本身只是实现了服务治理,而SpringCloud现在以及有21个子项目,以后还会更多,所以其实很多人都会说Dubbo和SpringCloud是不公平的,但是由于RPC以及注册中心元数据等原因,在技术选型的时候我们只能二者选其一,所以我们常常为用他俩来对比服务的调用方式Dubbo使用的是RPC远程调用,而SpringCloud使用的是 Rest API, 其实更符合微服务官方的定义服务的注册中心来看,Dubbo使用了第三方的ZooKeeper作为其底层的注册中心,实现服务的注册和发现,Spring Cloud使用Spring Cloud Netflix Eureka实现注册中心,当然SpringCloud也可以使用ZooKeeper实现,但一般我们不会这样做。服务网关,Dubbo并没有本身的实现,只能通过其他第三方技术的整合,而SpringCloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发,SpringCloud还支持断路器,与git完美集成分布式配置文件支持版本控制,事务总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素
其实如果仔细阅读过微服务提出者马丁福勒的论文的话可以发现其定义的服务间通信机制就是Http Rest。RPC最主要的缺陷就是服务提供方和调用方式之间依赖太强,我们需要为每一个微服务进行接口的定义,并通过持续继承发布,需要严格的版本控制才不会出现服务提供和调用之间因为版本不同而产生的冲突而REST是轻量级的接口,服务的提供和调用不存在代码之间的耦合,只是通过一个约定进行规范,但也有可能出现文档和接口不一致而导致的服务集成问题,但可以通过swagger工具整合,是代码和文档一体化解决,所以REST在分布式环境下比RPC更加灵活这也是为什么当当网的DubboX在对Dubbo的增强中增加了对REST的支持的原因
Dubbo是基于java接口及Hession2序列化的来实现传输的,Provider对外暴露接口,Consumer根据接口的规则调用。也就是Provider向Zookeeper注册的是接口信息,Consumer从Zookeeper发现的是接口的信息,通过接口的name,group,version来匹配调用。Consumer只关注接口是否匹配,而对此接口属于什么应用不关心。当然接口的注册信息里会包含应用的ip,hostname等。
SpringCloud的服务发现是基于Http协议来实现的,Provider对外暴露的是应用信息,比如应用名称,ip地址等等,Consumer发现的是应用的信息,当调用的时候随机选择一个Provider的IP地址,应用名称,然后依据Http协议发送请求。Consumer关注的是应用名称,根据应用名称来决定调用的是哪个服务集群,然后对此名称对应的服务集群做负载均衡。Provider接受到请求后,根据内置的SpringMVC来匹配路由处理请求。
Dubbo使用Zookeeper做服务发现和治理,Zookeeper是一个分布式协调框架,其有很多很实用的功能,服务发现仅仅是其中的一个。Zookeeper基于著名的CAP理论中的C(一致性),P(分区可用性)实现,它的ZAB(zookeeper atomic broadcast protocol)协议,保证了集群里状态的一致性。Client的每一个事务操作都由Leader广播给所有Follower,当超过半数的Follower都返回执行成功后,才执行事务的ack。对于因网络崩溃或者宕机等问题而执行失败的zookeeper节点,zookeeper会基于zab的崩溃恢复机制来处理,这里不再讲述。每一个操作都需要过半数的zookeeper节点执行成功才确认成功,那么当zookeeper集群过半数节点出现问题时,服务发现功能就不可用。
SpringCloud使用Eureka做服务发现和治理,它是一个专门用于服务发现和治理的框架,其基于CAP理论中的A(可用性),P(分区可用性)实现。EurekaServer节点间的服务信息同步是基于异步Http实现的。每隔Server节点在接收Client的服务请求时,立即处理请求,然后将此次请求的信息拷贝,封装成一个Task,存入Queue中。Server初始化时会启动一个线程定期的从TaskQueue中批量提取Task,然后执行。服务同步不保证一定成功,虽然有失败重试,但超过一定时限后就放弃同步。当然其有一个特性,当服务丢失后,同步的操作返回400,404后会立即将最新的服务信息同步过去,因此即使中途同步失败,不会对后续的同步有影响。
Dubbo使用Zookeeper做服务发现和治理,订阅Zookeeper下相应的znode。当节点发生变化,比如有新的元素增加,或者旧的元素移除,Zookeeper会通知所有订阅此节点的Client,将当前的全量数据同步给各Client,Dubbo里根据最新的数据来做相应处理,移除下线的,初始化新增的。每次更新都同步全量数据。
Eureka在启动时向Server进行一次全量拉取,获取所有的可用服务信息,之后默认情况下都是进行增量拉取。Server会将有变化的服务信息放在一个Queue里,Client每次同步时仅获取增量信息,根据信息里的操作类型,服务信息来对当前持有的服务做相应的处理,移除下线的,初始化新增的等。每次更新仅同步增量数据,也就是更新的数据。
Dubbo订阅Zookeeper下相应的节点,当节点的状态发生改变时,Zookeeper会立即反馈订阅的Client,实时性很高。
Eureka Server在接收到Client的更新操作,或者移除服务信息时,仅仅会将更新消息存放入recentlyChangedQueue中,不会主动的反馈其他Client。其他Client只有在拉取服务增量信息时才会感知到某个服务的更新,延时最大为30S,也就是拉取周期。
Dubbo Provider初始化时会创建一个Zookeeper Client,专门用于与Zookeeper集群交互。维持与集群间的长连接,定时发送心跳,维护Zookeeper上自身节点的存在。节点类型是临时节点,也就是当心跳超时或者长连接断开时,会立即移除Provider对应的节点。
Dubbo Consumer初始化时也会创建一个Zookeeper Client,专门用于与Zookeeper集群交互。维持长连接,创建EvenetListener,监听Provider节点的变动情况。当Provider节点新增或者移除时,Zookeeper会广播这个事件,然后将此节点的当前值(剩下的所有接口信息)发送给那些注册了此节点监听器的Client。Consumer获取到对应Provider节点下的所有接口信息后,移除已下线的,创建新增的。Zookeeper对服务信息的维护实时性和一致性比较高,但也可能因为网络问题或者集群问题导致服务不可用。
SpringCloud的服务信息回收仅基于心跳超时,与长连接无关。当心跳超时后,EurekaServer回收服务信息,然后将此动作同步给其他Server节点。当然可能一个服务信息会存在多个Server上,多次回收操作的同步具备幂等性。也就是说服务回收只需要通知一个Server节点就可以了,回收动作会通过Server节点传播开来。EurekaServer能够回收服务信息由个重要前提:上一分钟内正常发送心跳的服务的比列超过总数的85%,如果因为网络波动等原因造成大量服务的心跳超时,那么EurekaServer会触发自我保护机制,放弃回收那些心跳超时的服务信息。服务发现组件应该优先保证可用性,Consumer能够发现Provider,即使发现的是非可用的Provider,但因为Conusmer一般具备容错机制,不会对服务的正常调用有太多影响。从这点上看Eureka的服务发现机制要比Zookeeper稍微合理一点的。
Dubbo只有Consumer订阅Provider节点,也就是Consumer发现Provider节点信息
Eureka不区分Consumer或者Provider,两者都统称为Client,一个Client内可能同时含有Provider,Consumer,通过服务发现组件获取的是其他所有的Client节点信息,在调用时根据应用名称来筛选节点
Dubbo使用Zookeeper作为服务发现和治理的组件,所以需要搭建Zookeeper集群作为依赖。
SpringCloud使用Eureka作为服务发现和治理组件,在Spring应用中整合Eureka还是很简单的,引入依赖,加个注解,指定集群Server的serviceUrl,其他的都可以使用默认配置即可,启动应用,Eureka集群就搭建好了。同时配合SpringCloudConfg,能够统一管理Eureka的集群配置信息,可以动态的增加或减少EurekaServer的集群节点。Eurerka会每隔15分钟根据配置上的集群信息重新生成集群节点,覆盖之前的。这种机制比Zookeeper要更优秀一些,毕竟Eureka算是Spring生态里的一环,已经被整合的非常好了,能够以很多匪夷所思的方式来使用。
目前国内的分布式系统选型主要还是Dubbo毕竟国产,而且国内工程师的技术熟练程度高,并且Dubbo在其他维度上的缺陷可以由其他第三方框架进行集成进行弥补而SpringCloud目前是国外比较流行,当然我觉得国内的市场也会慢慢的偏向SpringCloud,就连刘军作为Dubbo重启的负责人也发表过点,Dubbo的发展方向是积极适应SpringCloud生态,并不是起冲突。
SpringCloud社区活跃度远高于Dubbo,毕竟由于梁飞团队的原因导致Dubbo停止更新迭代五年,而中小型公司无法承担技术开发的成本导致Dubbo社区严重低落,而SpringCloud异军突起,迅速占领了微服务的市场,背靠Spring混的风生水起,Dubbo经过多年的积累文档相当成熟,对于微服务的架构体系各个公司也有稳定的现状
SpringBoot是Spring推出用于解决传统框架配置文件冗余,装配组件繁杂的基于Maven的解决方案,旨在快速搭建单个微服务而SpringCloud专注于解决各个微服务之间的协调与配置,服务之间的通信,熔断,负载均衡等技术维度并相同,并且SpringCloud是依赖于SpringBoot的,而SpringBoot并不是依赖与SpringCloud,甚至还可以和Dubbo进行优秀的整合开发
总结:
自我保护机制会导致
远程过程调用(Remote Procedure Invocation)
也就是我们常说的服务的注册与发现直接通过远程过程调用来访问别的service。
优点:
缺点:
消息
使用异步消息来做服务间通信。服务间通过消息管道来交换消息,从而通信。
优点:
缺点:
微服务的优缺点分别是什么?说下你在项目开发中碰到的坑
优点
缺点
你所知道的微服务技术栈有哪些?请列举一二
多种技术的集合体
我们在讨论一个分布式的微服务架构的话,需要哪些维度
维度(SpringCloud)
服务开发
SpringBoot
Spring
SpringMVC
服务配置与管理
Netfilx公司的Archaiusm,阿里的Diamond
服务注册与发现
Eureka,ZooKeeper
服务调用
Rest,RPC,gRPC
服务熔断器
Hystrix
服务负载均衡
Ribbon,Nginx
服务接口调用
Feign
消息队列
Kafka,RabbitMq,ActiveMq
服务配置中心管理
SpringCloudConfing
服务路由(API网关)
Zuul
事件消息总线
SpringCloud Bus
…
参考:
https://www.cnblogs.com/matd/articles/10549336.html
https://www.jianshu.com/p/f5bf09c0ef0b