Rpc了解

news2024/11/29 3:56:54

1、为什么要有rpc?

因为微服务之间需要进行服务间的通信,不同服务之间的接口要互相调用。而常见的通信协议主要有 RPC 和 REST 协议

使用rpc的好处是:

引入RPC框架对我们现有的代码影响最小,同时又可以帮我们实现架构上的扩展

两者对比

 

2、什么是Rpc

Remote Procdeure Call ,即远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络实现的技术。

RPC 是一种进程间通信方式,允许像调用本地服务一样调用远程服务

例如微服务中有订单服务需要调用用户服务获取用户信息,之前的方法可能是通过http请求来访问接口,获取信息,现在调用时,只需要知道获取用户信息的接口的类名、方法名,传入相应参数,就可以获取到对应的用户信息。

3、Rpc流程

  1. 客户端以本地调用方式发起请求,请求内容包括:远程方法在本地的模拟对象,方法名,方法参数,将请求内容包装后的信息通过网络发送到服务端。
  2. 服务端收到消息后,进行解码为实际的方法名和参数
  3. 服务端本地服务执行并将结果返回
  4. 服务端将返回结果打包成消息并发送至客户端
  5. 客户端收到消息后,解码,获取响应内容

4、Rpc使用到的核心技术

  1. 代理,为什么要有代理,因为客户端只管发送请求,获取响应,至于过程如何不关心,所以需要一个代理来进行中间过程的封装。
  2. 反射,服务端收到请求后,需要通过反射机制来获取要调用的方法的对象,执行对应的方法
  3. 序列化  ,网络传输过程中需要先将数据进行序列化才能进行传输,接收到数据后需要将数据进行反序列化才能进行下一步操作。

5、一个简单的RpcDemo

发起服务端

package com.ljx.splearn.RpcDemo;

public class Main{

    public static void main(String[] args) throws Exception{
        //RPC调用,客户端获取要调用的服务并发起调用
        UserService service=(UserService)Client.getStub(UserService.class);
        User user = service.findUserByID(222);
        System.out.println(user.getName());

    }
}

client实现,重要类

package com.ljx.splearn.RpcDemo;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

public class Client{
    //远程调用类
    public static Object getStub(final Class clazz) throws Exception{
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //通过socket将请求发送到服务方
                Socket socket = new Socket("127.0.0.1", 8888);
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                String className = clazz.getName();
                String methodName = method.getName();
                Class[] parametersTypes = method.getParameterTypes();
                oos.writeUTF(className);
                oos.writeUTF(methodName);
                oos.writeObject(parametersTypes);
                oos.writeObject(args);
                oos.flush();
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Object o = ois.readObject();
                oos.close();
                socket.close();
                return o ;
            }
        };
        //通过代理实现方法调用
        Object o = Proxy.newProxyInstance(clazz.getClassLoader(),
                new Class[]{clazz},handler);
        return o;
    }
}

服务端启动一个socket,接收传递过来的请求数据,通过反射获取方法名和参数,并调用方法返回结果

package com.ljx.splearn.RpcDemo;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class Server {
    private static boolean running = true;
    public static void main(String[] args) throws  Exception{
        //启动一个socket方法
        ServerSocket serverSocket = new ServerSocket(8888);
        while (running){
            Socket socket = serverSocket.accept();
            process(socket);
            socket.close();
        }
        serverSocket.close();
    }
    private static void  process(Socket socket) throws Exception{
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        ObjectInputStream ois = new ObjectInputStream(in);
        
        // 拿到客户端传递过来的class
        String clazzName =ois.readUTF();
        String methodName =ois.readUTF();
        Class[] parameterTypes = (Class[])ois.readObject();
        Object[] args =(Object[])ois.readObject();
        //反射拿到class
        //通过反射可以获取所有的接口类
        Class clazz =Class.forName(clazzName);
        if(clazz.isInterface()){
            if(clazzName.equals("com.ljx.splearn.RpcDemo.UserService")){
                clazz = UserServiceImpl.class;
            }
        }
        //使用反射获取结果
        Method method = clazz.getMethod(methodName,parameterTypes);
        Object object = method.invoke(clazz.newInstance(),args);
        //通过socket将结果返回
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(object);
        oos.flush();
    }
}

