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