dubbo3认识yaml配置使用版与“入门进阶”使用教程

前言

最近在研究微服务,刚好学到了dubbo,入门踩了很多坑,也看了网上很多的视频或者文章,但是整体质量个人感觉要么比较老,要么过于底层,要么过于简单,反正感觉来说就是缺乏一个能够让开发者简单且灵活应用的教程。

这里在下给大家简单整理一下dubbo3的“简单进阶”应用,同时聊一下学习过程中踩的坑(笔者相对来说实力比较水,所以踩了很多坑~~)

先和大多数教程一样,来认识一下什么是dubbo以及dubbo3新特性吧

 

介绍

Dubbo 是一款由阿里巴巴开发的高性能、轻量级的开源服务框架,用于开发高性能的服务化应用程序。它主要提供了面向接口的远程方法调用(RPC)设计,允许开发者像调用本地对象一样调用远程对象,极大地简化了Java应用之间的服务调用。Dubbo内置了服务自动注册与发现机制,能够适合多种主流服务注册中心比如nacos,zookeeper等等,并且支持多种集群容错方案,能够与Spring框架无缝集成。

这样说得很模糊,通俗而言(既然通俗就难免不严谨哈),dubbo是一种掌管控制分布式服务或者微服务之间相互通信,相互协作的一个服务框架,依靠服务注册中心,提供的服务注册和暴露,dubbo就像是一座桥来搭载服务之间的关系

Dubbo3 是 Dubbo 的一个重要版本更新,也是截止目前为止的使用版本(2024年10月了,dubbo目前是3.3版本),它在原有的基础上增加了对云原生环境的支持,并且优化了多个方面以适应现代微服务架构的需求。以下是 Dubbo3 最核心的两个新特性

 

Triple 协议:

Dubbo3 引入了一个新的通信协议称为 Triple(大家都熟悉triple kill吧,哈哈哈),该协议是基于 HTTP/2的rpc协议规范,完全兼容高性能的grpc协议,可以提供更好的网络性能和更广泛的兼容性,同时支持多种语言的互操作性,为跨语言的微服务设计实现dubbo的解决方案,简而言之这个协议很强,很符合现代,也是官方推荐使用的协议(因为配置时,有多种协议选项,下面会讲)

服务发现模型改进:

 Dubbo3 改进了其服务发现机制,从之前的接口级别的服务发现转变为应用级别的服务发现,这有助于降低服务注册中心的压力,并且提高了服务发现的效率。

 

回顾

这里简单回顾服务注册中心,微服务嘛,简单而言就是一个项目被拆分为很多个小的服务,每个服务实例就是一个进程,每个服务由多个服务实例构成。

什么是接口级别服务发现呢,顾名思义,每个服务最终的连接源点还是服务的接口(简单理解为函数),接口级别服务就是以更细粒度拆分服务,将实际的应用实例的接口源点作为服务,不再是服务实例或者服务进程组成服务,而是其中的函数接口暴露出来组成服务。应用级别服务发现就可以大概理解为就是我上面对微服务的简述那样。简单对比来说呢就是,一个应用级别的服务可以被更细粒化拆分为多个接口级别服务。

前者感觉细粒度更高,更具体,那么为什么要选择后者呢,有诸多原因这里提两个较为核心的原因,一是为了与 Spring Cloud、Kubernetes 的服务模型保持一致,更好地互联互通和集成,二是降低服务注册中心压力,特别是在大规模微服务架构中,如果使用接口级别服务,那么服务注册中心压力将几何倍增长(很好理解,一个应用被拆分为了几个接口单独作为服务实例,大规模微服务下,本身应用实例都有很多了,再拆分为接口单独注册,可想而知)

 

代码

光说不练假把式,下面我们进入代码环节,更细致的认识一下它。

我这里的技术架构是springboot,nacos,dubbo,演示一个简单的小测试(关于下面测试代码中的一些解释,在下面展示代码后,我会一一讲一下,如果宝子们对代码不感兴趣,只想看解释的,可直接跳过下面代码)

