Skip to content

基于 Java + Etcd + Vert.x 的高性能 RPC 框架

Notifications You must be signed in to change notification settings

yehuoyiji/Java-RPC

Repository files navigation

🌞项目介绍

  • 本项目参考 Dubbo 开源项目自主设计实现的 Java 高性能 RPC 框架。开发者只需引入 Spring Boot Starter,就能通过注解和配置的方式快速使用框架,实现像调用本地方法一样轻松调用远程服务。

  • 本项目有较多的实现亮点:基于 Vert.x TCP 服务器 + 自定义协议实现网络传输;基于 Etcd 实现注册中心以完成服务的注册消费;还支持通过 SPI 机制动态扩展序列化器、负载均衡器、重试和容错策略等。

👾项目所用技术

SpringBoot Badge Etcd Badge Vert.x Badge Hutool Badge ZooKeeper Badge SPI机制 Badge GuavaRetrying Badge

🏄 Rpc框架初始流程

  • 服务提供方通过注册中心进行服务注册后启动Vert.x服务器。

    • 创建Vert.x实例,并通过Vert.x实例创建HTTP服务器。

    • 指定请求处理器(HttpServerHandle())进行请求的处理

      • Vert.x的处理器首先会对接收到的HttpServerRequest请求进行反序列化并赋值给RPC框架封装的RpcRequest, 并对RpcRequest进行非空校验。

      • 之后通过注册中心.get(rpcRequest.getServiceName())来获取服务的实现类,通过服务实现类的getMethod方法与RpcRequest里的方法名与参数类型拿到Method类。

      • 调用Method的invoke(服务实现类对象,服务实现类参数)方法(即之前传入的方法名,参数类型,实现类的实例,参数列表)拿到返回结果(这里是通过反射的原理来实现)

      • 将拿到的返回结果,返回类型等赋值给RPC框架的封装的RpcResponse里。

      • 将响应对象的请求头内容设置为JSON格式,之后将RpcResponse进行序列化为字节数组后,HttpServerResponse将字节数组转化为Buffer对象后使用end方法将其返回给客户端(很多HTTP服务器框架和库都设计成了使用特定的数据结构(如Buffer)来处理响应数据)。

    • 启动HTTP服务器并监听指定端口

  • 服务消费方首先通过动态代理获取UserService的代理对象。

    •    public static <T> T getProxy(Class<T> serviceClass) {
                return (T) Proxy.newProxyInstance(
                        serviceClass.getClassLoader(),
                        new Class[]{serviceClass},
                        new ServiceProxy());
            }

      使用这个方法,传入serviceClass的类加载器(用于加载代理类), new Class[]{serviceClass}数组:表示代理类要实现的接口, new ServiceProxy()用于处理代理方法的调用。

    • User user = new User();
      user.setName("yehuo");
      User newUser = userService.getUser(user);
      if(newUser!= null) {
            System.out.println(newUser.getName());
      }else {
            System.out.println("user == null");
      }

      创建User对象,并通过代理对象userService调用getUser方法,并传递user对象,此时因为调用了代理类的方法 ===> 所以会执行ServiceProxy的invoke方法(用于处理代理方法的调用)

    • 在ServiceProxy的invoke方法中

      • 首先会将传入的服务类名,方法名,参数类型,参数列表构造出RpcRequest类。

      • 之后将RpcRequest序列化为字节数组,并通过Hutool包的HttpRequest.post方法,传入自己数组,拿到返回值(使用HttpResponse来接收), 并获取字节数组,再通过反序列化赋值给RpcResponse并返回响应数据。

      • User newUser = userService.getUser(user);

      即newUser对象。

About

基于 Java + Etcd + Vert.x 的高性能 RPC 框架

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages