VSOA 微服务架构
VSOA(Vehicle SOA)是翼辉面向 “ 任务关键型云原生架构 ” 推出的系列产品之一。所谓任务关键(Mission-Critical)型系统,即应用于轨道交通、智能电网、工业自动化、汽车电子、医疗器械等与人生命息息相关场景的系统,此类系统对实时性、安全性、可靠性有极其苛刻的要求,通常需要系统具备功能安全、信息安全、故障隔离与恢复、可靠性、实时性等一系列能力。此类系统的任何一个环节失效都可能对生命财产和环境构成安全威胁乃至出现灾难性后果,任务关键型系统可将这种灾难和危害的发生控制在可接受的范围内。
回顾计算机技术的发展历史,业务设计方法论经历了快速的迭代。每一次的技术演进,都伴随着新的开发模式变革以及业务模型提升,所有这一切的直接效果是促进生产力的爆发式提升。第四次工业革命以数字化、信息化、网联化、智能化的憧憬开启软件定义未来的产业升级之路。在海量设备连接与海量数据驱动下,我们面临诸如 M2M、AIoT 等层出不穷的全新应用场景;同时,愈发复杂的系统、碎片化的软硬件终端节点、云计算与边缘端的融合等一些列问题亟需我们去面对和解决。
翼辉信息结合任务关键型领域特性与多年的行业技术积累推出了能够快速打通云计算与边缘端设备的、适用于任务关键型系统的:任务关键型分布式微服务 VSOA 架构。
分布式微服务架构强调:分布式通信、去中心化、无状态、服务松耦合等特性。已有的大型分布式通信产品很多,例如 CORBA、DDS、Kafka、ESB 以及其衍生产品 CXF、OpenESB、 JBoss ESB 等,这些产品广泛应用于互联网服务,且经过了长期的迭代,功能成熟。不过,若要将此类产品直接应用于任务关键型场景,仍可能面临实时性优化、整合困难、资源消耗大等问题。
翼辉信息 VSOA 设计为⼀个轻量级的适用于任务关键领域的微服务架构,方便开发者构建大型分布式松耦合软件系统,且支持并行开发。其主要特点为支持多种编程语言、多 CPU 架构环境与多操作系统平台,同时不依赖任何第三方库;架构简洁、资源占用小、服务响应速度快。使用者无需单独学习 IDL(Interface description language)语言,具有开发成本低、开发效率高等特点。考虑到任务关键型场景的多样性和碎片化特点,VSOA 汇集订阅/发布、RPC、高带宽数据流以及自定义数据报等功能于一体,可满足任何分布式应用模型;同时提供非入侵式仿真测试工具与便捷的开发环境,让开发者在享受云计算先进的开发体验以及高效的生产效率的同时,继续保持任务关键领域对业务功能和性能的高可靠需求。
VSOA 当前版本包含以下特征:
订阅与发布
基于订阅/发布的通信模型是实现去中心化通信功能的最直接有效的方式。订阅/发布是一种能够同时提供一对多和多对多的异步通信模式,它能使通信的各个参与者在时间、空间和控制流上完全解耦,能够很好地满足大规模分布式网络系统松散系统通信的需求。目前成熟且广为人知的订阅/发布中间件中,代表性产品的有前文提到的 DDS 和 Kafka 等。作为后来者,翼辉信息 VSOA 在充分吸收前辈产品优点的同时,重点针对任务关键实时应用场景,提供全新的订阅/发布接口,其基于 TCP 可靠传输,接口简洁,具备实时、高效和灵活的数据交互能力的特点,满足各种分布式实时通信应用需求。
var client = new vsoa.Client(); // Receive server published event client.on('message', (url, payload) => { console.log('event:', url); console.log('param:', JSON.stringify(payload)); }); // Subscribe topics client.subscribe('/foo/bar'); // "/" Catch all publish message. // "/a/b" Only catch "/a/b" publish message. // "/a/b/" Catch "/a/b" and "/a/b/..." all publish message.
// Receive server published event void onmessage (void *arg, struct vsoa_client *client, vsoa_url_t *url, vsoa_payload_t *payload) { printf("event: %.*s\n", (int)url->url_len, url->url); printf("param: %.*s\n", (int)payload->param_len, payload->param); } int main() { vsoa_url_t url; vsoa_client_t *client; client = vsoa_client_create(onmessage, ...); vsoa_client_connect(client, ...); // Subscribe topics url.url = "/foo/bar"; url.url_len = strlen(url.url); vsoa_client_subscribe(client, &url, ...); ... }
实时 RPC
发布/订阅模型常用于过程无关的消息处理,而 RPC(远程过程调用)则主要用于分布式系统中客户端主动调用服务的特定功能,远程调用像本地 API 一样方便,无需关心远程调用的逻辑, 常用于分布式计算或控制类应用。现有的 RPC 组件大多基于弱类型或自带数据类型反射功能的高级语言,或依赖较高层次的网络协议,如 gRPC 基于 HTTP/2,实际上现有的绝大多数 RPC 组件均设计为互联网服务,较难适应任务关键型场景。此外有使用 C 语言开发的 SunRPC,但其存在跨语言交互困难、不支持并行异步调用等难题,在大规模任务关键型应用中仍然缺乏广泛的适应性。 基于以上现状,VSOA 提供了⼀套全新的、接口简洁的 RPC,且支持 C/C++、JAVA、 JavaScript 等多种语言,尤其是在 C/C++ 这类同步强类型语言上也同样实现了同步原语的异步化功能,让使用不同编程语言的开发者具有相同的开发模式和体验。异步化的好处是可以并发执行 RPC 调用,不会因为前一个 RPC 执行缓慢而阻塞后面的 RPC 调用,这在大规模实时并发控制时显得极为重要。此外,VSOA 的 RPC 采用长连接技术,以保证实时应用领域的控制确定性,同时避免不必要的通信握手等开销,提高效率。
var client = new vsoa.Client(); // Callback mode client.call('/foo/bar', { method: vsoa.method.GET }, (error, payload) => { console.log('param:', JSON.stringify(payload)); }); // Promise mode client.fetch('/foo/bar').then(payload => { console.log('param:', JSON.stringify(payload)); }).catch(error => console.error(error));
var server = new vsoa.Server(); // Catch RPC server.on('/foo/bar', (cli, request, payload) => { cli.reply(0, request.seqno, { param: { hello: 1 } }); });
// RPC callback void get_foo (void *arg, struct vsoa_client *client, vsoa_header_t *vsoa_hdr, vsoa_payload_t *payload) { printf(...); } int main() { ... // Remote Call url.url = "/foo/bar"; url.url_len = strlen(url.url); vsoa_client_call(client, GET, &url, NULL, get_foo, ...); ... }
全双工高速并行数据流
利用订阅/发布和 RPC 功能,实际上已经能覆盖大部分网络通信模型的场景。不过,若我们的业务中涉及长时间的、大量的数据传输,例如文件下载或音视频传输服务,如果在一个服务里面将常规的 RPC 或订阅/发布功能与此类大数据传输功能混合在一起,则会影响 RPC 通道的实时响应,尤其在需要 RPC 实时控制的应用中就显得极不合理;另一种思路是针对此类大数据的每一个通信,均额外实现对应的服务,但这会给开发者带来额外的编程复杂度,同时增加了整个系统的资源开销。 在 VSOA 中提供了全双工高速并行数据流,这是第三类十分亮眼且优雅的通信手段。实际上,大带宽数据流通信往往具备请求随机性、传输时间长、实时性要求相对较低等特点。因此, VSOA 数据流通道被设计为一个在已有服务链路上建立的独立的、临时的、用户无感的传输隧道。独立带来的好处是此隧道不会影响命令通道的数据交互(不影响 RPC 实时性);临时性带来的好处是按需创建,此传输隧道在数据传输完成后可随时销毁,不持续占用连接资源;用户无感意味着这是在 VSOA 内部自动协商建立的传输隧道,无需用户关心创建隧道的细节(例如无需提前约定好一个确定的通信参数,避免复杂的设计实现)。综上,VSOA 数据流接口较完美地解决了以上提到的业务难题。
var client = new vsoa.Client(); // Fetch big size data client.fetch('/big/data').then((payload, tunid) => { var stream = client.createStream(tunid); // Duplex Stream stream.on('data', chunk => { console.log('Stream rece:', chunk.byteLength); }); }).catch(error => console.error(error));
var server = new vsoa.Server(); var buffer = new Buffer(...) // Big Data // Get big size data server.on('/big/data', (cli, request, payload) => { var stream = server.createStream(); cli.reply(0, request.seqno, stream.tunid); // Duplex Stream stream.on('connect', () => { stream.write(buffer); stream.close(); }); });
数据报
在 VSOA 的设计中,充分考虑到不同应用场景的差异化和定制化需求,在以上标准功能之外,提供另一种数据交互方式:DATAGRAM,即数据报,这是一种无过程依赖的传输类型。在使用习惯上,与 UDP 通信类似(但具备可靠传输特性)。在使用时,VSOA 会将 DATAGRAM 类型的数据直接抛出,无需等待对端应答,用于传输一些不需要确认的数据。例如,利用 VSOA 的 DATAGRAM 数据包可以用来搭建 VPN 网络。基于 DATAGRAM,客户端与服务端可以进行更加灵活的通信。使用 DATAGRAM 接口,可彻底摆脱基于 socket 的底层 API,统一且简化用户编程界面,扩展用户业务自定义处理流程,提高了业务的灵活性和扩展性。
var client = new vsoa.Client(); // Get datagram client.on('datagram', (url, payload) => { console.log(...); }); // Send datagram client.datagram(...);
var server = new vsoa.Server(); // Get datagram server.ondata = (cli, url, payload) => { console.log(...); }; // Send datagram cli.datagram(...);
统一的资源标识
制约任务关键型业务往高层模型转变的一个重大因素即是硬件设备的差异化、通信链路的碎片化以及众多自定义的、形式各异的通信协议。在 VSOA 的世界里,所有的差异化均得到统一,这里吸收了云计算的优点,所有的硬件、软件服务均提供统一的资源标签 URL。据此,我们可以从传统的基于硬件接口交互的视角往更为通用的资源访问视角迁移。资源标识能够彻底屏蔽软硬件差异,无需关心软硬件的物理位置以及实现细节,这使得对资源的统⼀调配乃至模型化构建服务成为可能。 VSOA 的 URL 以 vsoa:// 开始,类似 http:// 。此外,翼辉还提供 VSOA 到 HTTP 的代理桥接组件,在兼容已有软硬件设施的前提下,可完全让任务关键型设备与云计算服务相互融合。 例如:一个业务系统中,存在传感器数据采集服务,假定它的服务 URL 为 vsoa://domain/sensor ,该综合服务包含了红外、雷达等多种传感服务,它们的服务 URL 分别为 vsoa://domain/sensor/infrared 、 vsoa://domain/sensor/radar ,应⽤如果需要获取红外或者雷达专有信息服务,精准订阅它们 URL 即可,如果需要获取综合服务下面的所有子服务,则可直接通过订阅其父节点即可,通过这种订阅匹配机制,可以降低代码编写的复杂度,提高代码编写效率与质量。
VSOA 中的所有通信均采⽤ URL 标识资源,且已为常规应用场景定义了推荐的资源命名规则:
命名规则 | 适用说明 |
“/api/*” | RPC 命令 |
“/par/*” | 针对服务器参数的设置、获取以及发布 |
“/sta/*” | 针对服务器状态的获取以及发布 |
“/dbg/*” | 服务器调试信息 |
“/res/*” | 服务器资源 |
基于 VSOA 的 URL 推荐命名规则,不论是使用发布/订阅,还是 RPC 或者数据报等功能,均能得到统一,不用担心因整合不同类型的分布式产品带来的编程规范不一致的问题。同时,采用 VSOA 定义的推荐资源命名规则,更能将整个系统的服务功能和职责表达得更加清晰明确,易于扩展和管理。
域名管理
域名服务器(DNS)解决了位置无关的服务连接查询问题。与 DNS 类似,VSOA 体系中也提供了位置服务(Position Server),基于位置服务的能力,客户端无需知道服务提供方实际的网络地址即可与其建立连接,使得整个系统的兼容性、可靠性得到质的提升。此外,VSOA 的位置服务提供标准实现模板,支持多级位置服务级联查询,冗余服务管理等,同时也可定制化设计满足不同场景需求。例如,我们完全可以轻松实现服务的自发现功能, 即无需在 Position Server 中提前配置每个服务的地址信息,而是由服务主动向其报告自己的地址信息。不过,这种实现存在较大的安全隐患,容易带来域名劫持等问题,可通过数字签证和鉴伪等技术避免此类风险。
var client = new vsoa.Client(); // Connect client.connect('vsoa://example.com', ...);
int main() { struct sockaddr_in server; socklen_t serv_len = sizeof(struct sockaddr_in); ... // Query 'example.com' address vsoa_position_lookup(AF_INET, "example.com", (struct sockaddr*)&server, &serv_len, ...); ... // Connect vsoa_client_connect(...); }
流畅的数据交互体验
在基于 TCP/IP 的网络业务中,我们往往纠结于选择 UDP 还是 TCP,前者处理无过程依赖和无状态的场景非常适合,但需要应用层考虑传输可靠性与顺序问题;后者具备可靠传输,但面向连接且为流式数据,需要用户层考虑数据粘包问题。VSOA 深知用户痛点,已将以上提到的优点完美融合,内部使用 TCP 长连接,同时内部自动处理数据粘包等问题,用户完全不必考虑这类过于底层的问题。此外,借助于 VSOA 提供的数据建模自动化工具,可完全摆脱数据底层转换细节,专注服务设计,在流畅的数据交互体验中轻松构建你的业务。
QoS
针对实时应用场景,VSOA 利用协议栈 IP DSCP 为每一个数据包定义优先级等属性,同时在 VSOA 传输逻辑上实现了数据包优先级队列,两者配合实现 QoS 管理,VSOA 将 QoS 的核心实现放在协议栈与传输逻辑层可以使 VSOA 的应用更加轻量化。对上层开发者,其提供了简洁的 QoS 服务接口,遵循 SOA 方便、有序的理念,VSOA 为服务器与客户端之间的数据交互定义了一套优先级规则:客户端无法自行定义、更改服务优先级,必须向服务端申请,且最终是否申请成功完全由服务端决定,在保持灵活松散的架构下,避免整个系统变得无序、混乱甚至不可协调。
var server = new vsoa.Server(); // Set new client priority to 3 server.onclient = (cli, connect) => { if (connect) { cli.priority(3); } };
// On client callback void oncli(void *arg, vsoa_server_t *server, vsoa_cli_id_t id, bool connect) { if (connect) { vsoa_server_cli_priority(server, id, 3); } } int main() { ... vsoa_server_on_cli(server, oncli, ...); ... }
连接状态管理
网络通信中另一个必须面对的问题是连接状态管理,涉及的场景需求包括客户端、服务端的启动顺序无关性、连接状态监测、自动重连等。VSOA 充分考虑到这类需求,提供了简单且完善的接口解决此类问题。对于一个 VSOA 的客户端来说,可先于服务器重启,且轻松实现服务器在线探测并进⼊业务循环;也可轻松实现运行时断线重连(如服务器重启),无需考虑连接失败的情况下是否删除客户端对象或软件重启的问题;对于一些安全级别较高的服务,也可通过相关安全规则(如服务密码或异常行为监控)拒绝或主动断开客户端连接。
var client = new vsoa.Client(); // Connected client.on('connect', () => { // Subscribe client.subscribe(...); ... }); // Connect function connect() { client.connect('vsoa://...'); } // Error check client.on('error', error => { console.error(error); // Reconnect after 1s setTimeout(connect, 1000); }); // Connect connect();
VSOA 是一整套完善且体系化的分布式微服务平台。在 VSOA 的世界里,我们力图为开发者提供统一的、简洁而优雅的、标准化的、模型化的开发体验,让开发者不再局限于数据交互细节,更专注于业务模型的构建,加速产品迭代交付。
标准编程范式
VSOA 为服务端、客户端、域名服务以及数据流应用等提供标准化的范式业务模板,通常情况下开发者只需基于标准模块添加自己的定制化业务代码即可快速实现自己的业务系统构建。 VSOA 还为 C 语言版本提供低代码化功能,针对发布/订阅和 RPC 服务的常规功能逻辑,可使⽤ VSOA 参数同步器,仅用一行代码,即可自动处理数据序列/反序列化、发布、RPC 应答等功能,极致简洁。
var server = new vsoa.Server(); server.on('/foo', function(cli, request, payload) { server.syncer(cli, request, payload, data, param => { if (typeof param.foo === 'number') { data.foo = param.foo; return vsoa.code.SUCCESS; } else { return vsoa.code.ARGUMENTS; } }); });
// Command '/foo' routine static void command_foo (void *arg, vsoa_server_t *server, vsoa_cli_id_t cid, vsoa_header_t *vsoa_hdr, vsoa_payload_t *payload) { VSOA_PARAM_SYNCER_RPC(server, cid, foo, &my_server.data, vsoa_hdr, payload, NULL, NULL); }
轻松实现冗余健壮性设计
分布式系统中,各种服务运行在不同的软硬件平台上,且彼此之间通过网络进行交互,因此可能因网络质量和软硬件基础设施故障导致服务不可用,进而导致服务组合出现失效,影响软件的可用性。软件容错技术能保证被调用服务出现故障时,始终有可用的服务替代故障服务的功能,以保证软件在单个服务失效时,仍能为用户提供正常的业务功能。 在 VSOA 中,同一种服务可同时部署在不同的硬件平台上,实现通信的冗余安全;同时可搭配位置服务器(Position Server),再结合优秀而简单的连接状态管理,轻松实现客户端无感的备份服务切换,甚至也可部署多个位置服务器进一步增强整个系统的健壮性。
var pos = new vsoa.Position(...); // On query pos.onquery = (name, domain, reply) => { if (in_local_cache) { // In local server name cache if (main_serv_alive) { // Is main server alive? reply(undefined, main_address); } else { // Return slave server address reply(undefined, slave_address); } } else { // Cascading queries vsoa.lookup(name,(error, addr) => { reply(error, addr); }); } };
兼容碎片化的外设和协议
在任务关键型领域存在着繁杂多样的 OT 总线通信(CAN、RapidIO、1553B、RS232、 RS485 等),且存在通信协议差异化、定制化严重等问题,因此此类应用往往是 SOA 治理的难点。针对这种情况,VSOA 提供了连接 VSOA 体系与 OT 总线通信的代理桥接服务,将任务关键型外设、总线协议统一抽象为 VSOA 的标准资源标识,解决大型任务关键型复杂应用长久困扰的外设与协议碎片化问题。同时也可借助于外设的模型化统一能力,可以通过构建虚拟化外设代理服务实现对外设的仿真模拟,降低大型系统的仿真成本。
建模工具 JStruct
在互联网领域,通常基于高级语言开发应用服务,且已经形成大量广泛成熟的协议组件。但在传统的任务关键型应用领域,往往采用 C/C++ 这类强类型语言,这导致协议格式与语言强相关,尤其是遇到协议格式的变化时,往往导致整个系统需要重新编译部署,在大规模分布式应用场景中,这种变化带来的系统更新维护成本将是灾难性的。 JSON 作为现在最主流的数据交换语言之一,具有兼容性强、简洁、清晰的层次结构,相较于其他数据描述语言更加易读、易编写。但使用 C/C++ 进行本地数据类型与 JSON 数据之间的转换工作非常繁琐且容易出错,仍然存在以上问题。VSOA 中推荐采用 JSON 格式文本作为跨语言交互的基础数据,并为此提供了 JStruct 模型化工具,可使用⼀个 JSON 格式的数据接口描述文档,自动生成 C/C++ 本地数据类型与 JSON 数据之间的序列化/反序列化代码,在完全杜绝人工数据转换带来的潜在风险的同时,为开发者提供顺畅的低代码数据操作体验。 JStruct 的详细介绍:https://github.com/hanhui03/jstruct
#ifdef __cplusplus extern "C" { #endif /* Deserialize the JSON string into a structure 'data' */ bool foo_json_parse(struct data *, const char *, size_t); /* Free foo_json_parse() buffer, Warning: string type member can no longer be used */ void foo_json_parse_free(struct data *); /* Serialize the structure 'data' into a JSON string */ char *foo_json_stringify(const struct data *); /* Free foo_json_stringify() return value */ void foo_json_stringify_free(char *); #ifdef __cplusplus } #endif
非入侵仿真测试工具
在大型复杂应用中,随着复杂度的增加,排查问题也愈发困难,传统的调试方式中,已有的调试工具基本都集中于本地化单机测试,且往往需要重新构建应用,在故障复现概率极小的情况下,重新构建应用可能引入新的问题或者由于时序的变化导致故障无法重现,加剧了故障的排查难度。针对以上问题,VSOA 提供了非入侵的仿真测试工具,包括用于发布/订阅的数据监听器 vcl 和用于 RPC 的命令执行器 vcx ,可在开发阶段用于信息交互测试、数据激励;也可在现有系统运行时,无感知地对所有通信数据、交互过程进行监控、探测、诊断,极大提高生产力。
全面的语言、系统与环境支持
为了满足任务关键型应用以及万物互联的复杂环境需求,VSOA 在硬件、操作系统、开发语言以及运行时环境几个方面进行了全方位适配,当前的支持情况如下:
![]() |
![]() |
![]() |
![]() |
VSOA 期望能够给传统的任务关键型系统开发提供⼀个先进的架构,让我们在设计软件系统时不再过多关注硬件的功能和位置差异、软件的运行环境差异、通信链路差异等客观信息,基于 VSOA 的应用天然就应该假设我们的服务可以随时随地部署在任何系统任何硬件上,各分系统之间基于模型数据交互,不关心过程,只关心结果,实现开发模式和开发思维的全面升华。 翼辉信息的下一个目标是,利用 VSOA 搭配翼辉全套自研技术体系产品 EdgerOS、ECS Manager 容器管理平台、ECS Cloud 容器云、ECS 实时容器,让整个业务系统技术体系上升到一个全新的台阶,真正实现任务关键型软件系统开发的“四个现代化”:
翼辉信息的 ECS 容器保证了应用在开发与部署阶段的环境一致性,可以实现对整个应用运行环境的版本控制,一旦应用出现故障可以快速回滚,同时可以解决由于环境变化产生的程序不正常现象。ECS 容器极其轻量,对系统资源的占用开销极低,可广泛适应任务关键型软硬件的应用场景。ECS 容器具备完善的资源隔离与限制能力,可杜绝应用错误对操作系统与其他应用产生的影响,通过对容器内系统资源的配额管理能够更好的实现系统集成。同时,ECS 容器兼容 OCI 容器镜像标准和运行时标准,接近 Docker 使用习惯,可以与符合 OCI 标准的容器管理平台实现无缝对接。
基于翼辉信息的 EdgerOS、ECS 容器、容器管理平台、VSOA,可灵活构建出全自主技术体系的任务关键型云原生架构,实现部署容器化、管理自动化的 DevSecOps 功能,为行业用户的大型复杂应用提供可靠、实时、弹性、高可用的基础平台,广泛赋能场景复杂、跨域连接的智能制造、智能汽车、航空船舶等领域。