dubbo3.0-Rpc调用案例代码解析

​ 根据周瑜所讲的Dubbo3.0视频原理解析视频和内容,对源码的内容进行总结分析。视频源为【Dubbo3.0】地表最强!Dubbo快速入门教程,通俗易懂(3小时带你快速玩转)

依赖配置

​ 此处使用版本为dubbo官方推荐的3.2.0-beta.4版本,升级至此版本后需要兼容的springboot框架要求较高,而又因springboot版本升级后最低兼容JDK版本为17,所以需要更新JDK至17版本,并且IDEA版本需要提升至2022.3以上。但我相信聪明的你已经解决了这些问题了!

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.dubbo</groupId><artifactId>dubbo-producter</artifactId><version>0.0.1-SNAPSHOT</version><name>dubbo-producter</name><description>dubbo-producter</description><properties><java.version>17</java.version><dubbo.version>3.2.0-beta.4</dubbo.version></properties><dependencyManagement><dependencies><!--dubbo相关依赖通过pom引入,包括dubbo-spring-boot-starter--><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><dependencies><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></dependencies>
</project>

源码

​ 源码分为8个部分:程序入口http服务接收处理器本地接口注册(用于代替bean注入)请求处理器实体类服务注册负载均衡。以这种方式拆分,可以单独替换任何一部分。文末有各部分的调用关系时序图

1.程序入口

UserController

public class UserController {public static void main(String[] args) {UserService userService = ProxyFactory.getProxy(UserService.class);String testdubbo = userService.testdubbo();}
}

UserServiceImpl

public class UserServiceImpl implements UserService {@Overridepublic String testdubbo() {return new Random().nextDouble() + "";}@SneakyThrowspublic static void main(String[] args) {LocalRegister.regist(UserService.class.getSimpleName(), UserServiceImpl.class);RegisterUrl localhost = new RegisterUrl(InetAddress.getLocalHost().getHostName(), 8081);new DubboRegister().add(UserService.class.getSimpleName(),localhost);new HttpProvider().start(localhost.getHost(),localhost.getPort());}
}

2.http服务

HttpProvider

import com.dubbo.dubboproducter.web.DispatchServlet;
import lombok.SneakyThrows;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;public class HttpProvider {@SneakyThrowspublic void start(String host, Integer port){Tomcat tomcat = new Tomcat();Server server = tomcat.getServer();Service service = server.findService("Tomcat");Connector connector = new Connector();connector.setPort(port);StandardEngine standardEngine = new StandardEngine();standardEngine.setDefaultHost(host);StandardHost standardHost = new StandardHost();standardHost.setName(host);StandardContext standardContext = new StandardContext();standardContext.setPath("");standardContext.addLifecycleListener(new Tomcat.FixContextListener());standardHost.addChild(standardContext);standardEngine.addChild(standardHost);service.setContainer(standardEngine);service.addConnector(connector) ;tomcat.addServlet("","DispatchController", new DispatchServlet());standardContext.addServletMappingDecoded("/*","DispatchController");tomcat.start();tomcat.getServer().await();}
}

HttpConsumer

import com.dubbo.dubboproducter.utils.DubboObject;
import lombok.SneakyThrows;import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;public class HttpConsumer {@SneakyThrowspublic Object send(String host, Integer port, DubboObject dubboObject){URL http = new URL(URLEncoder.encode("http", StandardCharsets.UTF_8), URLEncoder.encode(host, StandardCharsets.UTF_8), port, "/");HttpURLConnection httpURLConnection = (HttpURLConnection) http.openConnection();httpURLConnection.setRequestMethod("POST");httpURLConnection.setDoOutput(true);ObjectOutputStream objectOutputStream = new ObjectOutputStream(httpURLConnection.getOutputStream());objectOutputStream.writeObject(dubboObject);objectOutputStream.flush();objectOutputStream.close();//        int responseCode = httpURLConnection.getResponseCode();
//        System.out.println("Status Code: "+responseCode);return new ObjectInputStream(httpURLConnection.getInputStream()).readObject();}
}

3.servlet请求接收处理

DispatchServlet

import com.dubbo.dubboproducter.reaction.DubboHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;public class DispatchServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {new DubboHandler().handler(req,resp);}
}

DubboHandler

import com.dubbo.dubboproducter.register.LocalRegister;
import com.dubbo.dubboproducter.utils.DubboObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;public class DubboHandler {@SneakyThrowspublic void handler(HttpServletRequest req, HttpServletResponse resp){//1.获取方法信息DubboObject dubboObject = (DubboObject) new ObjectInputStream(req.getInputStream()).readObject();//2.实例化对象并运行方法Class clazz = LocalRegister.get(dubboObject.getInterfaceName());//a.获取方法Method method = clazz.getMethod(dubboObject.getMethodName(), dubboObject.getParamsType());//b.实例化对象Object obj = clazz.getConstructor().newInstance();//c.运行方法Object invoke =  method.invoke(obj, dubboObject.getParams());new ObjectOutputStream(resp.getOutputStream()).writeObject(invoke);}
}

4.LocalRegister接口实现类的实现关系本地注册

import java.util.HashMap;public class LocalRegister {private static final HashMap<String,Class> map = new HashMap<>();public static void regist(String className, Class clazz){map.put(className,clazz);}public static void unregist(String className){map.remove(className);}public static Class get(String className){return map.get(className);}
}

5.proxy发送请求处理

ProxyFactory

import com.dubbo.dubboproducter.loadblance.RandomLoadBlance;
import com.dubbo.dubboproducter.reaction.HttpConsumer;
import com.dubbo.dubboproducter.register.DubboRegister;
import com.dubbo.dubboproducter.register.RegisterUrl;
import com.dubbo.dubboproducter.utils.DubboObject;import java.lang.reflect.Proxy;
import java.util.Set;public class ProxyFactory {@SuppressWarnings("unchecked")public static <T> T getProxy(Class interfaceClass){return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[]{interfaceClass},(o,m,arg) ->{DubboObject dubboObject = new DubboObject(interfaceClass.getSimpleName(), m.getName(),m.getParameterTypes(),arg);//获取注册中心的服务信息Set<RegisterUrl> registerUrls = new DubboRegister().get(interfaceClass.getSimpleName());//进行消费端负载均衡RegisterUrl registerUrl = RandomLoadBlance.blacne(registerUrls);return new HttpConsumer().send(registerUrl.getHost(), registerUrl.getPort(), dubboObject);});}}

6.DubboObject发送请求携带的实例对象

import lombok.AllArgsConstructor;
import lombok.Data;import java.io.Serializable;@Data
@AllArgsConstructor
public class DubboObject implements Serializable {private String interfaceName;private String methodName;private Class[] paramsType;private Object[] params;}

7.服务注册

DubboRegister

​ #- 远程服务注册

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.TypeReference;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;import java.io.*;
import java.util.*;public class DubboRegister {public Map<String, Set<RegisterUrl>> DUBBO_REGISTER = new HashMap<>();@SneakyThrowspublic void add(String interfaceName, RegisterUrl registerUrl){if (DUBBO_REGISTER.containsKey(interfaceName)){Set<RegisterUrl> registerUrls = DUBBO_REGISTER.get(interfaceName);registerUrls.add(registerUrl);}else {DUBBO_REGISTER.put(interfaceName,new HashSet<>(){{this.add(registerUrl);}});}JSONObject jsonObject = new JSONObject(DUBBO_REGISTER);File file = new File("./dubboTestregist.json");if (!file.exists()) file.createNewFile();FileWriter fileWriter = new FileWriter(file);fileWriter.write(jsonObject.toJSONString());fileWriter.close();}public Set<RegisterUrl> get(String interfaceName){DUBBO_REGISTER = getJson();Set<RegisterUrl> registerUrls = DUBBO_REGISTER.get(interfaceName);return registerUrls;}private Map<String, Set<RegisterUrl>> getJson(){try {FileReader fileReader = new FileReader("./dubboTestregist.json");String jsonString = IOUtils.toString(fileReader);return JSONObject.parseObject(jsonString,new TypeReference<Map<String, Set<RegisterUrl>>>(){{}});} catch (IOException e) {throw new RuntimeException(e);}}
}

RegisterUrl

import lombok.AllArgsConstructor;
import lombok.Data;import java.util.Objects;@AllArgsConstructor
@Data
public class RegisterUrl {private String host;private Integer port;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;RegisterUrl that = (RegisterUrl) o;return Objects.equals(host, that.host) && Objects.equals(port, that.port);}@Overridepublic int hashCode() {return Objects.hash(host, port);}
}

8.负载均衡

RandomLoadBlance

import com.dubbo.dubboproducter.register.RegisterUrl;import java.util.Optional;
import java.util.Set;public class RandomLoadBlance {public static RegisterUrl blacne(Set<RegisterUrl> registerUrls){Optional<RegisterUrl> any = registerUrls.stream().findAny();assert any.isPresent() : "1231231";return any.get();}
}

流程时序示意图

[JAVA-周瑜]dubbo-Rpc调用案例代码解析相关推荐

  1. java的时间变化_通过java记录数据持续变化时间代码解析

    这篇文章主要介绍了通过java记录数据持续变化时间代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.需求:获取count为null和不为n ...

  2. java中怎么实现指数幂,java中幂指数值的运算代码解析

    说到幂指数的运算我们就会用到Math.pow(doublea,doubleb),返回的结果是a的b次方. 在Java中,当我们计算2的n次方时,可以直接用Math.pow来计算.非常方便. 但是,已知 ...

  3. java怎么计算幂函数,java中幂指数值的运算代码解析

    说到幂指数的运算我们就会用到Math.pow(doublea,doubleb),返回的结果是a的b次方. 在Java中,当我们计算2的n次方时,可以直接用Math.pow来计算.非常方便. 但是,已知 ...

  4. 【Vue】Vue中传值的几种方法,案例代码解析

    目录 一.反向传值(子组件传值给父组件) 二.$refs 三.$parent 四.$children 五.$attrs/$listeners -----多层传值 六.$root ----根组件 七.依 ...

  5. 微信公众平台java开发详解(工程代码+解析)

    说明: 本次的教程主要是对微信公众平台开发者模式的讲解,网络上很多类似文章,但很多都让初学微信开发的人一头雾水,所以总结自己的微信开发经验,将微信开发的整个过程系统的列出,并对主要代码进行讲解分析,让 ...

  6. JAVA用JNI方法调用C代码实现HelloWorld

    一.首先是java运行环境的搭建,到官网下载java jdk安装即可(注意要修改环境变量).还可以顺便安装eclipse. 二.编写java代码,文件名HelloWorld.java public c ...

  7. java二进制命令_Java二进制指令代码解析

    常量入栈指令 操作码(助记符) 操作数 描述(栈指操作数栈) aconst_null null值入栈. iconst_m1 -1(int)值入栈. iconst_0 0(int)值入栈. iconst ...

  8. php 跳转qq群代码_一个简单QQ群聊案例代码解析(PHP实现)

    问题: 使用面向对象编程的方式实现以下业务逻辑: 1. 张三使用账号a,密码b登录了qq 2. 显示出张三最后的登录的时间 3. 张三查看了 1小时内的行政部门群的信息(这个群里有张三,李四,王五,其 ...

  9. 查询php copy函数源码,PHP copy函数使用案例代码解析

    copy-拷贝文件 说明 copy(string$source,string$dest[,resource$context]):bool 将文件从source拷贝到dest. 如果要移动文件的话,请使 ...

最新文章

  1. 视觉激光融合——VLOAM / LIMO算法解析
  2. ZooKeeper(一)linux上单机与集群的搭建
  3. el table 固定表头和首行_vue表格实现固定表头首列
  4. python functools模块方法
  5. Hasura GraphQL 内部表结构
  6. [python]一个遍历多层文件夹,然后替换文件内容和目录名称的案例
  7. ubuntu定时任务cron 访问网址php
  8. Eclipse下载与安装及汉化(详解版)
  9. 2020-10-04
  10. xp怎么看自己计算机密码,XP如何查看wifi密码?
  11. Web大学生网页作业成品——篮球网站设计与实现(HTML+CSS)
  12. Mac电脑下载软件的几个网站
  13. 3❤️Jenkins从零到壹❤️ :常用功能大全(JAVA 小虚竹)
  14. windows11截屏快捷键失效
  15. 17AHU排位赛3 D题 旋转吧!雪月花 ! (DFS序,线段树维护树上最值)
  16. 全景拍摄—焦距与对焦教程
  17. Druid连接池加密处理
  18. K8S集群扩容多master大概思路步骤
  19. 解构给默认值_函数的对象参数的解构和默认值
  20. 线上应用遇到了oom killer

热门文章

  1. Django 02 :部门管理 【面板设计(Bootstrap)+部门的增删改查(Django+MySQL)】
  2. 系统托盘不显示声音图标
  3. CloudSim仿真流程
  4. AngularJS 如何进行字符串换行 HTML 换行的互换
  5. x86系统和linux系统,ARM与X86的比较
  6. Java获取当天的起始和结束时间
  7. 找不到与以下参数匹配的产品_熟悉以下这8种套路,民间借贷案件打官司的时候不怕找不到好律师...
  8. python提取Excel多个sheet中固定单元格数据
  9. vista xp 双系统问题!(先装vista后装xp或者先装xp后装vista)
  10. CPAT:转录本蛋白编码能力预测软件