快捷搜索:  汽车  科技

java语言程序设计基础篇(手写JavaRPC框架之设计思路)

java语言程序设计基础篇(手写JavaRPC框架之设计思路)作为一个有经验的开发者,都会清楚,我们写代码就如同写文章。好的代码一定是思路清晰的,思路清晰的代码耦合性一定是很少的。我们举一个例子,最近大环境不好,大厂裁员较多,很多小伙伴都要面试吧,就举一个面试的问题,通过这个例子来解释下什么是架构。怎么理解架构?本篇文章主要会围绕以下三方面展开叙述,希望在通读全篇后,大家都能在脑子中形成对这三个方面的认识,因为下面的三个方面是通信层搭建的主要指导思想。上一篇我们也说了,实现RPC可以基于http也可以基于tcp。他们各有各的好处,如果是基于http其实我们的挑战就相对比较小一些,因为实现http的协议已经是在太多了,我们只用通过代理进行层层封装即可,而我们之所以要自己实现通信协议就是。作为Java程序猿还是要对底层通信协议的具体实现有点了解的。如果不了解的话也没关系,你只要知道他是二进制数据就可以了。我们一步一步通过代码编写将二进制数据转换成我们Ja

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(1)

天下代码一大抄 抄来抄去有提高 看你会抄不会抄!

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(2)

一、前言

隔壁老李又在喷我了: "完犊子了,小编这绝对是为了骗粉丝,而水的一篇文章,到了第二篇竟然还没有开始写代码,又是一篇纯概念文章"。

我也想写代码,但是在没有讲清楚思路之前,一定不要上来就蛮干,不然就毫无设计可言了。小编向各位观众老爷保证,下一篇文章绝对上代码。

本篇文章非常重要,这是我们本系列文章中的重中之重,本篇文章的主要内容就是设计我们自己的通信协议及架构,可以这样说如果没有了本篇文章的内容,就不可能实现RPC。因为RPC的最基本要求就是能实现远程通信。本篇文章是讲述通信层的设计思路,下一篇就是实战的编写。(ps: 其实下一篇比较好写,因为代码我早就写完了嘻嘻,而这一篇竟然酝酿了一周还写的...不忍直视)

二、目标

本篇文章主要会围绕以下三方面展开叙述,希望在通读全篇后,大家都能在脑子中形成对这三个方面的认识,因为下面的三个方面是通信层搭建的主要指导思想。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(3)

  1. 设计我们自己的通信协议
  2. 确定我们的通信层的架构
  3. 确定我们的工程结构
2.1 为什么我们要设计自己的通信协议呢?

上一篇我们也说了,实现RPC可以基于http也可以基于tcp。他们各有各的好处,如果是基于http其实我们的挑战就相对比较小一些,因为实现http的协议已经是在太多了,我们只用通过代理进行层层封装即可,而我们之所以要自己实现通信协议就是。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(4)

作为Java程序猿还是要对底层通信协议的具体实现有点了解的。如果不了解的话也没关系,你只要知道他是二进制数据就可以了。我们一步一步通过代码编写将二进制数据转换成我们Java语言能够认识的数据就好了。如果这个过程你学会了,那么一通百通,http如何实现的其实大概也能知道猜到一点。

2.2 为什么要讲通信层的架构?

怎么理解架构?

作为一个有经验的开发者,都会清楚,我们写代码就如同写文章。好的代码一定是思路清晰的,思路清晰的代码耦合性一定是很少的。我们举一个例子,最近大环境不好,大厂裁员较多,很多小伙伴都要面试吧,就举一个面试的问题,通过这个例子来解释下什么是架构。

  • 面试官说: 同学做一下自我介绍吧。

首先我们不能懵啊,如果懵了就说明没有头绪了,这样就容易讲乱,没有头绪在开发过程中的体现就是代码写的杂乱。比如你在介绍家乡的时候突然穿插了一下爱好,而在讲爱好的时候,又穿插的讲了一下家乡。这样就会导致主题不分明,听者会感觉会乱。所以这里我们就需要 单一职责。首先定义清楚你的讲话的结构,然后每个结构点就一个职责。

如下我们设计的面试架构是这些点:

姓名,家乡,大学,专业,兴趣爱好,单位职称 .

下面我们只用实现每个点的内容(主题清晰),最终将他组装成完成的自我介绍回答;

