[go: nahoru, domu]

Skip to content

kuangtianyu/RPC-FromZero

Repository files navigation

🏆RPC-KTY

🥥简介

  • RPC-KTY一款基于 Netty + Kyro / Protostuff + Zookeeper 实现的 RPC 框架。那么何为RPC框架呢?RPC(Remote Procedure Call)即远程过程调用,通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。通过 RPC 可以帮助我们调用远程计算机上某个服务的方法,这个过程就像调用本地方法一样简单。并且我们不需要了解底层网络编程的具体细节😄😄😄

💻技术栈

  • 🎥Java基础
    • 动态代理机制(态代理 + JDK / CGLIB / Javassit 动态代理)
    • Java I/O 系统
    • Java 并发/多线程
    • Java 网络编程(Socket 编程)
    • Java 注解
    • Java 反射
    • 序列化机制以及序列化框架(Kryo / Protostuff )的基本使用
  • 📙Netty:使 NIO 编程更加容易,屏蔽了 Java 底层的 NIO 细节
  • 📑Zookeeper:提供服务注册与发现功能,开发分布式系统的必备选择,具备天生的集群能力
  • 🗳Spring Framework(Spring):最强大的依赖注入框架,业界的权威标准

⛏ 功能列表

  • 🐵使用 Spring 提供依赖注入与参数配置,集成 Spring 通过注解注册服务,集成 Spring 通过注解消费服务
  • 🦍使用 Netty 进行网络传输,使 NIO 编程更加容易,屏蔽了 Java 底层的 NIO 细节
  • 🦮基于开源的序列化框架 Protostuff / Kyro 实现消息对象的序列化/反序列化
  • 🐈可优化:用户通过配置文件指定序列化方式,避免硬编码
  • 🐴自定义编解码器(底层利用 Protostuff / Kyro )实现
  • 🐂TCP 心跳机制
  • 🐏使用 JDK / CGLIB 动态代理机制调用远程方法(调用远程方法像调用本地一样简单)
  • 🐪使用 Zookeeper(ZkClient 客户端)实现服务注册和发现
  • 🐹客户端调用远程服务的时候进行负载均衡 :调用服务的时候,从很多服务地址中根据相应的负载均衡策略选取一个服务地址。目前使用的策略为随机负载均衡

🧠设计思路

🥭注册中心

  • 推荐使用 Zookeeper,注册中心负责服务地址的注册与查找,相当于目录服务。服务端启动的时候将服务名称及其对应的地址(ip+port)注册到注册中心,服务消费端根据服务名称找到对应的服务地址。有了服务地址之后,服务消费端就可以通过网络请求服务端了。
  • ZooKeeper 为我们提供了高可用、高性能、稳定的分布式数据一致性解决方案,通常被用于实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。并且,ZooKeeper 将数据保存在内存中,性能是非常棒的。

🍊网络传输

  • 既然要调用远程的方法就要发请求,请求中至少要包含你调用的类名、方法名以及相关参数吧!推荐基于 NIO 的 Netty 框架。
  • Netty 是一个基于 NIO 的 client-server(客户端服务器)框架,使用它可以快速简单地开发网络应用程序,它屏蔽了 Java 底层的 NIO 细节

🍏序列化和反序列化

  • 在网络传输的过程中,网络传输的数据必须是二进制的,所以 Java 对象在网络中传输我们需要将其序列化为二进制的数据,我们需要的还是 Java 对象,所以我们还需要将二进制反序列化为 Java 对象
  • 既然涉及到网络传输就一定涉及到序列化,你不可能直接使用 JDK 自带的序列化吧!JDK 自带的序列化效率低并且有安全漏洞。 所以,你还要考虑使用哪种序列化协议,比较常用的有 hession2、kyro、protostuff。

🍓动态代理

  • 另外,动态代理也是需要的。因为 RPC 的主要目的就是让我们调用远程方法像调用本地方法一样简单,使用动态代理可以屏蔽远程方法调用的细节比如网络传输,所以实际会通过代理对象来传输网络请求

🥝负载均衡

  • 当我们的系统中的某个服务的访问量特别大,我们将这个服务部署在了多台服务器上,当客户端发起请求的时候,多台服务器都可以处理这个请求,这时我们就需要负载均衡为我们避免单个服务器响应同一请求,容易造成服务器宕机、崩溃等问题

🍇传输/通信协议

  • 我们还需要设计一个私有的 RPC 协议(通信/传输协议),这个协议是客户端(服务消费方)和服务端(服务提供方)交流的基础。
  • 通过设计传输协议,我们定义需要传输哪些类型的数据, 并且还会规定每一种类型的数据应该占多少字节。这样我们在接收到二级制数据之后,就可以正确的解析出我们需要的数据。
  • 通常一些标准的 RPC 协议包含下面这些内容:
  • 魔数 : 通常是 4 个字节。这个魔数主要是为了筛选来到服务端的数据包,有了这个魔数之后,服务端首先取出前面四个字节进行比对,能够在第一时间识别出这个数据包并非是遵循自定义协议的,也就是无效数据包,为了安全考虑可以直接关闭连接以节省资源。
    • 序列化器编号 :标识序列化的方式,比如是使用 Java 自带的序列化,还是 json,kyro 等序列化方式。
  • 消息体长度 : 运行时计算出来

📚 参考资料

About

从0打造一个RPC框架

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages