Dubbo3入门实践,SpringBoot+Dubbo+Nacos+DubboAdmin

news2024/10/6 0:32:47

前言

        学习Dubbo的过程中发现官网文章太过简单,而且没有提供完整的项目整合,导致入门门槛比较高,初学者不知从何下手。本文将在SpringBoot的基础上整合Dubbo,注册中心使用当下流行的Nacos,还将使用Dubbo-Admin来管理服务。本文未提到Dubbo的基础知识与基本概念,这方面内容可以直接查阅【Dubbo官网-总体架构】。

步骤

  • SpringBoot多模块基础项目创建
  • Dubbo服务提供方实现
  • Dubbo服务消费方实现
  • 自定义Filter拦截所有消费请求
  • 自定义LoadBalance完成特殊负载均衡
  • DubboAdmin的使用

SpringBoot多模块基础项目创建

项目结构

└─dubbo-test
    │  pom.xml
    ├─dubbo-test-consumer(服务消费方)
    │  │  pom.xml
    │  └─src
    ├─dubbo-test-interface(消费方和提供方共享的接口定义)
    │  │  pom.xml
    │  └─src
    └─dubbo-test-provider(服务提供方)
        │  pom.xml
        └─src

        多模块的创建这里不再赘述,主要分为三个子模块。消费方和提供方共享接口定义模块,避免代码重复。服务提供方实现接口定义,消费方根据接口定义去请求提供方的具体实现,Dubbo完成了整个请求的过程。

Dubbo服务提供方实现

配置文件

dubbo:
  application:
    name: dubbo-test-provider
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
  config-center:
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
    group: dubbo
  metadata-report:
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
    group: dubbo

关键代码

//用户服务
@DubboService
public class UserServiceImpl implements IUserService {
    private static final Random random = new Random();

    @Override
    public User login(String username, String password) {
        if(!"123456".equals(password)){
            return null;
        }
        User user = new User();
        user.setId(random.nextInt(1000));
        user.setUsername(username + "_" + user.getId());
        user.setSex(user.getId()%2 == 0 ? "男" : "女");
        return user;
    }
}

//群组服务
@DubboService
@Component
public class GroupServiceImpl implements IGroupService {
    @Value("${dubbo.application.name}")
    private String appName;

    @Override
    public String join(Integer userId, String groupId) {
        return userId+"_"+groupId+"_"+appName;
    }
}

         这里实现了两个服务,均是来自dubbo-test-interface中的接口定义。用户服务做了一个简单的随机用户信息的创建,群组服务返回了当前属于哪一台主机(为后文自定义负载均衡做准备)。

Dubbo服务消费方实现

配置文件

server:
  port: 8888

dubbo:
  application:
    name: dubbo-test-consumer
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://192.168.0.129:8848
    username: nacos
    password: nacos
  config-center:
    address: nacos://192.168.0.129:8848
    group: dubbo
    username: nacos
    password: nacos
  metadata-report:
    address: nacos://192.168.0.129:8848
    group: dubbo
    username: nacos
    password: nacos
  consumer:
    filter: logFilter

关键代码

@RestController
public class UserController {
    @DubboReference
    private IUserService userService;

    @DubboReference(loadbalance = "groupLoadBalance")
    private IGroupService groupService;

    @GetMapping("/login")
    public User login(String username, String password){
        return userService.login(username, password);
    }

    @GetMapping("/join")
    public String join(Integer userId, String groupId){
        return groupService.join(userId, groupId);
    }
}

        代码引用了两个服务,其中IGroupService服务使用了自定义的负载均衡策略。

自定义Filter拦截所有消费请求

关键代码

@Slf4j
@Activate(group = CommonConstants.CONSUMER)
public class LogFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        log.info("开始调用,接口:{},参数:{}", invocation.getMethodName(), JSON.toJSONString(invocation.getArguments()));
        Result result = invoker.invoke(invocation);
        log.info("调用完成,结果:{}", JSON.toJSONString(result.getValue()));
        return result;
    }
}

配置 

        配置filter需要在yml增加【dubbo.consumer.filter: logFilter】,其中logFilter是自定义的过滤器名称,这个需要在resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter中配置,默认项目中是没有这个文件的,需要按文件夹路径逐一手动创建,具体参考【Dubbo官网-调用拦截扩展】。

自定义LoadBalance完成特殊负载均衡

        在现实业务中默认负载均衡策略可能不能满足需求,我们可以自定义负载均衡策略。这里通过继承Dubbo默认的RandomLoadBalance来进行自定义拓展,实现了一个通过群组id获取指定服务器的策略,达到了同一个群的用户在同一台服务器的业务效果。当然这里只是一个功能演示,有许多未考虑的情况,具体需求还需根据场景使用其它手段实现。

