SOA面向服务架构

SOA即面向服务架构。虽然,一开始我们对SOA面向服务架构的概念不了解,感觉很抽象。但是,当看到面向xxx的时候,我们很熟悉,讨论c++编程语言时,说c++是面向对象的编程语言。面相对象,那么对象作为一个基础的、核心的的概念,是c++的核心,c++中的概念都围绕着对象展开:类、抽象类、封装、继承、多态、模板等。那么对于SOA架构来说,则所有的概念都围绕着服务展开。

AP AUTOSAR标准基于SOA范式实现了通信模块(Specification of Communication Management),实现了面向服务的通信SOC(Service-Oriented Communication)。

本文以AP AUTOSAR(2311)通信规范文档为依据来讨论面向服务通信。

1SOC基本概念

面向服务通信,即通过服务这个基础概念把通信的概念涵盖进来。在自动驾驶中间价领域,即使我们完全没有听说过SOA的概念,当我们开发通信中间价的时候,我们常常需要开发如下功能:

(1)发布-订阅

一侧发布数据,一侧订阅数据,比如原生dds就支持这种语义。

(2)远程调用

远程调用,可以像调用本地函数那样调用远程的函数,可以有入参和返回值。

也可以向setter和getter类似的功能,远程设置一个属性或者获取一个属性。

SOC通过服务这个核心概念,把我们常用的一些通信范式进行了统一,SOC通过服务来提供发布-订阅、远程调用通信功能。当我们看到SOC的时候,完全不比纠结于面向服务到底是个什么概念,为什么叫面向服务,我们只需要知道面向服务,通过服务这个核心概念将发布-订阅、远程调用这些我们常见的通信范式进行了统一即可。

服务:

服务是核心概念,SOC中的所有概念都围绕着服务来展开。如上图所示,表示SOC的基本上示意图,有服务的提供者,服务的需求者。服务的提供者提供服务,服务的需求者查找服务,需求者找到服务之后便可以使用这个服务。

服务实例:

对于同一个服务,可以有一个服务端,也可以有多个服务端。每个服务端都是一个服务实例,服务实例用一个uint16类型的数据表示。

骨架和代理:

骨架又称为服务端,代理又称为客户端,类似于tcp/udp的服务端和客户端。服务端提供服务,客户端使用服务。

event:

event是发布订阅的通信范式。在SOC中,只能服务端发布数据,客户端订阅数据,不能翻过来。

trigger:

简化版的event,没有数据具体数据。类似于进程间通信的socket和信号量,socket可以传输具体的数据,信号量只是负责将线程唤醒。event类似于socket, trigger类似于信号量。服务端发送trigger,客户端接收trigger。

method:

method即方法,在c++或者java中,类中声明的函数,一般也叫方法。SOC里的方法和c++类中的方法概念是类似的,都是调用一个函数,可以传入参,可以有返回值,区别是c++中的方法是本地调用,SOC是远程调用。

服务端作为方法的提供者,客户端可以调用。

field:

field即字段。在c++中,当我们定义一个类的属性,常常把属性定义为private,如果有在类外部方位这个属性的需求,比如读和写,那么便会声明对应的setter、getter方法。SOC中的field与c++类中的setter、getter类似,可以通过setter和getter远程设置或读取该字段的值。

2基于dds实现SOC

2.1服务发现

服务发现是通信的前提,不管是event、method、field、trigger哪种通信方式,只有发现服务,才能够进行具体的通信。

2.1.1基于UserDataQosPolicy的服务发现

fastdds qos:UserDataQosPolicy-CSDN博客UserDataQosPolicy参考:fastdds qos:UserDataQosPolicy-CSDN博客

用DomainPaticipant来代表一个服务实例。当服务端OfferService的时候,创建对应的DomainParticiapant,并为DomainParticiapant设置UserData,UserData的格式按下图所示。前缀是ara.com://services/,后边是服务id,服务实例id,版本号。如果多个服务实例共用一个DomainParticipant,那么UserData也可以设置多个服务实例的信息。

客户端也应创建DomainParticiapant,并当发现新的DomainParticiapant的时候,读取发现的DomainParticiapant的UserData,来判断该服务实例是不是自己所要找的服务实例。

2.1.1.1PartitionQos

