RPC过程理念详解

RPC过程理念详解【updating…】

1.什么是进程通信?

在介绍RPC之前,先看进程通信——IPC,以下引自wikipedia

In computer science, inter-process communication or interprocess communication (IPC) refers specifically to the mechanisms an operating system provides to allow the processes to manage shared data. Typically, applications can use IPC, categorized as clients and servers, where the client requests data and the server responds to client requests.

【译:在计算机科学中,进程内部通信(IPC)通常指的是一个操作系统提供允许进程管理共享数据的机制。典型的,应用能够使用IPC将机器分为客户机(client)和服务器(server),其中客户机请求数据并且服务器响应客户端的请求】

2.什么是RPC

以下引自 wikipedia

In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it were a normal (local) procedure call, without the programmer explicitly coding the details for the remote interaction. That is, the programmer writes essentially the same code whether the subroutine is local to the executing program, or remote.[1] This is a form of client–server interaction (caller is client, executor is server), typically implemented via a request–response message-passing system. In the object-oriented programming paradigm, RPC calls are represented by remote method invocation (RMI). The RPC model implies a level of location transparency, namely that calling procedures is largely the same whether it is local or remote, but usually they are not identical, so local calls can be distinguished from remote calls. Remote calls are usually orders of magnitude slower and less reliable than local calls, so distinguishing them is important.

在分布式计算中,一个远程调用(RPC)指的是:当一个程序调用一个在不同地址空间(典型的情况就是在另外的一台共享网络的计算机)的子程序,这个子程序被编码成好像是一个正常的本地(local)程序调用,没有经过程序员显式的为远程交互而做的编码细节。也就是说,无论子程序是在本地还是在远端执行,程序员在本质上编写的代码都是相同的。这是一个client-server互动的过程(caller 是client,executor是server),典型实现是通过一个request-response消息传递机制【划重点】。在面向对象的编程范式中,RPC调用由远程方法调用RMI【划重点】表示。RPC模型暗示了位置透明,即调用过程很大程度上是相同的(无论是本地还是远程调用),但是通常来说,他们又不相同,因此需要将本地调用和远程调用区分开。远程调用通常比本地调用慢几个数量级,并且远程调用更不可靠,所以将其区分开是很重要的。

RPCs are a form of inter-process communication (IPC), in that different processes have different address spaces: if on the same host machine, they have distinct virtual address spaces, even though the physical address space is the same; while if they are on different hosts, the physical address space is different. Many different (often incompatible) technologies have been used to implement the concept.

RPCs是IPC(inter-process communication:进程间通信)的一种形式,因为不同的进程有着不同的地址空间:如果在相同的主机上,它们有着不同的虚拟地址空间,尽管物理地址空间是相同的,然而如果它们在不同的主机上,物理的地址空间就是不同的。许多不同的(经常是不兼容的)科技被用于实现此概念。

Message passing

RPC is a request–response protocol. An RPC is initiated by the client, which sends a request message to a known remote server to execute a specified procedure with supplied parameters. The remote server sends a response to the client, and the application continues its process. While the server is processing the call, the client is blocked (it waits until the server has finished processing before resuming execution), unless the client sends an asynchronous request to the server, such as an XMLHttpRequest. There are many variations and subtleties in various implementations, resulting in a variety of different (incompatible) RPC protocols.

An important difference between remote procedure calls and local calls is that remote calls can fail because of unpredictable network problems. Also, callers generally must deal with such failures without knowing whether the remote procedure was actually invoked. Idempotent procedures (those that have no additional effects if called more than once) are easily handled, but enough difficulties remain that code to call remote procedures is often confined to carefully written low-level subsystems.

RPC是一个request-response协议。一个RPC是由client初始化,它发送一个请求消息给已知的远端服务器,让其执行一个具体的程序,使用提供的参数。远端服务器发送一个响应到客户端,并且应用继续处理它自己的进程。当服务器正在处理调用时,客户端是阻塞的(它一直等到服务器完成进程再开始执行),除非客户端发送一个匿名的请求给服务器,诸如XMLHttpRequest。在不同的实现中有许多微妙的变化,导致各种不同(不兼容)的RPC协议。
在RPC以及本地调用之间的一个种重要区别是:远程调用可能会因为不可预知的网络问题失败。同样,调用者通常必须处理此类失败,尽管他们并不知道是否远程调用已经执行完了。幂等的过程是容易处理的,但是仍然存在巨大的困难:编写远程调用过程时,经常被限制于在精心编写低层次的子系统。

