Dubbo入门详解,API方式与SpringBoot方式

news2025/1/2 4:09:01

Hi I’m Shendi


Dubbo入门详解,API方式与SpringBoot方式



在之前一直使用的自己编写的RPC框架,因为是自己编写的,功能上比不过市面上的开源框架,包括后面Spring Cloud系列,如果还用自己编写的话就需要去做整合之类的,是一个庞大的工作量。

本着能不造轮子就不造轮子的想法,于是开始学习一下Dubbo



Dubbo

Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。

使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。



官方文档:https://cn.dubbo.apache.org/zh-cn/index.html



RPC、分布式、微服务

这里简述一下,RPC即远程过程调用(Remote Procedure Call),通过RPC,可以使得一个程序调用其他设备程序的函数(通过网络)

分布式即将多个程序通过网络方式进行通信,组成一个系统,通常使用RPC来实现分布式

而微服务是将一个程序拆分成多个程序,程序之间通过分布式的方式进行通信



快速入门


启动 Zookeeper

官方文档目前使用的 zookeeper,所以首先需要安装zookeeper,关于zookeeper的安装使用可以参考这篇文章

Zookeeper安装入门详解,简单使用



基于 Dubbo API 开发微服务应用

任意Maven项目,编辑 pom.xml 增加以下内容

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>3.2.0-beta.4</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-x-discovery</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.8.0</version>
    <exclusions>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-handler</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-epoll</artifactId>
        </exclusion>
    </exclusions>
</dependency>


注:依赖包大多都是用 org.apache.dubbo 的


服务提供者

新建两个包,一个api,包含服务接口定义,一个provider,包含服务接口的具体实现

在 api 包下新建一个接口,内容如下

public interface ITest {

	String sayHi(String name);
	
}

在 provider 包中新建一个类实现此接口,并发布服务端,内容如下

import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import demo.api.ITest;

public class Test implements ITest {

	public static void main(String[] args) {
		// 定义具体的服务
        ServiceConfig<ITest> service = new ServiceConfig<>();
        service.setInterface(ITest.class);
        service.setRef(new Test());

        // 启动 Dubbo
        DubboBootstrap.getInstance()
                .application("first-dubbo-provider")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .protocol(new ProtocolConfig("dubbo", -1))
                .service(service)
                .start()
                .await();
	}

	public String sayHi(String name) {
		return "hi, " + name;
	}
	
}

上面的 zookeeper 是 zookeeper地址,更改了端口上面的字符串也要对应更改

现在可以启动服务提供者了,启动后控制台会输出大量的信息…

等待一会,看到有以下信息就代表启动成功了

Got ping response for session id:…

在这里插入图片描述


这个东西会一直输出,是ZK的心跳机制日志

简单叙述一下上面实现的功能,相当于提供了一个sayHi接口,接口接收一个name参数,返回一个字符串,字符串内容为 hi, + 传递的name参数



服务消费者

新建一个包 client 用于专门存放客户端(消费者)

在包下新建一个类 Test2,用来订阅提供的服务并调用

内容如下

import java.io.IOException;

import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import com.alibaba.dubbo.config.ReferenceConfig;

import demo.api.ITest;

public class Test2 {

	public static void main(String[] args) throws IOException {
		ReferenceConfig<ITest> reference = new ReferenceConfig<>();
        reference.setInterface(ITest.class);

        DubboBootstrap.getInstance()
                .application("first-dubbo-consumer")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .reference(reference);
        
        ITest service = reference.get();
        String message = service.sayHi("dubbo");
        System.out.println("Receive result ======> " + message);
        System.in.read();
	}
	
}

运行后,输出了大量信息,最终可以看到以下信息

在这里插入图片描述


根据上面的代码就实现了一个简单的通过服务发现进行 RPC 调用了,代码简单,看一眼基本上就知道啥意思了



基于SpringBoot开发微服务应用

和API开发类似,但SpringBoot的特点是采用基于注解的配置方式,这样可以快速开发

官网的示例是使用的Maven多模块,有三个模块,分别为

  1. 接口
  2. 提供者
  3. 消费者

在上面,我们知道提供者和消费者都需要定义接口部分,提供者实现接口,消费者使用接口,为了使接口部分共用,所以官方示例使用的多模块


官方示例使用的IDEA,我这里列出Eclipse的流程

(当然不使用多模块也是可以的,也可以分成一个项目或者两个项目)