服务调用的接口和实体类

package com.ljx.splearn.RpcDemo;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.Serializable;

/**
 * @author lijianxi
 * @date 2023年01月16日 10:40 上午
 */
@Data
@AllArgsConstructor
public class User implements Serializable {
    Integer id;
    String name;

}

 

package com.ljx.splearn.RpcDemo;

public interface UserService {
    public User findUserByID(Integer id);
}

 

package com.ljx.splearn.RpcDemo;

public class UserServiceImpl implements UserService {
    @Override
    public User findUserByID(Integer id) {
        return new User(id, "ljx");
    }

 
}

启动server,调用main

结果如下

 6、RPC和HTTP

    1、RPC是远程过程调用,只是对不同应用间相互调用的一种描述,它是一种思想。具体怎么调用?实现方式可以是最直接的TCP通信,也可以是HTTP方式。
    2、HTTP是应用层的一种协议,负责服务之间的通信操作。
    3、dubbo是基于tcp通信的,gRPC是Google公布的开源软件,基于最新的HTTP2.0协议,底层使用到了Netty框架的支持。

 
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【7】SCI易中期刊推荐——计算机 | 人工智能(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

Barra模型因子的构建及应用系列二之Beta因子

一、摘要 在前期的Barra模型系列文章中,我们初步讲解并构建了Size因子。在Size因子基础上构建的单因子策略也获得了不错的绝对收益。而本期内容,我们在该系列下进一步构建Beta因子,其中基于Beta因子构建的策略在2022年实现了5.70%年化收益&a…

51单片机——点亮LED

目录 LED基本参数 参数信息 参数解读 拉电流与灌电流 电路示意图 电阻选取 灌电流与拉电流区别 程序编写与现象展示 LED基本参数 参数信息 产品名称贴片发光二极管产品型号0603发光颜色 绿、红、蓝、翠绿、白、黄 电压2V~3.3V电流5~20mA功率0.01~0.06W使用寿命约50000小…

小程序模板语法

小程序模板语法模板语法—数据绑定数据绑定的步骤应用场景示例模板语法—条件渲染条件渲染的两个方式wx:if vs hidden列表渲染—基础列表渲染简介基础用法手动指定索引和当前项的变量名列表渲染—进阶key的作用key的用法模板语法—数据绑定 数据绑定的步骤 在data中定义数据 P…

Unreal中Interface接口的使用

通过继承Unreal中的接口可以使不同的类有某种共同特性,这里记录一下接口的使用方式。Unreal中的接口分为两种:C接口和蓝图接口,C接口可在蓝图中使用;蓝图中的接口不能直接在C中使用,这里探究一下他们的关系:1.C的接口在C中使用:新建C类,继承UnrealInterface:接口中可以声明虚函…

Java运算符(二)

算术运算符1.1运算符和表达式运算符:对常量和变量进行操作的符号表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以成为表达式不同运算符连接的表达式体现的是不同类型的表达式举例说明:int a10;int b20;int cab;:是…

电脑投影左右切换

要同时使用几个显示器的情况 winp 投影 然后右键桌面 显示设置 长按选择左右屏幕

DRR(Digitally Reconstructured Radiograph)分类及原理

DRR(Digitally Reconstructured Radiograph)分类及原理 DRR(Digitally Reconstructured Radiograph),全称为数字重建放射影像,其是通过将三维 (3D) 图像(Volume)透视投影到二维 (2D) 图像平面上而生成的射线照相图像的模拟。DRR被…

Oracle客户端 PL/SQL Developer:

1、配置文件进行导入导出 2、提示“ORA-00900: 无效 SQL 语句“解决方法 在PL/SQL中的SQL窗口用desc想显示指定表格abs_generl.prodord_sku的结构,提示无效语句 PL/SQL切换到命令窗口,再用desc显示表格abs_generl.prodord_sku的结构,执行成功…

2023年面试题之Dubbo基础

1. 为什么要用 Dubbo?随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通…

libtorch c++ 使用预训练权重(以resnet为例)

任务: 识别猫咪。 目录 1. 直接使用 1.1 获取预训练权重 1.2 libtorch直接使用pt权重 2. 间接使用 2.1 BasicBlock 2.2 实现ResNet 2.3 BottleNeck 1. 直接使用 1.1 获取预训练权重 比如直接使用Pytorch版的预训练权重。先把权重保存下来,并打印…

vue+element详细完整实现个人博客、个人网站

一.前言 博客成品在线预览:点击访问 接上一篇《vueelementui实现非常好看的博客、网站首页,网站模板》。 上一篇实现了整个框架的搭建和首页的编码,在此基础上,这一期进行了最终的功能页面完善,增加了功能&#xff1a…

【自学Python】Python合并字符串

Python合并字符串 Python合并字符串教程 在开发过程中,很多时候我们有合并 字符串 的需求,即把一个 元祖 或 列表 中包含的多个字符串连接成一个字符串。这个操作是 分割字符串 的逆操作。 在 Python 中,合并字符串我们使用 join() 函数。…

过气明星李嘉明和《丁香花》唐磊,找哪个录制祝福视频值100万

说起娱乐圈的明星,给人的感觉都是光鲜亮丽,因为他们有流量有热度,想要赚钱就太容易了。过去的娱乐圈明星,都是靠自己的专业赚钱,比如说你是著名歌星,就要靠唱歌赚钱,如果你是影视明星&#xff0…

天天都接触的以太网接口,你知道有哪些类型和参数吗?

以太网接口简介 以太网接口是一种用于局域网组网的接口,包括:以太网电接口、以太网光接口。 为了适应网络需求,设备上定义了以下几种以太网接口类型: 二层以太网接口 是一种物理接口,工作在数据链路层,不…

ASP.NET Core 3.1系列(30)——Newtonsoft.Json实现JSON的序列化和反序列化

1、前言 在早期版本的ASP.NET Core项目中,Newtonsoft.Json的使用率非常高。虽然微软当前主推System.Text.Json来处理JSON的序列化和反序列化,但Newtonsoft.Json在这方面做的也是相当不错,下面就来介绍一下它的用法。 2、引入Newtonsoft.Jso…

echarts柱状图值为0是不显示以及柱状图百分比展示

echarts柱状图值为0是不显示以及柱状图百分比展示 1.效果展示 2.代码 <template><div id"container"><div id"main"></div></div> </template> <script>import * as echarts from echarts import * as lodash…

代码随想录第四天(203、707)

文章目录一、链表知识203. 移除链表元素提交看答案之后的豁然开朗707. 设计链表完全不会&#xff0c;看完答案后改的一、链表知识 1、链表在内存中的存储不是连续的 意思是这个链表的其实节点是2&#xff0c;终止节点是7 2、链表和数组的对比 数组的长的是固定的&#xff0c…

【Iot】阿里云物联网平台入门之什么是消息解析、什么是Topic、JavaScript脚本示例解析

在IoT场景中&#xff0c;很多传感器采集到的都是二进制数据&#xff0c;或者私有协议格式数据流&#xff0c;设备端又不具备转换成结构化JSON的能力&#xff0c;这时候我们可以借助IoT物联网平台云端自定义数据解析能力&#xff0c;转换Modbus&#xff0c;电力协议&#xff0c;…

YOLO家族系列模型的演变:从v1到v8(下)

昨天的文章中&#xff0c;我们回顾了 YOLO 家族的前 9 个架构。本文中将继续总结最后3个框架&#xff0c;还有本月最新发布的YOLO V8. YOLOR Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao “You Only Learn One Representation: Unified Network for Multiple Tasks”202…