简易版 RPC 框架实现 1.0 -http实现

RPC 是“远程过程调用(Remote Procedure Call)”的缩写形式,比较通俗的解释是:像本地方法调用一样调用远程的服务。虽然 RPC 的定义非常简单,但是相对完整的、通用的 RPC 框架涉及很多方面的内容,例如注册发现、服务治理、负载均衡、集群容错、RPC 协议等,如下图所示:

在这里插入图片描述
简易 RPC 框架的架构图

本课时我们主要实现RPC 框架的基石部分——远程调用,简易版 RPC 框架一次远程调用的核心流程是这样的:

  1. Client 首先会调用本地的代理,也就是图中的 Proxy。
  2. Client 端 Proxy 会按照协议(Protocol),将调用中传入的数据序列化成字节流。
  3. 之后 Client 会通过网络,将字节数据发送到 Server 端。
  4. Server 端接收到字节数据之后,会按照协议进行反序列化,得到相应的请求信息。
  5. Server 端 Proxy 会根据序列化后的请求信息,调用相应的业务逻辑。
  6. Server 端业务逻辑的返回值,也会按照上述逻辑返回给 Client 端。

这个远程调用的过程,就是我们简易版本 RPC 框架的核心实现,只有理解了这个流程,才能进行后续的开发。

在这里插入图片描述
这个版本写的非常简单实用http协议模拟的rpc实现

  • provider 是服务提供方
  • consumer 是服务调用方
    其实这两个都不算rpc框架内容,是使用者真正的业务代码
  • common 把rpc相关的都放入这一个模块中了

代码比较简单我们就直接从下面两个方便进行分析了

服务提供方

public class Provider {

    public static void main(String[] args) {
        Url url = new Url("localhost", 8099);
        //模拟远程注册中心
        RemoteMapRegister.regist(HelloService.class.getName(),url);
        //指明服务的实现类
        LocalRegister.regist(HelloService.class.getName(), HelloServviceImpl.class);
        //获取协议
        Protocal protocol = ProtoaclFactory.getProtocol();
        //启动 start
        protocol.start(url);
    }
}

URL 统一配置

比较简单不做赘述

远程注册中心

我们这个使用的内存+本地文件存储

public static void regist(String interfaceName, Url url){
//        REGISTER.putIfAbsent(interfaceName, new ArrayList<>());
        List<Url> urls = REGISTER.get(interfaceName);
        if(urls == null){
            List<Url> objects = new ArrayList<>();
            objects.add(url);
            REGISTER.put(interfaceName, objects);
        }else {
            urls.add(url);
        }
        saveFile();
    }

服务的实现类

实现类方便服务调用方进行调用

public class LocalRegister {

    private static Map<String, Class> map = new HashMap<>();
    public static void regist(String interfaceName, Class implClass){
        map.put(interfaceName,implClass);
    }

    public static Class get(String interfaceName){
        return map.get(interfaceName);
    }
}

代码中可以看出来非常简单,放到内存map中了

获取协议

其实说白了根据参数获取相关的协议实现

public static Protocal getProtocol(){
        String name = System.getProperty("protocalName");
        if(name == null || name.equals("")) name = "http";
        switch (name){
            case "http":
                return new HttpProtoacl();
            case "dubbo":
                return new DubboProtocal();
            default:
                break;
        }
        return new HttpProtoacl();
    }

根据不同的协议我们开启不同的服务,供服务调用方进行调用

开启服务

//启动 start
protocol.start(url);
根据不同的协议进行开启服务

 @Override
    public void start(Url url) {
        HttpServer httpServer = new HttpServer();
        httpServer.start(url.getHostName(),url.getPort());
    }

我这用的http服务,底层开启了一个tomcat服务

服务调用方

public static void main(String[] args) {
        HelloService proxy = ProxyFactory.getProxy(HelloService.class);
        System.out.println(proxy.say("hellow"));
    }

服务调用方 生成代理