依赖

首先,导入dubbo与nacos相关依赖:

定义全局版本参数信息:

dad549c38ceb4629bf4fb10defbb8515.png

服务端与客户端都需要的配置:

nacos相关依赖:

be7173307ead45308194b13016c608c2.png

对于bootstrap.yaml配置文件的友子不要忘了加下面这个依赖(可以参考我nacos那章有说哦):

51527f590157416c913fa3945fe6cf8c.png

dubbo相关基础依赖:

366272a3f76f4a8f8d471edf9c245521.png

c79586ab8c4c4f0795c86e04cc7589d9.png

 

配置

创建好后,我们先编写一下服务端的yaml配置:

provider端本地yaml:

e14e614d9f26416eb0d9e156ca1d93fc.png

provider端在注册中心的配置:

# nacos配置
spring:
  cloud:
    nacos:
      discovery:
        metadata:
          author-name: "guyueyuan"
          cls: "server"

# spring项目服务端口配置
server:
  port: 8763

# dubbo相关配置
dubbo:
# dubbo应用名称
  application:
    name: "test-dubbo-provider"
# dubbo应用使用的协议以及端口
  protocol:
     name: tri
     port: 50051
# 注册中心相关配置
  registry:
    address: nacos://192.168.199.1:8848
    group: dubbo-group
    register-mode: instance
    registry-type: service
# 服务自定义元数据
  metadata-report:
    address: nacos://192.168.199.1:8848
    parameters:
      author: "guyueyuan"

 

consumer端本地相关配置:

spring:
  cloud:
    nacos:
      config:
        server-addr: "127.0.0.1:8848"
        refresh-enabled: true
        file-extension: yaml
        enable-remote-sync-config: true
  application:
    name: "test-consumer"
  profiles:
    active: dev

consumer端在配置中心的相关配置:

spring:
  cloud:
    loadbalancer:
      enabled: true
    nacos:
      discovery:
        metadata:
          author-name: "guyueyuan"
          cls: "client"
        server-addr: "127.0.0.1:8848"
server:
  port: 8764
dubbo:
  application:
# consumer端dubbo服务的名
    name: "test-dubbo-consumer"
#    dubbo注册状态检查的一个参数,一般开发环境加
    qos-enable: true
    qos-port: 22223
  registry:
    address: nacos://192.168.199.1:8848
    group: dubbo-group
# 这是注册中心的组别,可以和实际调用的服务组别不同
#    parameters:
#      register-consumer-url: true
#  Dubbo 3.0.0 版本以后,增加了是否注册消费者的参数,如果需要将消费者注册到 nacos 注册中心上
  metadata-report:
    address: nacos://192.168.199.1:8848
    parameters:
      author: "guyueyuan"

 

代码以及注解

java代码与注解使用部分:

服务端:

建立一个service的类和接口

9bbe602af4df4fe9b854e26e09739ced.png

类上面写上@DubboService注解,可以写上组和版本

@DubboService(group = "dubbo-group-tx",version = "1.0.0")
public class DubboTestServiceImp implements DubboTestService {

    public String responseNameHello(String name){
        System.out.println("name is: "+name);
        return "hello:"+name;
    }
}

在配置启动类上面写上启动nacos和dubbo的注解

@EnableDiscoveryClient
@SpringBootApplication
@EnableDubbo
public class ServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }
}

消费者端:

在该模块的与服务模块一样的路径下创立一个与服务模块一样的接口,就是说这个接口,在各自的模块的相对路径是一样的,但其实正确开发中不会这样玩,我这里只是写例子,下面也会详细讲解

29fca0fd8b1d48f7b8292d12a7f2529b.png

写一个controler来使用,注意看这里的@DubboReference注解及其参数

@RestController
@RequestMapping("test_cloud")
public class MainController {
    