新建一个Maven项目,Packaging选择pom,pom.xml增加以下依赖

	<properties>
        <dubbo.version>3.2.0-beta.4</dubbo.version>
        <spring-boot.version>2.7.8</spring-boot.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

然后新建三个模块,分别为

  • demo-consumer(消费者)
  • demo-provider(提供者)
  • demo-interface(共用接口)

在项目处右键 -> New -> Other -> Maven -> Maven Module

在这里插入图片描述


Packaging选择jar,创建模块

更改demo-provider和demo-consumer的pom.xml内容,将SpringBoot需要的内容copy进来,并增加以下依赖

	<dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-samples-spring-boot-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

除上面的依赖外,还需要引入共用部分,demo-interface

<dependency>
    <groupId>demo-interface</groupId>
    <artifactId>demo-interface</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

贴一下项目图

在这里插入图片描述


共用部分(demo-interface)

demo-interface模块为共用部分,在src/main/java下新建一个包命名为demo,包下新建一个接口命名为Service

Service内定义提供者消费者所用的行为,内容如下

在这里插入图片描述


因为这个模块只需要创建接口就可以了,因此pom基本上不需要引入任何依赖



服务提供者(demo-provider)

提供者和消费者都需要引入共用部分,在上面有说过

demo-provider模块为提供者,新建一个包,命名为 demo.provider,在包下新建一个类,命名为 ServerImpl

ServerImpl 实现共用部分(interface)提供的接口 Service,内如如下

package demo.provider;

import org.apache.dubbo.config.annotation.DubboService;

import demo.Service;

@DubboService
public class ServiceImpl implements Service {

	@Override
	public String sayHi(String name) {
		return "hi, " + name;
	}

}

和基于API开发不同的是在类上多了个 @DubboService 注解

@DubboService注解是一个用于标记服务提供者接口的注解。 该注解的作用是将一个接口标记为一个Dubbo的服务提供者,使得该接口的实现类可以被Dubbo注册和暴露为一个可供其他服务调用的服务。被@DubboService注解标记的接口实现类将会被Dubbo框架扫描到,并且会自动生成相应的服务接口代理对象,并注册到Dubbo的注册中心,供其他服务消费方进行调用。使用该注解可以简化Dubbo服务的发布与暴露的步骤,提高开发效率。


然后创建SpringBoot启动类 ProviderApplication,内容如下

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

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

增加了 @EnableDubbo 注解,经尝试,没有这个注解也没问题(但避免其他问题还是加上比较好)


修改SpringBoot的配置文件,因为我创建的Maven项目,那么就需要在 src/main/resources 下新建 application.properties 或者 application.yml

properties

dubbo.application.name=demo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181

yml

dubbo:
  application:
    name: dubbo-springboot-demo-provider
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

这样,服务提供者就做好了



服务消费者(demo-consumer)

demo-consumer为消费者模块,新建一个包demo.consumer,在包下先新建启动类 ConsumerApplication,内容如下

package demo.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

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

这里需要编写Web接口,所以pom.xml内需要增加web依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


新建一个类,命名为 TestControl 内容如下

package demo.consumer;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import demo.Service;

@RestController
public class TestControl {

	@DubboReference
    private Service service;
	
	@GetMapping("/")
	public String test(String name) {
		return service.sayHi(name);
	}
	
}

上面定义了一个Web接口,路由为 /,接口接收一个参数name,接口将调用Service金额可的sayHi函数,并将name参数传入。

这里的service使用了 @DubboReference 注解注入,调用sayHi实际等于调用了 demo-provider 的实现类的 sayHi


这里原理我就不去了解了,略微猜一猜,照我的思路,大致应该就是提供者与消费者连接zookeeper,消费者通过zookeeper与提供者进行rpc通信,消费者使用 @DubboReference 注入的对象我猜大概是RPC发送数据到提供者,例如类为Service,函数为sayHi,那么就发个 Service|sayHi,提供者接收到数据后就去找对应实现类,和实现类的函数然后执行返回数据这样,剩下的就是细节问题了,比如参数之类的。当然,我这里只是以我的思路来实现这样的框架,提供一个简单的思路,要知道具体还是要去看源码、文档和debug


SpringBoot配置文件同提供者一样,但是需要有 server.port 设置 web 端口

这样,消费者也做好了


不通过注解方式获取 Service,通过Context 获取

这里延伸以一下,有的时候不能使用注解注入对象,这个时候就需要用别的方式获取提供者对象了

获取代码如下

