冰河技术
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
  • RPC框架介绍

    • 【置顶】这次我设计了一款TPS百万级别的分布式、高性能、可扩展的RPC框架
  • 第一篇:整体设计

    • 第01章:开篇,从零开始手撸一个能在实际场景使用的高性能RPC框架
    • 第02章:高性能分布式RPC框架整体架构设计
    • 第03章:RPC服务核心注解的设计与实现
    • 第04章:实现RPC服务核心注解的扫描与解析
  • 第二篇:服务提供者

    • 第05章:服务提供者收发消息基础功能实现
    • 第06章:自定义网络传输协议的实现
    • 第07章:自定义网络编解码的实现
    • 第08章:模拟服务消费者与服务提供者之间的数据交互
    • 第09章:服务提供者调用真实方法的实现
    • 第10章:测试服务提供者调用真实方法
    • 第11章:服务提供者扩展支持CGLib调用真实方法
  • 第三篇:服务消费者

    • 第12章:实现服务消费者与服务提供者直接通信
    • 第13章:服务消费者异步转同步直接获取返回结果
    • 第14章:服务消费者异步转同步的自定义Future与AQS实现
    • 第15章:服务消费者同步、异步、单向调用的实现
    • 第16章:服务消费者回调方法的实现
    • 第17章:服务消费者实现动态代理功能屏蔽构建请求协议对象的细节
    • 第18章:服务消费者整合动态代理实现直接调用接口返回结果数据
    • 第19章:服务消费者动态代理实现异步调用
    • 第20章:服务消费者动态代理扩展优化
  • 第四篇:注册中心

    • 第21章:注册中心基础服务功能的实现
    • 第22章:服务提供者整合注册中心实现服务注册
    • 第23章:服务消费者整合注册中心实现服务发现
  • 第五篇:负载均衡

    • 第24章:服务消费者实现基于随机算法的负载均衡策略
  • 第六篇:SPI扩展序列化机制

    • 第25章:对标Dubbo实现SPI扩展机制的基础功能
    • 第26章:基于SPI扩展JDK序列化与反序列化机制
    • 第27章:基于SPI扩展Json序列化与反序列化机制
    • 第28章:基于SPI扩展Hessian2序列化与反序列化机制
    • 第29章:基于SPI扩展FST序列化与反序列化机制
    • 第30章:基于SPI扩展Kryo序列化与反序列化机制
    • 第31章:基于SPI扩展Protostuff序列化与反序列化机制
  • 第七篇:SPI扩展动态代理机制

    • 第32章:基于SPI扩展JDK动态代理机制
    • 第33章:基于SPI扩展CGLib动态代理机制
    • 第34章:基于SPI扩展Javassist动态代理机制
    • 第35章:基于SPI扩展ByteBuddy动态代理机制
    • 第36章:基于SPI扩展ASM动态代理机制
  • 第八篇:SPI扩展反射机制

    • 第37章:基于SPI扩展JDK反射机制调用真实方法
    • 第38章:基于SPI扩展CGLib反射机制调用真实方法
    • 第39章:基于SPI扩展Javassist反射机制调用真实方法
    • 第40章:基于SPI扩展ByteBuddy反射机制调用真实方法
    • 第41章:基于SPI扩展ASM反射机制调用真实方法
  • 第九篇:SPI扩展负载均衡策略

    • 第42章:基于SPI扩展随机算法负载均衡策略
    • 第43章:基于SPI扩展加权随机算法负载均衡策略
    • 第44章:基于SPI扩展轮询算法负载均衡策略
    • 第45章:基于SPI扩展加权轮询算法负载均衡策略
    • 第46章:基于SPI扩展Hash算法负载均衡策略
    • 第47章:基于SPI扩展加权Hash算法负载均衡策略
    • 第48章:基于SPI扩展源IP地址Hash算法负载均衡策略
    • 第49章:基于SPI扩展源IP地址加权Hash算法负载均衡策略
    • 第50章:基于SPI扩展Zookeeper的一致性Hash算法负载均衡策略
  • 第十篇:SPI扩展增强型负载均衡策略

    • 第51章:基于SPI扩展增强型加权随机算法负载均衡策略
    • 第52章:基于SPI扩展增强型加权轮询算法负载均衡策略
    • 第53章:基于SPI扩展增强型加权Hash算法负载均衡策略
    • 第54章:基于SPI扩展增强型加权源IP地址Hash算法负载均衡策略
    • 第55章:基于SPI扩展增强型Zookeeper一致性Hash算法负载均衡策略
    • 第56章:基于SPI扩展最少连接数负载均衡策略
  • 第十一篇:SPI扩展实现注册中心

    • 第57章:基于SPI扩展实现Zookeeper注册中心
    • 第57-X章:注册中心阶段性作业
  • 第十二篇:心跳机制

    • 第58章:心跳机制交互数据模型设计
    • 第59章:心跳机制增强数据模型与协议解析设计
    • 第60章:服务消费者向服务提供者发送心跳信息并接收心跳响应
    • 第61章:服务消费者心跳间隔时间配置化
    • 第62章:服务提供者向服务消费者发送心跳消息并接收心跳响应
    • 第63章:服务提供者心跳间隔时间配置化
    • 第63-X章:心跳机制阶段性作业
  • 第十三篇:增强型心跳机制

    • 第64章:服务提供者增强型心跳检测机制
    • 第65章:服务消费者增强型心跳检测机制
  • 第十四篇:重试机制

    • 第66章:服务消费者实现服务订阅的重试机制
    • 第67章:服务消费者连接服务提供者的重试机制
  • 第十五篇:整合Spring

    • 第68章:服务提供者整合Spring
    • 第69章:基于Spring XML接入服务提供者
    • 第70章:基于Spring注解接入服务提供者
    • 第71章:服务消费者整合Spring
    • 第72章:基于Spring XML接入服务消费者
    • 第73章:基于Spring注解接入服务消费者
    • 第73章-X:整合Spring阶段作业
  • 第十六篇:整合SpringBoot

    • 第74章:服务提供者整合SpringBoot
    • 第75章:基于SpringBoot接入服务提供者
    • 第76章:服务消费者整合SpringBoot
    • 第77章:基于SpringBoot接入服务消费者
    • 第77章-X:整合SpringBoot阶段作业
  • 第十七篇:整合Docker

    • 第78章:基于Docker接入服务提供者
    • 第79章:基于Docker接入服务消费者
    • 第79章-X:整合Docker阶段作业
  • 第十八篇:整合SpringCloud Alibaba

    • 第80章:整合SpringCloud Alibaba实际项目
    • 第80章-X:整合SpringCloud Alibaba阶段作业
  • 第十九篇:结果缓存

    • 第81章:结果缓存通用模型设计
    • 第82章:服务提供者支持结果缓存
    • 第83章:服务消费者支持结果缓存
    • 第83章-X:结果缓存阶段作业
  • 第二十篇:路由控制

    • 第84章:服务消费者直连某个服务提供者
    • 第85章:服务消费者直连多个服务提供者
    • 第85章-X:路由控制阶段作业
  • 第二十一篇:延迟连接

    • 第86章:服务消费者支持延迟连接服务提供者
    • 第87章:服务消费者支持非延迟连接服务提供者
    • 第87章-X:延迟连接阶段作业
  • 第二十二篇:并发控制

    • 第88章:并发控制基础模型设计
    • 第89章:服务提供者支持并发控制
    • 第90章:服务消费者支持并发控制
    • 第90章-X:并发控制阶段作业
  • 第二十三篇:流控分析

    • 第91章:流控分析后置处理器模型设计
    • 第92章:服务提供者整合流控分析
    • 第93章:服务消费者整合流控分析
    • 第93章-X:流控分析阶段作业
  • 第二十四篇:连接控制

    • 第94章:连接控制基础模型设计
    • 第95章:服务提供者整合连接控制
    • 第95章-X:连接控制阶段作业
  • 第二十五篇:SPI扩展连接淘汰策略

    • 第96章:基于SPI扩展最早连接淘汰策略
    • 第97章:基于SPI扩展最晚连接淘汰策略
    • 第98章:基于SPI扩展先进先出连接淘汰策略
    • 第99章:基于SPI扩展使用次数最少连接淘汰策略
    • 第100章:基于SPI扩展最近未被使用连接淘汰策略
    • 第101章:基于SPI扩展随机连接淘汰策略
    • 第102章:基于SPI扩展拒绝连接淘汰策略
    • 第102章-X:SPI扩展连接拒绝策略阶段作业
  • 第二十六篇:数据缓冲

    • 第103章:数据缓冲基础模型设计
    • 第104章:服务提供者整合数据缓冲
    • 第105章:服务消费者整合数据缓冲
    • 第105章-X:数据缓冲阶段作业
  • 第二十七篇:服务容错(降级)

    • 第106章:服务容错设计与研发
    • 第107章:服务容错效果测试
    • 第108章:服务容错失效问题修复
    • 第108章-X:服务容错阶段作业
  • 第二十八篇:服务限流

    • 第109章:服务限流基础模型设计
    • 第110章:服务提供者整合服务限流
    • 第111章:服务消费者整合服务限流
    • 第111章-X:服务限流阶段作业
  • 第二十九篇:基于SPI扩展限流策略

    • 第112章:基于SPI扩展Semaphore限流策略
    • 第113章:基于SPI扩展Guava限流策略
    • 第113章-X:基于SPI扩展限流策略阶段作业
  • 第三十篇:超出限流规则

    • 第114章:服务提供者超出限流上限触发的规则
    • 第115章:服务消费者超出限流上限触发的规则
    • 第115章-X:超出限流规则阶段作业
  • 第三十一篇:服务熔断

    • 第116章:服务熔断基础模型设计
    • 第117章:服务提供者整合服务熔断
    • 第118章:服务消费者整合服务熔断
    • 第118章-X:服务熔断阶段作业
  • 第三十二篇:基于SPI扩展熔断策略

    • 第119章:基于SPI扩展错误率熔断策略
    • 第119章-X:基于SPI扩展熔断策略阶段作业
  • 第三十三篇:异常监控

    • 第120章:异常监控后置处理器基础模型设计
    • 第121章:服务提供者整合异常监控
    • 第122章:服务消费者整合异常监控
    • 第122章-X:异常监控阶段作业
  • 维护篇:持续维护篇

    • 第fix-01章:修复服务消费者读取配置优先级的问题
    • 第fix-02章:修复Zookeeper一致性Hash负载均衡泛型类型不匹配的问题
    • 第fix-03章:修复自定义扫描器递归扫描文件标识不起作用的问题
    • 第fix-04章:修复基于SpringBoot启动服务消费者Netty Group多次连接的问题
    • 第fix-05章:修复基于计数器的限流策略不起作用的问题
    • 第fix-06章:修复基于SpringBoot启动服务消费者无法同时连接多个服务提供者的问题
    • 第fix-07章:更新基于Semaphore的限流策略
    • 第fix-08章:优化服务熔断半开启状态的执行逻辑
  • 番外篇

    • 《从零开始手写RPC框架》电子书重磅发布

