为什么说要搞定微服务架构,先搞定 RPC 框架?

RPC 微服务   2016-08-25 21:41:06 发布
您的评价:
     
3.0
收藏     0收藏
文件夹
标签
(多个标签用逗号分隔)

第一章聊了【 “为什么要进行服务化,服务化究竟解决什么问题”

第二章聊了【 “微服务的服务粒度选型”

今天开始聊一些 微服务的实践 ,第一块, RPC 框架的原理及实践 ,为什么说要搞定微服务架构,先搞定RPC框架呢?

一、需求缘起

服务化的一个好处就是,不限定服务的提供方使用什么技术选型,能够实现大公司跨团队的技术解耦 ,如下图:

服务 A 是欧洲团队提供服务,欧洲团队的技术背景是 Java ,可以用 Java 实现服务;

服务 B 是美洲团队提供服务,可以用 C++ 实现服务;

服务 C 是中国团队提供服务,可以用 Go 实现服务;

服务的上游调用方,按照接口、协议即可完成对远端服务的调用。

但实际上, 99.9% 的公司的团队规模有限,技术团队人数也有限,基本是使用同一套技术体系来调用和提供服务 的:

这样的话, 如果没有统一的服务框架, RPC 框架 , 各个团队的服务提供方就需要各自实现一套序列化、反序列化、网络框架、连接池、收发线程、超时处理、状态机等“业务之外”的重复技术劳动 ,造成整体的低效。所以, 统一 RPC 框架 把上述“业务之外”的技术劳动统一处理, 是服务化首要解决的问题 。

在达成【“使用统一的 RPC 框架”是正确的道路】这个一致的前提下,本文期望用简单通俗的言语简述一下一个通用 RPC 框架的技术点与实现。

二、 RPC 背景与过程

什么是 RPC ( Remote Procedure Call Protocol ),远程过程调用?

先来看下什么是本地函数调用,当我们写下:

int result = Add(1, 2);

这段代码的时候,我们知道,我们传入了 1 , 2 两个入参数,调用了本地代码段中的一个 Add 函数,得到了 result 出参。此时, 传入数据,传出数据,代码段在同一个进程空间里,这是本地函数调用 。

那有没有办法,我们能够调用一个跨进程(所以叫 “ 远程 ” ,典型的,这个进程部署在另一台服务器上)的函数呢 ?

 

最容易想到的, 两个进程约定一个协议格式,使用 Socket 通信,来传输【入参】【调用哪个函数】【出参】 。

假设请求报文协议是一个 11 字节的字节流:

( 1 )前 3 个字节填入函数名

( 2 )中间 4 个字节填入第一个参数

( 3 )末尾 4 个字节填入第二个参数

同时可以设计响应报文协议是一个 4 字节的字节流:

即处理结果。

调用方的代码可能变为:

request = MakePacket(“add”, 1, 2);

SendRequest_ToService_B(request);

response = RecieveRespnse_FromService_B();

int result = unMakePacket(respnse);

简单解释一下:

( 1 )讲传入参数变为字节流

( 2 )将字节流发给服务 B

( 3 )从服务 B 接受返回字节流

( 4 )将返回字节流变为传出参数

服务方的代码可能变为:

request = RecieveRequest();

args/function = unMakePacket(request);

result = Add(1, 2);

response = MakePacket(result);

SendResponse(response);

这个过程也很好理解:

( 1 )服务端收到字节流

( 2 )将字节流转为函数名与参数

( 3 )本地调用函数得到结果

( 4 )将结果转变为字节流

( 5 )将字节流发送给调用方

这个过程用一张图描述如上,调用方与服务方的处理步骤都是非常清晰的。 这个过程存在最大的问题是什么呢?

回答:调用方太麻烦了,每次都要关注很多底层细节

( 1 )入参到字节流的转化,即序列化应用层协议细节

( 2 ) socket 发送,即网络传输协议细节

( 3 ) socket 接受

( 4 )字节流到出参的转化,即反序列化应用层协议细节

能不能调用层不关注这个细节呢?

回答:可以, RPC 框架就是解决这个问题的,它能够让调用方“像调用本地函数一样调用远端的函数(服务)” 。

三、 RPC 框架职责

通过上面的讨论, RPC 框架要向调用方屏蔽各种复杂性,要向服务提供方也屏蔽各类复杂性 :

( 1 )调用方感觉就像调用本地函数一样

( 2 )服务提供方感觉就像实现一个本地函数一样来实现服务

所以整个 RPC 框架又分为 client 部分与 server 部分,负责把整个非( 1 )( 2 )的各类复杂性屏蔽,这些复杂性就是 RPC 框架的职责。

再细化一些, client 端又包含:序列化、反序列化、连接池管理、负载均衡、故障转移、队列管理,超时管理、异步管理等等等等职责。

server 端包含:服务端组件、服务端收发包队列、 io 线程、工作线程、序列化反序列化、上下文管理器、超时管理、异步回调等等等等职责。

however ,因为篇幅有限,这些细节不做深入展开。

 

四、结论

( 1 ) RPC 框架是架构微服务化的首要基础组件 ,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节

( 2 ) RPC 框架的 职责 是: 让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务

 

来自:http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959553&idx=1&sn=c1084e91875721c5f6baf544450afa38&scene=0

 

扩展阅读

今日头条架构演进之路
支撑微博千亿调用的轻量级RPC框架:Motan
微服务架构的基础框架选择:Spring Cloud还是Dubbo?
storm简介
谈谈如何使用Netty开发实现高性能的RPC服务器

为您推荐

iOS 第三方开源库-----AFNetworking
Effective Go 中文版
贝叶斯分类
web安全实战
基于fis的前端模块化和工程化方案

更多

RPC
微服务
相关文档  — 更多
相关经验  — 更多
相关讨论  — 更多