微服务架构是互联网上的热门话题,也是互联网技术发展的必然结果。它提倡将单一的应用程序拆分成一组小的服务,服务之间相互协调配合,为用户提供最终的价值。虽然目前还没有公认的微服务架构技术标准、规范或草案,但已经有一些在业界有影响力的开源微服务架构框架提供了微服务的核心思想,如Dubbo、SpringCloud。各大互联网公司也有自研的微服务框架,但其模式与这两者相差不大。微服务的主要优势是降低复杂度,将原本耦合在一起的复杂业务拆分成一个服务,避免了原有复杂度的无休止积累。每个微服务专注于单一功能,通过定义良好的接口清晰表达服务边界;每个服务开发者只关注服务本身,通过缓存、DAL等各种技术手段提升系统性能。完全透明。可独立部署由于微服务有独立运行的进程,所以每个微服务都可以独立部署。业务迭代时,只需要发布迭代相关的服务,减少了测试的工作量和服务发布的风险。容错在微服务架构中,当一个组件发生故障时,该故障被隔离在单个服务中。例如,通过限流和熔断来减少错误带来的危害,保证核心服务的正常运行。扩展单体架构的应用也可以实现水平扩展,也就是将整个应用完全复制到不同的节点上。当应用的不同组件有不同的扩展需求时,微服务架构体现了它的灵活性,因为每个服务都可以根据实际需要独立扩展。本文主要从微服务的技术选型、通信协议、服务依赖方式、启动方式、运行方式等方面对Dubbo和SpringCloud两种开发框架进行综合比较。架构师可以根据公司的技术实力和项目的特点选择合适的微服务架构平台,从而安全的实施项目的微服务改造或开发过程。核心组件微服务的核心要素是服务发现、注册、路由、熔断、降级、分布式配置。基于上述必要条件,对Dubbo和SpringCloud进行对比。Dubbo在整体架构中的核心组件(如下图所示):Provider:暴露服务的提供者,可以通过jar或者容器来启动服务。消费者:调用远程服务的服务消费者。Registry:服务注册和发现中心。监控:统计服务和调用次数,调用时间监控中心。(可以在Dubbo的控制台页面显示,目前只有简易版。)Container:服务运行的容器。Dubbo整体架构SpringCloud整体架构(如下图所示):ServiceProvider:暴露服务的提供者。服务消费者:调用远程服务的服务消费者。EureKaServer:服务注册中心和服务发现中心。SpringCloud整体架构点评:从整体架构来看,两者模型相似,都需要服务提供者、注册中心和服务消费者。微服务架构的核心元素Dubbo只实现了服务治理,而SpringCloud子项目涵盖了微服务架构下的众多组件,服务治理只是其中的一个方面。Dubbo提供了多种Filter。对于上面提到的“none”元素,可以通过扩展Filter来改进。例如:分布式配置:可以使用淘宝的diamond和百度的disconf实现分布式配置管理。服务追踪:可以使用京东开源的Hydra,或者扩展Filter使用Zippin进行服务追踪。批量任务:可以使用当当网开源的Elastic-Job和tbschedule。点评:从核心要素来看,SpringCloud更胜一筹。在开发过程中,只要集成SpringCloud的子项目,就可以顺利完成各种组件的集成,而Dubbo需要实现各种Filter进行定制开发。成本和技术难度略高。通信协议基于通信协议层比较两个框架支持的协议类型和运行效率。支持协议DubboDubbo使用RPC通信协议,提供序列化方式如下:服务消费者机器远大于服务提供者或机器数量。RMI:RMI协议使用JDK标准java.rmi.*实现,使用阻塞短连接和JDK标准序列化。Hessian:Hessian协议用于集成Hessian服务。Hessian底层使用HTTP通信和Servlet来暴露服务。Dubbo默认嵌入了Jetty作为服务端实现。HTTP:使用Spring的HttpInvoker实现。Webservice:基于CXF的frontend-simple和transports-http实现。SpringCloudSpringCloudRESTAPI使用HTTP协议。性能对比使用一个包含10个属性,请求10万次的Pojo对象。Dubbo和SpringCloud使用不同的线程数,每次请求的耗时(ms)如下:说明:客户端和服务端配置均使用阿里云的ECS服务器,4核8G配置,Dubbo使用默认的Dubbo协议。点评:Dubbo支持多种通信协议,消费者和服务端使用长链接交互,通信速度略优于SpringCloud。如果对系统的响应时间有严格的要求,长链接比较合适。服务依赖模式Dubbo服务提供者和消费者依赖于接口,服务调用设计如下:接口层:服务接口层,定义了服务对外提供的所有接口。Molel层:服务的DTO对象层。业务层:业务实现层,实现Interface接口,与DB进行交互。因此需要为每个微服务定义自己的Interface接口,通过持续集成发布到私有仓库。调用方应用对微服务提供的抽象接口有很强的依赖性,开发、测试、集成环境都需要严格管理版本依赖。通过maven的install&deploy命令将Interface和Model层发布到仓库中,服务调用者只需要依赖Interface和Model层即可。开发调试阶段只发布Snapshot版本,业务调试完成后发布Release版本。每次迭代的版本号用于区分版本。可以通过xml配置访问Dubbo,不侵入程序。Dubbo接口依赖方式SpringCloud服务提供者和服务消费者通过Json进行交互,所以只需要定义相关的Json字段,消费者和提供者没有接口依赖。服务配置通过注解实现,对程序有一定的侵入性。点评:Dubbo的服务依赖度高,需要完善的版本管理机制,但很少有程序入侵。而SpringCloud通过Json进行交互,省略了版本管理的问题,但是需要统一管理具体字段的含义,并且自带的RestAPI交互为跨平台调用奠定了基础。组件运行流程下图中Dubbo中的每个组件都需要部署在单独的服务器上。网关用于接受前端请求,聚合服务,批量调用后台原子服务。每个服务层都与一个单独的数据库交互。Dubbo组件运行流程Dubbo组件运行:Gateway:前端网关,具体业务操作,Gateway通过Dubbo提供的负载均衡机制自动完成。Service:原子服务,只提供与业务相关的原子服务。Zookeeper:原子服务注册到ZK。SpringCloud组件运行SpringCloudSpringCloud组件运行:所有请求统一通过API网关(Zuul)访问内部服务。网关收到请求后,从注册中心(Eureka)获取可用服务。负载通过Ribbon均衡后,分发到后端的特定实例。微服务通过Feign进行通信和处理业务。点评:业务部署方式相同,需要预装网关隔离外部直接调用原子服务的风险。Dubbo需要自己开发API网关,而SpringCloud可以通过Zuul配置完成网关定制。SpringCloud在使用上稍微好一点。微服务架构组成及注意事项使用Dubbo还是SpringCloud并不重要,重点在于如何合理使用微服务。下面是互联网的总体架构图,其中各个环节都是微服务的核心部分。架构分解:网关集群:数据聚合、接入客户端鉴权、消息防重放和数据篡改、函数调用业务鉴权、响应数据脱敏、流量并发控制等业务集群:一般来说,移动网关访问和浏览器访问需要隔离,防止业务耦合。本地缓存:由于客户端访问业务可能需要调用多个服务聚合,本地缓存有效降低了服务调用频率,也提高了访问速度。本地缓存一般采用自动过期方式,业务场景允许一定的数据延迟。服务层:原子服务层,实现基本的增删改查功能。如果需要依赖其他服务,需要在Service层主动调用。RemoteCache:在访问DB之前的一层分布式缓存,减少DB的交互次数,提高系统的TPS。DAL:数据访问层。如果单表数据量过大,需要使用DAL层进行数据分库分表处理。MQ:消息队列用于解耦服务之间的依赖关系,可以通过MQ执行异步调用。数据库主从:服务过程中的必经阶段,用于提高系统的TPS。注意:推荐使用jar方式启动服务,启动速度更快,更便于监控。缓存,缓存,缓存,在系统中可以使用缓存的地方,尽量使用缓存,合理使用缓存可以有效提高系统的TPS。服务拆分要合理,尽量避免服务拆分造成的服务循环依赖。合理设置线程池,避免设置过大或过小导致系统异常。综上所述,Dubbo诞生于阿里巴巴家族,是阿里巴巴服务化治理的核心框架,广泛应用于中国各家互联网公司;只需要通过Spring进行配置即可完成服务,对应用没有任何侵入。设计的目的是为了服务专注于自己的业务。虽然Dubbo曾经因为阿里内部原因暂停维护版本,但是框架本身的成熟度和文档的完备性完全可以满足各大互联网公司的业务需求。如果我们使用配置中心和分布式跟踪,需要自己去集成,无形中增加了Dubbo的使用难度。SpringCloud是著名的Spring家族的产物,专注于企业级开源框架的开发。自发布以来,SpringCloud仍在高速发展,几乎考虑了服务治理的方方面面,开发起来非常方便简单。Dubbo在2017年重启维护,发布了2.5.7更新版本,而SpringCloud更新非常快,已经更新到Finchley.M2。因此,企业需要根据自身的研发水平和阶段,选择合适的架构来解决业务问题。Dubbo和SpringCloud都是实现微服务的有效工具。