【置顶】这次我设计了一款TPS百万级别的分布式、高性能、可扩展的RPC框架

作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.site
文章汇总:https://binghe.site/md/all/all.html

大家好,我是冰河~~

没错,这次冰河又要搞事情了,这次准备下手的是RPC框架项目。为什么要对RPC框架项目下手呢,因为在如今分布式、微服务乃至云原生不断发展的过程中,RPC作为底层必不可少的通信组件,被广泛应用在分布式、微服务和云原生项目中。

为啥要开发RPC框架

事情是这样的,在开发这个RPC框架之前,我花费了不少时间算是对Dubbo框架彻底研究透彻了。

冰河在撸透了Dubbo2.x和Dubbo3.x的源码之后,本来想给大家写一个Dubbo源码解析的专栏。为此,我其实私下准备了一个多月:画流程图、分析源码、写测试Demo,自己在看Dubbo源码时,也为Dubbo源码添加了非常详细的注释。这里,就包含Dubbo2.x和Dubbo3.x的源码。

当我就这么熬夜肝文一个多月后,突然发现一个问题:Dubbo经过多年不断的迭代开发,它的源码已经非常多了,如果以文章的形式将Dubbo的源码面面俱到的分析到位,那还不知道要写到何年何月去了。当我写文章分析Dubbo的最新版本3.x时,可能写到专栏的中后期Dubbo已经更新到4.x、5.x,设置有可能是6.x、7.x了。

