【上汽零束SOA】云管端一体化SOA软件平台系列介绍之五:服务实现篇

近来SOA技术在汽车圈可谓是风生水起, 各路大咖关于SOA的文章也层出不穷,有写电子电气架构的,有写服务设计的,有写具体实现协议的,而我接下来从SOA软件实现的角度,结合一个具体的软件开发实例,让更多的朋友们理解什么是SOA,SOA背后的实质是什么,SOA框架承担哪些职责,SOA服务开发者要做哪些事情,SOA开发过程中可能潜在哪些问题等等。

SOA是一种方法论, 除了公认的一些特点外(譬如接口契约, 松耦合等),业界尚未有统一的定义。既然没有统一的定义,也就没有统一的实现方式。不过得益于一些标准化协会、开源组织及商业公司的共同努力,业界一时间出现了很多SOA框架,譬如W3C组织定义的Web Service,OMG组织定义的Corba,微软的WCF,阿里的duboo等,在很多领域(尤其是互联网领域),SOA架构成为大量应用场景首选的解决方案。

而在汽车领域,目前非常热门的框架要数Genivi组织定义的CommonAPI和AUTOSAR组织定义的Adaptive AUTOSAR(简称AP)(AP平台内容较多, SOA框架核心部分是ara::com)。AP的ara::com和CommonAPI有很多的相似性,对于开发者而言,CommonAPI实现起来会容易许多,而且CommonAPI是开源的,而AP则多是由商业公司(譬如Vector, Electrobit等公司)闭源提供。本文将基于开源的CommonAPI介绍,同时对比AP实现,让大家看到更多实现细节的同时,也可以看到CommonAPI和AP的差异。

当然,上汽零束的云管端一体化SOA软件平台也提供基于SOA的服务开发工具链和方法论,相关信息零小束也会在日后逐步公开,敬请期待。

一、设定应用场景

首先我们还是基于一个应用场景来定义服务。譬如以导航为例, 可以把计算一条路径的模块定义成一个服务。原因很简单,算路过程里面的实现还是蛮复杂的,里面会用到若干算法,通过把算路定义成服务,可以很好的把算路过程分离出来,很多基于算路的应用,譬如HMI等可以独立于算路模块,单独进行设计,这样可以达到模块解耦的目的。如下图所示:

二、服务接口定义

首先我们得认识一下什么是服务接口, 服务接口不同于传统应用的函数接口。因为SOA有一个基本特点,就是“接口契约”。“接口契约”简单点说就是一种接口描述语言IDL,不同的SOA框架接口描述语言不尽相同,譬如SOAP框架基于xml语言,定义若干标签,通过标签描述交互数据及交互指令。而CommonAPI则是采用一种Franca设计的语言。

定义接口描述语言最大的好处就是,软件开发过程得到解耦。服务端开发团队和客户端开发团队在开发过程中不再依赖对方的交付,而仅依赖于该描述文件。一旦服务接口定义完毕, 双方可以独立开发,独立测试,可以有效地提高开发效率。

对于上述场景中的算路服务,我们假设该服务中提供一个算路接口,譬如叫CalcRoute,该接口由2个输入参数(一个是起点道路ID,一个是终点道路ID),1个输出参数(算路结果,由多条道路组成的一个list)。这里仅仅是一个示例,实际场景会复杂许多。那么基于CommonAPI框架定义的接口文件为如下形式:

服务接口定义看起来非常容易,基本上有一些编程经验的朋友,上手应该会比较快的,因为定义服务接口只需额外记住一些规则即可。譬如输入参数用in标识,输出参数用out标识, 定义数组要使用array,定义一个服务要用interface等等。如果我们要把接口设计得强大,要用到的特性就会更多一些,无论怎样,想做服务开发,服务接口提供哪些特性,开发者都是需要进一步深入了解一下的。

顺便说一下AP,AP在配置上就会稍微复杂一些,虽然仍然绕不开一些常见的概念:接口、方法、事件等,但是两者的形式还是有许多不同。CommonAPI的接口是基于纯文本的,所见即所得,一看接口就能看出个所以然来。而AP则是基于ARXML的,ARXML也是一种XML,不过直接写XML还有点困难,因此AUTOSAR组织定义了一整套的XML Schema,有很多的标签,定义了很多的特性,因此基本上只能通过图形化工具配置,而各家供应商定义的工具使用方法各异,各家供应商对ARXML的理解或者实现存在一些偏差,不兼容的现象也时有发生,甚至同一家供应商定义的不同上下游产品,也存在兼容性问题。这些对于开发者而言,确实是一件很让人头疼的事情。

三、服务接口代码生成

接口定义完毕,接下来就要进行代码生成了。通常至少会生成两个类,一个提供给服务端开发使用, 另外一个则提供给客户端使用。提供给服务端的通常叫Skeleton, 提供给客户端的通常叫Proxy。如下图所示:

该图除了描述代码生成过程之外,也基本描述了程序(服务端和应用端)的依赖组成以及函数接口调用流程。为帮助大家的理解,这里简单描述如下:

无论是服务端或者应用端,其核心组成主要是三部分:

1) 业务功能代码,譬如算路算法的实现等;

2) 服务接口生成代码 ;

3) 框架库,所谓的框架库是指一些常用的功能,不依赖于用户定义的功能,SOA框架设计者通常把这些功能单独定义成lib库。