如果服务端有两个,实例id分别是1和2。客户端有两个,客户端1和客户端2,分别需要服务端1和服务端2,那么客户端1只需要发现服务端1的DataWriter和DataReader,客户端2只需要发现服务端2的DataWriter和DataReader。虽然1和2的topic相同,data type也相同,但是实际使用中客户端1不需要发现服务端2,客户端2也不需要发现服务端1。这种使用需求,可以通过PartitionQos来实现。

客户端:

针对发现的每个服务实例,都创建一个Publisher和SubScriber,PartitionQos配置为PartitionQos。

服务端:

服务端也需要创建一个Publisher和Subscriber,并配置PartitionQos。

2.1.3dds和SOC映射关系

1、当服务端调用OfferService

(1)用DomainParticipant代表一个服务实例

(2)针对每个event,创建一个topic和DataWriter

(3)针对每个trigger,创建一个topic和DataWriter

(4)针对method,创建一个request topic和一个reply topic,服务端要创建request topic的DataReader和reply topic的DataWriter

(5)field处理

①如果field中包含notifier,notifier与event类似,那么需要创建一个topic和DataWriter

②当hadGetter或hasSetter,创建一个request topic和一个reply topic,服务端要创建request topic的DataReader和reply topic的DataWriter

(6)为Domainparticipant设置user data

2、当服务端调用StopOfferService

(1)将user data从Domainparticipant的qos中移除

(2)移除在OfferService时创建的DataWriter和DataReader

3、当客户端调用FindService、StartFindService

(1)绑定一个BuiltinParticipantListener

(2)查找已经法相的DomainParticipant,根据客户端配置的关注的服务实例,向用户反悔对应服务实例的handle

4、当客户端调用StopFindService

解绑BuiltinParticipantListener

2.1.2基于topic的服务发现机制

基于topic进行服务发现,则需要内不创建一个topic ara.com://services/discovery,该topic的data type为ServiceAnnouncementMessage。每个进程都要创建该topic以及对应的DataWriter和DataReader。

ServiceAnnouncementMessage不是周期性发送,那么怎么保证新上线的DataReader能发现在之前上线的DataWriter发布的服务信息呢,需要按如下配置DataWriter的qos。

当identifier type设置为SERVICE_INSTANCE_RESOURCE_TOPIC_PREFIX,则服务端和客户端的Publisher和Subscriber不需要设置PartitionQos,而是会通过topic名来进行分区划分。实际使用的topic名格式如下:

ara.com://services/<InterfaceID>/<InstanceID>/<TopicName>

当identifier_type设置为SERVICE_INSTANCE_RESOURCE_PARTITION,则需要对Publisher和Subscriber设置Partition Qos。

2.2event

(1)struct名字在用户的名字之后加了后缀EventType

(2)struct字段增加了instance_id

2.3trigger

(1)struct名是固定的TriggerType

(2)struct成员只有一个,即实例id

2.4method

RequestHeader和ReplyHeader均是omg定义的规范https://www.omg.org/spec/DDS-RPC/1.0/PDF。RequestHeader终版instanceName即服务实例的实力id,requestId是DataWriter的guid。

2.5field

field中的notifier与event类似,只不过struct命名有区别。。

setter、getter使用的data type,与method类似。同样的,struct命名有区别。

相关推荐
C澒2 小时前
SLDS 自营物流系统:Pickup 揽收全流程
前端·架构·系统架构·教育电商·交通物流
vx-bot5556662 小时前
企业微信ipad协议的事件驱动架构与实时监听实践
架构·企业微信·ipad
绝无仅有3 小时前
计算机网络核心面试知识深入解析
后端·面试·架构
Asher05093 小时前
Spark核心基础与架构全解析
大数据·架构·spark
Traced back3 小时前
【.NET7 WinForm 实战】三层架构+EF Core+多数据库+完整功能(源码+教程+脚本)
数据库·架构·.net
绝无仅有4 小时前
Java多线程并发问题解决方案全解析
后端·面试·架构
够快云库4 小时前
制造业非结构化数据治理:架构解析与实战复盘
大数据·人工智能·架构·企业文件安全
Fox爱分享4 小时前
字节三面:千万级订单对账,怎么保证“一分钱不错”?答不出“流式比对+缓冲池”,基本就挂了
面试·程序员·架构
up_dong5 小时前
从“对话框”到“工作流”:AI 进阶路上的那次关键断舍离
人工智能·架构