与其这么费劲吧咧的分析源码,还不如从零开始带着大家一起手撸一个能够在实际生产环境使用的、分布式、高性能、可扩展的RPC框架。这样,大家也能够直观的感受到一个能够在实际场景使用的RPC框架是如何一步步开发出来的。

相信大家在学完《RPC手撸专栏》后,自己再去看Dubbo源码的话,就相对来说简单多了。你说是不是这样的呢?

你能学到什么?

既然是整个专栏的开篇嘛,肯定是要告诉你在这个专栏中能够学习到哪些实用的技术的。这里,我就画一张图来直观的告诉你在《RPC手撸专栏》能够学到哪些技术吧。

rpc-2022-06-25-001

相信小伙伴们看到《RPC手撸专栏》涉及到的知识点,应该能够了解到咱们这个从零开始的《RPC手撸专栏》还是比较硬核的吧?

另外,咱这RPC项目支持同步调用、异步调用、回调和单向调用。

  • 同步调用

rpc-2022-06-30-002

  • 异步调用

rpc-2022-06-30-003

  • 回调

rpc-2022-06-30-004

  • 单向调用

rpc-2022-06-30-005

对,没错,咱们《RPC手撸专栏》最终实现的RPC框架的定位就是尽量可以在实际环境使用。通过这个专栏的学习,让大家深入了解到能够在实际场景使用的RPC框架是如何一步步开发出来的。

