首页 > 其他分享 >SpringCloud微服务集成Dubbo

SpringCloud微服务集成Dubbo

时间:2024-03-28 11:48:36浏览次数:20  
标签:集成 dubbo Dubbo admin SpringCloud nacos blog address

1、Dubbo介绍

Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。
Dubbo官网:https://cn.dubbo.apache.org/zh-cn/
Dubbo文档:https://cn.dubbo.apache.org/zh-cn/overview/quickstart/
Dubbo GitHub地址:https://github.com/apache/dubbo
Dubbo 使用版本对应关系:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明#2021x-分支 选择和项目相互对应的版本进行使用。这里我使用的是Dubbo 2.7.8

2、Dubbo连接注册中心

Dubbo推荐使用Zookeeper作为注册中心,Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境。除此之外Dubbo还可以使用阿里巴巴的nacos做注册中心。Nacos作为注册中心Dubbo使用与ZooKeeper基本相同,在使用上,不同的地方只有以下两点:

  • 1、导入的依赖,配置不同;
  • 2、注解不同,ZooKeeper使用@Service、@Reference注解,Nacos使用@DubboService、@DubboReference注解;

3、Dubbo负载均衡

  • RandomLoadBalance:加权随机,默认算法,默认权重相同;
  • RoundRobinLoadBalance:加权轮询,默认权重相同;
  • LeastActiveLoadBalance:最少活跃优先+加权随机,能者多劳;
  • ConsistentHashLoadBalance:一致性Hash,确定入参,确定提供者,适用于有状态的请求;

4、Dubbo Admin下载与使用

官网地址:https://github.com/apache/dubbo-admin
Dubbo和Dubbo Admin版本说明:https://cn.dubbo.apache.org/zh-cn/blog/2019/01/07/新版-dubbo-admin-介绍/

4.1、修改配置文件

进入dubbo-admin-server的resources目录,修改application.properties文件修改配置中心。默认为zookeeper:

admin.registry.address注册中心 
admin.config-center 配置中心 
admin.metadata-report.address元数据中心

由于我使用nacos,修改注册中心为nacos。 nacos注册中心有 GROUP 和 namespace:

admin.registry.address=nacos://127.0.0.1:8848?group=DEFAULT_GROUP&namespace=public&username=nacos&password=nacos
admin.config-center=nacos://127.0.0.1:8848?group=dubbo&username=nacos&password=nacos
admin.metadata-report.address=nacos://127.0.0.1:8848?group=dubbo&username=nacos&password=nacos
//改为自己的注册中心:
admin.registry.address=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
admin.config-center=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
admin.metadata-report.address=nacos://localhost:8848?group=DEFAULT_GROUP&namespace=23857f22-27ac-4947-988a-1b88d4eeb807&username=nacos&password=nacos
4.2、Dubbo Admin项目打包

在项目根目录进行打包,跳过测试:

mvn clean package -Dmaven.test.skip=true

进入dubbo-admin-0.6.0/dubbo-admin-distribution/target 进行启动后端:

java -jar dubbo-admin-0.6.0.jar

dubbo-admin-ui 目录下执行命令启动前端:

npm run dev

这是官方项目开发环境说明,打开项目就能看到:

4.3 访问dubbo admin

浏览器输入地址进行访问,之前的dubbo-admin老版本用的是Tomcat启动的,后端端口是8080(可能会冲突),前端端口是8081

http://localhost:8081

新版的dubbo-admin用的是Netty,默认配置端口是38080,前端端口38082

http://localhost:38082 或 http://localhost:38080

用户名密码都是root
登录成功:

5、SpringCloud集成Dubbo

在SpringBoot模块中引入maven依赖:

<!-- Dubbo Spring Cloud Starter -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

这里使用用户模块和订单模块模拟微服务使用Dubbo RPC的调用。在提供者模块中加入Dubbo依赖,在配置文件中设置dubbo连接注册中心和配置中心:

dubbo:
  application:
    name: user-service-model-provider
  protocol:
    name: dubbo
    port: -1
  provider:
    group: DEFAULT_GROUP
    version: 2.0
  #port: 20881
  registry:
    address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
    #配置nacos自定义命名空间
    parameters:
      namespace: 23857f22-27ac-4947-988a-1b88d4eeb807
    group: DEFAULT_GROUP
#  registry:
#    address: zookeeper://${zookeeper.address:127.0.0.1}:2181
  metadata-report:
    address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
    #配置nacos自定义命名空间
    parameters:
      namespace: 23857f22-27ac-4947-988a-1b88d4eeb807