ReferenceConfig<Service> referenceConfig = new ReferenceConfig<>();
referenceConfig.setInterface(Service.class);
Service service = referenceConfig.get();


启动应用

运行 ProviderApplicationConsumerApplication


需要注意的是,需要先启动提供者再启动消费者,否则消费者模块会报错导致整个程序Over。这个问题是由 @DubboReference 注解导致的,默认在启动时会去检查对应的提供者是否可用,当然,可以通过配置之类的取消掉检查。

有以下几种解决办法

  1. 注解上增加参数check = false,例 @DubboReference(check = false)

  2. SpringBoot配置文件增加内容

    • properties增加 dubbo.consumer.check=false

    • yml增加

    •   dubbo:
          consumer:
            check: false
      
  3. 在启动类或配置类增加以下代码

    •   @Bean
        public ConsumerConfig consumerConfig() {
            ConsumerConfig consumerConfig = new ConsumerConfig();
            consumerConfig.setCheck(false);
            return consumerConfig;
        }
      

启动后,消费者服务会爆一些错误,但不影响,通过浏览器访问地址,效果如下

在这里插入图片描述


问题解决

[DUBBO] qos-server can not bind localhost:22222, dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind
...

Fail to start qos server: , dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind

这个错误是说 qos 服务的端口被占用了,因为带Dubbo启动就会自动启动 qos server,默认端口为22222,上面我在同一台电脑上启动了提供者,消费者,所以就报这个错误了

Dubbo的QoS(Quality of Service)服务器是一个独立的服务器,用于提供Dubbo服务的质量保证和对服务的相关指标进行监控和管理。

可以通过修改SpringBoot配置文件的方式解决

properties

# 是否启用,默认启用
dubbo.application.qosEnable=true
# 端口,默认22222
dubbo.application.qosPort=12345
dubbo.application.qosAcceptForeignIp=false


至此,基础使用已经ok了




END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/726985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenResume一个功能强大的开源简历生成器,太炫了

OpenResume 是一个功能强大的开源简历生成器和简历解析器。目标是为每个人提供免费的现代专业简历设计&#xff0c;让任何人都能充满信心地申请工作。 核心优势 「实时UI更新」:当输入简历信息时&#xff0c;简历 PDF 会实时更新&#xff0c;因此可以轻松查看最终输出。 「现…

LeetCode刷题 | 647. 回文子串、516. 最长回文子序列

647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#…

ModaHub魔搭社区:清华开源ChatGLM语言模型一键部署教程

目录 ChatGLM是什么 傻瓜式安装部署 一.下载 二、解压 ChatGLM懒人安装包 ChatGLM是什么 ChatGLM和ChatGPT类似&#xff0c;是由清华大学开发的开源大型语言模型。由于它是开源的&#xff0c;所以带来了很多的可能性&#xff0c;比如可以像Ai绘画一样自己微调模型。 目前…

老板说,给我把这个 JS React 项目迁移到 TypeScript

在我们日益发展的网络开发领域中&#xff0c;JavaScript 长期以来一直是首选的语言。它的多功能性和普及性推动了许多应用和网站取得成功。然而&#xff0c;随着项目规模和复杂性的增长&#xff0c;维护 JavaScript 代码库可能变得具有挑战性、容易出错且难以扩展。 走出来的第…

5-Spring cloud之Feign的使用——服务器上实操

5-Spring cloud之Feign的使用——服务器上实操 1. 前言2. 搭建Feign2.1 添加子模块——dog-api2.1.1 子模块结构2.1.2 pom文件2.1.3 核心接口DogClientApi 2.2 添加子模块——dog-consumer-feign-802.2.1 子模块结构2.2.2 pom文件2.2.3 yml文件2.2.4 主启动类2.2.5 controller …

Linux里git的使用

git的使用 一.前置要求1.git的安装2.注册Gitee并创建仓库 二.git三板斧 一.前置要求 1.git的安装 2.注册Gitee并创建仓库 然后记住下面的网址。 之后将仓库克隆到云服务器里。记得输入gitee的账号和密码。 查看目录&#xff0c;可以发现仓库已经在目录里了。 进入目录&#xf…

python毕设课设大作业《火车票分析助手》程序

在PyCharm中运行《火车票分析助手》即可进入如图1所示的系统主界面。 图1 系统主界面 具体的操作步骤如下&#xff1a; &#xff08;1&#xff09;在主界面“车票查询”选项卡中依次输入&#xff0c;出发地、目的地以及出发时间&#xff0c;然后单击“查询”按钮&#xff0c;…

