目前而言,SOA 架构在汽车软件中的应用也是刚刚开始。对SOA 在汽车领域的应用很多企业也是在摸索着前进。在这个过程中,有三大需求在推动着SOA的发展:
传统汽车电子电器架构的 SOA 化;
车载娱乐系统(IVI, In-Vehicle Infotainment) 与车联网需要SOA进行更广泛的应用集成;
SOA 架构风格对于自动驾驶系统来说也是一个非常合适的架构决策。最直接的因素有两个:
自动驾驶系统中“多种传感器的感知和融合、复杂多变场景的规划决策、高实时要求的控制执行”涉及大量类型差异很大的计算,需要能被分解成不同的服务子系统,独立进化;
解决的办法至少有以下几种:
SOA 的通讯协议采用 DDS, 某些 DDS 的实现已经内置了共享内存通讯,这是目前采用比较多的方式。有数据序列化动作,实现零拷贝有一定难度。优点是已经有成熟的实现。
基于共享内存的虚拟网卡,这个适合基于PCIe的跨SoC通讯。有数据序列化动作,实现零拷贝有一定难度。
与服务装配相配合,透明实现进程内、跨进程、跨主机的多种优化手段自动适配。后文详述。
自动驾驶系统在运行中可以看作是一个“感知融合→决策规划→控制执行”的流水线在持续运转。其中涉及大量不同种类的算法接续执行、相互合作。算法对执行性能的要求主要有两点:
单个算法的执行速度尽可能快,从而让整个流水线的总延迟时间尽可能短
每个算法的执行时间的波动率尽可能小,从让整个流水线延迟的波动率稳定
一种极端的任务调度方式是全部交给操作系统来处理。每个算法服务作为单独的进程存在,由操作系统去分配进程的执行时间。开发者能影响任务调度的方式只是设置每个进程的优先级。大多数自动驾驶原型系统的开发就是这么做的。这种方式的缺陷在于:
以“操作系统进程”为单位的调度粒度过大,无法对算法动作执行的时机做精准调度
蓝色部分是与特定通讯通道无关的公共部分,包括3个模块:
SOA通讯接口定义 IDL规范:Franca。以及Franca的语义解析工具。
根据Franca 生成通讯代码的工具
通讯通道无关的运行时库,Common API Runtime
绿色部分是特定通讯通道相关,包括:
特定通讯通道的绑定规范
特定通讯通道的代码生成工具
特定通讯通道的运行时库
橙色部分是用户需要为特定 SOA 应用需要编写的内容,包括:
特定SOA应用的接口定义,需要遵循 Franca 规范
特定SOA应用对某一个通讯通道的绑定定义,需要遵循该通讯通道的绑定规范。
图4. 7 SOA 服务部署示例
服务的部署情况如下:
服务1 与服务2 在同一个服务容器进程A 中;
服务3部署在容器进程B中,容器进程B 与 A 是同一个 OS 内的两个进程,
服务4、5 在另一个 OS 中的服务容器进程内
服务2 的 handle_α直接被容器进程A通API直接调用
服务3 所在容器进程通过共享内存获取事件再调用其方法
服务4 通过网络(SOME/IP)收到事件并处理
如上文所述,中间件Runtime 至少有三个场景需要对用户代码进行调用:
服务端中间件Runtime收到RPC请求后调用用户代码进行处理
服务端中间件Runtime接收到订阅的事件后调用用户代码进行处理
客户端中间件Runtime收到RPC的响应后回调用户注册的 callback函数
一个对用户(中间件的使用者)友好的中间件系统应该对用户屏蔽复杂的线程管理,用户只需要提供方法函数供中间件Runtime 调用。中间件Runtime 执行线程有很多设计决策需要考虑。
能否为来自不同客户端的请求绑定一个需要访问的资源标识,将需要相同资源标识的任务分配到同一个任务队列中,这样用户代码就不需要为不同客户端来源的请求访问竞争资源时做加锁处理。
SOA 服务在IDL定义中已经给出了详细的数据类型定义,方法名称和参数定义,所以直接根据IDL定义生成基于HTTP的RESTful接口是完全可行的。中间件实现应该允许我们扩展 IDL定义,支持在 IDL 描述中直接指定为某个接口的某个方法生成 RESTful API。比如下面的例子中,指定Math接口支持 RESTful 访问: