最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

[JAVA

运维笔记admin61浏览0评论

[JAVA

[JAVA

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=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .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();}
}

流程时序示意图

发布评论

评论列表(0)

  1. 暂无评论