配置添加成功后,在业务模块service层,新建一个对外提供的dubbo实现类UserExternalServiceImpl,需要使用@DubboService注解,@Service注解尽量不要使用,可以使用@Componet代替。代码如下:

//@Service
@Component
@DubboService(timeout = 1000 * 10,group = "userGroup",version = "2.0")
public class UserExternalServiceImpl implements IUserExternalService {

    @Autowired
    private IUserService userService;


    @Override
    public Response selectUserAll() {
//        try {
//            TimeUnit.MILLISECONDS.sleep(1000*5);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return Response.success(userService.selectUserAll());
    }

    @Override
    public Response insert(UserExternal userExternal) {
//        boolean flag = true;
//        if (flag == true){
//            throw new ParamException(500,"用户模块出现错误,需要回滚");
//        }
//        try {
//            TimeUnit.MILLISECONDS.sleep(20000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        User user=new User();
        BeanUtils.copyProperties(userExternal,user);
        boolean save = userService.save(user);
        if (save){
            return Response.success();
        }else {
            return Response.fail();
        }
    }
}

然后还需要在新建一个专门存dubbo的对外接口服务模块用interface-module名称,在该模块中新建一个IUserExternalService接口,该接口实现在用户模块中的UserExternalServiceImpl实现类:

public interface IUserExternalService {

    Response<List<UserExternal>> selectUserAll();

    Response insert(UserExternal user);
}

现在我们的接口提供方已经编写完成了,接下来开始编写接口使用方也就是消费者。在订单模块中引入dubbo依赖,在配置文件中将dubbo连接注册中心和配置中心:

dubbo:
  application:
    name: order-service-model-consumer
  consumer:
    group: DEFAULT_GROUP
    version: 2.0
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
    #配置nacos自定义命名空间
    parameters:
      namespace: 23857f22-27ac-4947-988a-1b88d4eeb807
#  registry:
#    address: zookeeper://${zookeeper.address:127.0.0.1}:2181
  cloud:
    subscribed-services: user-service-model-provider
  metadata-report:
    address: nacos://${nacos.address:127.0.0.1}:8848?username=nacos&password=nacos
    #配置nacos自定义命名空间
    parameters:
      namespace: 23857f22-27ac-4947-988a-1b88d4eeb807

下面我们需要引入刚刚新建存dubbo接口模块的依赖包,然后就可以使用该接口了。首先建一个IDubboUserService的接口实现DubboUserServiceImpl类,意思是这个类是专门存放通过dubbo接口调用用户模块的业务类,后续在订单模块中处理用户模块信息都可以在该业务类中进行处理。
IDubboUserService类代码:

public interface IDubboUserService {

    List<UserExternal> selectUserAll();

}

DubboUserServiceImpl业务类代码,需要在该类中使用@DubboReference(group = "userGroup",version = "2.0")注解注入IUserExternalService接口信息,通过Dubbo RPC实现远程调用,注意group 和version 需要和提供方相互对应,不然会注入失败:

@Service
@Slf4j
public class DubboUserServiceImpl implements IDubboUserService {

    @DubboReference(group = "userGroup",version = "2.0")
    private IUserExternalService userExternalService;

    @Override
    public List<UserExternal> selectUserAll() {
        //添加blog
        Blog blog = new Blog();
        blog.setUid(UUID.randomUUID().toString());
        blog.setTitle("dubbo测试Test");
        blog.setContent("啊");
        blog.setSummary("12");
        blog.setTagUid("3c16b9093e9b1bfddbdfcb599b23d835");
        blogService.insert(blog);
        //处理相关逻辑
        Response<List<UserExternal>> response = userExternalService.selectUserAll();
        UserExternal user = new UserExternal();
        user.setUserName("dubbo测试Test");
        user.setAccount("system");
        user.setEmail("[email protected]");
        Response insert = userExternalService.insert(user);
        System.out.println(insert);
        return response.getModel();
    }
}

通过上面的代码,就可以实现服务模块与模块之间的远程调用了。使用Dubbo在订单模块调用用户模块就和调用其他业务类代码一样通过依赖注入就可以了,是不是非常方便。

5、dubbo使用Sentinel进行限流和异常兜底

需要引入Maven依赖:

        <!-- 在dubbo中使用 Sentinel 需要添加下面依赖 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-apache-dubbo-adapter</artifactId>
        </dependency>