十九、Jenkins版本构建完成,触发自动化测试

十九、Jenkins版本构建完成&#xff0c;触发自动化测试 1.构建后操作-Build other projects 2.关联自动化测试工程 这样版本构建完成&#xff0c;就会执行自动化测试

金九银十跳槽涨薪Java面试题!568页真题+答案解析,大厂都在考

2023年一半又过去了&#xff0c;各大企业的招聘也又开始大量放岗了&#xff0c;各位苟着的小伙伴们要抓住机会了&#xff01; 但很多小伙伴对面试不够了解&#xff0c;不知道如何准备&#xff0c;对面试环节的设置以及目的不了解&#xff0c;尤其是面试题还很难&#xff0c;有些…

RocketMQ5.0--事务消息

RocketMQ5.0–事务消息 一、事务消息概览 RocketMQ事务消息的实现原理基于两阶段提交和定时事务状态回查来决定消息最终是提交还是回滚&#xff0c;消费者可以消费事务提交的消息&#xff0c;如下图所示。事务消息的作用&#xff1a;确保本地业务与消息在一个事务内&#xff0…

成功解决:java file outside of source root

前言 我复制一个很小项目的代码&#xff0c;然后重新命名后。用IDEA打开&#xff0c;发现.java文件的左下方有个橘色的标志。 1、问题文件 这里显示 Java file outside of source root。 查阅资料发现&#xff1a;这个问题是指Java文件不在源代码根目录之内。这可能会导致…

使用pytest命令行实现环境切换

目录 前言 pytest_addoption(parser, pluginmanager) 在conftest.py文件中定义命令行参数 获取命令行参数 设置不同环境的全局变量 定义测试类及测试方法 测试验证 前言 在自动化测试过程中经常需要在不同的环境下进行测试验证&#xff0c;所以写自动化测试代码时需要考…

Android12之IBinder中[[clang::lto_visibility_public]]作用(一百六十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

MySQL自治平台建设的内核原理及实践(上)

总第565篇 2023年 第017篇 本文整理自美团技术沙龙第75期的主题分享《美团数据库攻防演练建设实践》&#xff0c;系超大规模数据库集群保稳系列&#xff08;内含4个议题的PPT及视频&#xff09;的第4篇文章。 本文作者在演讲后根据同学们的反馈&#xff0c;补充了很多技术细节&…

如何绘制「UML类图」

一、UML类图简介 类图以反映类的结构(属性、操作)以及类之间的关系为主要目的&#xff0c;描述了软件系统的结构&#xff0c;是一种静态建模方法。类图用来描述系统中有意义的概念&#xff0c;包括具体的概念、抽象的概念、实现方面的概念等&#xff0c;是对现实世界中事物的抽…

设计模式--------结构型模式

结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低&#xff0c;满足“合成复用原则”…

web 页面布局:(三)position 坐标系布局

web 页面布局&#xff1a;&#xff08;三&#xff09;position 坐标系布局 页面坐标系position 设置fixedrelativeabsolutesticky 应用场景 页面坐标系 因为所有文本内容&#xff0c;是从左向右读&#xff0c;自上而下读&#xff0c;和书写习惯&#xff0c;读书习惯一致&#…

惊呆了!这个银行管理技巧也太厉害了吧

在金融行业&#xff0c;蓄电池监控是一项至关重要的任务。随着金融机构的数字化转型和依赖电力的增加&#xff0c;蓄电池成为保障金融系统正常运行的关键组成部分。 因此&#xff0c;对蓄电池的状态进行监控和维护&#xff0c;确保其高效可靠地工作&#xff0c;对金融行业的稳定…

深度学习06-pytorch从入门到精通

文章目录 概述环境准备安装cuda和cudnn安装pytorch 基础张量定义numpy转换数学函数随机数计算函数矩阵处理函数 自动梯度案例计算图 torchvision模块TransformsDataSetDataLoader自定义数据集 nn模块nn.ModuleCNN图像处理层nn.Conv2dnn.AvgPool2d和nn.MaxPool2dnn.Linearnn.Bat…

TransFuse

方法 Transformer分支 将不同尺度的特征图 t 0 、 t 1 和 t 2 t^0、t^1和t^2 t0、t1和t2保存起来&#xff0c;之后与对应的CNN分支的特征图融合。 CNN分支 以基于ResNet的模型为例&#xff0c;模型通常有五个块&#xff0c;每个块对特征图进行两倍下采样。我们获取第 4( g 0…