关键代码

@Slf4j
public class GroupLoadBalance extends RandomLoadBalance {
    private static final Map<String, Integer> groupMapping = new HashMap<>();

    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
        log.info("进入自定义负载均衡,{}", url.getAbsolutePath());
        //获取调用方法名称
        String methodName = invocation.getMethodName();
        if(!"join".equals(methodName) || invocation.getArguments() == null
                || invocation.getArguments().length != 2){
            //直接采用默认策略
            log.info("不满足条件,直接采用默认策略");
            return super.select(invokers, url, invocation);
        }
        //获取群组参数
        String groupId = (String) invocation.getArguments()[1];
        Integer selected = groupMapping.get(groupId);
        if(selected != null){
            //查找已有的服务器
            for(Invoker<T> invoker : invokers){
                if(selected.equals(invoker.hashCode())){
                    log.info("查找到群组对应的服务器,直接返回");
                    return invoker;
                }
            }
        }
        //未找到已有的服务器则使用默认策略选择服务器
        log.info("当前群组没有对应服务器,使用默认策略选择服务器");
        Invoker<T> randomSelected = super.select(invokers, url, invocation);
        //保存群组对应的服务器
        groupMapping.put(groupId, randomSelected.hashCode());
        return randomSelected;
    }
}

配置

        自定义负载均衡不用再yml中增加配置,只需要在引用时使用名称指定特定负载均衡策略即可,如上文提到的@DubboReference(loadbalance = "groupLoadBalance")。同filter一样,也需要在resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance中配置名称和对应的Class地址,具体参考【Dubbo官网-负载均衡扩展】。

DubboAdmin的使用

        dubbo-admin是官方推出的一个后台管理软件,可以查看当前dubbo的运行情况并做动态配置调整。可以从官方仓库【apache/dubbo-admin】拉取代码部署,也可以直接使用官方准备好的docker运行,还可以下打好包的jar文件运行。这里使用官方Releases的0.5.0版本运行,下载地址【apache-dubbo-admin-0.5.0-bin-release.zip】。

        下载后打开bin/config/application.properties文件,将原本的zookeeper配置注释,打开下面的nacos注释并修改链接信息。如下图所示:

        然后使用 bin/startup.cmd脚本启动即可,停止则使用shutdown.cmd。

        最后打开浏览器输入http://localhost:8080/即可访问,默认账号root,密码root。

完整代码

printlin/dubbo-test

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

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

相关文章

RationalDMIS 2020 叶片检测 -快速定义叶片截面线方法

1.快速定义叶片截面线方法 用多平面切割叶片CAD定义曲线的方法,用来快速定义叶片截面曲线;自定义多个平面,使用这些平面切割CAD,生成多个叶片曲线(BladeCurve):再将生成的叶片曲线(BladeCurve)自动打断为两个子曲线(Curve);上述所有生成的曲线(Curve)都会添加到元…

[附源码]Python计算机毕业设计Django常见Web漏洞对应POC应用系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

使用 Rainbond 搭建本地开发环境

在开发之前&#xff0c;你需要在本地安装各种开发工具和服务&#xff0c;比如&#xff1a;Mysql、Redis、Nacos 等等&#xff0c;我们都知道在个人电脑上安装这些服务相当的繁琐&#xff0c;可能会遇到很多问题&#xff0c;环境问题、依赖问题等等。 在需要团队协作业务联调的…

第十三章《集合》第5节:Map集合

List、Set和Queue都是Collection接口的子接口,因此从更高层次来说它们属于统一类型的集合。Map接口也代表一种集合,但它不是Collection子接口,因此它属于另一种类型的集合。Map用于保存具有映射关系的数据。映射关系的数据分为两部分,就好比电话本一样,如图13-20所示。 图…

运筹说 第82期 | 算法介绍之图与网络分析(二)

本期我们继续进行运筹学之图与网络分析算法的讲解&#xff0c;我们将对图与网络分析的基础知识进行一个简单的回顾&#xff0c;并介绍求解最大流问题和最小费用最大流的MATLAB和Python相关代码&#xff0c;以帮助大家利用工具快速求解最大流问题和最小费用最大流问题&#xff0…

Spring的Bean意义

一、Spring概述 1. Spring家族 官网&#xff1a;https://spring.ioSpring发展到今天已经形成了一种开发的生态圈&#xff0c;Spring提供了若干个项目&#xff0c;每个项目用于完成特定的功能。 2. Spring体系结构 ⑴. Spring Framework系统架构图 Spring Framework是Spri…

四、【React-Router5】样式丢失问题

文章目录1、先上结论2、修改上一节代码3、发现问题4、分析原因5、3个解决办法1、先上结论 public/index.html 中 引入样式时不写 ./ 写 / [ 常用 ]public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% [ 常用 ]使用 HashRouter 2、修改上一节代码 点击访问 上节代码&…

