Dubbo的学习笔记

发布时间:2023年12月21日

目录

架构

zookeeper的简单介绍

简单案例

Dubbo-admin的简单使用

Dubbo高级特性

序列化

地址缓存

超时与重试

多版本

负载均衡

集群容错

服务降级


Dubbo是阿里巴巴开源的一个高性能、轻量级RPC框架

架构

  • provider:暴露服务的服务提供方
  • container:服务运行容器
  • consumer:调用远程服务的服务消费方
  • registry:服务注册与发现的注册中心
  • monitor:统计服务的调用次数和调用时间的监控中心

zookeeper的简单介绍

Dubbo建议使用Zookeeper作为服务注册中心

Zookeeper安装有两个需要注意的地方,首先是需要修改conf目录下的zoo_sample.cfg文件名,因为Zookeeper的生效配置文件名叫zoo.cfg,其次,需要修改该文件中的数据存放路径,最好和zookeeper安装目录同一路径

zookeeper的启动,去bin目录下执行如下命令

zkServer.sh start

查看zookeeper的状态

./zkServer.sh status

创建一个简单MVC项目后续我们在该项目上添加Dubbo

简单案例

一个Service模块一个Web模块,结构如下

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return userService.sayHello();
    }
}
@Service
public class UserServiceImpl implements UserService {
    @Override
    public String sayHello() {
        return "hello dubbo";
    }
}

启动服务查看运行情况

接下来我们在此基础上加入Dubbo的使用

修改Service中的Service注解为dubbo中的注解,原先的Service注解是将UserService注册到Spring中的IOC容器当中,现在我们不需要由Spring管理,而是通过dubbo来远程调用,因此修改此处的Serivce注解

修改application.xml配置文件,添加dubbo的配置

<!--dubbo的项目名称,需要唯一-->
<dubbo:application name="dubbo-service"/>
<!--配置注册中心-->
<dubbo:registry address="zookeeper://192.168.116.128:2181"/>
<!--配置需要扫描@Service注解的包路径-->
<dubbo:annotation package="com.zmt"/>

补全Service的目录结构就可以启动dubbo-service模块了

此时修改dubbo-web模块,首先去掉pom文件中的dubbo-service模块的引用,这时Controller中就会报错,为了避免报错,我们需要在本地创建一个对应的UserSerivce接口来进行注入,但由于不是Spring注入了,我们还需要修改注入注解为Dubbo的远程注入注解

@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * 1.从注册中心获取userService的访问url
     * 2.进行远程调用RPC
     * 3.将结果封装为一个代理对象,给变量赋值
     * */
    @Reference
    private UserService userService;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return userService.sayHello();
    }
}

这是我们需要在web模块同样添加一份dubbo的配置信息

<!--dubbo的项目名称,需要唯一-->
<dubbo:application name="dubbo-web"/>
<!--配置注册中心-->
<dubbo:registry address="zookeeper://192.168.116.128:2181"/>
<!--配置需要扫描@Service注解的包路径-->
<dubbo:annotation package="com.zmt"/>

修改完毕后,就可以启动web模块了。在启动过程中会报一个错误

这个错误指的是端口占用,这是因为我们是一台机器运行了两个dubbo服务,在生产环境中不会出现这个错误,但是这个错误不会影响程序运行。如果不希望出现该错误信息,我们可以修改dubbo的配置文件,添加一个修改端口的参数即可

    <!--dubbo的项目名称,需要唯一-->
    <dubbo:application name="dubbo-web">
        <dubbo:parameter key="qos.port" value="33333"/>
    </dubbo:application>
    <!--配置注册中心-->
    <dubbo:registry address="zookeeper://192.168.116.128:2181"/>
    <!--配置需要扫描@Service注解的包路径-->
    <dubbo:annotation package="com.zmt"/>

此时我们的项目结构大致如下

我们实现两个模块调用时,在web层创建了service层的接口,但是在开发时接口可能存在很多,方法也有很多,我们不一定保证在开发时保证不出错,因此,我们存在一个更好的解决方案,那就是再创建一个公共模块,web与service共同依赖该模块,那么结构就变成下面这张图了

新创建一个接口模块

我们将service与web模块中的接口删除,然后在pom文件中引入接口模块,导入接口模块中的接口即可。

Dubbo-admin的简单使用

dubbo-admin管理平台,是图形化的服务管理页面

从注册中心中获取到所有的提供者/消费者进行配置管理

路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能

下载完并解压后根据下面步骤进行即可

1、在dubbo-admin-server里面中找到application.properties修改zookeeper的地址

如果修改了需要在dubbo-admin-server目录执行mvn clean install -Dmaven.test.skip=true

2、在dubbo-admin-distribution中找到tager目录下的jar包运行完成后

3、在dubbo-admin-ui中执行npm run dev

Dubbo高级特性

序列化

在开发时,pojo模块里面的实体类都要实现Serializable接口,目的是序列化,传输数据

地址缓存

注册中心挂了的话,服务还是可以进行正常访问的。

原因:dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后再调用则不会访问注册中心。当服务提供地址发生改变时,注册中心会通知服务消费者。

超时与重试

服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。在某个峰值时刻,大量请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩,Dubbo利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问则自动断开连接。

设置连接超时timeout(默认为1000ms)可以在服务生产方与服务消费方两个地方设置,两个地方都设置timeout的话,服务消费者处的设置优先生效(但不推荐),一般只在服务生产者者里设置超时时间,因为只有服务生产者处知道自己的服务压力是否过大。

连接超时的话,会进行重试操作retries,默认是重试两次,一共发起三次请求

多版本

当我们需要让服务消费者从版本2处获取服务时,dubbo会让一部分用户先使用新功能,用户反馈没问题之后再将所有的用户迁移到新的服务提供方,这称之为灰度发布。dubbo中使用version属性来设置和调用同一个接口的不同版本。

@Service(version = "1.0") //将这个类提供的方法对外发布,将访问的地址ip,端口,路径注册到注册中心
public class UserServiceImpl implements UserService {
    @Override
    public String sayHello() {
        return "hello dubbo";
    }

    @Override
    public User findUserById(int id) {
        User user = new User(1, "zhangsan");
        return user;
    }
}
@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * 1.从注册中心获取userService的访问url
     * 2.进行远程调用RPC
     * 3.将结果封装为一个代理对象,给变量赋值
     * */
    @Reference(version = "1.0")
    private UserService userService;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return userService.sayHello();
    }

    @RequestMapping("/findById")
    public User findByUser(int id){
        return userService.findUserById(id);
    }
}

负载均衡

负载均衡的四种策略:

  • Random:根据权重比例随机分配(这个是默认)
  • RoundRobin:按权重轮询(1、2、3按着顺序来)
  • LeastActive:最少活跃调用数,相同时随机
  • ConsistentHash:一致性Hash,相同参数的请求总是发到统一提供者。

集群容错

集群容错模式:

  • Failover Cluster:即上面的超时重试。失败重试一般用于读操作,写操作可能会出现多次写入重复
  • Failfast Cluster:快速失败,只发起一次调用,通常用于写的操作
  • Failsafe Cluster:失败安全,出现异常时,直接忽略,返回一个空结果
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回。
  • Broadcast Cluster:广播调用所有的提供者,逐个调用,任意一台报错则报错

服务降级

服务降级:(服务器在挂掉的边缘时,释放一些不重要的服务来维持核心服务的使用)

  • mock=force:return null :表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响
  • mock=fail:return null :表示消费方对服务的方法调用在失败后,在返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响
文章来源:https://blog.csdn.net/zmbwcx/article/details/135140435
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。