服务调用方拿不到提供方的实例因此只能通过代理的方式进行访问

 public static <T> T getProxy(final Class interfaceClass){
       return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Invocation invocation = new Invocation(interfaceClass.getName(), method.getName(), method.getParameterTypes(), args);
                List<Url> urlList=RemoteMapRegister.get(interfaceClass.getName());
                Url url = SimpleLoadBalance.random(urlList);
                Protocal protocol = ProtoaclFactory.getProtocol();
                String result= protocol.send(url,invocation);
                return result;
            }
        });
    }

代理中做的事情

  1. 根据远程的注册中心获取URL,即配置信息
  2. 提供方可能存在多个实例, 因此是用负载均衡进行流量负载
  3. 根据协议,发送请求,这个地方我们发送请求没做任何逻辑,实际rpc这个地方会存在很多逻辑
  4. 获取到响应数据返回给调用方

总结

其实这个在一定意义上算不上rpc 框架, 只能说是帮我们简单的理解rpc工作的流程,比只看概念具体一点,方便理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/463830.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

离散时间傅里叶变换和离散傅里叶变换

离散时间傅里叶变换和离散傅里叶变换 { X ( k ) DFT [ x ( n ) ] ∑ n 0 N − 1 x ( n ) W N n k k 0 , 1 , . . . , N − 1 x ( n ) IDFT [ X ( k ) ] 1 N ∑ n 0 N − 1 x ( n ) W N − n k n 0 , 1 , . . . , N − 1 \begin{cases} X(k)\textbf{DFT}[x(n)]\sum\limi…

解决:IDEA编译Java程序时报编译失败

1、问题展示&#xff1a; 2、解决方法&#xff1a;

Magical Combat VFX

这个包包含30个可供游戏使用的VFX,有各种口味,为您的游戏增添趣味! 所有VFX都经过了很好的优化,可以在所有平台上使用。 这个包特别有一堆闪电魔法,有两种主要的变体,一种是深色的,另一种是浅色的。但它也提供了一系列其他视觉效果,如神圣咒语、音乐主题等等! 我们提供…

【CSP】2021-09-2 非零段划分 索引+递推/差分+前缀和

2021-09-2 非零段划分 索引递推/差分前缀和 2021-09-2 非零段划分 索引递推/差分前缀和索引递推思路差分前缀和思路遇到的问题索引递推完整代码差分前缀和完整代码 2021-09-2 非零段划分 索引递推/差分前缀和 一开始写的时候没有发现直接从a数组求q的规律&#xff0c;怎么也想…

NCV8705MTADJTCG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述&#xff1a; NCV8705 是一款低噪音、低功耗和低泄漏线性电压稳压器。该器件具有卓越的噪音和 PSRR 规格&#xff0c;适用于使用视频接收器、成像传感器、音频处理器或需要外部洁净电源的任何部件的产品。NCV8705 使用创新的自适应接地电流电路 可确保轻负载调节下的超…

基于DFA敏感词查询的算法简析

基于DFA敏感词查询的算法简析 1.背景 项目中需要对敏感词做一个过滤&#xff0c;首先有几个方案可以选择&#xff1a; a.直接将敏感词组织成String后&#xff0c;利用indexOf方法来查询。 b.传统的敏感词入库后SQL查询。 c.利用Lucene建立分词索引来查询。 d.利用DFA算法…

3.python安装Selenium框架

1. 命令安装 pip install selenium下载慢,可以换源: pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/查看是否换源成功 pip config get global.index-url安装好后,查看版本信息: pip show selenium2.下载对应的浏览器驱动 https://registry.npmm…

【Elasticsearch】windows安装elasticsearch教程及遇到的坑

一、安装参考 1、安装参考&#xff1a;ES的安装使用(windows版) elasticsearch的下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch ik分词器的下载地址&#xff1a;https://github.com/medcl/elasticsearch-analysis-ik/releases kibana可视化工具下载…

Vue2 引入使用ElementUI详解

目录 1 安装2 引入2.1 全局引入2.1.1 引入2.1.2 使用 2.2 按需引入2.2.1 引入2.2.2 使用 3 总结 1 安装 推荐使用 npm 的方式安装&#xff0c;它能更好地和 webpack打包工具配合使用。&#xff08;本项目使用安装方式&#xff09; npm i element-ui -S也可以使用其他的包管理…

Notepad++从文件夹查找文本内容

目录 一、背景二、Notepad搜索2.1 测试用例2.2 操作说明 一、背景 在日常的办公、学习或编程中&#xff0c;我们时长会遇到需要在大量文件中搜索特定文本内容的情况&#xff1a; 无论是快速定位某个项目中的代码片段&#xff1b;还是检索文档资料库中的相关信息等。 掌握如何…

蓝桥杯:模拟、枚举

目录 引言一、修剪灌木二、特殊年份三、刷题统计 引言 本篇文章主要介绍蓝桥杯的模拟和枚举的题目&#xff0c;这种题在 B B B 组还是比较简单的&#xff0c;后续也会一直往里加新的真题&#xff0c;加油&#xff01; 一、修剪灌木 标签&#xff1a;第十三届蓝桥杯省赛C B组…

音乐创作利器FL Studio21水果软件助你轻松实现音乐创意

音乐创作利器——FL Studio21水果软件&#xff0c;让你的音乐梦想起航&#xff01; 副标题&#xff1a;一款强大的电脑数码编曲软件&#xff0c;助你轻松实现音乐创意&#xff01; 一、FL Studio21水果软件——音乐制作的得力助手** 在音乐创作的道路上&#xff0c;有一款得心…

uniapp样式穿透修改uview的按钮button图标

需求&#xff1a; 想给按钮icon和text改字体颜色&#xff0c;结果发现图标颜色并没有改变 .u-button{width: 300rpx;background-color: aliceblue;color: #aaaa7f;margin-top: 20rpx; }接下来用样式穿透解决 1、首先&#xff0c;给UI组件包裹一层view <view class"t…

Javaweb学习记录(一)Maven

Maven是一款Java项目管理工具&#xff0c;下面将介绍Maven的实际作用和相关的操作 Maven项目依赖的添加 在Maven项目中添加依赖&#xff0c;通过dependencies标签添加所有依赖&#xff0c;所有依赖都添加在里面&#xff0c;而单个依赖就使用dependency标签添加进项目&#xf…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑抽水蓄能电站参与容量交易辅助服务的双层优化策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

IntelliJ IDEA 2023.3.4创建JavaWeb应用和集成Tomcat服务器

1. 创建项目 如下图所示&#xff0c;只需要给项目起一个项目名称&#xff0c;然后点击Create即可&#xff1a; 2. Project Structure 设置 创建完成后如下图 3. 集成Tomcat服务器 4. 实现Servlet接口 当我们实现Servlet接口时&#xff0c;发现没有Servlet相关的依赖时&am…

碳素光线疗法与中医

看得见的穴位碳素光线疗法 最近日本的医疗随着科学技术的发达&#xff0c;在基础研究、临床各领域取得了显著的发展。日本人的平均寿命比战前大幅延长&#xff0c;结核及其他疑难杂症、癌症等疾病也在逐渐被压制。其中&#xff0c;作为癌症的辅助疗法&#xff0c;日本癌症学会等…

布隆过滤器原理介绍和典型应用案例

整理自己过去使用布隆过滤器的应用案例和理解 基本介绍 1970年由布隆提出的一种空间效率很高的概率型数据结构&#xff0c;它可以用于检索一个元素是否在一个集合中&#xff0c;由只存0或1的位数组和多个hash算法, 进行判断数据 【一定不存在或者可能存在的算法】 如果这些…

C#求水仙花数

目录 1.何谓水仙花数 2.求三位数的水仙花数 3.在遍历中使用Math.DivRem方法再求水仙花数 1.何谓水仙花数 水仙花数&#xff08;Narcissistic number&#xff09;是指一个 n 位正整数&#xff0c;它的每个位上的数字的 n 次幂之和等于它本身。例如&#xff0c;153 是一个 3 …

数据类型【mysql数据库】

一、数值类型 默认都是有符号&#xff0c;无符号要在对应的类型后跟unsigned 在语言上&#xff0c;可能会有截断&#xff0c;但mysql会对不合法的数据做拦截。所以&#xff0c;mysql中&#xff0c;数据类型本身也是一种约束&#xff08;约束使用者&#xff09;&#xff0c;保证…