SpringCloud与Dubbo的区别
两者都是现在主流的微服务框架,但却存在不少差异:
-
初始定位不同: SpringCloud定位为微服务架构下的一站式解决方案;Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用和治理
-
生态环境不同: SpringCloud依托于Spring平台,具备更加完善的生态体系;而Dubbo一开始只是做RPC远程调用,生态相对匮乏,现在逐渐丰富起来。
-
调用方式: SpringCloud是采用Http协议做远程调用,接口一般是Rest风格,比较灵活;Dubbo是采用Dubbo协议,接口一般是Java的Service接口,格式固定。但调用时采用Netty的NIO方式,性能较好。
-
组件差异比较多,例如SpringCloud注册中心一般用Eureka,而Dubbo用的是Zookeeper
SpringCloud生态丰富,功能完善,更像是品牌机,Dubbo则相对灵活,可定制性强,更像是组装机。
-
SpringCloud:Spring公司开源的微服务框架,SpirngCloud 定位为微服务架构下的一站式解决方案。
-
Dubbo:阿里巴巴开源的RPC框架,Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断
两者的生态对比:
Spring Cloud 的功能很明显比 Dubbo 更加强大,涵盖面更广,而且作为 Spring 的旗舰项目,它也能够与 Spring Framework、Spring Boot、Spring Data、Spring Batch 等其他 Spring 项目完美融合,这些对于微服务而言是至关重要的。
使用 Dubbo 构建的微服务架构就像组装电脑,各环节选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果使用者是一名高手,那这些都不是问题。
而 Spring Cloud 就像品牌机,在 Spring Source 的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础原理有足够的了解。
通信协议
Dubbo
-
通信协议:Dubbo 默认使用单一长连接和NIO(Non-blocking I/O)异步通讯方式。这意味着服务消费者和服务提供者之间建立一个长连接,通过这个连接发送多个请求和响应,减少了连接建立和关闭的开销。
-
特点:这种方式适合于小数据量大并发的服务调用场景,尤其是在服务消费者的数量远大于服务提供者时,可以有效地减少连接资源的消耗。
代码示例:
在Dubbo中,服务提供者和消费者通过定义和服务引用接口来实现通信。以下是一个简单的服务提供者和消费者的例子:
服务接口:
public interface GreetingService {
String sayHello(String name);
}
服务提供者:
@Service
public class GreetingServiceImpl implements GreetingService {
public String sayHello(String name) {
return "Hello, " + name;
}
}
服务消费者:
public class Consumer {
@Reference
private GreetingService greetingService;
public String doSayHello(String name) {
return greetingService.sayHello(name);
}
}
Spring Cloud
-
通信协议:Spring Cloud 使用基于HTTP协议的REST API进行服务间的调用。这意味着服务之间的交互通过标准的HTTP请求和响应来完成,通常使用JSON或XML作为数据交换格式。
-
特点:使用HTTP协议的REST API具有跨语言和跨平台的优势,因为HTTP是Web服务的事实标准。然而,相比于NIO,基于HTTP的REST调用可能会有更多的开销,尤其是在高并发场景下。
代码示例:
在Spring Cloud中,可以使用RestTemplate或WebClient来实现REST API的调用:
服务提供者(Controller):
@RestController
public class GreetingController {
@GetMapping("/greet")
public ResponseEntity<String> greet(@RequestParam String name) {
return ResponseEntity.ok("Hello, " + name);
}
}
服务消费者(使用RestTemplate):
@Service
public class GreetingServiceClient {
private final RestTemplate restTemplate;
private final String greetingServiceUrl;
public GreetingServiceClient(@Value("${greeting.service.url}") String greetingServiceUrl) {
this.restTemplate = new RestTemplate();
this.greetingServiceUrl = greetingServiceUrl;
}
public String doGreet(String name) {
String url = greetingServiceUrl + "/greet?name=" + name;
return restTemplate.getForObject(url, String.class);
}
}
对比
-
性能:Dubbo的NIO异步通讯在高并发小数据量的场景下,性能通常优于基于HTTP的REST调用,因为它减少了网络连接的建立和关闭的开销。
-
跨语言和跨平台:Spring Cloud的REST API具有更好的跨语言和跨平台特性,因为HTTP协议是通用的网络协议,而Dubbo的自定义协议则主要限于Java环境。
-
开发便利性:对于习惯了HTTP协议的开发者来说,Spring Cloud的REST API可能更易于理解和使用。而Dubbo的NIO通讯则可能需要对Java NIO有更好的理解。
Dubbo和Spring Cloud在通信协议上的区别主要体现在性能、跨语言支持和开发便利性上。开发者需要根据具体的应用场景和需求来选择最合适的通信协议。
性能方面
Spring Cloud性能调优
Feign 在高并发场景下,通常需要进行如下性能优化,有明显瓶颈,需要改造。
· 调整服务容器到 UnderTow ,在负载大的情况下Undertow 的性能有提高;
· 曾有同学表示将HTTPURLConnection 改成 Httpclient /Okhttp,这样可以优化性能,其实单次调用性能Httpclient差很多,HttpClient 因为封装了很多方便开发者处理的方法,性能比HTTPURLConnection差,改进同时Httpclient 需要设置复用连接池,效果可见一般;
· 开启Gzip;
· Feign中HttpMessageConverters 默认使用jackson2方式进行序列化和反序列化,可以将其改造为ProtoBuf,降低Cpu 损耗并且响应时间也降低。
Dubbo性能调优
主要是配置而无需改造。
负载均衡
Ribbon 的负载均衡策略
· 随机;
· 规则轮询;
· 空闲策略;
· 响应时间策略。
Feign默认使用Ribbon作为负载均衡的组件,Ribbon需要进行全局配置,个性化配置比较麻烦。
Dubbo 的负载均衡策略
· 随机;
· 权重轮询;
· 最少活跃调用数;
· 一致性Hash策略。
Dubbo 可以使用路由策略,然后再进行负载均衡。
容错机制
Spring cloud 的 Hystix 提供了服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能。
Dubbo 提供了一整套 FailOver、FailFast、Failsafe、FailBack、Aviailable、Broadcast、Forking 策略,以及Mock。
路由、流量调度、ABtest
Ribbon需自己实现,应用不灵活
Ribbon主要通过扩展 AbstractLoadBalancerRule负载均衡的方法来实现,在负载均衡的部分还要进行改造升级。
Dubbo更加灵活方便
Dubbo通过界面化、校本化配置路由规则,可以实现灰度发布、动态流量调度、容量计算等,方案成熟。
另外,Dubbo 还支持多版本调用。