Dubbo 最早是 Alibaba 开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo 采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
官网地址:http://dubbo.apache.org/zh-cn/
简单来说,dubbo是一种提供PRC(远程服务调用)服务的框架,一些老鸟可能有了解过jdk提供的rmi,这也是一种提供rpc服务的模块,但是使用rmi太麻烦了并且功能远远不如dubbo好,所以我们一般使用dubbo作为我们的rpc框架。
RPC是远程服务调用的缩写,其功能是能够在主机A上调用主机B提供的方法,实现跨主机的调用。在实际应用中往往将一个大型项目中分成多个模块,而总有一些模块是公共模块(其他模块都需要调用它),将这些公共模块提取出来放在机房中并为其部署集群,然后其他模块分布在另外的服务器上,需要用到公共模块的方法的时候直接调用就行。
(二) 为什么要用到RPC?其实这是应用开发到一定的阶段的强烈需求驱动的。
如果我们开发简单的单一应用,逻辑简单、用户不多、流量不大,那我们用不着。
当我们的系统访问量增大、业务增多时,我们会发现一台单机运行此系统已经无法承受。此时,我们可以将业务拆分成几个互不关联的应用,分别部署在各自机器上,以划清逻辑并减小压力。此时,我们也可以不需要RPC,因为应用之间是互不关联的。
当我们的业务越来越多、应用也越来越多时,自然的,我们会发现有些功能已经不能简单划分开来或者划分不出来。此时,可以将公共业务逻辑抽离出来,将之组成独立的服务Service应用 。而原有的、新增的应用都可以与那些独立的Service应用 交互,以此来完成完整的业务功能。
所以此时,我们急需一种高效的应用程序之间的通讯手段来完成这种需求,所以你看,RPC大显身手的时候来了!
其实描述的场景也是服务化 、微服务和分布式系统架构的基础场景。即RPC框架就是实现以上结构的有力方式。
透明化的远程方法调用,仅通过简单的配置就能完成像调用本地方法一样调用远程方法,大大提高了工作效率提供软负载均衡和容错机制,可在内网替代F5等硬负载均衡设备,降低成本服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的 IP 地址,并且能够平滑添加或删除服务提供者。 (四) Dubbo的架构
虚线代表异步,实线代表同步
provider是服务提供方,dubbo要求服务方必须基于spring容器,服务方将consumer调用的接口实现,通过dubbo提供的service注解(注意是dubbo的不是spring的)将接口实现类暴露给注册中心。
2. registry注册中心,provider将服务暴露给注册中心(包括服务的ip地址、端口、接口实现类等等),consumer再通过注册中心得到暴露服务的信息,从而调用被暴露的服务
3. consumer只需要配置registry的信息,就可以从注册中心那里获得暴露的服务
4. monitor监控中心,监控 Provider 的压力情况等。
每隔 2 分钟 Consumer 和 Provider 会把调用次数发送给 Monitor,由 Monitor 进行统计。
**我们可以从图中了解到,除了consumer调用远程方法是同步的以外,其它均是异步操作,也就是说consumer调用远程服务的时候会阻塞后面的代码,而像provider向registry暴露服务,consumer从registry获取服务信息这类操作都是异步的,高效的。
**
- 搭建注册中心集群,这里我采用的是zookeeper配置公共接口模块,provider实现该模块的所有接口,consumer通过该模块的接口和动态代理来使用provider暴露的服务provider配置好注册中心和服务后启动,启动后会自动将服务信息发送到registry中consumer向registry中订阅所需要的服务,registry会将服务信息通知给consumerconsumer得到服务信息后便可以实现远程调用了
优点:
采用 NIO 复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,
性能较好(推荐使用)
缺点:
大文件上传时,可能出现问题(不使用 Dubbo 文件上传)
优点:
JDK 自带的能力。
缺点:
偶尔连接失败.
优点:
可与原生 Hessian 互操作,基于 HTTP 协议
缺点:
需 hessian.jar 支持,http 短链接开销大
- 优点:
支持分布式.很多周边产品. 2) 缺点:
受限于 Zookeeper 软件的稳定性。Zookeeper 是一款专门为分布式架构提供辅助型处
理的软件,稳定较优。
- 优点:
去中心化,不需要单独安装软件. 2) 缺点:
2.2.1 Provider 和 Consumer 和 Registry 不能跨机房(路由)
- 优点:
支持集群,性能高缺点:
要求服务器时间同步.否则可能出现集群失败问题.
- 优点:
标准 RPC 服务.没有兼容问题
8缺点:
不支持集群.
api模块主要是提供接口和实体类,在此demo中我为了方便在api模块中添加了mybatis-plus依赖,自动生成代码(在实际持久层框架不会在该模块中)
pom
org.springframework.boot spring-boot-starterorg.springframework.boot spring-boot-starter-testtest com.baomidou mybatis-plus-boot-starter3.4.2 mysql mysql-connector-javaruntime org.projectlombok lombok
实体类
@Data
@EqualsAndHashCode(callSuper = false)
public class Consumer implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(condition = SqlCondition.LIKE)
private String username;
private String password;
private Integer sex;
private String phoneNum;
private String email;
private LocalDateTime birth;
private String introduction;
private String location;
private String avator;
@TableField(fill= FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}
接口
public interface IConsumerService extends IService(二) provider{ List findAllUser(); List findUseronCondition(Consumer consumer); int deleteUser(Consumer consumer); int updateUser(Consumer consumer); }
pom
org.springframework.boot spring-boot-starterorg.springframework.boot spring-boot-starter-testtest org.junit.vintage junit-vintage-enginecom.codexie commons_api0.0.1-SNAPSHOT org.apache.dubbo dubbo-spring-boot-starter2.7.6 org.apache.dubbo dubbo-registry-zookeeper2.7.6
配置文件
dubbo:
应用名称
application:
name: springbootProvider
registry:
protocol: zookeeper
address: 101.43.***.***:2181,101.43.***.***:2182,101.43.***.***:2183
timeout: 10000
protocol:
name: dubbo
port: 20883
scan:
base-packages: com.codexie.provider.service.impl
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://127.0.0.1:3306/musical-site?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
mapper接口和service实现类
mapper接口 public interface ConsumerMapper extends baseMapper(三) consumer{ } service实现类 @Service #此注解是dubbo提供的不是spring提供的,不要用错 public class ConsumerServiceImpl extends ServiceImpl implements IConsumerService { @Autowired private ConsumerMapper consumerMapper; @Override public List findAllUser() { List list = consumerMapper.selectList(new QueryWrapper<>()); return list; } @Override public List findUseronCondition(Consumer consumer) { QueryWrapper wrapper = new QueryWrapper<>(consumer); List list = consumerMapper.selectList(wrapper); return list; } @Override public int deleteUser(Consumer consumer) { return consumerMapper.deleteById(consumer.getId()); } @Override public int updateUser(Consumer consumer) { return consumerMapper.updateById(consumer); } }
pom
org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-testtest com.codexie commons_api0.0.1-SNAPSHOT org.apache.dubbo dubbo-spring-boot-starter2.7.6 org.apache.dubbo dubbo-registry-zookeeper2.7.6
配置文件
dubbo:
application:
name: springbootConsumer
registry:
protocol: zookeeper
address:101.43.***.***:2181,101.43.***.***:2182,101.43.***.***:2183
timeout: 10000
protocol:
name: dubbo
consumer:
loadbalance: roundrobin
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://127.0.0.1:3306/musical-site?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
业务接口以及实现类
public interface UserService {
List findAllUserService();
List findUserByCon(Consumer consumer);
boolean addUser(Consumer consumer);
boolean addUserList(List list);
int delUser(Consumer consumer);
int updateUser(Consumer consumer);
}
实现类
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Reference
IConsumerService consumerServiceImpl;
@Override
public List findAllUserService() {
return consumerServiceImpl.findAllUser();
}
@Override
public List findUserByCon(Consumer consumer) {
return consumerServiceImpl.findUseronCondition(consumer);
}
@Override
public boolean addUser(Consumer consumer) {
return consumerServiceImpl.save(consumer);
}
@Override
public boolean addUserList(List list) {
return consumerServiceImpl.saveBatch(list);
}
@Override
public int delUser(Consumer consumer) {
return consumerServiceImpl.deleteUser(consumer);
}
@Override
public int updateUser(Consumer consumer) {
return 0;
}
}
controller
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userServiceImpl;
@RequestMapping("all")
public List findAll(){
return userServiceImpl.findAllUserService();
}
@RequestMapping("add")
public Map addUser(Consumer consumer){
HashMap 