    @DubboReference(group = "dubbo-group-tx",version = "1.0.0")
    DubboTestService dubboTestService;


    @GetMapping("/dubbo/{name}")
    public String getNameHelloByDubbo(@PathVariable String name){
        String newName= dubboTestService.responseNameHello(name);
        System.out.println("old:"+name);
        System.out.println("new:"+newName);
        return newName;
    }

 

相关结果展示

至此,代码部分就写完了,启动事先准备好的nacos服务,先启动provider端,再启动consumer端的模块,登录nacos服务网页,你会看见如下页面:

ba05358f587a42c79435b61e3c24a277.png

这三个,分别是consumer端和provider端的服务以及provider端的dubbo服务(如果还有更多的,不用担心,下面我会说一下大概原因)

访问consumer端的controler层的服务端口:

3a868cdeb2c34daf8d76dd21369139b5.png

如果这里页面访问显示正常,那么,恭喜你,已经实现了使用dubbo进行两个模块的桥接通信!!!

 

讨论研究

当然,如果只是上面操作下来,和普通教程里面的展现如出一辙,只是给大家展现了一个套路的写法,下面,我将粗略为大家讲一下一些相关配置和参数的使用原理以及小编所踩的坑

pom方面

1:很多教程可能有很多个子依赖来组成,但是,拿dubbo而言,基本的功能,其实只用我上面代码里面的那个大依赖就行了,比如与nacos整合,使用triple协议,但是这样肯定会有很多没有必要的包,所以使用大依赖与否看实际开发环境,这里只是小编一个案例;

2:使用好maven的版本统一管理真的很有必要,小编最开始对maven运用还不是很知道一些操作原理,只会按照一些套路操作,导致出现了很多不知道依赖版本和依赖版本冲突问题,所以这里建议如果有码友有相同问题的,可以稍微减缓一下进度,巩固也是非常重要的

3:如果使用的tri通信协议(后面会讲),并且使用的是Protobuf (IDL) + Triple 协议方式(就是使用类似传统grpc的调用风格使用dubbo),在pom的解析proto文件的插件那里,要加入<protocPlugins>加入dubbo风格封装,这里代码对不是很懂maven的码友而言理解可能稍微有点点困难,但这是官网写法,这种一般cv就够了

<plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
                    <outputDirectory>build/generated/source/proto/main/java</outputDirectory>
                    <protocPlugins>
                        <protocPlugin>
                            <id>dubbo</id>
                            <groupId>org.apache.dubbo</groupId>
                            <artifactId>dubbo-compiler</artifactId>
                            <version>${dubbo.version}</version>
                            <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
                        </protocPlugin>
                    </protocPlugins>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

 

配置方面

配置文件部分,nacos相关就不讲了,这里主要说一下dubbo的相关配置属性:

1:这里的教程代码主要是用的yaml和注解方式配置,但是,dubbo的配置有很多方式,这里建议,在一般业务的场景下,使用yaml和注解的方式就够了,只有在可能特殊比较复杂的地方,可以考虑用javaAPI的方式(很多教程都是用的这个方式,但是对初学者可能并不是很喜欢)

2:对dubbo的配置也是一个nacos服务,所以也有分组和名字,命名空间,在application下面有name属性,这个本来也是属于dubbo应用原本的属性,对于分组,则是写在register属性下面的和服务注册相关了(还有注册中心地址呀等等和服务注册中心相关的配置)

3:对于protoc属性,是配置通信协议的,默认下,是dubbo2协议,但是官方建议改为新的tri协议,这里的协议改动,在后面使用时其实与传统的dubbo没有区别,只是tri协议有更多的适配功能,tri向下兼容。另外,不是说配置了这个就会占用这个端口,要被扫描出或者配置了dubbo:server:才有服务才会再有配置服务。注意,使用了tri协议,其实可以底层是兼容grpc,就是说不用dubbo,即使使用单纯的grpc连接,也是可以的

4:怎么时候才会是被配置成消费还是服务端,主要看你的注解扫描(@DubboService和@DubboReference)或者dubbo:server和dubbo:client配置。也可以拥有是消费服务双模式。

5:dubbo:metadata-report:是用来向注册中心提供元数据,为什么这里也要加注册中心地址,这是dubbo设计就是这样的,上面那个register属性,主要管和服务注册中心的连接,这里更多的是元数据的报告

6:qos的基本配置,可以见上面的代码中,一般是开发模式下才用那个,但是注意,端口号,小编最开始的时候,默认端口号和我电脑上的某个应用端口冲突了

7:对于负载均衡策略,dubbo提供了很多解决方案,也有全局默认解决方案,对于全局解决方案,使用dubbo:consumer(provider):loadbalance:下面的属性,对于接口级别使用方案:在配置接口的时候有loadbalance属性的。另外,也有方法级别配置和javaApi的高级配置,这些可以建议看官网具体哟,负载均衡一般是写在consumer端的哟

8:负载均衡,和dubbo多服务实例的更一步理解:一个服务的不同服务实例,就是相同的name不同的端口(nacos节有讲),负载均衡,是在消费者端配置,用于处理消费者选取服务提供者的策略。服务消费者启动后,会从Nacos订阅所需的服务列表,并根据负载均衡策略选择合适的服务实例进行调用。注意认识,负载均衡主要是在消费者本地端,服务与服务实例的管理主要是在nacos。nacos负责服务的注册与发现,提供服务实例的信息,并进行健康检查

9:由于,dubbo是有接口级别定义的,所以在定义一个服务接口或者使用一个消费者接口实例的时候,会可以配置,接口分组,版本,负载均衡,响应时长等等信息,比如当服务者端为@DubboService(group = "dubbo-group-tx",version = "1.0.0")就需要相同的消费接口实例比如:

@DubboReference(
        group = "dubbo-group-tx",
        version = "1.0.0",
        loadbalance = "roundrobin", // 负载均衡策略
        timeout = 5000, // 响应时长(毫秒)
        retries = 2, // 重试次数
        check = false // 是否进行健康检查
    )

另外,注意接口名称也要一样哦!(完全相对路径名,从“java”文件包下面的路径一直到类名)

10:启动注解:@EnableDubbo不要忘了,另外,扫描的时候,默认是扫描与加了这个启动注解的配置类所在的目录及子目录下面,但是也可以自定义使用:EnableDubbo(scanBasePackages = {"org.apache.dubbo.springboot.demo.provider"}),后面那个可以是字符串也可以是这种字符串数组(不要python写多了不认识java数组了哈!)

11: instance应用级启动,在官网中,推荐使用dubbo3应用级配置服务,在使用上,代码上都是一样的,也就是改个register:register-mode: instance(默认是all,为了和dubbo2兼容),上面也说过了接口级和应用级的区别,所以一般遵循官网推荐原则哟。虽然代码上都是一样的,但是在注册中心控制台就能够看到接口注册和服务注册的不同,这里也可以区官网详细了解一下

 

服务使用上

服务端:

1:服务端的服务接口代码主要有两种写的风格,一般是传统的java-Interface方式,还有就是上面有提到的Protobuf (IDL) + Triple。对于这两种方式,前者是通用的,后者只能是tri协议才可以。前者是通用的,也是最有dubbo代码风格的写法。后者主要是适应融合类似grpc传统写法的方式。第一种,上面代码已经展示过了,这里介绍一下第二种代码(dubbo其实还有很多风格,比如restful结合openfigne等等,但是目前不是主推的方式,有需要的码友可以去官网研究一下,使用都很简单的):

package test.demo3.demos.controler;

//这里这个导入认识一下,只有软件包下面的才能导入进来
import grpc_gen.DubboHelloServiceTriple;
import grpc_gen.HelloRequest;
import grpc_gen.HelloResponse;
import org.apache.dubbo.config.annotation.DubboService;


@DubboService
public class GrpcControler extends DubboHelloServiceTriple.HelloServiceImplBase {

