0


dubbo安装及使用

dubbo安装及使用

新手笔记,存在错误还请指正

尚硅谷dubbo

dubbo的github地址
dubbo官方文档

dubbo使用

dubbo和zookeeper的关系

dubbo和zookeeper的关系

zookeeper安装

zookpper安装

dubbo快速入门

概念

Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。(rpc的两个核心模块即:通讯,序列化。)
设计架构:
在这里插入图片描述

环境搭建

一、打开zookeeper
二、安装dubbo-admin管理控制台
dubbo本身并不是一个服务软件。它其实就是一个jar包能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。所以不用在Linux上启动什么dubbo服务。
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序,不过这个监控即使不装也不影响使用。
下载地址:
dubbo-admin
进入目录,修改dubbo-admin配置:
修改 src\main\resources\application.properties 指定zookeeper地址
在这里插入图片描述
打包dubbo-admin,cmd中运行:

mvn clean package -Dmaven.test.skip=true 

运行dubbo-admin

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

在浏览器中访问localhost:7001即可访问管理页面(用户名密码均为root)
三、创建工程
需求:
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;我们现在需要创建两个服务模块。

订单服务web模块:创建订单等
用户服务web模块:查询用户地址等

实现:两个模块在不同的服务器并且A可以远程调用B的功能。
1、服务提供者
在这里插入图片描述
定义一个实体bean,和一个服务提供service


public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String phoneNum;
    private String isDefault;

    public UserAddress() {
        super();
    }

    public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum, String isDefault) {
        this.id = id;
        this.userAddress = userAddress;
        this.userId = userId;
        this.consignee = consignee;
        this.phoneNum = phoneNum;
        this.isDefault = isDefault;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getConsignee() {
        return consignee;
    }

    public void setConsignee(String consignee) {
        this.consignee = consignee;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public String getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault;
    }

    @Override
    public String toString() {
        return "UserAddress{" +
                "id=" + id +
                ", userAddress='" + userAddress + '\'' +
                ", userId='" + userId + '\'' +
                ", consignee='" + consignee + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", isDefault='" + isDefault + '\'' +
                '}';
    }
}
public class UserServiceImpl implements UserService {
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("UserServiceImpl.....old...");
        // TODO Auto-generated method stub
        UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
        return Arrays.asList(address1,address2);
    }
}

2、服务消费者

加入同样的bean实体和一个订单service

public class OrderServiceImpl implements OrderService {
    UserService userService;
    @Override
    public List<UserAddress> initOrder(String userId) {
        // TODO Auto-generated method stub
        System.out.println("用户id:"+userId);
        //1、查询用户的收货地址
        List<UserAddress> addressList = userService.getUserAddressList(userId);
        for (UserAddress userAddress : addressList) {
            System.out.println(userAddress.getUserAddress());
        }
        return addressList;
    }
    
}

但userservice和订单service在不同的工程中,这时就需要用到dubbo.

工程架构
1、分包
建议将服务接口,服务模型,服务异常等均放在 API 包中,因为服务模型及异常也是 API 的一部分,同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
如果需要,也可以考虑在 API 包中放置一份 spring 的引用配置,这样使用方便,只需在 spring 加载过程中引用此配置即可,配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml。
2、粒度
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。
创建公共接口工程
创建公共接口工程,将上述bean和功能接口复制进去,将服务者和消费者的bean和service接口删掉:
在这里插入图片描述
在consumer和provider中引入公共接口依赖:

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>gmall-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

引入dubbo

为了使订单service可以成功实现远程调用用户service,需要使用dubbo进行改造。
步骤:

1、将服务提供者注册到注册中心(暴露服务)
    1)、导入dubbo依赖(2.6.2)\操作zookeeper的客户端(curator)
    2)、配置服务提供者
 
2、让服务消费者去注册中心订阅服务提供者的服务地址

首先在服务和消费模块引入依赖:

        <!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.2</version>
        </dependency>

        <!--ZooKeeper客户端实现 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>

服务端provider.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd
       ">

<!--    配置提供者-->
    <!--当前应用/服务的名字(同样的服务名字相同,不要和别的服务同名)  -->
    <dubbo:application name="user-service-provider"></dubbo:application>
    <!--指定注册中心的地址  -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <!--使用dubbo协议,将服务暴露在20880端口  -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 指定需要暴露的服务 ref:指向服务的真正实现对象-->
    <dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl" />
    <bean id="userServiceImpl" class="com.atguigu.gmail.service.impl.UserServiceImpl"></bean>
    
</beans>

服务端consumer.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan>
    <!-- 应用名 -->
    <dubbo:application name="order-service-consumer"></dubbo:application>
    <!-- 指定注册中心地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" ></dubbo:registry>
    <!-- 声明需要调用的远程服务的接口:生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="userService" interface="com.atguigu.gmall.service.UserService"></dubbo:reference>

