RPC框架基础概念理解以及使用初体验
RPC:Remote Procedure Call(远程服务调用)
RPC是做什么的
通过RPC框架机器A某个进程可以通过网络调用机器B上的进程方法,就像在本地上调用一样。
RPC可以基于HTTP或者TCP协议通信,TCP协议相对性能较高。
调用图示(引用zhanglijun童鞋的图)
图片描述:
- client发出调用方法(服务)的请求
- client stub作为中转站,进行
请求接口、方法、参数以及服务地址、请求Id
的封装,包装成RequestMessage
对象、序列化——编码,最后传输到网络上去 - 服务端(service)经过网络接受到RequestMessage
- 首先server stub进行字节流的反序列化、解析
requestMessage
——解码,最后将请求转发给server - server调用
method(...)
,返回结果给server stub - server stub将
result
、返回状态码、请求id等进行包装成ResponseMessage
、序列化——编码、传输 - client stub得到字节流,进行反序列化、解析
ResponseMessage
——解码,将结果返给client - client最终得到结果
RPC框架就是将2-7这几个步骤封装起来,帮忙处理网络IO、编解码、序列化、服务寻址等工作,这些工作对于调用方和服务方都是透明的。由此,我们也可以得出结论,我们就需要使用代码实现2-7步骤所需要处理的工作。下面列举实现一个轻量级RPC框架所需要解决的几个问题。
RPC框架的实现需要解决的几个问题
如果想实现一个轻量级rpc框架需要解决什么问题呢:
请求封装问题
机器A想要调用机器B上面的方法method()
,那么A机器就需要详细描述自己的需求——要调用那个ip上那个端口的进程、调用哪个service,这些都需要描述清楚。
详细如下:
- 接口名称,一个接口提供一种服务,比如
HelloworldService
- 方法名称,定位一个接口内的某个方法
- 参数——类型与值,client调用就需要client指定入参,服务端是肯定不知道这些的
- 超时时间
- requestId,每一个client发出请求时都需要绑定一个唯一指定requestId,这是因为在并发请求的时候一个服务方可能服务多个client的请求,有了这个requestId,client stub才能将返回结果发放给特定的请求线程而不会混淆。
返回消息对象封装问题
- 返回值
- 状态code,表示这次请求成功与否
- requestid
序列化的问题
网络IO需要传输请求消息对象以及响应消息对象,这样才能达到双方通信的目的。但是网络是以字节(byte)准确的说是比特传输信息的,因此需要一种技术将对象转换成字节(序列化),以及再将字节转换成对象(反序列化)。java自身是有序列化工具的,借助ObjectOutputStream
等类就可以序列化对象。但是他的性能、拓展性都不是很好,因此一般借助于第三方的序列化工具
目前,互联网公司主流使用protobuf
、thrift
、jackson
、hessian
等
网络通信问题
消息序列化之后就是网络通信了,使用java nio是可以实现一个通信框架的,但这属于高难度动作——专家模式。就码农way而言,使用netty通信框架,省事省力,经过测试完善的框架也不容易出错
服务发布的问题
一般情况,如果客户端依赖的服务挂掉或者切换地址等,那么客户端可能就无法工作或者需要改变配置。为了能够达到自动切换服务、寻址等问题,就需要一个服务注册和发现功能的框架。市面上流行的是zookeeper,他可以将上线的服务注册进去,提供给客户端调用。zookeeper会不断对服务进行心跳检测,一旦服务挂掉,就会在注册中心把他消掉。客户端可以在注册中心切换到其他可用的服务
zookeeper的服务注册格式:/{service}/{version}/{ip:port}
关于RPC框架的初体验
这里并不是商用的RPC框架,没有服务治理、插件支持等功能,使用的是@黄勇
写的轻量级分布式 RPC 框架,目的在于理解rpc框架核心代码的功能模块结构、相关技术选型以及如何运行等几个问题
关于框架的几点理解
rpc-sample-api
模块,定义了服务接口,这个代码无论客户端和服务端都需要用到的rpc-sample-server
模块,对rpc-sample-api的接口进行了实现,启动RpcBootstrap
类,就会将rpc-server模块写的RPCServer和注入容器中。这个模块相当于前面LBS大大图片里的server端,真正提供服务的实现的模块rpc-server
模块,相当于server stub
,他负责将扫描到的被@RpcService
注解的类注册到zookeeper,对请求、返回值消息进行序列化、编解码,处理请求等rpc-client
模块,就相当于client stub
,他负责将client的请求进行编码,发送出去,到zookeeper注册中心去发现可用服务,进行调用rpc-register-zookeeper
模块,该模块的ZookeeperServiceDiscovery
类为rpc-client
模块提供服务发现功能。而zookeeperServiceRegistry
类为rpc-server
模块提供了服务注册的功能。其实就是实例化一个ZkClient
对zookeeper服务进行访问,然后对zookeeper进行注册服务和发现服务rpc-common
模块,定义了一些工具类和消息对象。消息对象用于封装请求和返回值消息,工具类主要用于序列化、编解码等功能
最后,由于本人之前并没有对netty
和protobuf
等工具有详细了解,代码细节无法详述,这里只是简单地归纳出该框架的几点模块关系以及作用
运行步骤
这里主要是本人运行该框架的几个步骤,其实非常简单
- 下载源码到IDEA,地址
https://gitee.com/huangyong/rpc.git
- 安装、启动zookeeper服务,不了解的童鞋可以参考 zookeeper安装和使用 windows环境
- 启动rpc-server,就是
rpc-sample-server
下的RpcBootstrap
类即可,这边服务端就算启用了
- 接下来运行
rpc-sample-client
下面的几个类,可以看到客户端代码其实是通过RpcProxy.create(...)
获取实例,并得到了返回值
小结
本文总结了RPC服务是做什么的以及RPC框架相关的几个概念,接下来描述了如果我们自己写RPC框架需要解决的几个问题。并且使用@黄勇
童鞋的开源demo,进行rpc使用的初体验,勉强对rpc框架有了基本的认识。如果想深入使用、了解的童鞋可以尝试使用阿里的hsf、谷歌的gRpc构建自己的微服务应用或者分布式计算等
参考
RPC框架基础概念理解以及使用初体验的更多相关文章
- RPC 框架 Dubbo 从理解到使用(二)
本篇文章为系列文章,未读第一集的同学请猛戳这里:RPC 框架 Dubbo 从理解到使用(一) 本篇文章讲解 Dubbo 支持的注册中心.Dubbo 负载均衡策略和 Dubbo 控制台的安装. 注册中心 ...
- RPC 框架 Dubbo 从理解到使用(一)
技术架构演变 单一应用架构 通俗地讲,"单体应用(monolith application)"就是将应用程序的所有功能都打包成一个独立的单元.当网站流量很小时,只需一个应用,将所有 ...
- WCF分布式开发步步为赢(1):WCF分布式框架基础概念
众所周知,系统间的低耦合一直是大型企业应用系统集成追寻的目标,SOA面向服务架构的出现为我们的如何利用现有企业系统资源进行企业ERP系统设计和实现提供了重要的参考原则.SOA如此炙手可热,各大厂商都推 ...
- (一)SpringBoot基础篇- 介绍及HelloWorld初体验
1.SpringBoot介绍: 根据官方SpringBoot文档描述,BUILD ANYTHING WITH SPRING BOOT (用SPRING BOOT构建任何东西,很牛X呀!),下面是官方文 ...
- (一)SpringBoot2.0基础篇- 介绍及HelloWorld初体验
1.SpringBoot介绍: 根据官方SpringBoot文档描述,BUILD ANYTHING WITH SPRING BOOT (用SPRING BOOT构建任何东西,很牛X呀!),下面是官方文 ...
- Elasticsearch基础概念理解
熟悉ES中的几个关键概念: 节点(Node):一个elasticsearch运行的实例,其实就是一个java进程.一般情况下,一台机器运行在一台机器上. 集群(Cluster): 好几个有相同集群名称 ...
- Struts2框架基础概念总结
一.struts2框架 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的 ...
- JAVA类与对象(一)----基础概念理解
面向对象基本概念 面向对象是一种新兴的程序设计方法,或者说是一种新的程序设计规范,其基本思想是使用对象.类.继承.封装.消息等基本概念来进行程序设计.它是从现实世界客观存在的事物(即对象)出发来构造软 ...
- 基础概念——理解IP地址和域名
从程序员角度,可以把因特网看做是世界范围内的主机集合: 1)主机集合被映射为一组32位的IP地址. 2)这个IP地址被映射为一组称为因特网域名的标识符. 3)因特网主机上的进程能够通过连接和任何其他因 ...
随机推荐
- 我使用的brackets插件
livereload atom dark theme autoprefixer auto save files on window blur beautify brackets file icons ...
- 60、Docker 学习笔记(CentOS 7.1)
#基本概念 -x86_64-minimal.tar.gz | docker import - centos:v7.mini``` 然后查看导入的镜像: ##上传镜像 >用户可以通过 docker ...
- 【input】——数据传入后台
1.复选框 checkbox <label class="checkbox"> <input type="checkbox" name=&qu ...
- matlab 摘要
matlab中的向量与矩阵 如果定义一个A = [1, 2, 3]; 则A为一个行向量 但是A(:)返回的是一个列向量 关于函数的返回值 在function [a, b, c] = fit_quadr ...
- GitKraken使用教程-基础部分(5)
7. 提交代码 1) 查看文件改动 修改了某个文件后,在程序右侧会出现已修改文件的列表(如图 1‑1),这里以Test.git 为例,修改了19264.h 的文件编码,将其改为utf8.Unstage ...
- C# 多线程之线程同步
多线程间应尽量避免同步问题,最好不要线程间共享数据.如果必须要共享数据,就需要使用同步技术,确保一次只有一个线程访问和改变共享状态. 一::lock语句 lock语句事设置锁定和接触锁定的一种简单方法 ...
- maven课程 项目管理利器-maven 1-1课程概述
1 为什么使用maven? 多框架应用项目,jar包太多且冲突,为了解决这个问题,引入maven.(类似还有ant,gradle) 2 课程概述 maven快速入门 maven核心知识 maven建造 ...
- Day1 了解web前端
Day1 了解web前端 一.职业发展路线: 前端页面制作.前端开发.前端架构师 二.1)前端工程师主要职责: 利用HTML/CSS/JavaScript等各种Web技术进行客户端产品的开发.完 ...
- web项目无法被Eclipse的Tomcat识别的解决办法
Eclipse 导入外部项目无法识别为web项目并且无法在部署到tomcat下 1.进入项目目录,找到 .project 文件: 2.找到 <natures> 代码段,在里面加入如下标签内 ...
- es6-正则
RegExp构造函数 在ES5中,RegExp构造函数的参数有两种情况. 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag). var regex = new RegExp( ...