rpc服务架构图解(架构解密从分布式到微服务)

聊聊 RPC

每个分布式系统都离不开多进程的通信问题,包括本机上多进程之间的IPC通信和基于网络的远程通信技术,后者是分布式系统架构中的核心和关键基础技术之一,就远程通信而言,抛开各种专用系统的远程通信协议如 NFS、FTP、SNMP、SMTP、POP3不说,各种通用的远程通信技术也在不断发展和变化,比如从最古老的RPC远程通信技术到曾经风靡一时的SOAP( Web Service)协议,再到后面红极一时的HTTP REST。如今,由于移动互联网和大数据时代的兴起,支持多语言与高性能传输的各种 RPC架构再次成为热点技术。

IPC通信

从严格意义上来说,一个系统由多个独立的进程组成,而且进程之间有数据交互的逻辑,那么,不管这几个进程是否被部署在一台主机上,这样的系统都可以叫作分布式系统。IPC( Inter-Process Communication)就是为了解决单主机上多进程之间的通信问题而诞生的一种古老技术。由于进程与操作系统是密切相关的,因此操作系统的不同会导致IPC的具体实现也各有不同,但不管是 Windows系统还是Linux系统,都支持以下几种进程间的通信技术。

rpc服务架构图解(架构解密从分布式到微服务)(1)

  • 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系的进程间的通信,有名管道克服了管道没有名称的限制,因此,除了有管道所具有的功能,它还允许无亲缘关系进程间的通信。由于管道存在只能承载无格式字节流及缓冲区大小受限等缺点,所以使用管道进行IPC通信的做法已经不太普遍。
    • 套接字(Socket):起初是由UNIX系统的BSD分支开发出来的,现在 Linux和 Windows系统都支持Socket, Socket如果用于本地进程间的通信,则要比普通的TCP/IP快很多,这也是一种比较通用的进程间通信的方式。
    • 共享内存:将文件映射到内存中,多个进程通过共享文件的方式使得多个进程可以访问同一块内存空间,这是最快的IPC形式。
    • 管道用作IPC通信时,有以下缺点。
    • 只支持单向数据流(双向通信就需要两个管道)。
    • 匿名管道的缓冲区是有限的(匿名管道存在于内存中,在管道创建时为缓冲区分配一个页面大小的内存)。
    • 管道所传送的是无格式的字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、记录),等等。

    命名管道(Named Pipe或FIFO)不同于匿名管道之处,在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程及FIFO的创建进程之间),因此,与FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out)的原则,对管道及FIFO的读总从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如寻址等文件的定位操作。

    Socket API原本是为网络通信设计的,但后来在Socket 的框架上发展出一种IPC机制,就是UNIX Domain Socket。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP。虽然普通的TCP Socket也可用于同一台主机的进程间通信(通过loopback地址127.0.0.1),但UNIX Domain Socket 在同一台主机上的传输速度是TCP Socket 的两倍,这是因为UNIX Domain Socket不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层的数据从一个进程复制到另一个进程,所以速度更快。

    UNIX Domain Socket用于IPC通信的具体编程方式与普通的TCP Socket编程没有太大的差别,性能又高,还很容易从单机通信扩展为多主机间的通信,所以这种方式逐步代替了管道的方式。

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,所以必然需要某种同步机制,互斥锁和信号量都可以。

    采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的复制。对于像管道和套接字这种方式,需要在内核和用户空间进行4次数据复制,共享内存则只复制两次数据:一次从输入文件到共享内存区;另一次从共享内存区到输出文件。实际上,进程之间在共享内存时始终保持共享区域,直到通信完毕。这样,数据的内容一直被保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存通信方式的效率是非常高的。

    Linux内核支持多种共享内存方式,例如mmap()系统调用、Posix共享内存及系统共享内存。目前主流的做法是通过 mmap()实现共享内存,当多个程序调用mmap()映射到同一个文件时,它们实际访问的必然是同一个共享内存区域对应的物理页面。

    本文给大家讲解的内容是架构解密从分布式到微服务:带大家聊聊RPC——IPC通信
    1. 下篇文章给大家讲解的是架构解密从分布式到微服务:古老又有生命力的 RPC;
    2. 觉得文章不错的朋友可以转发此文关注小编;
    3. 感谢大家的支持!
    ,

    免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

      分享
      投诉
      首页