dubbo远程调用(rpc)-->快速入门+管理控制台+整合Springboot开发

Posted 编程小栈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo远程调用(rpc)-->快速入门+管理控制台+整合Springboot开发相关的知识,希望对你有一定的参考价值。

文章目录

一、Apache Dubbo概述

1. Dubbo简介

Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。

什么是RPC?

RPC全称为remote procedure call,即远程过程调用。比如两台服务器A和B,A服务器上部署一个应用,B服务器上部署一个应用,A服务器上的应用想调用B服务器上的应用提供的方法,由于两个应用不在一个内存空间,不能直接调用,所以需要通过网络来表达调用的语义和传达调用的数据。

注:RPC并不是一个具体的技术,而是指整个网络远程调用过程。

RPC是一个泛化的概念,严格来说一切远程过程调用手段都属于RPC范畴。各种开发语言都有自己的RPC框架。Java中的RPC框架比较多,广泛使用的有RMI、Hessian、Dubbo等。

Dubbo官网地址:http://dubbo.apache.org

Dubbo提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

2. Dubbo架构

Dubbo架构图(Dubbo官方提供)如下:

虚线都是异步访问,实线都是同步访问

蓝色虚线:在启动时完成的功能 红色虚线(实线):都是程序运行过程中执行的功能

节点角色说明:

节点角色名称
Provider暴露服务的服务提供方
Consumer调用远程服务的服务消费方
Registry服务注册与发现的注册中心
Monitor统计服务的调用次数和调用时间的监控中心
Container服务运行容器

调用关系说明:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

二、 Dubbo快速入门

1. 点对点直连

【1】服务提供者-service项目

1.创建maven项目,导入jar包坐标
2.编写Service层代码
3.编写测试类,用于发布服务

1.创建maven项目,导入jar包坐标

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.5</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>

2.编写Service层代码

package com.ahcfl.service;

public interface HelloService 
    String sayHello(String name);


========================================
    
package com.ahcfl.service.impl;

import com.ahcfl.service.HelloService;

public class HelloServiceImpl implements HelloService 
    @Override
    public String sayHello(String name) 
        return "hello "+name;
    

3.编写测试类,用于发布服务

package com.ahcfl.app;

import com.ahcfl.service.HelloService;
import com.ahcfl.service.impl.HelloServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;

import java.io.IOException;

public class ProviderApp 
    /**
     * 将服务发布出去
     */
    public static void main(String[] args) throws IOException 
        //1.创建提供服务的类对象
        HelloService helloService = new HelloServiceImpl();
        //2.创建服务提供方应用配置
        ApplicationConfig providerApp = new ApplicationConfig();
        // 设置应用名称
        providerApp.setName("Provider_hello");
        //3.注册中心配置
        // 设置无注册中心
        RegistryConfig registryConfig = new RegistryConfig(RegistryConfig.NO_AVAILABLE);
        //4.访问配置
        ProtocolConfig protocol = new ProtocolConfig();
        // 访问服务提供者时,遵循的协议
        protocol.setName("dubbo");
        // 访问服务提供者时,使用的端口
        protocol.setPort(20880);
        // 访问服务提供者时,线程数量
        protocol.setThreads(200);
        //5.服务提供者暴露服务配置
        ServiceConfig<HelloService> service = new ServiceConfig<>();
        // 设置应用配置
        service.setApplication(providerApp);
        // 设置注册中心
        service.setRegistry(registryConfig);
        // 设置访问配置
        service.setProtocol(protocol);
        // 设置服务接口
        service.setInterface(HelloService.class);
        // 设置应用实例
        service.setRef(helloService);
        // 设置服务提供者版本
        service.setVersion("1.0");
        //6.暴露服务
        service.export();

        System.in.read();
    


【2】服务消费者-web项目

1.创建maven项目,导入jar包坐标
2.编写服务接口
3.编写测试类,用于消费dubbo发布的服务

1.创建maven项目,导入jar包坐标

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.5</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>

2.编写服务接口

package com.ahcfl.service;

public interface HelloService 
    String sayHello(String name);

3.编写测试类,用于消费dubbo发布的服务

package com.ahcflahcfl.app;

import com.ahcfl.service.HelloService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;

import java.lang.reflect.Proxy;

