Netty RPC Demo 实现

本文通过一个RPC框架Demo,介绍了如何使用Netty实现RPC。主要包括:接口定义、客户端调用过程、服务端处理逻辑。客户端通过代理类调用接口,Netty处理请求和响应。服务端专注于业务代码,RPC框架负责请求路由和结果返回。
摘要由CSDN通过智能技术生成

Netty RPC Demo 实现


简介

    一个 RPC 框架 Demo 的简单实现(业务场景中还没用过RPC,但Dome应该还是有那个意思的)

    完整的项目工程地址:RPC-Demo

工程运行说明

  • 服务端启动:rpcfx-demo-server:ServerApplication
  • 客户端启动:rpcfx-demo-client:ClientApplication

工程结构说明

RPC-DEMO
├─rpcfx-core: 框架核心部分,client、server的代理
|
├─rpcfx-demo-api: 接口定义部分,类似于web后端给前端写的接口文档
|
├─rpcfx-demo-client: 客户端,调用接口发送请求
|
└─rpcfx-demo-server: 服务端,接收请求,进行CURD之类的

关于 RPC 的一些思考

    秦老师说过一句话,可以道破其本质:RPC 就是为了 OOP。下面以HTTP的相似场景举例:

在这里插入图片描述

    上面是一个比较简略的使用postman或者浏览器访问的数据流程,因为HTTP协议本质传输的也是一个问题。在自己接触的写前端请求后端接口,传输的基本是字符串

    下面是 RPC 的:

    RPC表示不想这么玩,咱后端就要有后端的样子,要像平时使用类,调用方法那样才用的爽。

    类比平时Web的开发,客户端就像Vue前端,服务端就是使用Spring boot web写的那些业务CURD服务,RPC框架就是Spring Boot Web框架

    RPC框架想达到的目的有如下几个:

  • 1.客户端:封装屏蔽从客户端发送请求到服务端,并将结果序列号成对象的过程,让客户端感觉像在本地调用类方法一样
  • 2.服务端:封装屏蔽服务端根据请求路由到基本的处理类和函数的查找,让服务端只专心写好CRUD即可

代码实现

    根据上面的描述,客户端只需要调用接口获取结果进行处理,服务端只需要实现好接口CRUD就行了,其它的全由 RPC 框架帮你搞定

    代码编写的大致流程如下:

  • 1.定义接口:类似于后端给前端编写的 API 文档
  • 2.客户端调用:客户端调用接口,获取结果,并反序列化成对象
  • 3.服务端接收处理:服务端接收到请求,匹配相应的实现类,调用相应的方法,得到结果返回返回

1.定义接口:类似于后端给前端编写的 API 文档

    类似于接口文档,描述了能提供哪些功能、能返回什么、需要传什么参数。即本工程的 API 模块

public interface UserService {
   

    /**
     * find by id
     * @param id id
     * @return user
     */
    User findById(Integer id);
}

2.客户端调用:客户端调用接口,获取结果,并反序列成对象

    客户端只需要简单的使用RPC生成的代理,进行调用即可

2.1 客户端业务代码
public class ClientApplication {
   

    public static void main(String[] args) {
   
        RpcClient jdk = new RpcClientJdk();
        UserService userService = jdk.create(UserService.class, "http://localhost:8080/");
        User user = userService.findById(1);
        if (user == null) {
   
            log.info("Clint service invoke Error");
            return;
        }
        System.out.println("find user id=1 from server: " + user.getName());
    }
}
2.2 RPC 框架客户端:代理类生成、netty请求发送和响应处理

    下面的发送请求和读取结果序列号返回都是 RPC 框架的事情了,大致代码如下:

    生成代理类:

public class RpcClientJdk extends RpcProxy implements RpcClient {
   

    @Override
    public <T> T create(Class<T> serviceClass, String url) {
   
        // 查询是否之前生成过,存储的直接返回
        if (!isExit(serviceClass.getName())) {
   
            add(serviceClass.getName(), newProxy(serviceClass, url));
        }
        return (T) getProxy(serviceClass.getName());
    }

    private <T> T newProxy(Class<T> serviceClass, String url) {
   
        ClassLoader loader = RpcClientJdk.class.getClassLoader();
        Class[] classes = new Class[]{
   serviceClass};
        return (T) Proxy.newProxyInstance(loader, classes, new RpcInvocationHandler(serviceClass, url));
    }
}

    请求发送与返回处理具体实现

/**
 * 用于jdk、cglib、buddy
 *
 * @author lw1243925457
 */
@Slf4j
public class RpcInvocationHandler implements InvocationHandler, MethodInterceptor {
   

    private final Class<?> serviceClass;
    private final String url;

    <T> RpcInvocationHandler(Class<T> serviceClass, String url) {
   
        this.serviceClass = serviceClass;
        this.url = url;
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
   
        return process(serviceClass, method, args, url);
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) {
   
        return process(serviceClass, method, args, url);
    }

    /**
     * 发送请求到服务端
     * 获取结果后序列号成对象,返回
     * @param service service name
     * @param method service method
     * @param params method params
     * @param url server host
     * @return object
     */
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值