Dubbo·上
- 一、导入
 - 1、基础知识
 - 1.1、什么是分布式系统
 - 1.2、发展演变
 - 1.2.1 单一应用架构
 - 1.2.2分布式应用架构
 - 1.2.3 流动计算架构
 
- 1.3 RPC
 - 1.3.1 什么是RPC
 - 1.3.2 RPC核心模块
 
- 二、Dubbo概念
 - 三、设计架构
 - 四、环境搭建
 - 4.1 Zookeeper注册中心
 - 4.2 测试Zookeeper
 - 4.1 监控中心
 
- 五、测试
 - 5.1 需求
 - 5.2分析
 - 5.3编码
 - 5.3.1创建公共接口
 - 5.3.2创建服务提供者
 - 5.3.3创建服务消费者
 - 5.3.4 将服务提供者注册到注册中心(暴露服务)
 - 5.3.5 查看服务是否注册并暴露
 - 5.3.5 配置消费者
 
一、导入
1、基础知识
1.1、什么是分布式系统
定义:
分布式系统是若干个计算机的集合,这些计算甲对于用户来说就像单个相关系统
分布式系统是建立在网络之上的软件系统。
1.2、发展演变
演变图
 
1.2.1 单一应用架构

当网站流量很小时,只需要一个应用,将所有功能部署在一起,以减少部署节点和成本,此时,用于简化增删改查工作量的数据访问框架(ORM)是关键
垂直应用架构
 
1.2.2分布式应用架构

各功能之间一定的分离、页面与逻辑一定的分离
分布式难点:
在于如何远程过程调用和、如何拆分业务,提高业务复用程度
1.2.3 流动计算架构

1.3 RPC
1.3.1 什么是RPC
RPC(Remote Procedure Call):
本质是两个服务器之间架起一个网络通信连接,通过这个连接来调用功能

是一种进程间通信方式,他是一种思想技术,非规范的。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不是程序员显式编码这个远程调用的细节,即程序员无论是调用本地的还是远程的函数,本质上编写的调用基本相同。
例子:
 
1.3.2 RPC核心模块
1、通讯
 2、序列化
RPC框架有很多:
 dubbo、gRBC、HSF
二、Dubbo概念

1、面向接口代理的高性能RPC调用:
如服务器A调服务器B上面的代码,只需要将B上面的接口所在的方法拿来调用。dubbo会自动找B服务器上面的对应代码,并屏蔽调用细节
2、智能负载均衡
 根据服务器的"闲忙"来均衡分配任务,让每台服务器负载均衡
3、服务注册与发现
当业务非常多的时候,业务被分布在各个服务器。这是我们会产生几个问题
 
1、如何知道各个业务在哪台服务器?
2、如果有一台服务器坏了怎么办?
这时我们引入了注册中心
 
将前端页面代码和逻辑代码放到注册中心,形成一个清单。
 这个清单会给出对应的页面或者逻辑代码在哪台服务器上,并会监听服务器的状态
三、设计架构

Registry(注册中心): 会将web和业务代码的信息注册到注册中心
 Provider(服务提供者): 如业务代码
 **Consumer(服务消费者)😗*如web页面
 Container(Dubbo框架容器):
 **Monitor(监控中心)😗*服务者和消费者的信息会发送到监控中心
运行流程
 当dubbo容器启动时,服务提供者会将提供的信息注册到注册中心,注册中心就会知晓有哪些服务,哪些服务上线了。当服务消费者启动的时候,会从注册中心订阅需要的服务,如果某一个服务提供者出现了变更。注册中心会将该信息告知给消费者
 。如果多个服务器都提供了相同的业务功能,消费者可以根据负载均衡算法选择合适的服务器进行调用,每次调用的信息会定时统计发送到监控中心。
四、环境搭建
4.1 Zookeeper注册中心
1、下载Zookeeper,官网:https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz
 
 2、下载好后解压,然后找到D:\app\apache-zookeeper-3.8.0-bin\conf目录
 将conf目录下的zoo_sample.cfg复制一份改名为zoo.cfg