public class ConsumerApp 
    /**
     * 服务消费者方
     */
    public static void main(String[] args) 
        //1.当前应用配置
        ApplicationConfig application = new ApplicationConfig();
        // 设置应用的名称
        application.setName("Consumer_hello");

        //2.连接注册中心配置
        RegistryConfig registry = new RegistryConfig(RegistryConfig.NO_AVAILABLE);


        //3.引用远程服务
        ReferenceConfig<HelloService> reference = new ReferenceConfig<HelloService>();
        // 设置应用配置
        reference.setApplication(application);
        // 设置注册中心配置
        reference.setRegistry(registry);
        // 设置服务提供者的访问路径
        String url = "dubbo://10.254.29.50:20880/com.ahcfl.service.HelloService";
        reference.setUrl(url);
        // 设置服务接口的字节码文件
        reference.setInterface(HelloService.class);
        // 设置版本号
        reference.setVersion("1.0");

        //4.远程过程调用
        // 调用get方法会生成接口的代理类对象,在代理类对象中的方法内,完成远程过程调用
        HelloService helloService = reference.get();
        String str = helloService.sayHello("tom");
        System.out.println("远程过程调用返回值: "+str);
    


2. zookeeper注册中心

注: 先启动Zookeeper服务

【1】服务提供者

package com.ahcfl.app;

import com.ahcfl.service.HelloService;
import com.ahcfl.service.impl.HelloServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;

import java.io.IOException;

public class ProviderApp 
    /**
     * 服务提供者应用
     * 作用: 用于发布服务,让外界调用
     */
    public static void main(String[] args) throws IOException 
        //TODO:1.创建提供服务的类实例
        HelloService helloService = new HelloServiceImpl();
        //TODO:2.当前应用配置: 创建应用配置信息
        ApplicationConfig applicationConfig = new ApplicationConfig();
        // 配置应用名称
        applicationConfig.setName("Provider_hello");
        //TODO:3.注册中心配置: 配置注册中心的路径
        // 配置当前没有可以使用的注册中心(点对点直连-web项目直接访问service项目)
        //RegistryConfig registryConfig = new RegistryConfig(RegistryConfig.NO_AVAILABLE);
        // 配置zookeeper注册中心地址
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        //TODO:4.设置访问提供者的协议与端口
        ProtocolConfig protocolConfig = new ProtocolConfig();
        // 设置访问时的协议
        protocolConfig.setName("dubbo");
        // 设置访问时的端口 dubbo协议默认访问端口为20880
        protocolConfig.setPort(20880);
        // 设置访问当前服务的最大线程数
        protocolConfig.setThreads(200);
        //TODO:5.发布服务 (发布服务时,需要设置泛型,用于描述当前发布的是哪个接口对应的服务)
        ServiceConfig<HelloService> serviceConfig = new ServiceConfig<>();
        // 设置当前应用的配置信息
        serviceConfig.setApplication(applicationConfig);
        // 设置注册中心配置
        serviceConfig.setRegistry(registryConfig);
        // 设置访问时的协议与端口配置
        serviceConfig.setProtocol(protocolConfig);
        // 设置服务接口
        serviceConfig.setInterface(HelloService.class);
        // 设置提供服务的实现类对象
        serviceConfig.setRef(helloService);
        // 设置当前服务的版本号
        serviceConfig.setVersion("1.0.0");
        // 发布服务
        serviceConfig.export();

        System.in.read();
    


【2】服务消费者

package com.ahcfl.app;

import com.ahcfl.service.HelloService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;

import java.io.IOException;

public class ConsumerApp 
    /**
     * 服务消费者: 用于远程调用service项目中的代码
     */
    public static void main(String[] args) throws IOException 
        //TODO:1.创建消费者应用配置
        ApplicationConfig applicationConfig = new ApplicationConfig();
        // 设置应用名称
        applicationConfig.setName("Consumer_hello");
        //TODO:2.连接注册中心配置: 配置注册中心地址
        // 没有注册中心
        //RegistryConfig registryConfig = new RegistryConfig(RegistryConfig.NO_AVAILABLE);
        // 设置zookeeper注册中心地址
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        //TODO:3.引用远程服务 (在本应用中创建接口的实现类,在实现类中完成远程调用)
        ReferenceConfig<HelloService> referenceConfig = new ReferenceConfig<>();
        // 设置应用名称
        referenceConfig.setApplication(applicationConfig);
        // 设置注册中心
        referenceConfig.setRegistry(registryConfig);
        // TODO:设置消费者路径(每一个人生成的消费者虚拟路径都不一样,注意修改)
        // String url = "dubbo://10.254.34.38:20880/com.ahcfl.service.HelloService";
        // referenceConfig.setUrl(url);
        // 设置服务接口
        referenceConfig.setInterface(HelloService.class);
        // 设置版本
        referenceConfig.setVersion("1.0.0");

        // 远程调用提供者提供的方法
        HelloService helloService = referenceConfig.get();
        String result = helloService.sayHello("Tom");
        System.out.println("远程过程调用的结果: "+result);
        System.in.read();
    


