Dubbo-一文带你快速了解和使用springboot集合Dubbo

一、何为Dubbo?它是用来干什么的?

Dubbo 最早是 Alibaba 开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo 采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
官网地址:http://dubbo.apache.org/zh-cn/
简单来说,dubbo是一种提供PRC(远程服务调用)服务的框架,一些老鸟可能有了解过jdk提供的rmi,这也是一种提供rpc服务的模块,但是使用rmi太麻烦了并且功能远远不如dubbo好,所以我们一般使用dubbo作为我们的rpc框架。

(一) 什么是RPC

RPC是远程服务调用的缩写,其功能是能够在主机A上调用主机B提供的方法,实现跨主机的调用。在实际应用中往往将一个大型项目中分成多个模块,而总有一些模块是公共模块(其他模块都需要调用它),将这些公共模块提取出来放在机房中并为其部署集群,然后其他模块分布在另外的服务器上,需要用到公共模块的方法的时候直接调用就行。

(二) 为什么要用到RPC?

其实这是应用开发到一定的阶段的强烈需求驱动的。
如果我们开发简单的单一应用,逻辑简单、用户不多、流量不大,那我们用不着。
当我们的系统访问量增大、业务增多时,我们会发现一台单机运行此系统已经无法承受。此时,我们可以将业务拆分成几个互不关联的应用,分别部署在各自机器上,以划清逻辑并减小压力。此时,我们也可以不需要RPC,因为应用之间是互不关联的。
当我们的业务越来越多、应用也越来越多时,自然的,我们会发现有些功能已经不能简单划分开来或者划分不出来。此时,可以将公共业务逻辑抽离出来,将之组成独立的服务Service应用 。而原有的、新增的应用都可以与那些独立的Service应用 交互,以此来完成完整的业务功能。
所以此时,我们急需一种高效的应用程序之间的通讯手段来完成这种需求,所以你看,RPC大显身手的时候来了!
其实描述的场景也是服务化 、微服务和分布式系统架构的基础场景。即RPC框架就是实现以上结构的有力方式。

(三) 使用Dubbo的优势

  • 透明化的远程方法调用,仅通过简单的配置就能完成像调用本地方法一样调用远程方法,大大提高了工作效率
  • 提供软负载均衡和容错机制,可在内网替代F5等硬负载均衡设备,降低成本
  • 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的 IP 地址,并且能够平滑添加或删除服务提供者。

(四) Dubbo的架构

Dubbo-一文带你快速了解和使用springboot集合Dubbo_第1张图片
虚线代表异步,实线代表同步

1. provider

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获取服务信息这类操作都是异步的,高效的。
**

(五) 执行流程

  1. 搭建注册中心集群,这里我采用的是zookeeper
  2. 配置公共接口模块,provider实现该模块的所有接口,consumer通过该模块的接口和动态代理来使用provider暴露的服务
  3. provider配置好注册中心和服务后启动,启动后会自动将服务信息发送到registry中
  4. consumer向registry中订阅所需要的服务,registry会将服务信息通知给consumer
  5. consumer得到服务信息后便可以实现远程调用了

(六) Dubbo支持的协议

1 Dubbo 协议(官方推荐协议)

优点:
采用 NIO 复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,
性能较好(推荐使用)
缺点:
大文件上传时,可能出现问题(不使用 Dubbo 文件上传)

2 RMI(Remote Method Invocation)协议

优点:
JDK 自带的能力。
缺点:
偶尔连接失败.

3 Hessian 协议

优点:
可与原生 Hessian 互操作,基于 HTTP 协议
缺点:
需 hessian.jar 支持,http 短链接开销大

(七) Dubbo支持的注册中心

1 Zookeeper(官方推荐)

  1. 优点:
    支持分布式.很多周边产品. 2) 缺点:
    受限于 Zookeeper 软件的稳定性。Zookeeper 是一款专门为分布式架构提供辅助型处
    理的软件,稳定较优。

2 Multicast

  1. 优点:
    去中心化,不需要单独安装软件. 2) 缺点:
    2.2.1 Provider 和 Consumer 和 Registry 不能跨机房(路由)

3 Redis

  1. 优点:
    支持集群,性能高
  2. 缺点:
    要求服务器时间同步.否则可能出现集群失败问题.

4 Simple(不推荐)

  1. 优点:
    标准 RPC 服务.没有兼容问题
    8
  2. 缺点:
    不支持集群.

二、Dubbo案例

(一) api模块

api模块主要是提供接口和实体类,在此demo中我为了方便在api模块中添加了mybatis-plus依赖,自动生成代码(在实际持久层框架不会在该模块中)

pom

 
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.2
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            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 {
    List findAllUser();

    List findUserOnCondition(Consumer consumer);

    int deleteUser(Consumer consumer);

    int updateUser(Consumer consumer);
}

(二) provider

pom

 
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
		
        
            com.codexie
            commons_api
            0.0.1-SNAPSHOT
        
        
            org.apache.dubbo
            dubbo-spring-boot-starter
            2.7.6
        
        
            org.apache.dubbo
            dubbo-registry-zookeeper
            2.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 {

}


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);
    }
}

(三) consumer

pom


        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            com.codexie
            commons_api
            0.0.1-SNAPSHOT
        
        
            org.apache.dubbo
            dubbo-spring-boot-starter
            2.7.6
        
        
            org.apache.dubbo
            dubbo-registry-zookeeper
            2.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 map = new HashMap<>();
        boolean b = userServiceImpl.addUser(consumer);
        if(b){
            map.put("msg","ok");
        }else{
            map.put("msg","err");
        }
        return map;
    }


}

你可能感兴趣的:(dubbo,spring,boot,java,rpc,dubbo,分布式)