代码结构

我将这个bhrpc项目的定位为可在实际场景使用的、分布式、高性能、可扩展的RPC框架,目前总体上已经开发并完善的功能会达到120+个子项目,大家看图吧。

rpc-2022-08-24-003

rpc-2022-08-24-006

项目大量使用了对标Dubbo的自定义SPI技术实现高度可扩展性,各位小伙伴可以根据自己的需要,按照SPI的设计要求添加自己实现的自定义插件。

rpc-2022-08-24-001

演示效果

说了那么多,咱们一起来看看这个RPC框架的使用效果吧,因为咱们这个RPC框架支持的调用方式有:原生RPC调用、整合Spring(XML/注解)、整合SpringBoot、整合SpringCloud、整合SpringCloud Alibaba,整合Docker和整合K8S七种使用方式。

这里,咱们就以 整合Spring注解的方式 来给大家演示下这个RPC框架。

RPC核心注解说明

为了让大家更好的了解这个RPC框架,我先给大家看下RPC框架的两个核心注解,一个是RPC的服务提供者注解@RpcService,一个是RPC的服务调用者注解@RpcReference。

(1)服务提供者注解@RpcService的核心源码如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description bhrpc服务提供者注解
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface RpcService {

    /**
     * 接口的Class
     */
    Class<?> interfaceClass() default void.class;

    /**
     * 接口的ClassName
     */
    String interfaceClassName() default "";

    /**
     * 版本号
     */
    String version() default "1.0.0";

    /**
     * 服务分组,默认为空
     */
    String group() default "";

    /**
     * 延迟发布,预留
     */
    int delay() default 0;

    /**
     * 是否导出rpc服务,预留
     */
    boolean export() default true;
}

(2)服务调用者注解@RpcReference的核心源码如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description bhrpc服务消费者
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Autowired
public @interface RpcReference {

    /**
     * 版本号
     */
    String version() default "1.0.0";

    /**
     * 注册中心类型, 目前的类型包含:zookeeper、nacos、etcd、consul
     */
    String registryType() default "zookeeper";

    /**
     * 注册地址
     */
    String registryAddress() default "127.0.0.1:2181";

    /**
     * 负载均衡类型,默认基于ZK的一致性Hash
     */
    String loadBalanceType() default "zkconsistenthash";

    /**
     * 序列化类型,目前的类型包含:protostuff、kryo、json、jdk、hessian2、fst
     */
    String serializationType() default "protostuff";

    /**
     * 超时时间,默认5s
     */
    long timeout() default 5000;

    /**
     * 是否异步执行
     */
    boolean async() default false;

    /**
     * 是否单向调用
     */
    boolean oneway() default false;

    /**
     * 代理的类型,jdk:jdk代理, javassist: javassist代理, cglib: cglib代理
     */
    String proxy() default "jdk";

    /**
     * 服务分组,默认为空
     */
    String group() default "";
}

这里,我只列出了服务提供者注解@RpcService和服务调用者注解@RpcReference的部分源码,后续在RPC框架不断完善的过程中,大家就可以慢慢看到源码的全貌和其每个注解实现的功能。这里,我就不详细介绍了。