3、在D:\app\apache-zookeeper-3.8.0-bin目录下创建一个名为data的目录,用于存放数据
 再打开zoo.cfg文件,将dataDir=…/data
 
4、启动zookeeper服务
 
5、启动客户端连接zookeeper
 
 连接成功
 
4.2 测试Zookeeper
Zookeeper是一个树形的目录服务

我们可以获取根结点是否有有没有值,没有。
 
 查看根目录
 
 我们可以在zookeeper下面创建一个临时文件
 
4.1 监控中心
详细安装可参考https://blog.csdn.net/weixin_45480785/article/details/118975741
1、在dubbo项目官网找到GitHub的地址dubbo的GitHub地址
1、然后再找到Dubbo Admin

2、然后下载压缩包

3、打开项目下的dubbo-admin-server项目,启动之前我们需要先修改spring boot的核心配置文件
admin.registry.address=zookeeper://127.0.0.1:2181
admin.config-center=zookeeper://127.0.0.1:2181
admin.metadata-report.address=zookeeper://127.0.0.1:2181
 

4、用Maven打包项目,并启动项目
前提是你电脑上安装了maven
D:\dubbo\dubbo-admin\dubbo-admin-server>mvn clean package
 
5、打包完成后在/target文件夹下有一个项目打包成的jar包,然后运行它
java -jar dubbo-admin-server-0.5.0.jar 
 

可能会产生端口占用问题,此时请参考这篇文章http://wjhsh.net/timingstarts-p-12604211.html
6、.启动前端vue项目
 
D:\dubbo\dubbo-admin\dubbo-admin-ui> npm install
 
D:\dubbo\dubbo-admin\dubbo-admin-ui> npm run dev
 

 点击第一个链接:


至此,监控中心搭建完毕

五、测试
5.1 需求

5.2分析

5.3编码
5.3.1创建公共接口

pojo
package com.study.dubbo.pojo;
import java.io.Serializable;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 13:37
 */
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;//用户地址
    private String consignee;//收货人
    private String phoneNum;//电话号码
    private String isDefault;//是否默认地址 Y-是 N-否
    public UserAddress(){}
    public UserAddress(Integer id, String userAddress, String consignee, String phoneNum, String isDefault) {
        this.id = id;
        this.userAddress = userAddress;
        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 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 + '\'' +
                ", consignee='" + consignee + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", isDefault='" + isDefault + '\'' +
                '}';
    }
}
 
Service
package com.study.dubbo.service;
import com.study.dubbo.pojo.UserAddress;
import java.util.List;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 13:44
 */
public interface UserService {
    public List<UserAddress> getUserAddressList(String userId);
}
 
package com.study.dubbo.service;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 13:59
 */
public interface OrderService {
    /**
     * 初始化订单
     * @param userId
     */
    public void initOrder(String userId);
}
 
Ipml
package com.study.dubbo.service.Impl;
import com.study.dubbo.pojo.UserAddress;
import com.study.dubbo.service.UserService;
import java.util.Arrays;
import java.util.List;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 13:45
 */
public class UserServiceImpl implements UserService {
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        UserAddress address1 = new UserAddress(1,"北京市东城区","李老师","13102347856","Y");
        UserAddress address2 = new UserAddress(2,"达州市通川区","张老师","17102347856","N");
        return Arrays.asList(address1,address2);
    }
}
 
package com.study.dubbo.service.Impl;
import com.study.dubbo.pojo.UserAddress;
import com.study.dubbo.service.OrderService;
import com.study.dubbo.service.UserService;
import java.util.List;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 14:01
 */
public class OrderServiceImpl implements OrderService {
    UserService userService;
    @Override
    public void initOrder(String userId) {
        //1、查询用户的收获地址
        List<UserAddress> userAddressList = userService.getUserAddressList(userId);
        System.out.println(userAddressList);
    }
}
 
5.3.2创建服务提供者

在服务提供者内导入Dubbo的依赖
    <!--导入dubbo-interface的依赖-->
    <dependencies>
        <dependency>
            <groupId>org.study</groupId>
            <artifactId>interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
 
