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


    前言

            学习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服务提供方实现

    配置文件

    1. dubbo:
    2. application:
    3. name: dubbo-test-provider
    4. protocol:
    5. name: dubbo
    6. port: -1
    7. registry:
    8. address: nacos://192.168.0.129:8848
    9. username: nacos
    10. password: nacos
    11. config-center:
    12. address: nacos://192.168.0.129:8848
    13. username: nacos
    14. password: nacos
    15. group: dubbo
    16. metadata-report:
    17. address: nacos://192.168.0.129:8848
    18. username: nacos
    19. password: nacos
    20. group: dubbo

    关键代码

    1. //用户服务
    2. @DubboService
    3. public class UserServiceImpl implements IUserService {
    4. private static final Random random = new Random();
    5. @Override
    6. public User login(String username, String password) {
    7. if(!"123456".equals(password)){
    8. return null;
    9. }
    10. User user = new User();
    11. user.setId(random.nextInt(1000));
    12. user.setUsername(username + "_" + user.getId());
    13. user.setSex(user.getId()%2 == 0 ? "男" : "女");
    14. return user;
    15. }
    16. }
    17. //群组服务
    18. @DubboService
    19. @Component
    20. public class GroupServiceImpl implements IGroupService {
    21. @Value("${dubbo.application.name}")
    22. private String appName;
    23. @Override
    24. public String join(Integer userId, String groupId) {
    25. return userId+"_"+groupId+"_"+appName;
    26. }
    27. }

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

    Dubbo服务消费方实现

    配置文件

    1. server:
    2. port: 8888
    3. dubbo:
    4. application:
    5. name: dubbo-test-consumer
    6. protocol:
    7. name: dubbo
    8. port: -1
    9. registry:
    10. address: nacos://192.168.0.129:8848
    11. username: nacos
    12. password: nacos
    13. config-center:
    14. address: nacos://192.168.0.129:8848
    15. group: dubbo
    16. username: nacos
    17. password: nacos
    18. metadata-report:
    19. address: nacos://192.168.0.129:8848
    20. group: dubbo
    21. username: nacos
    22. password: nacos
    23. consumer:
    24. filter: logFilter

    关键代码

    1. @RestController
    2. public class UserController {
    3. @DubboReference
    4. private IUserService userService;
    5. @DubboReference(loadbalance = "groupLoadBalance")
    6. private IGroupService groupService;
    7. @GetMapping("/login")
    8. public User login(String username, String password){
    9. return userService.login(username, password);
    10. }
    11. @GetMapping("/join")
    12. public String join(Integer userId, String groupId){
    13. return groupService.join(userId, groupId);
    14. }
    15. }

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

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

    关键代码

    1. @Slf4j
    2. @Activate(group = CommonConstants.CONSUMER)
    3. public class LogFilter implements Filter {
    4. @Override
    5. public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
    6. log.info("开始调用,接口:{},参数:{}", invocation.getMethodName(), JSON.toJSONString(invocation.getArguments()));
    7. Result result = invoker.invoke(invocation);
    8. log.info("调用完成,结果:{}", JSON.toJSONString(result.getValue()));
    9. return result;
    10. }
    11. }

    配置 

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

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

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

    关键代码

    1. @Slf4j
    2. public class GroupLoadBalance extends RandomLoadBalance {
    3. private static final Map groupMapping = new HashMap<>();
    4. @Override
    5. public Invoker select(List> invokers, URL url, Invocation invocation) throws RpcException {
    6. log.info("进入自定义负载均衡,{}", url.getAbsolutePath());
    7. //获取调用方法名称
    8. String methodName = invocation.getMethodName();
    9. if(!"join".equals(methodName) || invocation.getArguments() == null
    10. || invocation.getArguments().length != 2){
    11. //直接采用默认策略
    12. log.info("不满足条件,直接采用默认策略");
    13. return super.select(invokers, url, invocation);
    14. }
    15. //获取群组参数
    16. String groupId = (String) invocation.getArguments()[1];
    17. Integer selected = groupMapping.get(groupId);
    18. if(selected != null){
    19. //查找已有的服务器
    20. for(Invoker invoker : invokers){
    21. if(selected.equals(invoker.hashCode())){
    22. log.info("查找到群组对应的服务器,直接返回");
    23. return invoker;
    24. }
    25. }
    26. }
    27. //未找到已有的服务器则使用默认策略选择服务器
    28. log.info("当前群组没有对应服务器,使用默认策略选择服务器");
    29. Invoker randomSelected = super.select(invokers, url, invocation);
    30. //保存群组对应的服务器
    31. groupMapping.put(groupId, randomSelected.hashCode());
    32. return randomSelected;
    33. }
    34. }

    配置

            自定义负载均衡不用再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

  • 相关阅读:
    数据挖掘与机器学习:Apripori算法
    以生命健康为中心的物联网旅居养老运营平台
    md编辑器常用语法模板
    ssm基于微信小程序的游泳馆管理系统+uinapp+java+计算机毕业设计
    300元开放式耳机推荐哪款好用一点、最便宜的开放式耳机
    PHP PDO
    转录组分析小故事丨什么是RNAseq?
    ⑲霍兰德ES*如何选专业?高考志愿填报选专业
    app毕业设计开题报告基于Uniapp+SSM实现的Android的网店系统实现的App购物商城电商
    Java中的正则表达式
  • 原文地址:https://blog.csdn.net/Print_lin/article/details/128102304