其由此不难发现, 应用程序和服务程序的本质基本是相同的,只是对于服务而言,提供服务实现,对于应用而言,调用服务接口,角色不同而已。

该图中描述了一个接口的调用过程, 应用端发起调用, Proxy将函数调用encoding成数据流, 发送到服务端,服务端接收后,decoding成函数调用,服务端触发其执行代码,这样就完成一次函数的调用。我们可以先简单讨论到这里,下文我们可以再详细讨论一下该过程。

生成代码以及类图如下图所示:


 

其中绿色代表代码自动生成的, 而白色则代表开发者需要完成的, 不难发现,客户端只需调用RouteCalcProxy即可, 该类提供两个方法,一个是同步调用方法,一个是异步调用。所谓同步调用就是指当客户端调用该方法时,会阻塞在调用处,直到服务端响应完该调用。这种方式对客户端而言,调用简单,但存在被服务端阻塞住的风险。因此,还定义一种异步调用方法,客户端调用时,需要设置一个callback函数,会通过该回调函数响应来自服务端的结果。这样,当某一个服务需要很长时间的时候, 客户端就有机会避免被卡死。

AP生成的方法和这个类似,重点提两个小差别:

1) 服务端称之为Skeleton。无论是Skeleton,还是Stub,这两种称谓在业界主流框架中都有被采用的,所以我们知道服务继承于该类即可。

2) Proxy里只有一个基于future的方法,估计AUTOSAR认为无论是同步调用还是异步调用都可以通过future方式完成吧。同步调用,无非是调用结束后,多执行下future的wait函数而已,有利有弊吧。AUTOSAR估计也是做出大量讨论之后做出的结论,零小束在这里就不多加评论了。

四、服务端代码开发


 

如下图所示,我们做了一个最精简的实现。当用户请求算法接口时,我们仅仅是打印一句话,返回一个简单的结果:

单纯构建一个服务类还不够,还需要有地方创建该对象。

我们在主函数中创建一个RouteCalc的对象, 然后将该对象注册到runtime中,这样服务端的代码就基本完成了。

五、客户端代码开发

我们再来看下客户端的代码实现,客户端代码实现起来也比较简单,先构建一个Proxy实例,然后不断查询该Proxy是否存在(Proxy Available的前提是服务已经ready)。当与服务连接成功后,就可以使用该Proxy调用服务的相关接口了。

六、服务部署配置

到目前为止,我还没有提及任何关于SOME/IP事情,那是因为服务定义和SOME/IP定义是两个完全独立的过程。对于客户端用户而言,他们关心Stub类即可,对于服务端用户而言,他们只关心Proxy类即可。这其实就是常说的Language Binding,而至于最终底层是通过IPC通信或者是网络通信,而网络通信又分为若干协议,是SOME/IP通信,亦或者是DDS通信,上层开发者是无需太多关心的。而用户数据向SOME/IP数据流或者DDS数据流Encoding的过程又被称为Network Binding, 也就是说一条算路的method请求,最终会被序列化成一条SOME/IP报文。

那么该method会对应SOME/IP消息格式里的method么?如果是的,那么method的id是多少呢?这里我们就得引入一个新的文件,fdepl文件, Franca创建专门的语言用于描述该文件,该文件定义服务接口与SOME/IP的对应关系,如下图所示:

通过该文件我们可以定义calcRoute方法所对应的Method ID, Service ID以及Instance ID。该文件也对应一个代码生成器,代码生成之后会产生很多SOME/IP相关的实现文件。

从上图中不难发现,又生成了新的基于SOME/IP的proxy和stub,它们基于服务接口描述,实现了序列化与反序列化到SOME/IP协议的过程, 是对FIDL生成代码的扩充,这样就彻底实现了从一个接口调用转化成一条SOME/IP消息的过程。

AP和CommonAPI在这个环节基本也是类似的,但不同于CommonAPI, AP的服务定义与部署仅仅是Arxml中的两种不同标签而已,不像CommonAPI,是通过两种不同的文件类型和代码生成器来进行区分。

七、结语

基于CommonAPI + SOME/IP框架的的服务端和客户端程序到这里基本就完成了。我们可以看到客户端程序可以像调用普通函数一样调用一个服务接口,而诸如序列化过程,通信细节,我们基本完全不需要考虑。这就是SOA框架的最大特点,开发人员将主要精力用于业务场景的服务设计上,框架提供序列化、反序列化,通信等基础能力,极大的地简化程序的设计过程。也因为如此, SOA框架适用于大型的,复杂的业务场景,可以通过构建服务的方式,解耦相关功能,降低项目失败的风险。

SOA架构只是一种设计方法,项目落地还需基于一个具体的SOA框架, SOA框架质量的好坏从某种层面上决定了项目能否成功。然而仅有好的框架还不够,还要看服务架构的质量,而这又会涉及很多内容,譬如服务接口是否合理,服务对异常处理的能力如何,服务的依赖关系等等。

零束云管端一体化SOA软件平台旨在提供一个优秀的SOA框架,简化软件开发的难度,让服务开发和应用开发成为一件轻松的事情。相关信息后续也将逐步公开。

基于统一的平台的服务和应用,为应用生态提供了基础。后续系列文章将就云管端一体化SOA软件平台与应用生态的关系为大家带来更多分享,敬请期待!

作者:零小束
文章来源:上汽零束SOA开发者论坛 
原文链接:
https://bbs.z-onesoft.com/omp/community/front/api/page/mainTz?articleId=7488
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值