当然啦,在这个RPC框架实现的原生调用方式中,可以不用这些注解就能够实现远程调用。

效果演示

接口定义

定义两个接口,分别为HelloService和HelloPersonService,源码如下所示。

  • HelloService接口源码
public interface HelloService {
    String hello(String name);
    String hello(Person person);
}
  • HelloPersonService接口源码
public interface HelloPersonService {
    List<Person> getTestPerson(String name,int num);
}

实现服务提供者demo

(1)创建HelloService接口和HelloPersonService接口的实现类HelloServiceImpl和HelloPersonServiceImpl,如下所示。

  • HelloServiceImpl类源码
@RpcService(interfaceClass = HelloService.class, version = "1.0.0")
public class HelloServiceImpl implements HelloService {

    @Override
    public String hello(String name) {
        return "Hello! " + name;
    }

    @Override
    public String hello(Person person) {
        return "Hello! " + person.getFirstName() + " " + person.getLastName();
    }
}

可以看到,在HelloServiceImpl类上添加了RPC服务提供者注解@RpcService,表示将其发布为一个RPC服务。

  • HelloPersonServiceImpl类源码
@RpcService(interfaceClass = HelloPersonService.class, version = "1.0.0")
public class HelloPersonServiceImpl implements HelloPersonService {
    @Override
    public List<Person> getTestPerson(String name, int num) {
        List<Person> persons = new ArrayList<>(num);
        for (int i = 0; i < num; ++i) {
            persons.add(new Person(Integer.toString(i), name));
        }
        return persons;
    }
}

可以看到,在HelloPersonServiceImpl类上添加了RPC服务提供者注解@RpcService,表示将其发布为一个RPC服务。

(2)创建服务提供者demo的配置类ServerConfig,在ServerConfig类中注入RegistryService注册中心接口的实现类,以及RPC服务提供者的核心类RpcServer,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 基于注解的配置类
 */
@Configuration
@ComponentScan(value = {"io.binghe.rpc.demo"})
@PropertySource(value = {"classpath:rpc.properties"})
public class SpringAnnotationProviderConfig {

    @Value("${registry.address}")
    private String registryAddress;

    @Value("${registry.type}")
    private String registryType;

    @Value("${registry.loadbalance.type}")
    private String registryLoadbalanceType;

    @Value("${server.address}")
    private String serverAddress;

    @Value("${reflect.type}")
    private String reflectType;

    @Bean
    public RpcSpringServer rpcSpringServer(){
        return new RpcSpringServer(serverAddress, registryAddress, registryType, registryLoadbalanceType, reflectType);
    }
}

(3)创建服务提供者demo的启动类ServerTest,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description RPC整合Spring注解,服务提供者demo启动类
 */
public class ServerTest {
    public static void main(String[] args){
        new AnnotationConfigApplicationContext(ServerConfig.class);
    }
}

实现服务调用者demo

(1)创建测试服务调用者的TestService接口,如下所示。

public interface TestService {
    void printResult();
}

(2)创建TestService接口的实现类TestServiceImpl,在TestServiceImpl类上标注Spring的@Service注解,并在TestServiceImpl类中通过@RpcReference注解注入HelloService接口的实现类和HelloPersonService接口的实现类,并实现TestService接口的printResult()方法,源码如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试RPC服务调用者
 */
@Service
public class TestServiceImpl implements TestService {

    @RpcReference(version = "1.0.0", timeout = 3000, proxy = "javassist", isAsync = true)
    private HelloService helloService;
    
    @RpcReference(proxy = "cglib")
    private HelloPersonService helloPersonService;

    @Override
    public void printResult() {
        String result = helloService.hello("binghe");
        System.out.println(result);
        result = helloService.hello(new Person("binghe001", "binghe002"));
        System.out.println(result);
        System.out.println("=================================");
        List<Person> personList = helloPersonService.getTestPerson("binghe", 2);
        personList.stream().forEach(System.out::println);
    }
}

通过TestServiceImpl类的源码我们可以看到,远程调用HelloService接口的方法时使用的是javassist动态代理,远程调用HelloPersonService接口时,使用的是cglib动态代理。

(3)创建服务调用者demo的配置类ClientConfig,如下所示。

@Configuration
@ComponentScan(value = {"io.binghe.rpc.*"})
@PropertySource(value = {"classpath:rpc.properties"})
public class ClientConfig {
}

(4)创建服务调用者demo的启动类ClientTest,如下所示。

public class ClientTest {

    public static void main(String[] args){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ClientConfig.class);
        TestService testService = context.getBean(TestService.class);
        testService.printResult();
        context.close();
    }
}

启动服务测试

(1)启动Zookeeper,这里,为了演示简单,就直接在我本机启动单机Zookeeper好了,启动后的效果如下图所示。

rpc-2022-06-25-002

(2)启动服务提供者ServerTest类,启动后输出的日志信息如下所示。

13:43:36,876  INFO ConnectionStateManager:228 - State change: CONNECTED
13:43:36,905  INFO RpcClient:79 - use cglib dynamic proxy...
13:43:36,942  INFO CuratorFrameworkImpl:235 - Starting
13:43:36,943  INFO ZooKeeper:868 - Initiating client connection, connectString=127.0.0.1:2181 

可以看到,服务提供者已经将发布的服务注册到了Zookeeper中。

(3)登录Zookeeper客户端查看Zookeeper中注册的服务,如下所示。

  • 查看HelloService接口发布的服务信息
[zk: localhost:2181(CONNECTED) 5] get /binghe_rpc/io.binghe.rpc.test.client.HelloService#1.0.0/65eb0d7f-4bf7-4a0a-bafc-1b7e0e030353

{"name":"io.binghe.rpc.test.client.HelloService#1.0.0","id":"65eb0d7f-4bf7-4a0a-bafc-1b7e0e030353","address":"127.0.0.1","port":18866,"sslPort":null,"payload":{"@class":"io.binghe.rpc.center.meta.ServiceMeta","serviceName":"io.binghe.rpc.test.client.HelloService","serviceVersion":"1.0.0","serviceAddr":"127.0.0.1","servicePort":18866},"registrationTimeUTC":1656135817627,"serviceType":"DYNAMIC","uriSpec":null,"enabled":true}
  • 查看HelloPersonService接口发布的服务信息
[zk: localhost:2181(CONNECTED) 7] get /binghe_rpc/io.binghe.rpc.test.client.HelloPersonService#1.0.0/882a5cdb-f581-4a83-8d56-800a8f14e831

{"name":"io.binghe.rpc.test.client.HelloPersonService#1.0.0","id":"882a5cdb-f581-4a83-8d56-800a8f14e831","address":"127.0.0.1","port":18866,"sslPort":null,"payload":{"@class":"io.binghe.rpc.center.meta.ServiceMeta","serviceName":"io.binghe.rpc.test.client.HelloPersonService","serviceVersion":"1.0.0","serviceAddr":"127.0.0.1","servicePort":18866},"registrationTimeUTC":1656135817274,"serviceType":"DYNAMIC","uriSpec":null,"enabled":true}

通过Zookeeper客户端可以看出,HelloService接口和HelloPersonService接口发布的服务都已经被注册到Zookeeper了。

(4)启动服务提供者ClientTest类,实现RPC调用,输出的日志信息如下所示。

13:56:47,391  INFO ConnectionStateManager:228 - State change: CONNECTED
13:56:47,488  INFO RpcClient:76 - use javassist dynamic proxy...
13:56:47,518  INFO ConnectionStateManager:228 - State change: CONNECTED
13:56:47,545  INFO RpcClient:79 - use cglib dynamic proxy...
13:56:48,253  INFO RpcConsumer:85 - connect rpc server 127.0.0.1 on port 18866 success.
Hello! binghe
Hello! binghe001 binghe002
=================================
0 binghe
1 binghe

可以看到,在ClientTest类的命令行输出了远程调用的结果信息。并输出了调用HelloService接口的远程方法使用的是javassist动态代理。调用HelloPersonService接口的远程方法使用的是cglib动态代理。

咱们一起手撸的RPC框架其实还有很多非常强大的功能,这里,就不一一演示了,后面咱们都会一起手撸来实现它。

一点点建议

咱们这个专栏属于实战类型比较强的专栏,加上咱们一起从零开始手撸的RPC框架会涉及众多的知识点。正所谓纸上得来终觉浅,绝知此事要躬行。冰河希望大家在学习这个专栏的时候勤动手,跟着专栏一起实现代码。期间要多动脑,多总结,这样才能够加深对各项知识点的理解。切忌眼高手低,学了半天却最终啥也没学会。