Sequence of events
  1. The client calls the client stub. The call is a local procedure call, with parameters pushed on to the stack in the normal way.
  2. The client stub packs the parameters into a message and makes a system call to send the message. Packing the parameters is called marshalling.
  3. The client’s local operating system sends the message from the client machine to the server machine.
  4. The local operating system on the server machine passes the incoming packets to the server stub.
  5. The server stub unpacks the parameters from the message. Unpacking the parameters is called unmarshalling.
  6. Finally, the server stub calls the server procedure. The reply traces the same steps in the reverse direction.

调用过程

  • 1.客户端调用客户端存根。这个调用是一个本地过程调用,将参数以正常的方式写入到栈中。
  • 2.客户端存根打包参数到一个消息中并且让系统调用发送消息。打包参数被称之为集结。
  • 3.客户端的本地操作系统发送这个消息从客户端机器到服务端机器。
  • 4.远程主机的操作系统传递到达的包到server stub(服务器存根)
  • 5.server stub服务器存根解包,并从消息中获取参数。解包参数的过程又被称之为unmarshalling
  • 6.最终,server stub调用服务器程序。回复过程与此相反,但主要步骤相同。
3.

啰里啰嗦的介绍了一大堆,是不是还没有理解RPC是什么? 不用担心,上面只是一个术语概念的阐述。下面会对RPC 进行一个详细的阐述。

4. 为什么需要远程调用?

单集群,单线程的服务已经不能够满足业务的发展了,那么就会使用多集群,多线程。但是多个集群和多线程之间就需要使用远程调用。【因为各个线程,机器之间需要传递消息。】
举例来说:如今的大型网站都是分布式部署的。当用户下单时:可能涉及到物流、支付、库存、红包等多个系统,而多个系统又是分别部署在不同的集群的机器上的,不同的集群分别由不同的团队负责。而要想实现下单流程,就需要用到远程调用。

下单{
    库存->减少库存
    支付->扣款
    红包->红包抵用
    物流->生成物流信息
}

RPC 是指计算机 A 上的进程,调用另外一台计算机 B 上的进程,其中 A 上的调用进程被挂起,而 B 上的被调用进程开始执行,当值返回给 A 时,A 进程继续执行。调用方可以通过使用参数将信息传送给被调用方,而后可以通过传回的结果得到信息。而这一过程,对于开发人员来说是透明的。

在这里插入图片描述

由于各服务部署在不同机器上,要想在服务间进行远程调用免不了网络通信过程,服务消费方每调用一个服务都要写很多网络通信相关的代码,不仅复杂而且极易出错。如果有一种方式能让我们像调用本地服务一样调用远程服务,而让调用者对网络通信这些细节透明,那么将大大提高生产力,比如服务消费方在执行orderService.buy("HHKB键盘")时,实质上调用的是远端的服务。这种方式其实就是RPC。而提供了这种功能的工具我们称之为RPC框架。

在RPC框架中主要有三个角色:ProviderConsumerRegistry。如下图所示:
在这里插入图片描述

RPC Server就是服务提供方;RPC Client就是服务需求方; 而Registry 就是一个注册中心。

在这里插入图片描述

服务提供者启动后主动向注册中心注册机器ip、port 以及提供的服务列表; 服务消费者启动时向注册中心获取服务提供方地址列表,可实现软负载均衡和 Failover

5. 实现RPC需要用到的技术

一个成熟的RPC框架需要考虑的问题有很多,这里只介绍实现一个远程调用需要用到的基本技术,感兴趣的朋友可以找一些开源的RPC框架代码来看下。

5.1 动态代理

生成 client stub和server stub需要用到Java 动态代理技术,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。

5.2 序列化

为了能在网络上传输和接收 Java对象,我们需要对它进行序列化和反序列化操作。
可以使用Java原生的序列化机制,但是效率非常低,推荐使用一些开源的、成熟的序列化技术,例如:protobuf、Thrift、hessian、Kryo、Msgpack

5.3 NIO

当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推荐使用Netty 作为底层通信框架。

5.4 服务注册中心

可选技术: Redis、Zookeeper、Consul、Etcd

想起我曾经面试的时候,一个面试官问我的问题:你觉得可以用redis 替换 zookeeper么?那么现在你觉得呢?

6.参考文章
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值