    @Override
    public HelloResponse hello(HelloRequest request) {
        System.out.println(request.getName());
/*       return super.hello(
HelloRequest.newBuilder().setName("hello:"+request.getName()).build()
);
*/
        return HelloResponse.newBuilder().setResult("hello:"+request.getName()).build();
//        不要使用上面那个super,原因估计要去抓了源码才知道
//        映射对应与服务发现?
    }
}

(这里我遇见的坑就在注释里面了~~~)提一下,要用这个方式,protoc必须要是用了dubbo插件辅助生成,生成dubbo相关配置与传统protoc生成类相融合的使用类,在作为服务端的时候,这个就相当于原来的grpc的包含服务类的类(这里都是非主类,但是也可以拆开)。

说一下上面两个注释:

第一个是,protobuf工具生成后,我发现我在src目录下的代码引用不了生成的类,我现在的目录结构是下面这样的,刚开始的时候,我没有将那个grpc-gen变成软件包(下面这个图是变成软件包了的,注意这个和普通目录图标不一样,主要是idea内部反射会失败,强行引用会过不了编译),而那个又不在src目录下,所以引用不了,还有一个坑,我当时把生成的这些类手动cv移动到src目录下,可以引用了,但是启动报错,说什么配置问题,我一直以为是版本问题,这里把我卡了很久~~总之,生成的文件不要乱动,要么生成的时候指定好位置,(这里也可以看出,其实小编很水,软件包这个,以前只知道与普通目录有区别,但具体没去研究过,这里不就出问题了!!!)400984cafe57496588a353d932dd87e7.png

第二个注释,估计要去研究源码才知道,小编暂时还没去研究过,就是使用了他自带的那个super的返回的话,会出现返回错误,反正,就重写方法后,完全自己重写就行了,反而也更能看懂代码

 

客户端:

客户端主要的方式还是定义接口,然后使用加@DubboReference,但是不同的风格,对接口可能不一样?比如,最传统的dubbo就是最传统的自定义接口,见上代码。protobuf风格,就是protobuf生成的那个服务接口(上面图片那个最后的那个接口,其实,稍微看点点源码,也知道服务类那个也是继承了这个接口的,只是被dubbo封装了的)。还有就是restful风格的,下面我从官网拉了接口的代码,更多详细还是看官网

// 接口
@FeignClient(name = "spring-cloud-provider-for-dubbo")
public interface UserServiceFeign {
    @RequestMapping(value="/users/list", method = RequestMethod.GET, produces = "application/json")
    List<User> users();
}

//使用
@DubboReference
private UserServiceFeign userService;

 

结语

上面代码也其实只是很简单的入门基础,注意上面有很多只是小编自己的理解,在专业术语上肯定不严谨,主要是为了帮助和小编一样的小菜码友们更好的入门理解。但是小编在这里忠告一下,官方文档才是最严谨的,一切以官方为准,如果有实力的码友能够挖源码的,也以源码为准。

由于小编才开始写博客加上技术度不是很高,如果对上面文章或者代码有什么问题的或者想法的,欢迎评论区留言哟!

下面是相关直达连接

官网:https://cn.dubbo.apache.org/zh-cn/

springcloud整合:

https://cn.dubbo.apache.org/zh-cn/blog/2023/10/07/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5%E9%9B%B6%E6%94%B9%E9%80%A0%E5%AE%9E%E7%8E%B0-spring-cloud-apache-dubbo-%E4%BA%92%E9%80%9A/

grpc整合(tri):https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/protocols/protocol/

负载均衡:

https://cn.dubbo.apache.org/zh-cn/overview/reference/proposals/heuristic-flow-control/

spring结合基础使用:

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/develop/springboot/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值