[架构之路-63]:目标系统 - 平台软件 - 基础中间件 - TIPC透明进程间通信与AF_TIPC Socket
Posted 文火冰糖的硅基工坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[架构之路-63]:目标系统 - 平台软件 - 基础中间件 - TIPC透明进程间通信与AF_TIPC Socket相关的知识,希望对你有一定的参考价值。
目录
第1章 什么是TIPC透明进程间通信
1.1 概述
透明进程间通信(Transparent Inter-process Communication,缩写为TIPC)是一种用于进程间通信的网络通信协议,原本是为集群间通信特别设计的。它允许设计人员能够创建可以和其它应用快速可靠地通信应用,无须考虑其在集群环境中的物理位置(IP地址)。
TIPC原先是爱立信公司提出的透明进程间通信协议,主要用于高可用(HA)和集群系统中。它允许设计人员能够创建可以和其它应用快速可靠地通信应用,无须考虑在其它需要通信的应用在集群环境中的位置。
1.2 TIPC的来由
在可信网络环境下,TCP/IP协议的很多操作是冗余的,例如三次握手,增加了应用程序的通信时间,不利于对时间响应要求比较高的应用,比如 处理集群成员节点由于重启,down机等各种原因导致的增加和减少。 TIPC针对可信网络环境,减少了建立通信连接的步骤和寻址目标地址的操作 (在TCP/IP协议里, 完成这些操作节点间最少也需要9次包交换, 而使用TIPC则可以减少到2次)。这可以提高节点间信息交换的频率以及减少节点间等待的时间。
平时我们使用的socket,TCP也好,UDP也好,用来标识一对socket的通信,无非是用两个socket的IP地址和端口号,即五元组。比如使用UDP的socket,要发一个datagram到另一个socket,需要指定对端的地址,这个地址是由那台机的IP和端口组成。socket是在内核中管理,当内核检测到socket有数据可读时,就会通知拥有这个socket的进程去读取里面的数据。
这里的不方便之处在于,要指定对端地址,我们必须知道这个socket在哪台机,端口是多少,才能发送数据出去。能不能只提供一些应用层的信息,就可以让内核自己去查到socket的位置,再把消息发过去? TIPC做的就是这样的事。
1.3 如何实现TIPC的路由
使用TIPC,我们在创建socket的时候在内核中注册自己的服务类型service type,那么在发送端,只需要指定服务类型就可以由内核路由到相应的socket。这个时候,对应用层来说,对端地址仅仅是一个服务类型service type! 很显然,内核维护着这么一张TIPC的路由表,即由服务去查找socket。而每台机都有这样的路由表,他们之间信息就像能够共享一样地为整个集群的TIPC socket服务。有了TIPC,这个socket使用了哪个IP,那个端口,我们都不再需要知道,很好很强大。
1.4 TIPC还具有如下特性:
- 有些时候多个进程提供同样的服务,仅仅是为了负载平衡或其他原因,这种情况可以用一个整数变量instance来标识不同socket,但是指定同样的service type。这个时候socket的地址是由service type和instance共同来指定。发送数据时候只需要指定service type和一个instance的值,也可以指定service type和instance的一个区间。对于后者,就是broadcast你的datagram。
- 管理前面说的TIPC路由表的是内核当中的一个进程叫做name server。它知晓着集群中所有的TIPC socket。在发送datagram给服务某个service的socket之前,你可以向它请求服务这个service的socket是否已经在工作了,它会告诉你service的状态。并且注册了一个observer,当你关心的socket起来之后发消息通知你,这样就可以避免你把datagram发给一个根本不存在的socket。
- 特点:网路中服务位置透明,自动发现机制,可靠性,标准套接字接口的支持,无连接,有链接,多播。
备注:TIPC是Linux内核TCP/IP协议栈的一部分。它与AF_INET、AF_UNIX、AF_TIPC是一体的,处于并列的位置。
1.5 port
Port 是TIPC网络协议的通信标识,具有网络唯一性,由运用程序创建port时由TIPC自动生成。
Port ID 典型标识是<z.c.n,:ref>, ref 是32位参考值,在node结点上是唯一的
Port ID属于TIPC网络通信的物理地址标识, 用于TIPC协议消息通信的内部路由。
Port name 形式 atype, instance #名字
Btype, lower, bound #名字序列
Port name 和port ID 的映射是由TIPC的port 发布关联的,当应用bind指定的port name 时,TIPC自动生成关联port ID ,并在指定的网络区域发布。
第2章 Linux下的TIPC
2.1 TIPC内核模块安装
(1)TIPC内核模块安装
- modprobe 利用depmod创建的依赖文件来自动加载相关的模块
- insmod 向正在运行的内核加载模块
- lsmod 显示当前加载的内核模块信息/proc/modules
- rmmod 从当前运行的内核中卸载内核模块
- depmod 处理可加载内核模块的依赖关系
- /proc/kallsyms 内核符号和模块符号表的信息
- root # modprobe tipc, 就可以将tipc模块加载到内核(当然,这里的TIPC模块是Linux已经支持的)
(2)配置TIPC
- 参考文档:Linux TIPC 1.7 User's Guide
- 配置网络: root# tipc-config -netid=1234 -addr=1.1.8 -be=eth:eth0
- 远程管理: root# tipc-config -dest=1.1.9 -n
- 禁用远程管理: root# tipc-config -mng=disable
(3)通信测试
- 可以参考:tipc-config包中的demo
2.2 TIPC编程
(1)TIPC网络结构
网络地址:<Zone, Cluster, Node> 255.4095.4095
网络ID:TIPC网络还使用网络ID,这允许多个逻辑网络使用相同的物理媒介(例如,相同的以太网网线),并且不会相互干扰,因为每个节点仅仅识别来自相同网络ID节点的流量。
当物理链接(如以太网)建立好了之后,TIPC会自动建立连接来和网络中其它节点通信。
注意:
- TIPC网络地址不像IP网络地址,在TIPC中每个节点仅有一个网络地址,即使节点有多个网络接口。
- 网络管理员会分配网络地址和网络ID,程序员没必要关注到这些内容。
- 网络管理员会配置好每个节点的网络接口。
(2)消息传送概览
TIPC应用程序在端点间(端口)通过交换数据单元(消息)进行通信。
从应用程序的角度,一个消息就是从1~66000字节长的字符串,内部结构由应用程序决定,一个端口是一个实体可以以连接或无连接的方式发送和接收消息。
注意点
- TIPC网络包含的节点可能运行在不同的CPU类型上,或者使用不同的操作系统,应用程序必须保证他们的消息格式的一致性。在一些情况下,可能需要大小端转换或者强制使得消息域固定大小。
- 一些相同的条件,阻止发送消息的条件可能也会使得阻止返回消息。
(3)TIPC寻址
网络地址: <Z.C.N> <8bit, 12bit, 12bit>
端口ID: <Z.C.N:ref> ref也是32位整数
端口名称:虽然可以使用TIPC端口发送消息,通常情况下,使用功能性地址,而不使用发送端口来知晓目的地址的物理位置,这就简化了通信,尤其是服务端口动态创建、删除或重新定位的时候,或者多个端口提供服务的时候。在TIPC中功能地址的基本单元就是端口名称。指定为type, instance,大小为32bit, 32bit。
不像端口ID,端口名称在TIPC网络中可以不唯一,应用程序可以给一个端口名称分配多个端口,多个端口名称可以分配给一个端口。
端口名称序列:用于指定范围内相似的端口名称,type, lower bound, upper bound,每个域大小32bit。
一些限制:
- type值0~63被TIPC保留
- 端口名称和名称序列被服务端口使用,而不是客户端口。
- 端口名称序列不能重叠。但不同节点上的重叠名称序列是可以的。
注意点:
- 程序员不得不担心选择TIPC名称和名称序列。
- 在TIPC网络中好的名称(或名称序列)与IP网络中广为人知的端口号一样。
- 应用程序必须使用与其他应用程序没有冲突的TIPC名称(或名称序列)
结合了一些有意思的特点,一些非常独特,来达到整体目标:
(1) 整个集群从通信的角度来看是单个计算机
(2) 能使得应用可以跟踪、适应拓扑变化
(3) 进程通信的透明性,网络拓扑由内核模块TIPC维护
2.3 TIPC网络结构
TIPC网络是由单个的处理单元或节点组成. 网络节点是严格分层的, 规则如下:
1:相关节点的集合构成一个cluster:
如果cluster中的每一个节点都至少有一条直达其他每个节点的路径(即cluster的节点是全连通的), 那么这些节点构成一个cluster, 每个cluster有1~4095个节点.
2:相关cluster的集合构成一个zone:
如果zone中的每一个cluster都至少有一条直达其他每个cluster的路径(即zone的cluster是全连通的), 那么这些cluster构成一个zone, 每个zone有1~4095个cluster, 每个cluster的大小不必相同.
3:相关zone的集合构成一个TIPC网络:
如果网络中的每一个zone都至少有一条直达其他每个zone的路径(即网络的zone是全连通的), 那么这些zone构成一个TIPC网络, 每个TIPC网络有1~255个zone, 每个zone的大小不必相同.
节点一般是按照邻近关系分组, TIPC的通信质量随着节点距离增加而下降,在一个典型的TIPC网络中,同一cluster中的节点间通信最频繁,其次是同一zone而不同cluster的节点,而不同zone中的节点基本没有通信。
TIPC网络地址是和整个物理结点相关联的,地址模式映射到逻辑网络拓扑。<z.c.n>方式。 Z(zone 8位),C(cluster, 12位), N(node, 12位), 共32位。 一个网络可包括255个域(zone)。zone:区域;cluster:集群;node:节点。
TIPC网络中的每个节点都有一个由zone ID,cluster ID和node ID组成的地址,一般标记为<Z.C.N>。其中: 1<=Z<=255,1<=C,N<=4095。如果一个TIPC网络节点还没有被分配地址,那么就以<0.0.0>标记它。TIPC网络一般也有自己的ID。这样可以使多个逻辑TIPC网络共同使用相同的物理介质(如以太网LAN等)而不相互干扰。
注意:
- TIPC2.0只支持单cluster的网络。
- TIPC网络节点的地址和IP有很大区别, 每个TIPC节点最多只有一个地址, 没有网络接口(interface)的概念。
- 每个节点的地址以及TIPC网络的ID都由网络管理员负责分配, 程序员不用关心这些。
第3章 Linux TIPC的编程接口
3.1 TIPC的socket地址
socket地址是个16字节的结构,如下所示:
struct sockaddr unsigned short sa_family; /* 地址家族, AF_xxx */ char sa_data[14]; /*14字节协议地址*/ ;
为了编程可以更加方便通常我们会针对不同的协议定义不同的并行结构,
如tipc的socket地址定义如下:
struct sockaddr_tipc unsigned short family; /* AF_TIPC */ unsigned char addrtype; /* TIPC_ADDR_NAME */ signed char scope; /* TIPC_CLUSTER_SCOPE */ union struct tipc_portid id; struct unsigned long type; unsigned long instance; unsigned long domain; /* 0: own zone */ name; addr; ;
3.2 tipc的地址
tipc的地址描述如下:port。Z表示zone, C表示cluster,N表示node。Port可以看成是一个socket
当启动tipc服务的时候,确定当前node(可以是一块单板,也可以是一台主机)的地址。我们创建一个socket就创建了一个port。Tipc提供名字服务,在sockaddr_tipc中指定name,把sockaddr_tipc和port绑定起来,向指定的名字发送消息就会发到对应的socket,而下层的则不需要用户去感知。名字和端口支持1对多的关系,一个名字对应多个端口
3.3 创建socket
int socket(int domain, int type, int protocol);这个函数的目的是创建一个socket,然后返回一个socket描述符。
Domain在这里是AF_TIPC,
type通常有SOCK_STREAM,SOCK_DGRAM两种,表示面向流或面向包。
Protocol通常设置为0。
3.4 bind操作
一旦有一个socket,我们可能要将socket和机器上的某个地址关联起来,这个操作由bind来完成。
Bind和connect,原socket在应用bind的时候我们需要自己指定端口,connect则会自动为我们选定接口,但对于tipc应用层,不存在这种关系。(待确认)
3.5 getsockname
根据socket描述符获取当前的地址。
3.6 setsockopt
其参数如下:int sockfd, int level, int optname, const void *optval, socklen_t optlen
当level为SOL_TIPC,也就是使用tipc时,optname有如下值可以选择。
1) TIPC_IMPORTANCE
这个值用来标识本socket消息的重要性,设置为重要时本socket在发生拥塞时,消息丢失的可能性很小。 从下面的字面意思可以看出其含义,不再赘述。
TIPC_LOW_IMPORTANCE, 低优先级 TIPC_MEDIUM_IMPORTANCE, 中优先级 TIPC_HIGH_IMPORTANCE 高优先级 TIPC_CRITICAL_IMPORTANCE. 紧急优先级
默认是TIPC_LOW_IMPORTANCE
2)TIPC_SRC_DROPPABLE
同样是作为拥塞控制,如果设置为此值,则在拥塞发生时,tipc会丢弃消息,否则,将吧消息放入队列缓存。
默认情况下: 对SOCK_SEQPACKET, SOCK_STREAM, SOCK_RDM 三种传输方式,也就是可靠链接,则将消息缓存,对SOCK_DGRAM,也就是不可靠链接,将消息丢弃。
3)TIPC_DEST_DROPPABLE
仍然为拥塞控制服务。针对下面三种情况有用,消息不能发送到目的地址,或者目的地址不存在,或者目的地址发生了拥塞。如果使能这个功能,在发生以上三种情况是,消息将被丢弃,否则会将消息返回给发送者。
默认情况下:SOCK_SEQPACKET ,SOCK_STREAM两种传输方式,返回给发送者。
对SOCK_RDM and SOCK_DGRAM则将消息丢弃。这样做的目的是在在使用面向链接的情况下发生通信失败时进行合适的处理,同时不增加面向无链接的情况下通信失败的处理的复杂性。
4)TIPC_CONN_TIMEOUT
设置connect的超时时间,单位是毫秒
用sendto时,这个选项是没有意义的。
以上是关于[架构之路-63]:目标系统 - 平台软件 - 基础中间件 - TIPC透明进程间通信与AF_TIPC Socket的主要内容,如果未能解决你的问题,请参考以下文章
[架构之路-58]:目标系统 - 平台软件 - 中间件软件(嵌入式)与中间件平台(中台)
[架构之路-61]:目标系统 - 平台软件 - 基础中间件 - 远程过程(函数)调用RPC原理与其网络架构
[架构之路-57]:目标系统 - 平台软件 - 用户空间驱动与硬件抽象层HAL
[架构之路-60]:目标系统 - 平台软件 - 基础中间件 - Linux进程间通信的主要方式