微服务主要的优势:
1.降低复杂度 将原来耦合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界;每个服务开发者只专注服务本身,通过使用缓存、DAL 等各种技术手段来提升系统的性能,而对于消费方来说完全透明。
2.可独立部署 由于微服务具备独立的运行进程,所以每个微服务可以独立部署。当业务迭代时只需要发布相关服务的迭代即可,降低了测试的工作量同时也降低了服务发布的风险。
3.容错 在微服务架构下,当某一组件发生故障时,故障会被隔离在单个服务中。比如通过限流、熔断等方式降低错误导致的危害,保障核心业务正常运行。
4.扩展 单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。 当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。
微服务的劣势:
1.开发者需要应对创建分布式系统所产生的额外的复杂因素
l 目前的IDE主要面对的是单体工程程序,无法显示支持分布式应用的开发
l 测试工作更加困难
l 需要采用服务间的通讯机制
l 很难在不采用分布式事务的情况下跨服务实现功能
l 跨服务实现要求功能要求团队之间的紧密协作
2.部署复杂
3.内存占用量更高
对比:
Dubbo 核心部件(如下图):
-
Provider:暴露服务的提供方,可以通过 jar 或者容器的方式启动服务。
-
Consumer:调用远程服务的服务消费方。
-
Registry:服务注册中心和发现中心。
-
Monitor:统计服务和调用次数,调用时间监控中心。(Dubbo 的控制台页面中可以显示,目前只有一个简单版本。)
-
Container:服务运行的容器。
Spring Cloud总体架构(如下图):
-
Service Provider: 暴露服务的提供方。
-
Service Consumer:调用远程服务的服务消费方。
-
EureKa Server: 服务注册中心和服务发现中心。
微服务架构核心要素:
Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件,服务治理只是其中的一个方面。
Dubbo 提供了各种 Filter,对于上述中“无”的要素,可以通过扩展 Filter 来完善。例如:
-
分布式配置:可以使用淘宝的 diamond、百度的 disconf 来实现分布式配置管理。
-
服务跟踪:可以使用京东开源的 Hydra,或者扩展 Filter 用 Zippin 来做服务跟踪。
-
批量任务:可以使用当当开源的 Elastic-Job、tbschedule。
-
点评:从核心要素来看,Spring Cloud 更胜一筹,在开发过程中只要整合 Spring Cloud 的子项目就可以顺利的完成各种组件的融合,而 Dubbo 却需要通过实现各种 Filter 来做定制,开发成本以及技术难度略高。
通讯协议:
Dubbo 使用 RPC 通讯协议,提供序列化方式如下:
-
Dubbo:Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
-
RMI:RMI 协议采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式。
-
Hessian:Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 HTTP 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。
-
HTTP:采用 Spring 的 Http Invoker 实现。
-
Webservice:基于 CXF 的 frontend-simple 和 transports-http 实现
Spring Cloud 使用 HTTP 协议的 REST API。
性能比较
使用一个 Pojo 对象包含 10 个属性,请求 10 万次,Dubbo 和 Spring Cloud 在不同的线程数量下,每次请求耗时(ms)如下:
说明:客户端和服务端配置均采用阿里云的 ECS 服务器,4 核 8G 配置,Dubbo 采用默认的 Dubbo 协议。
点评:Dubbo 支持各种通信协议,而且消费方和服务方使用长链接方式交互,通信速度上略胜 Spring Cloud,如果对于系统的响应时间有严格要求,长链接更合适。
组件运行流程:
Dubbo
下图中的每个组件都是需要部署在单独的服务器上,Gateway 用来接受前端请求、聚合服务,并批量调用后台原子服务。每个 Service 层和单独的 DB 交互。
Dubbo 组件运行:
-
Gateway:前置网关,具体业务操作,Gateway 通过 Dubbo 提供的负载均衡机制自动完成。
-
Service:原子服务,只提供该业务相关的原子服务。
-
Zookeeper:原子服务注册到 ZK 上。
SpringCloud:
Spring Cloud组件运行:
-
所有请求都统一通过 API 网关(Zuul)来访问内部服务。
-
网关接收到请求后,从注册中心(Eureka)获取可用服务。
-
由 Ribbon 进行均衡负载后,分发到后端的具体实例。
-
微服务之间通过 Feign 进行通信处理业务。
点评:业务部署方式相同,都需要前置一个网关来隔绝外部直接调用原子服务的风险。