好了,今天的开篇文章就到这儿吧,如果文章对你有点帮助,记得给冰河一键三连哦,欢迎将文章转发给更多的小伙伴,冰河将不胜感激~~

一起出发

我会将《RPC手撸专栏》的源码获取方式放到知识星球中,同时在微信上会创建专门的知识星球群,冰河会在知识星球上和星球群里解答球友的提问。

欢迎大家将文章或者星球转发到群里或者朋友圈,这些内容冰河将用下班、周末、假期的时间不断完善。通过视频+文章+知识小册+直播+作业的形式与你一起学习、提升和进步,最终的目的就是提升你的技术实力,让你在职场走的更远,顺便多赚些钱。

星球提供的服务

冰河整理了星球提供的一些服务,如下所示。

加入星球,你将获得:

1.学习从零开始手撸可用于实际场景的高性能RPC框架项目(火热进行中)

2.学习SpringCloud Alibaba实战项目—从零开发微服务项目

3.学习高并发、大流量业务场景的解决方案,体验大厂真正的高并发、大流量的业务场景

4.学习进大厂必备技能:性能调优、并发编程、分布式、微服务、框架源码、中间件开发、项目实战

5.提供站点 https://binghe.site 所有学习内容的指导、帮助

6.GitHub:https://github.com/binghe001/BingheGuide - 非常有价值的技术资料仓库,包括冰河所有的博客开放案例代码

7.可以发送你的简历到我的邮箱,提供简历批阅服务

8.提供技术问题、系统架构、学习成长、晋升答辩等各项内容的回答

9.定期的整理和分享出各类专属星球的技术小册、电子书、编程视频、PDF文件

10.定期组织技术直播分享,传道、授业、解惑,指导阶段瓶颈突破技巧

如何加入星球

加入星球:扫描优惠券二维码即可加入星球。

sa-2022-04-21-007

  • 扫码 :通过扫描优惠券二维码加入星球。
  • 链接 :打开链接 http://m6z.cn/6aeFbs 加入星球。
  • 回复 :在公众号 冰河技术 回复 星球 领取优惠券加入星球。

特别提醒: 苹果用户进圈或续费,请加微信 hacker_binghe 扫二维码,或者去公众号 冰河技术 回复 星球 扫二维码加入星球。

好了,今天就到这儿吧,我是冰河,我们下期见~~

写在最后

如果你觉得冰河写的还不错,请微信搜索并关注「 冰河技术 」微信公众号,跟冰河学习高并发、分布式、微服务、大数据、互联网和云原生技术,「 冰河技术 」微信公众号更新了大量技术专题,每一篇技术文章干货满满!不少读者已经通过阅读「 冰河技术 」微信公众号文章,吊打面试官,成功跳槽到大厂;也有不少读者实现了技术上的飞跃,成为公司的技术骨干!如果你也想像他们一样提升自己的能力,实现技术能力的飞跃,进大厂,升职加薪,那就关注「 冰河技术 」微信公众号吧,每天更新超硬核技术干货,让你对如何提升技术能力不再迷茫!

加群交流

本群的宗旨是给大家提供一个良好的技术学习交流平台,所以杜绝一切广告!由于微信群人满 100 之后无法加入,请扫描下方二维码先添加作者 “冰河” 微信(hacker_binghe),备注:学习加群。

冰河微信

公众号

分享各种编程语言、开发技术、分布式与微服务架构、分布式数据库、分布式事务、云原生、大数据与云计算技术和渗透技术。另外,还会分享各种面试题和面试技巧。内容在 冰河技术 微信公众号首发,强烈建议大家关注。

公众号:冰河技术

星球

加入星球 冰河技术,可以获得本站点所有学习内容的指导与帮助。如果你遇到不能独立解决的问题,也可以添加冰河的微信:hacker_binghe, 我们一起沟通交流。另外,在星球中不只能学到实用的硬核技术,还能学习实战项目!

关注 冰河技术公众号,回复 星球 可以获取入场优惠券。

知识星球:冰河技术

在 GitHub 上编辑此页
上次更新: 2026/4/29 16:18
Contributors: binghe001
阅读全文
×

扫码或搜索:冰河技术
发送:290992
即可立即永久解锁本站全部文章

星球会员
跳转链接