由于限流和兜底是消费方要处理的事情,所以我们只需要在订单模块中引入上面依赖即可。在DubboUserServiceImpl中,通过@SentinelResource注解处理,代码如下:

@Service
@Slf4j
public class DubboUserServiceImpl implements IDubboUserService {

    @DubboReference(group = "userGroup",version = "2.0")
    private IUserExternalService userExternalService;

    @Autowired
    private IBlogService blogService;

//    @PostConstruct
//    private void initFlowRules(){
//        System.out.println("Sentinel initFlowRules start===");
//        List<FlowRule> rules = new ArrayList<>();
//        FlowRule rule = new FlowRule();
//        rule.setResource(IDubboUserService.class.getName());
//        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//        // Set limit QPS to 20.
//        rule.setCount(20);
//        rules.add(rule);
//        FlowRuleManager.loadRules(rules);
//        System.out.println("Sentinel initFlowRules end====");
//    }


    @Override
    @SentinelResource(value = "com.itmy.user.service.IUserExternalService:selectUserAll()", //当前方法的路径
            blockHandler = "selectUserAll",
            blockHandlerClass = CustomerBlockHandler.class, //触发限流 走该类的blockHandler = "selectUserAll"方法
            fallback = "selectUserAllFallback",
            fallbackClass = UserFallback.class, //dubbo调用接口异常,走该类的  fallback = "selectUserAllFallback"方法
            exceptionsToIgnore = {IllegalArgumentException.class})
    //fallback 负责业务异常 blockHandler限流方法 exceptionsToIgnore 报该异常fallback不处理
    @GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 30000,name = "order_tx_group")  //seata事务注解,目前没有使用后面会在seata博客中介绍。
    public List<UserExternal> selectUserAll() {
        //添加blog
        Blog blog = new Blog();
        blog.setUid(UUID.randomUUID().toString());
        blog.setTitle("dubbo事务测试Test");
        blog.setContent("dubbo事务测试Test啊的服务器打");
        blog.setSummary("12");
        blog.setTagUid("3c16b9093e9b1bfddbdfcb599b23d835");
        blogService.insert(blog);
        //处理相关逻辑
        Response<List<UserExternal>> response = userExternalService.selectUserAll();
//        boolean flag = true;
//        if (flag == true){
//            throw new ParamException(500,"用户模块出现错误,需要回滚");
//        }
        UserExternal user = new UserExternal();
        user.setUserName("dubbo事务");
        user.setAccount("system");
        user.setEmail("[email protected]");
        Response insert = userExternalService.insert(user);
        System.out.println(insert);
        return response.getModel();
    }
}

CustomerBlockHandler处理限流的相关代码:

@Slf4j
public class CustomerBlockHandler {

    /**
     * 查询用户热点限流测试
     * @param name
     * @param email
     * @param exception
     * @return
     */
    public static Response selectUserBlockException(@RequestParam(value = "name",required = false) String name,
                                                    @RequestParam(value = "email",required = false) String email,
                                                    BlockException exception){
        log.error("CustomerBlockHandler|selectUserBlockException is fail");
        return Response.fail(FallbackErrorEnum.USER_MODULE_FALL);
    }

    /**
     * 查询限流
     * @return
     */
    public static Response redisFindBlockException(BlockException exception){
        log.error("添加订单 redis|添加用户 redis信息,调用接口被限流。。。。。");
        return Response.fail(FallbackErrorEnum.REDIS_FIND_FALL);
    }


    public List<UserExternal> selectUserAll(BlockException exception){
        log.error("添加订单|添加用户信息,触发限流控制。。。。。");
        throw new ParamException(600,"添加用户信息异常:"+exception.getMessage());
    }

}

UserFallback异常处理:

@Slf4j
public class UserFallback {

    public static List<UserExternal> selectUserAllFallback(Throwable throwable) {
        log.error("添加订单|添加用户信息异常,触发熔断兜底操作。");
        throw new ParamException(600,"添加用户信息异常,触发兜底操作");
    }
}

6、总结

SpringCloud集成Dubbo到目前为止就介绍完毕了,希望本博客对你有所帮助。目前只介绍了如何使用dubbo,dubbo还有需多需要去学习的地方,让我们持续学习新的知识,来应对工作中的各种问题。

标签:集成,dubbo,Dubbo,admin,SpringCloud,nacos,blog,address
From: https://www.cnblogs.com/sowler/p/18099925

相关文章

  • springboot 集成elasticsearch Ik分词
    前提是我们elasticsearch服务已经集成了IK分词,具体集成下载对应的elasticsearchIK分词插件,在es插件包下创建IK文件夹,将下载好的IK包上传上去解压后重启es1、pom引入co.elastic.clientselasticsearch-java7.16.2jakarta.jsonjakarta.json-api2.0.1org.springframew......
  • TAPD与钉钉对接集成返回符合查询条件的所有需求打通钉钉机器人推送
    TAPD与钉钉对接集成返回符合查询条件的所有需求打通钉钉机器人推送数据源系统:TAPDTAPD全名为腾讯敏捷产品研发平台,已在腾讯内部运营12年,并于2017年5月正式对外开放。TAPD在腾讯内部服务着QQ、微信、王者荣耀等上万个产品,在外部则为美团点评、同程艺龙、欧派、TCL、新东方在......
  • 「DevExpress中文教程」如何将DevExtreme JS HTML编辑器集成到WinForms应用
    在本文中我们将演示一个混合实现:如何将webUI工具集成到WinForms桌面应用程序中。具体来说,我们将把DevExtremeJavaScriptWYSIWYGHTML编辑器(作为DevExtreme UI组件套件的一部分发布的组件)集成到WindowsForms应用程序中。获取DevExtremev23.2正式版下载DevExpress技术交......
  • Profinet转ModbusTCP:从站设备转换与集成案例
    本案例旨在探讨如何将ModbusTCP设备数据成功地接入到西门子PROFINET网络中。为了实现这一目标,我们将使用西门子S7-1200型PLC以及Profinet转ModbusTCP网关作为关键设备。为了模拟Modbus从站,我们将使用电脑安装modbuspoll软件。首先需要了解Profinet和ModbusTCP这两种协议的基本概......
  • RestCloud数据集成平台-监听SqlServer数据库表,并同步数据到MongoDB数据库表详细教程(实
    上一篇:RestCloud数据集成平台-Windows全量包安装部署详细教程1.数据源管理数据源主要用来建立与用户的数据库的链接。数据源管理主要用来对用户添加的所有数据链接进行管理,主要包括新建数据源、测试链接、修改链接、复制链接、查询链接和删除链接等功能。1.1.创建链接......
  • 无人车+工厂车间集成无缝,这款网关产品了解一下
    ​诸位朋友们,大家好!今天给大家介绍一款引领工业无人化发展的黑科技——星创易联科技的SV900-5G车载网关。相信大家对无人驾驶技术都很感兴趣,它代表着未来出行和生产的全新方式。而要实现真正的"无人化",离不开无人车网关这个智能大脑的作用。SV900就是一款专为工业场景打造......
  • 【实战教程】Spring Boot项目集成华为openGauss数据库的关键步骤与注意事项
    引言:随着国产数据库技术的崛起,华为openGauss凭借其高性能、安全可靠及易用性成为了众多开发者的首选方案。本篇技术文章将聚焦于如何在SpringBoot项目中成功集成华为openGauss数据库,并揭示其中的一些关键步骤与注意事项,助您轻松驾驭这一强大的数据库引擎。正文:一、环境准备......
  • FUSB302BMPX 可编程USB芯片控制器 接口集成电路 302B Type-C Control IC with PD
    FUSB302BMPX是一种可编程的USBType-C控制器,由安森美半导体公司生产。它支撑USBType-C检测,包含衔接和方向,并集成了USBBMC功率输送协议的物理层,可完成高达100W的电源和角色交换。该控制器适用于希望完成DRP/SRC/SNKUSBType-C衔接器的系统规划人员。此外,FUSB302BMPX支撑USB3......
  • 云原生最佳实践系列 3:基于 SpringCloud 应用玩转 MSE
    概述随着业务不断创新,大型的单个应用和服务会被拆分为数个甚至数十个微服务,微服务架构已经被广泛应用。微服务的好处在于快速迭代,迭代过程保障线上流量不受损。依赖开源产品缺少专业运维工具,常常需要投入较大的运维人力和成本。本实践基于云原生应用产品提供微服务注册配置中心......
  • Dapr云原生应用开发系列7:工作流集成
    题记:这篇介绍一个很有意思的东西,Dapr和LogicApps这样的工作流引擎集成。 Dapr工作流 在1年多前,Dapr的孵化团队搞了一个很有意思的东西:把Dapr和LogicApps集成起来,实现Dapr内置的工作流引擎。 官方文档:https://docs.dapr.io/developing-applications/integrations/azure......