5.3.3创建服务消费者

 在消费者内导入Dubbo的依赖
    <!--导入dubbo-interface的依赖-->
    <dependencies>
        <dependency>
            <groupId>org.study</groupId>
            <artifactId>interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
 
5.3.4 将服务提供者注册到注册中心(暴露服务)
1、在服务提供者里导入dubbo依赖,然后引入zookeeper客户端
    <!--引入dubbo依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.12</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
    <!--注册中心使用的是zookeeper,引入操作zookeeper的客户端-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>3.3.0</version>
        </dependency>
 
2、配置服务提供者
在服务提供者的resources下面新建一个名为provider的spring.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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--1、指定当前服务/应用名字(同样的服务名字相同,别和别的服务相同)-->
       <dubbo:application name="dubbo-provider"></dubbo:application>
        <!--2、指定注册中心的位置-->
       <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
        <!--3、指定通信规则(通信协议和通信端口)-->
       <dubbo:protocol name="dubbo" port="20080"></dubbo:protocol>
        <!--4、暴露服务 ref:指向服务的真正实现对象-->
    <dubbo:service interface="com.study.dubbo.service.UserService" ref="UserServiceImpl"></dubbo:service>
    <!--服务的实现-->
    <bean id="UserServiceImpl" class="com.study.dubbo.service.Impl.UserServiceImpl"></bean>
</beans>
 
创建方法,让服务提供者跑起来
package com.study.controller;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 15:09
 */
public class MainApplication {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
        ioc.start();
        System.in.read();
    }
}
 
出现如下样式,则运行成功
 
5.3.5 查看服务是否注册并暴露
回到dubbo监控中心查看服务
我们可以看到第二个出现在了我们的监控中心,表明服务提供者已经注册并暴露成功
 
5.3.5 配置消费者
1、在服务消费者里导入dubbo依赖,然后引入zookeeper客户端
    <!--引入dubbo依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.12</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
    <!--注册中心使用的是zookeeper,引入操作zookeeper的客户端-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>3.3.0</version>
        </dependency>
 
在dubbo-consumer创建一个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://dubbo.apache.org/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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <context:component-scan base-package="com.study.service.Impl"></context:component-scan>
    <!--1、指定当前服务/应用名字(同样的服务名字相同,别和别的服务相同)-->
    <dubbo:application name="dubbo-consumer"></dubbo:application>
    <!--2、指定注册中心的位置-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
    <!--3、声明需要调用远程服务的接口,生成远程服务代理-->
   <dubbo:reference interface="com.study.dubbo.service.UserService" id="UserService"></dubbo:reference>
</beans>
 
在调用远程的接口
package com.study.service.Impl;
import com.study.dubbo.pojo.UserAddress;
import com.study.dubbo.service.OrderService;
import com.study.dubbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 14:01
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    UserService userService;
    @Override
    public void initOrder(String userId) {
        System.out.println("用户id:"+userId);
        //1、查询用户的收获地址
        List<UserAddress> userAddressList = userService.getUserAddressList(userId);
        for (UserAddress u : userAddressList) {
            System.out.println(u.getUserAddress());
        }
    }
}
 
然后创建一个mian方法让消费者程序运行起来,并启动
package com.study.controller;
import com.study.dubbo.service.OrderService;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
 * @author ZS
 * @Description
 * @date 2022/12/2 15:56
 */
public class MianApplication {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
        OrderService bean = ioc.getBean(OrderService.class);
        bean.initOrder("1");
        System.out.println("调用完成...");
        System.in.read();
    }
}
 
最后启动MianApplication ,则会看到调用的结果


![[附源码]Python计算机毕业设计SSM健身房管理系统 (程序+LW)](https://img-blog.csdnimg.cn/4db19bd817d44493bdfe5075a4304682.png)









![[附源码]计算机毕业设计基于springboot学习互助辅助系统](https://img-blog.csdnimg.cn/86d641360aa14f468d97076d88df02c8.png)