[附源码]SSM计算机毕业设计学生档案管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【错误 :Segmentation fault 】以及gdb调试 core duumped文件

core dumped文件&#xff08;核心转储文件&#xff09; 当进程意外终止&#xff0c;系统可以将该进程的地址空间的内容急终止的一些其它信息转储到核心转储文件 它的触发条件&#xff0c;当系统收到以下信号时就会产生coredumped文件。 SIGABRT &#xff1a;异常终止(abort)时…

野火FPGA进阶(1):基于SPI协议的Flash驱动控制

文章目录第48讲&#xff1a;基于SPI协议的Flash驱动控制0. 理论部分1. Flash全擦除实验key_filterflash_be_ctrlspi_flash_betb_flash_be_ctrltb_spi_flash_be2. Flash扇区擦除实验key_filterflash_se_ctrlspi_flash_se3. 数据读操作key_filteruart_txflash_read_ctrlspi_flash…

专注于元宇宙实际应用方案的企业

元宇宙的话题持续火热。国内互联网大厂正在加大对元宇宙相关技术和应用的研发&#xff0c;元宇宙正在逐步成为创新创业的主战场。企业元宇宙在教育、会展、文创、旅游、博物馆、文化艺术、娱乐、社交、版权、零售等等领域发力&#xff0c;增加客户对企业的认同。 也许未来只需一…

接口测试学习第一天

1. 接口 接口的定义&#xff1a;是指系统或组件之间的交互点&#xff0c;通过这些交互点可以实现数据的交互。&#xff08;数据交互的通道&#xff09; 接口的分类&#xff1a;硬件接口和软件接口&#xff1b;我们这里只关注软件层面的接口&#xff1b; 1.1 接口的类型 接…

LeetCode-28-找出字符串中第一个匹配项的下标

1、KMP算法$$ 解决本问题最简单的方法就是暴力穷举&#xff0c;思路简单但时间复杂度为O(m∗n)O(m*n)O(m∗n)。此处我们仅考虑最优的KMP算法&#xff0c;时间复杂度为O(mn)O(mn)O(mn)。 KMP算法的优化之处在于当我们对比haystackhaystackhaystack和needleneedleneedle时&…

[附源码]计算机毕业设计springboot基于Java酒店管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

亚马逊商品销售数据爬虫分析报告

家电产业和消费者升级悄然地展开。 市场的这种变化使消费者对家用电器的期望不再仅仅是一个简单的功能满足&#xff0c;而是更多的细节体验和技术创新。 通过洞察家用电器的消费特点&#xff0c;有利于确定市场的未来趋势&#xff0c;从而积极应对市场变化。 ▼ 我们围绕亚马逊…

AI智能视频技术在考古工作中的安防应用

文物考古关系着民族文化的传承、历史的记录与保留&#xff0c;工作意义重大。考古发掘工地由于面积大、区域多且分散&#xff0c;以及周边环境复杂&#xff0c;因此安全防护工作开展困难&#xff0c;整体的安全形势不容乐观。 一、考古现场安保面临问题&#xff1a;1、考古遗址…

K - Scholomance Academy Gym - 103202K

题目链接 题意&#xff1a;很长&#xff0c;读了很长时间才懂&#xff1a; 就是给一个物品评分&#xff0c;假设分数大于等于x&#xff0c;就将其判断为正数&#xff0c;否则判断为负数 这样判断肯定会出现一些误判&#xff0c;那么我们将判为负数的正数成为假正数&#xff0…

C. Set or Decrease(二分 + 有两个不确定情况如何二分)

Problem - 1622C - Codeforces 给你一个整数数组a1,a2,...,an和整数k。 在一个步骤中&#xff0c;你可以 选择某个索引i并将ai减少1&#xff08;使aiai-1&#xff09;。 或者选择两个索引i和j&#xff0c;将ai等于aj&#xff08;使aiaj&#xff09;。 为了使数组∑i1nai≤k的…

启动服务提供者报 zookeeper not connected错

今天启动zookeeper的服务提供者后&#xff0c;报 zookeeper not connected错&#xff0c;记录一下解决过程 意思是zookeeper注册中心连接不上&#xff0c;无非两个原因&#xff1a; 第一&#xff1a;zookeeper没有启动好。第二&#xff1a;zookeeper的ip以及端口号配置没配好 …

算法day35|860,406,452

目录 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球 860.柠檬水找零 class Solution:def lemonadeChange(self, bills: List[int]) -> bool:five,ten,twenty 0,0,0for bill in bills:#情况一&#xff1a;如果bills是5元&#xff0c;不需要找零if bill…