// 姓名,家乡,大学,专业,兴趣爱好,单位职称 public interface Introduce{ // 这是一个介绍类 负责介绍自己 public void introduce(); } public class XiaoMing implements Introduce{ // 将任务进行拆分 拆分的维度是逻辑顺序 然后抽离出方法 抽离的维度是单一职责。 // 这样的好处是工能化 模块化 便于复用。 public void introduce(){ sout("我叫小明"); // 主题介绍家乡 introduceHometown(); // 主题介绍学校 introduceSchool(); // 主题介绍专业 introduceMajor(); // 主题介绍兴趣爱好 introduceInterest(); sout("从业xx年 目前在公司的职称是xxx"); } private void introduceHometown(){ sout("我的老家是河南南阳") sout("我的家乡就坐落在河南南阳邓州市") sout("邓州市一个美丽的城市 是中国邓姓的发源地") sout("邓州也是河南境内人口最多的一个县级城市") } private void introduceSchool(){ sout("我大学是在河南大学") sout("河南大学简称河大,是一所位于中国河南省开封市涵盖文、史、哲、经、管、 法、理、工、医、农、教育、艺术等12个学科门类的省部共建型综合性公立大学。") } private void introduceMajor(){ sout("我的专业是计算机与信息工程") } private void introduceInterest(){ sout("我的个人爱好是写博客、打游戏、做美食、偶会也会跑跑步") } }

有没有发现单一职责的设计,会很大程度提高我们的代码利用率呢? 我们要的就是这个效果,所以我们在开始编码之前,最好提前定义清楚我们的架构是怎么样的。

上面的例子,不知道小编有没有给大家解释清楚,但是总归我们的目的,是要在设计的时候就要明确责任划分,尽可能的单一职责。尽可能的解耦。

要想设计一个好的框架,首先一定要有一个好的架构设计。这一点我们可以直接参考dubbo的设计架构。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(5)

上半部分不用看,我们只用看通信层就好了。

  • serialize 序列化层,负责将二进制数据转成Java认识的数据类型
  • transport 传输层,负责发送和接收数据
  • exchange 转换层,通信层和业务逻辑层转换的地方。
  • protocol 协议层,告诉serialize用什么协议来encode和decode数据的

所以说,天下代码一大抄,抄来抄去有提高,就看你会抄不会抄了。 我们的设计就主要参考dubbo来了。

2.3 工程结构设计

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(6)

目前市面上的框架基本上都是自己来定制通信层,而通信层基本也不会单独的提供出去。但是本系列小编希望是通信层和业务能分开。通信层可以做RPC也可以利用通信层去实现消息队列或者是web容器。所以因为这个设计,就要求我们的项目能单独的去发布。所以我们整体的项目结构是由三个部分组成的,如下。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(7)

三、核心知识点3.1 通信层协议定义

什么是协议呢?

其实就是规则,我们按照什么样的方式将二进制数据转换成Java对象。

如下图,我们的一条数据会分为4个部分

  1. 第一部分占用一个字节是协议标记,用来标记是http协议还是自定义协议。
  2. 第二部分占用一个字节是序列化标记,用来确定我们的真实报文使用什么来进行序列化和反序列化。
  3. 第三部分占用四个字节,用来表示数据的字节长度,确定真实报文的长度。
  4. 第四部分长度不固定,是真实的传输数据。最终会通过第二部分将这些二进制数据转换成Java对象。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(8)

以上就是我们定义的数据解析协议,通过上面的规则将二进制数据,转换成Java对象。

读到这里你有没有一点收获呢?

有没有发现,其实协议的概念,其实很简单,就是一个规则或者说是约定。能让彼此都互相认识的一个约定。

在本系列中,我们会自定义一个协议,同时也会兼容支持http协议。如果感兴趣,就跟着小编一起coding吧。

3.2 通信层架构设计

前面说了,我们是站在巨人的肩膀上的,根据dubbo的设计思路和我们的目标,我们也来画一张图。

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(9)

我们的最终架构如上图。

作用 serialize 序列化协议层 包含了多种序列化协议 codec 数据解码器和编码器的具体实现层 exchange API交换层 业务层API和通信层API交换数据的地方,负责将业务数据转换成二进制数据发送,也负责将二进制数据转换成业务数据返回 model 基础数据模型 business 提供给开发者用来实现业务的api api Fluent 风格的api 这种风格的好处是不需要记住接下来的步骤和方法

3.3 工程结构

java语言程序设计基础篇(手写JavaRPC框架之设计思路)(10)

为了符合前面我们定的目标,所以我们要有一个大的工程。

项目名 职责 mojito-net 底层通信模块 mojito-rpc rpc模块 mojito-spring-boot-starter springboot自动化配置

由此我们的项目诞生了。下一篇我们就开始手撸代码吧。

. ├── README.md ├── mojito-net │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ └── resources │ └── test │ └── java ├── mojito-rpc │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ └── resources │ └── test │ └── java ├── mojito-spring-boot-starter │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ └── resources │ └── test │ └── java └── pom.xml

猜您喜欢: