首页 > 编程语言 >【Java手写RPC框架系列-1】—— 基础知识准备:RPC+Netty

【Java手写RPC框架系列-1】—— 基础知识准备:RPC+Netty

时间:2024-08-13 23:29:05浏览次数:15  
标签:Netty 调用 Java RPC fd 服务端 客户端

代码随想录知识星球介绍
https://articles.zsxq.com/id_m76jd72243bi.html
基于Netty手写实现RPC
https://www.cnblogs.com/mic112/p/15565795.html

项目背景与介绍

  • RPC:
    • 远程过程调用协议:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样;
    • 要点
      • RPC是协议
      • 网络协议或者网络IO模型对其透明;RPC客户端认为自己在调用本地对象;不关心传输层协议
      • 信息格式透明:参数以某种信息格式传递给网络上另一台计算机,信息格式是怎么构成的,调用者不关心
      • 跨语言能力:不清楚远程服务器的应用程序是使用什么语言运行;对调用方来说,无论服务器方使用什么语言,本次调用都应该成功;返回值也应该按照调用方程序语言所能理解的形式进行描述。
  • 常用RPC技术或框架
    • 应用级
    • 远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)
    • 通信框架:MINA和Netty
  • 目的:仿照市场主流的RPC框架设计思想,使用java手动实现一个高性能、高可用性的RPC框架

业内主流RPC

  1. Thrift:thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
  2. Dubbo:Dubbo是一个分布式服务框架,以及SOA治理方案。其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。 Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,Dubbo自2011年开源后,已被许多非阿里系公司使用。

基础需求

  • 场景:
    服务端B:有一个用户表
    1.UserService 里有一个功能: getUserByUserId(Integer id)
    2.UserServiceImpl 实现了UserService接口和方法
    客户端A
    • 调用getUserByUserId方法, 内部传一个Id给服务端,服务端查询到User对象返回给客户端
  • 实现过程:
    • 客户端A

      • 调用getUserByUserId方法时,内部将调用信息处理后发送给服务端B,告诉B我要获取User
      • 外部调用方法,内部进行其它的处理——这种场景我们可以使用动态代理的方式,改写原本方法的处理逻辑。比如,当我们正常调用getUserByUserId方法,代码逻辑是去数据库中找user,但是在当前远程调用的场景下肯定不能走这样的逻辑;我们通过动态代理的方式,绕过【去数据库查询】这原始的逻辑,改成封装信息发送到B中请求调用服务
    • 服务器B:

      • 监听A请求,接收A的调用信息,并根据信息得到A想调用的服务与方法
      • 根据信息找到对应的服务,进行调用后将结果发送回给A
    • A和B之间通信

      • Java的Socket网络编程通信
      • 为了方便A,B直接对信息进行处理,将请求信息和返回信息封装成统一的消息格式

网络IO通信

  • 传统BIO模式/同步阻塞IO:客户端向服务端发起一个数据读取请求,客户端在收到服务端返回数据之前,一直处于阻塞状态,直到服务端返回数据后完成本次会话。
    • 一个连接一个线程
    • 客户端有连接请求时,服务器端启动一个线程进行处理
    • 适合场景:HTTP请求
    • 阻塞点:
      • 服务端接收客户端连接时的阻塞;
      • 客户端和服务端IO通信时,数据未就绪情况下阻塞;
  • NIO/非阻塞IO:客户端向服务端发起请求时,如果服务端的数据未就绪的情况下, 客户端请求不会被阻塞,而是直接返回。
    • 客户端只能通过轮询的方式来获得请求结果
    • NIO仍然有一个弊端,就是轮询过程中会有很多空轮询,而这个轮询会存在大量的系统调用(发起内核指令从网卡缓冲区中加载数据,用户空间到内核空间的切换),随着连接数量的增加,会导致性能问题。
  • 多路复用机制
    • 单个进程监视多个文件描述符(fd)
    • 一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作
    • 常见多路复用方式:
      • 【select】:进程可以通过把一个或者多个fd传递给select系统调用,进程会阻塞在select操作上,这样select可以帮我们检测多个fd是否处于就绪状态,这个模式有两个缺点
        • 当前进程需要线性轮询所有的fd,也就是监听的fd越多,性能开销越大
        • 在单个进程中能打开的fd是有限制的,默认是1024
      • 【poll】:
      • 【epoll】:inux还提供了epoll的系统调用,epoll是基于事件驱动方式来代替顺序扫描,因此性能相对来说更高
        • 当被监听的fd中,有fd就绪时,会告知当前进程具体哪一个fd就绪,那么当前进程只需要去从指定的fd上读取数据即可,另外,epoll所能支持的fd上线是操作系统的最大文件句柄,这个数字要远远大于1024