优化:服务接口抽取

思考: 在入门案例中service层的接口分别在两个项目中都存在,这样合理吗? 该如何优化

不合理.
将冗余的接口抽离成一个独立的java项目,哪个项目需要使用此接口,直接依赖当前项目即可

三、 Dubbo管理控制台

我们在开发时,需要知道Zookeeper注册中心都注册了哪些服务,有哪些消费者来消费这些服务。

之前都是通过zookeeper客户端命令来查看。除了命令外,我们也可以通过部署一个管理中心来实现。

管理中心是Dubbo编写好的, 直接拿过来运行使用即可。Dubbo提供的管理平台有两种一种war包,一种jar包。

1. jar包部署管理平台

dubbo-admin-2.6.0.jar 下载

直接将dubbo-admin.jar命令窗口运行即可

访问: http://localhost:8081
    
注意1-端口:
    为了防止内置tomcat端口与我们常用的端口冲突,我已将端口设置成了8101
    也可通过外部指定配置进行端口的设置
        java -jar jar包名 --server.port=端口号
注意2-zookeeperk地址:
		如果你的zookeeper没有存放在本机,需要编辑jar包中的配置,设置你的zookeeper地址与端口
内置账号:
  账户1: root
  密码: root
  账户2: guest
  密码: guest

2. war包部署管理平台

(1)dubbo-admin-2.6.0.war 下载到tomcat的webapps目录下

(2)启动tomcat,此war文件会自动解压

(3)访问tomcat服务 http://localhost:8080/dubbo-admin-2.6.0/

注意: 
如果你的zookeeper不是部署在本机, 那么需要在项目解压后WEB-INF下的dubbo.properties文件中的dubbo.registry.address对应的值需要设置成你使用的Zookeeper的ip地址和端口号
dubbo.registry.address=zookeeper://192.168.190.137:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

访问http://localhost:8080/dubbo-admin-2.6.0/,输入用户名(root)和密码(root)

当启动服务提供者工程和服务消费者工程,可以在查看到对应的信息

四、Dubbo开发SpringBoot

1. Dubbo文档查询

Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程过程调用。

本章节就是要创建两个应用(app/项目),一个作为服务的提供方,一个作为服务的消费方。

通过Dubbo来实现服务消费方远程调用服务提供方的方法。

版本开发要求说明: 开发中所有的版本统一,避免环境问题导致的代码无法运行

  • jdk1.8 环境变量配置要OK
  • springboot 2.4.0
  • dubbo 2.7.5
  • zookeeper 3.5.8
  • maven 环境搭建OK 连接好阿里云远程仓库
Dubbo在线文档地址: 此地址有可能发生变动,具体地址应通过官网查找 
	http://dubbo.apache.org/zh/docs/v2.7/user/configuration/
注解配置Dubbo相关API:
	http://dubbo.apache.org/zh/docs/v2.7/user/configuration/annotation/

2. 架构模型

经典开发模式:

采用Dubbo 框架SOA面向服务开发流程:

3. 代码实现

步骤:
1.创建三个模块  编写依赖
    dubbo_api:     存放接口规范  普通的maven项目
    dubbo_service: 服务提供方    springboot构建的web项目
    dubbo_web:     服务消费方    springboot构建的web项目
    dubbo_service模块依赖dubbo_api
    dubbo_web模块依赖dubbo_api
2.编写dubbo_api
    创建接口规范
3.编写dubbo_service
    导入jar包依赖
    编写服务代码[完成接口实现]
    编写配置文件,完成注册中心配置
	编写引导类,启动服务器,完成服务注册
4.编写dubbo_web
    导入jar包
    编写Controller代码
    编写配置文件,完成注册中心配置
    编写引导类,启动服务器,完成服务注册

1、创建三个模块 并设置依赖关系

<!--dubbo_service模块依赖dubbo_api-->
<dependency>
    <groupId>com.ahcfl</groupId>
    <artifactId>dubbo_api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

<!--dubbo_web模块依赖dubbo_api-->
<dependency>
    <groupId>com.ahcfl</groupId>
    <artifactId>dubbo_api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

2、编写dubbo_api 创建接口规范

package com.ahcfl.service;

public interface UserService 
    String sayHello(String name);
    String findAll();

3、编写dubbo_service 服务提供方

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.5</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupIdDubbo的使用

Dubbo实战快速入门

Dubbo快速入门分析

RPC框架与Dubbo完整使用

RPC框架与Dubbo完整使用

Dubbo 入门