SOME/IP standard keynotes
标准链接:SOME/IP(Scalable service-Oriented MiddlewarE over IP)。
- 1.2 Applicability of the protocol
- 4 Protocol Specification
- 6 Protocol usage and guidelines
1.2 Applicability of the protocol
SOME/IP shall be used for inter-ECU Client/Server Serialization.
NOTE
SOME/IP协议是为跨主机的Server/Client SOA架构设计的,包括对应的服务发现协议SOME/IP-SD也是只对跨主机的服务发现进行了规定,对主机内的Server/Client通信方式、服务发现都没有定义
4 Protocol Specification
![]() |
---|
Server/Client 交互模式;图片来源:vsomeip |
- Server与Client之间通过TCP/UDP直接建立链接通信
- 每个Server可以同时与多个Client建立连接
- Server通过[sourceIP, sourcePort, dstIP, dstPort, Protocol]五元组确定Client,每个Client可以与Server以TCP和UDP建立两个通道
- Client负责发起所有TCP链接;Client负责将TCP链接的随机端口号和UDP的端口号发送给Server
- Server负责主动通过TCP和UDP发送数据给Client
- Server收到eventgroup的订阅后,就会将event数据主动通过已经建立的TCP或者已知的UDP端口号发给Client
- Server发送的Client地址是在SubscribeEventGroup服务发现消息中由Client告知Server的
- Server收到method的Request请求,处理请求,原路通过通信链接返回结果
- Server没有Client的概念,它只知道有通信连接和订阅信息
- 从Server的角度看,一个Server,即一个Service Instance,对外监听了两个传输层端口(也可以只监听一个),一个TCP端口,用于接收Client的连接请求;一个UDP端口,用于向Client的UDP端口发送数据
- Server中的每个event,method只能选择TCP或者UDP通道(SOME/IP-SD 5.1.2.6)
NOTE
- 具体的实现中Server/Client可以是不同的实体,例如在vsomeip中,一个vsomeip的application类中可以offer多个、request多个服务的实例
- 协议只规定服务相关的概念,以及与底层传输层TCP,UDP的绑定关系,具体的实现可以不同;但是都需要对TCP,UDP链接进行管理
Server提供的Service由events、methods、fields组成:
-
event:Client订阅event,Server接收到订阅后,当条件满足会主动将event群发给订阅方;Client只能通过eventgroup的形式订阅event;一个eventgroup可以包含一个或者多个当前Service下的event
-
method:Client向Server发起Request,包含参数;Server收到Request后,接收参数,执行相关逻辑,得到返回结果,将返回结果以Response的形式返回给Client
-
field:event和method的组合。包含一个值,当这个值满足某些条件时Server群发该值给所有订阅者(event);这个值可以被set,Client可以调用setter方法设定这个值(method);也可以通过getter方法获取这个值(method)
4.1 Specification of SOME/IP Message Format (Serialization)
4.1.2 Header
4.1.2.1 Message ID [32 Bit]
- 消息ID全局唯一,唯一的确定一个event或者method
- 由两部分组成,分别占[16 bits]:
- Service ID:所属的service ID
- Method ID:这里Method ID可以是服务内部的method或者event的ID。
NOTE
注意没有Instance ID
4.1.2.4 Request ID [32 Bit]
这个字段跟method,field中的setter,getter(特殊的methods)相关,用于在client所在的机器上唯一的确定当前client的一次method的调用:
- 这个字段只有在client的机器上才有意义,server不关心这个字段,server只是将该字段拷贝到response消息头中
- client与server建立TCP/UDP连接后,每一个method都只能在一个通信连接上通信,那么在client这一侧,可能有多个调用方同时在这个连接上发送method请求;在server端,它不关心这个是谁的请求,它只是负责处理这个请求并将结果从收到请求的TCP/UDP链接发送出去;在client这一侧,则需要Request ID来区分收到的来自server的回复是哪一个请求的,这样才能把收到的回复结果放入相应的promise中
这个ID由两部分组成,分别占[16 bits]:
- Client ID [16 Bits]:这个Client ID不是当前server/client服务中的client,而是服务client中的使用方:
- 服务client可以理解为一个TCP/UDP链接通道;Client ID中的client可以理解为向这个TCP/UDP链接发送的一个method请求message的唯一标识符;这个标识符用于把收到的server的response与一次请求唯一对应起来
- 每一个服务client下的每一个method(即每一个Message ID),都有自己独立的Client ID范围:Client ID唯一性的适用范围是Message ID
- Session ID [16 Bits]:当前Client ID下当前method请求消息的计数器
NOTE
这里Client ID不是与Service ID对应的Client一方的ID,而是Client的一个用户的ID
4.2 Specification of SOME/IP Protocol
4.2.1 Transport Protocol Bindings
[PRS_SOMEIP_00138] If a server runs different instances of the same service, messages belonging to different service instances shall be mapped to the service instance by the transport protocol port on the server side.c(RS_SOMEIP_00015)
- SOME/IP支持TCP或者UDP传输层协议
- 如果一个Machine上同时提供多个同一个Service ID的不同Instance,则这些Instance必须被绑定到不同的Port口,无论是TCP还是UDP,详细原因分析看4.2.1.3
- 一个Service Instance可以使用的传输层通信方式:
- TCP单播
- UDP单播
- UDP组播
NOTE
这三个Port口是可以同时存在的,但是每一个最多只能有一个;对于服务下面的Event或者Method,只能同时对应一个TCP单播或者UDP单播,不能同时使用两个,这点在SOME/IP-SD 5.1.2.6中有规定
4.2.1.1 UDP Binding
[PRS_SOMEIP_00943] The client and server shall use a single UDP unicast connection for all methods, events, and notifications of a Service-Instance which are configured to be communicated using UDP unicast.c(RS_SOMEIP_00010)
server和client之间一旦建立了TCP/UDP的通道(UDP没有connection,但是此处我们认为相互发现后即是链接),TCP通道负责当前服务下所有配置为使用TCP的event,method,field;UDP通道负责当前服务下所有配置为使用UDP的event,method,field
[PRS_SOMEIP_00942] The client and server may use a single UDP multicast address per each Service-Instance which are configured to be communicated using UDP multicast.c(RS_SOMEIP_00010)
如果server/client之间配置了UDP组播通信,则所有的配置为UDP通信方式的event,method,field都可能通过这个组播地址通信, 在SOME/IP-SD中:
[PRS_SOMEIPSD_00134] Unicast/Multicast switching for event and notification event transmission via UDP dFor events and notification events which are configured to be transmitted via UDP (see [PRS_SOMEIPSD_00802]) SOME/IP-SD shall support automated switching from unicast to multicast communication if a configured threshold of the numbers of subscribers was reached.c(RS_SOMEIPSD_00025, RS_-SOMEIPSD_00016)
4.2.1.2 TCP Binding
[PRS_SOMEIP_00707] The client and server shall use a single TCP connection for all methods, events, and notifications of a Service-Instance which are configured to be communicated using TCP.c(RS_SOMEIP_00010)
server和client之间一旦建立了TCP/UDP的通道(UDP没有connection,但是此处我们认为相互发现后即是链接),TCP通道负责当前服务下所有配置为使用TCP的event,method,field;UDP通道负责当前服务下所有配置为使用UDP的event,method,field
在使用TCP传输层协议时,必须关闭Nagle算法,保证每次数据发送都必须马上打包成一个TCP segment发送出去,目的是保证消息消息实时性。
Nagle算法将多个TCP发送积累成一个大的TCP segment发送的算法,目的是提高TCP数据包的payload比例;因为一个TCP报文的头部占40-Byte,如果单个segment的payload过小,则发送的数据大部分都是头部信息,降低了报文的利用率,增加了线上阻塞的风险
TCP的链接发起、重连、关闭都是由client端决定的
- 当server端调用了StopOfferService接口停止服务后,不能自行终断TCP链接,而应该是client端来操作,否则client端会进行重连,造成资源浪费
4.2.1.3 Multiple Service-Instances
- 首先一个机器上,可以针对同一个Service提供多个不同的Service Instance,即服务的实例
- 每一个Service Instance在一个Service ID下有一个全局唯一的Instance ID
- 已知SOME/IP的消息头是不包含Service Instance ID信息的(SOME/IP-SD的消息中是包含Instance ID信息的)
- 以上就会导致一个问题:client如何通过SOME/IP消息头来判断这个消息来自同一个机器上的哪一个Instance
无论是UDP还是TCP都有一个(srcIP, srcPort, dstIP, dstPort)的tuple来表示一个通信链接:
- 不同机器上的服务实例,无论是同一个服务还是不同的服务,都可以通过通信链接来区分不同的Instance
- 同一个机器上的不同的Service,可以通过其唯一的Service ID来区分
- 同一个机器上的相同的Service,因为它们有相同的Service ID,而且SOME/IP消息头不包含Instance ID的信息,只能通过通信链接来区分不同的Instance;从client的视角来看srcIP, dstIP是不能变动的,那么能区分的就只有srcPort或者dstPort,而Instance ID是由服务的提供方,即server侧定义的,所以区分也自然应该由server端来区分:
- 同一个Host上相同的Service的不同Instance需要绑定到不同的Port端口
4.2.1.4 Transporting large SOME/IP messages of UDP (SOME/IP-TP)
针对一个UDP报文放不下的数据,SOME/IP使用SOME/IP-TP(SOME/IP Transport Protocol)来分成多个UDP报文发送,基本的原理就是每一个分割后的UDP报文都自带一个Session ID接收端通过Session ID来进行组装。SOME/IP标准的建议是能使用UDP的地方尽量使用UDP,只有在传输很大的数据,且没有严格的延迟要求的情况下才使用TCP
4.2.2 Request/Response Communication
- 所有Request的参数必须按照在函数调用中的实际参数位置顺序进行序列化
4.2.3 Fire&Forget Communication
- 与普通Request/Response的区别在与不会等待Response
Fire&Forget不是返回值为
void
的特殊情况,当然Fire&Forget返回值类型是void
,但是与普通Request/Response返回值是void
不同,Fire/Forget不会等待,所以无法确定,其请求的任务是否执行完毕。但是普通的返回void
的情况下,虽然返回值是void
,但是可以通过std::future
的get()
方法来判断服务方是否已经执行完毕,这种情况往往需要服务方发送完成的标志位给到请求方。而Fire&Forget情况下,服务提供方是不会发送任何回复给请求方的,这也是为什么Fire&Forget的请求永远不会返回错误码。
4.2.4 Notification Events
[PRS_SOMEIP_00930] When more than one subscribed client on the same ECU exists, the system shall handle the replication of notifications in order to save transmissions on the communication medium.c(RS_SOMEIP_00042) This is especially important, when notifications are transported using multicast messages.
AUTOSAR要求当一个client机器上有多个订阅同一个服务ID的Client时,实现上需要考虑降低网络流量,这其实确定了SOME/IP的实现往往需要一个中心节点。只有通过这个中心节点,做统一的收发管理,才能最大程度的优化网络流量。
4.2.4.1 Strategy for sending notifications
订阅发送的三种模式:
- 周期发送
- 事件触发发送
- 值变化超过某个范围发送
4.2.5 Fields
Fields是Events和Methods的融合体,具体表现在:
- 一个Fields需要至少包含一个
getter
,一个setter
,一个notifier
getter
和setter
,本质就是Methodsnotifier
,本质就是Event
6 Protocol usage and guidelines
6.1 Choosing the transport protocol
SOME/IP的传输层协议是具体到一个消息的:
- 每一个Event,Method等都可以配置自己的传输层协议
在UDP和TCP的选择上,建议如下:
-
1400Bytes,且在错误发生时没有严格实时性要求的,使用TCP
- 如果在错误发生时实时性要求<100ms,使用UDP
- 如果错误发生时实时性要求<100ms,且消息>1400 Bytes,使用SOME/IP-TP