什么是fd:在linux中,内核把所有的外部设备都当成是一个文件来操作,对一个文件的读写会调用内核提供的系统命令,返回一个fd(文件描述符)。而对于一个socket的读写也会有相应的文件描述符,成为socketfd。

【使用NIO的api来完成多路复用机制,实现伪异步IO。】
【Netty的I/O模型是基于非阻塞IO实现的,底层依赖的是JDK NIO框架的多路复用器Selector来实现。一个多路复用器Selector可以同时轮询多个Channel,采用epoll模式后,只需要一个线程负责Selector的轮询,就可以接入成千上万个客户端连接。】



  • 异步IO
    • 数据就绪后,客户端不需要发送内核指令从内核空间读取数据,而是系统会异步把这个数据直接拷贝到用户空间,应用程序只需要直接使用该数据即可;

Netty —— 高性能通信框架

Netty提供了上述三种Reactor模型的支持,我们可以通过Netty封装好的API来快速完成不同Reactor模型的开发,这也是为什么大家都选择Netty的原因之一,除此之外,Netty相比于NIO原生API,它有以下特点:

  • 提供了高效的I/O模型、线程模型和时间处理机制
  • 提供了非常简单易用的API
  • 对数据协议和序列化提供了很好的支持
  • 稳定性,Netty修复了JDK NIO较多的问题
  • 可扩展性在同类型的框架中都是做的非常好的
  • 性能层面的优化
    • 对象池复用
    • 零拷贝技术

标签:Netty,调用,Java,RPC,fd,服务端,客户端
From: https://www.cnblogs.com/P201821440041/p/18357932

相关文章

  • Java 运算符(详解)
    文章目录一、简介二、算术运算符三、自增自减运算符四、关系运算符五、逻辑运算符六、位运算符六、赋值运算符七、条件运算符八、字符串连接符九、运算符优先级一、简介在Java中,运算符是用来对数据进行操作和处理的符号,这些符号能使得Java程序进行各种数学计算、......
  • Leetcode JAVA刷刷站(20)有效的括号
    一、题目概述二、思路方向     在Java中,要判断一个仅包含括号('(',')','{','}','[',']')的字符串是否有效,你可以使用栈(Stack)数据结构来实现。栈是一种后进先出(LIFO,LastInFirstOut)的数据结构,非常适合用来处理这类问题。以下是具体的实现步骤和代码示例:创......
  • Java并发类的主要API方法-Semaphore
    一、Semaphoreemaphore是Java并发包(java.util.concurrent)中的一个同步工具类,类Semaphore所提供的功能完全就是synchronized关键字的升级版,但它提供的功能更加的强大与方便,主要的作用就是控制线程并发的数量,而这一点,单纯地使用synchronized是做不到的。emaphore它用......
  • Java数组06:常见排序算法
    1.冒泡排序冒泡排序(BubbleSort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完......
  • Java数组07:稀疏数组
    1.线性结构线性结构是最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。线性结构有两种不同存储结构,即顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的,即在内存中是连续的,例如数组。链式存储的线性表称为链表,链表中的存储元......
  • Java数组05:Arrays 类
    数组的工具类java.util.Arrays由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。文档简介:此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。......
  • 一款Java 性能监控和统计工具——MyPerf4J!【送源码】
    背景随着所在公司的发展,应用服务的规模不断扩大,原有的垂直应用架构已无法满足产品的发展,几十个工程师在一个项目里并行开发不同的功能,开发效率不断降低。于是公司开始全面推进服务化进程,把团队内的大部分工程师主要精力全部都集中到服务化中。服务化可以让每个工程师仅在自己......
  • Java基础-学习笔记10
    **10内部类**内部类一个类的内部又完整的嵌套了另一个类的结构,被嵌套的类成为内部类,嵌套其他类的类称为外部类。是类的第五大成员(属性、方法、构造器、代码块、内部类)。内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。classOuter//外部类{......
  • Java数组04:多维数组
    多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。多维数组的动态初始化(以二维数组为例)直接为每一维分配空间,格式如下:type[][]typeName=newtype[typeLength1][typeLength2];type可以为基本数据类型和复合数据类型,arraylen......
  • java
    markdown二级标题字体markdownmarkdownmarkdownmarkdown引用哈哈哈分割线图片![截图](C:\Users\黄刘洋\Pictures\Screenshots\屏幕截图2024-08-13161113.png)超链接点击跳转4399列表AA表格名字性别生日张三男1977.1.1代码publi......