之前看到很多人说Dubbo和SpringCloud怎么选,其实Spring Cloud与Dubbo的比较本身是不公平的,主要前者是一套较为完整的架构方案,而Dubbo只是其中的服务治理的解决方案。
注:
- springcloud是微服务架构的一整套技术解决方案的技术栈,是这些技术栈的框架集合,包含了服务治理、注册中心、配置中心、客户端负载均衡、网关、限流熔断、分布式链路追踪、分布式事务等技术栈,而Dubbo只是处理服务治理的解决方案的框架。
- 同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件
- 在Spring Cloud Alibaba的整合之下,Dubbo用户既可以享受到原本RPC带来性能优势,又可以更好的享受Spring Cloud的各种福利;而对于Spring Cloud用户来说,在服务治理层面,又对了一个不错的可选项。可以说这块的整合是真正的让这两大用户群体得到了很好的融合,起到了互相成就的作用。不用再同时顾虑Eureka和Zookeeper的配置,只需要关注和维护好Nacos一个即可
SpringCloud里面服务治理的解决方案是:Eureke或Nacos注册中心+ Feign或Ribbon进行调用服务调用,自从spring cloud alibab框架从springcloud孵化后,dubbo也可以是SpringCloud中另一种服务治理的解决方案:即Nacos+Dubbo实现服务调用,各有优劣,要根据不同情况使用。
为什么用dubbo?spring cloud怎么整合dubbo?在微服务中实现远程服务调用,一般是用Feign基于HTTP协议调用远程服务,也有用dubbo基于RPC协议进行远程服务调用。
比较项 | Feign(RESTful) | Dubbo |
---|---|---|
通讯协议 | HTTP | 默认Dubbo协议 |
性能 | 略低 | 较高 |
灵活度 | 高 | 低 |
注:
- RESTful是基于HTTP协议进行交互的,HTTP协议包含大量的请求头、响应头信息。而dubbo是基于dubbo自定义的二进制协议进行传输,消息体比较简单,传输数据要小很多
- dubbo默认采用dubbo协议,dubbo协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低
- dubbo好比方言,RESTful好比普通话。方言在局部地区交流更快,普通话更容易在大部分地区交流
微服务里面既可以使用Feign、也可以使用Dubbo进行远程调用,可根据情况使用不同的远程调用
DEMO
一、创建生产者的api的jar
在jar里面提供接口,生产者和消费者都引入这个jar
二、生产者
1)引入依赖
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- 引入dubbo服务提供者的api -->
<dependency>
<groupId>com.xinlin.springcloud.demo</groupId>
<artifactId>products-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2)配置文件修改
server:
port: 9002
spring:
application:
name: products-service
datasource:
url: jdbc:mysql://127.0.01:3306/test?useSSL=true
username: admin
password: admin-123
cloud:
nacos:
discovery:
server-addr: localhost:8848
dubbo:
scan:
base-packages: com.xinlin.demo.products.service #dubbo扫描的包目录
protocol:
name: dubbo #dubbo协议
port: 20880 #端口
registry:
address: nacos://localhost:8848 #dubbo注册中心的地址
# spring-cloud://localhost #用spring cloud的注册中心
注:
dubbo.protocol.name 默认使用dubbo协议,也可以使用其他协议,例如http协议
dubbo.protocol.port = -1 表示从20880开始,如果被占用则端口号加1
3)服务端创建dubbo服务
package com.xinlin.demo.products.service.impl;
import com.xinlin.demo.products.service.DubboService;
import org.apache.dubbo.config.annotation.Service;
@Service
public class DubboServiceImpl implements DubboService {
@Override
public String findUserInfo(Integer id) {
String info = String.format("dubbo服务查询的用户信息:用户id=[%s]",id);
return info;
}
}
注:这里的@Service是Dubbo的注解,表示dubbo服务
三、消费者
1)消费者端引入依赖,同生产者的pom一样
2)配置文件修改
dubbo:
application:
name: comsumer-service
scan:
base-packages: com.xinlin.demo.comsumer
registry:
address: nacos://127.0.0.1:8848
注:可以和生产者一样,只要端口号不一样即可,但是消费者没有提供服务的话,可以不指定dubbo协议和端口
3)消费者注入dubbo
@Autowired
private PorductService porductService;
//Reference为dubbo的注解
@Reference(timeout = 18000,check = false)
private DubboService dubboService;
@RequestMapping(value = "/findUser/{id}")
public String findUser(@PathVariable("id") Integer id){
//调用dubbo服务,获取用户信息
String info = dubboService.findUserInfo(id);
return info;
}
四、测试验证
1)先启动nacos的注册中心,再分别启动生产者、消费者的服务
2)可以看到消费者成功调用了生产者的dubbo服务
注:nacos的注册中心的启动参考这篇:spring cloud 使用nacos作为注册中心
五、启动异常问题
引入spring-cloud-starter-dubbo后启动项目失败:java.lang.IllegalStateException: No application config found or it’s not a valid config! Please add <dubbo:application name="…" /> to your spring config,检查源码是说dubbo.application.name这个配置没有,但是我配置了也是提示这个异常,再检查发现是jar版本问题
我这个问题的解决方案:
spring-cloud-alibaba-dependencies由2.1.0.RELEASE修改为2.1.1.RELEASE即可解决
具体原因:引入spring-cloud-starter-dubbo后启动项目失败