</beans>

在orderServiceImpl中给其加上@Service注解,将给userservice上加@Autowired注解注入容器。
启动服务

//服务端
public class MainApplication {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:provider.xml");
        context.start();
        System.in.read();
    }
}
//消费端
public class MainApplication {
    @SuppressWarnings("resource")
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:consumer.xml");
        OrderService order = context.getBean(OrderService.class);
        order.initOrder("1");
                System.in.read();

    }

}

两个应用启动成功后在dubbo admin管理页面就可以看到相应的信息。

访问initOrder请求,会调用UserService获取用户地址;
调用成功。说明我们order已经可以调用远程的UserService了;

监控中心安装

前面安装过的dubbo-admin是图形化的服务管理页面;安装时需要指定注册中心地址,即可从注册中心中获取到所有的提供者/消费者进行配置管理。

dubbo-monitor-simple是一个简单的监控中心;
安装步骤:
安装
1、下载 dubbo-ops
ops
2、修改配置指定注册中心地址
进入 dubbo-monitor-simple\src\main\resources\conf
修改 dubbo.properties文件
在这里插入图片描述

3、打包dubbo-monitor-simple

mvn clean package -Dmaven.test.skip=true

4、解压 tar.gz 文件,并运行dubbo-monitor-simple-2.0.0中bin目录下的start.bat
在这里插入图片描述

如果缺少servlet-api,自行导入servlet-api再访问监控中心

访问8080端口:
在这里插入图片描述在consumer.xml和provider.xml中配置监控中心

<!--    所有服务配置连接监控中心,进行监控统计-->
    <!-- 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心 -->
    <dubbo:monitor protocol="registry"></dubbo:monitor>

与springboot整合

新建springboot的provider和consumer项目,将service实现复制进去,同样的将gmall-interface通用接口的依赖导入两个应用中。

引入dubbo和curator的依赖
在两个应用中引入依赖,注意springboot和dubbo的版本要适配。

<!--    我的是springboot2.6.7-->
       <dependency>
           <groupId>org.apache.dubbo</groupId>
           <artifactId>dubbo-spring-boot-starter</artifactId>
           <version>2.7.8</version>
       </dependency>
       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-framework</artifactId>
           <version>4.3.0</version>
       </dependency>

       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-recipes</artifactId>
           <version>4.3.0</version>
       </dependency>
       <dependency>
           <groupId>org.apache.zookeeper</groupId>
           <artifactId>zookeeper</artifactId>
           <version>3.4.9</version>
           <exclusions>
               <exclusion>
                   <groupId>org.slf4j</groupId>
                   <artifactId>slf4j-log4j12</artifactId>
               </exclusion>
           </exclusions>
       </dependency>

properties文件配置:

提供者配置:
dubbo.application.name=boot-user-service-provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
dubbo.scan.base-package=com.atguigu.gmall #配置包扫描规则,开启了的话基于不用配置@EnableDubbo了
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.monitor.protocol=registry
#application.name就是服务名,不能跟别的dubbo提供端重复
#registry.protocol 是指定注册中心协议
#registry.address 是注册中心的地址加端口号
#protocol.name 是分布式固定是dubbo,不要改。
#base-package  注解方式要扫描的包
消费者配置:
server.port=8081  #和监控中心端口号重叠,改一下
dubbo.application.name=boot-order-service-consumer
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo
dubbo.monitor.protocol=registry

在要暴露的提供者服务上加上dubbo的@service注解

import org.apache.dubbo.config.annotation.DubboService;
@DubboService //暴露服务
@Component
public class UserServiceImpl implements UserService {

   @Override
   public List<UserAddress> getUserAddressList(String userId) {
   ......
   }

在消费者服务中引入远程调用service注解

@Service
public class OrderServiceImpl implements OrderService {

  //@Autowired
   @DubboReference
  UserService userService;
  ......
  }

在两个应用中要开启dubbo功能

@EnableDubbo //开启基于注解的dubbo功能
@SpringBootApplication
public class BootOrderServiceConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(BootOrderServiceConsumerApplication.class, args);
    }

}

在消费者服务中增加controller层

@Controller
public class OrderController {
    
    @Autowired
    OrderService orderService;
    
    @ResponseBody
    @RequestMapping("/initOrder")
    public List<UserAddress> initOrder(@RequestParam("uid")String userId) {
        return orderService.initOrder(userId);
    }

}

访问如下地址

//随便带上一个uid
http://localhost:8081/initOrder?uid=1

访问成功:
在这里插入图片描述

dubbo配置

可以看我整理的另一篇文章:
dubbo配置

dubbo高可用

文章地址:
dubbo高可用


本文转载自: https://blog.csdn.net/sashaSloan/article/details/125421463
版权归原作者 sashaSloan 所有, 如有侵权,请联系我们删除。

“dubbo安装及使用”的评论:

还没有评论