爱智EdgerOS之深入解析高效可靠的轻量级服务VSOA

一、VSOA 简介

① 什么是 SOA?

SOA (Service Oriented Architecture) ,即面向服务的架构,是一种分布式计算的软件设计方法,软件的部分组件(调用者),可以通过网络上的通用协议调用另一个应用软件组件执行、运作,让调用者获得服务。这里的服务应视为软件功能的一个独立单元,可以远程访问并独立执行与更新,比如说需要查询的指定状态信息或者要执行的某项操作。换句话说,SOA 集成了独立部署和维护的软件组件,并允许它们相互通信和协同工作,以构建一个跨系统的软件应用。

② 什么是 VSOA?

  • VSOA(Vehicle SOA)是翼辉面向“任务关键型云原生架构”推出的系列产品之⼀。所谓任务关键(Mission-Critical)型系统,即应⽤于轨道交通、智能电网、⼯业⾃动化、汽⻋电⼦、医疗器械等与⼈⽣命息息相关场景的系统,此类系统对实时性、安全性、可靠性有极其苛刻的要求,通常需要系统具备功能安全、信息安全、故障隔离与恢复、可靠性、实时性等⼀系列要求。此类系统的任何⼀个环节失效都可能对⽣命财产和环境构成安全威胁乃⾄出现灾难性后果,任务关键型系统可将这种灾难和危害的发⽣控制在可接受的范围内。

二、VSOA 的优势

  • 目前市面上主流的任务关键型架构,通常会遇到学习和使用繁琐、依赖复杂、代码整合麻烦和实时性低等问题。于是翼辉信息 VSOA 设计为⼀个轻量级的适⽤于任务关键领域的微服务架构,⽅便开发者构建大型分布式松耦合软件系统,且⽀持并⾏开发。
  • 其主要特点为⽀持多种编程语⾔、多 CPU 架构环境与多操作系统平台,同时不依赖任何第三⽅库;架构简洁、资源占用小、服务响应速度快。使用者无需单独学习 IDL(Interface description language)语言,具有开发成本低、开发效率高等特点。考虑到任务关键型场景的多样性和碎片化特点,VSOA 汇集订阅/发布、RPC、高带宽数据流以及⾃定义数据报等功能于⼀体,可满⾜任何分布式应用模型;同时提供非⼊侵式仿真测试工具与便捷的开发环境,让开发者在享受云计算先进的开发体验以及高效的⽣产效率的同时,继续保持任务关键领域对业务功能和性能的⾼可靠需求。
  • VSOA 兼容多种通信风格,开发人员可以根据不同的应用场景采用不同的通信方式,VSOA 支持以下特性:
    • 支持统一 URL 的资源标记;
    • 支持 URL 匹配订阅和发布模型;
    • 支持实时的远程过程调用;
    • 支持并行多个命令序列;
    • 支持多通道全双工高速并行数据流;
    • 支持网络 QoS 控制;
    • 轻松实现服务器容错设计;
    • 支持多语言绑定。

三、VSOA 通信机制

  • VSOA 传输数据的有效负载分为 param 和 data 两种形式,param 可以为 object 或 string ,data 为 Buffer。
/**
 * server.publish(url[, payload])
 * @param url {string}
 * @param payload {object} 
 */
server.publish('/a/b/c',{
    
     param:{
    
     hello:'hello'}})
server.publish('/a/b',{
    
     param:{
    
     hello:'hello'}, data:new Buffer([1,2,3])})

① subscribe / publish

在这里插入图片描述

  • 基于订阅/发布的通信模型是实现去中⼼化通信功能的最直接有效的⽅式。server 端发布一个消息,所有订阅此 URL 的 client 端都可以收到该消息。URL 通过 / 作为分隔符,当 client 订阅 /A 的消息, server 发布的类似 /A 、/A/B 、/A/B/C 等消息都可以匹配接收到。
/**
 * server.js
 */
server.publish('/a/b/c',{
    
     param:{
    
     hello:'hello'}})
server.publish('/a/b',{
    
     param:{
    
     hello:'hello'}, data:new Buffer([1,2,3])})

/**
 * client.js
 */
client.subscribe('/a', function (error) {
    
    
  if (error) {
    
    
    console.error('Subscribe error', error)
  }
})
client.on('message', function (url, payload) {
    
    
  console.log('Message:', url, JSON.stringify(payload))
})

② datagram

在这里插入图片描述

  • 这是一种无依赖的通信方式,server / client 将 DATAGRAM 类型的数据发送之后, ⽆需等待对端应答。通常 DATAGRAM 类型的数据用于传输一些不需要确认的数据。
/**
 * client.js
 */
client.datagram('/foo', {
    
     "param": {
    
     'client send time': new Date().toLocaleString() } })
 
client.on('datagram', (url, payload) => {
    
    
  console.log('client receive Datagram:', url, JSON.stringify(payload))
})

/**
 * server.js
 */
server.ondata = function (cli, url, payload) {
    
    
  console.log('server receive datagram', url, JSON.stringify(payload.param))
  /*
  * do something or reply a message
  */
  cli.datagram('/bar', {
    
     param: `${
    
    new Date().toLocaleString()} ` })
}

③ call / fetch

在这里插入图片描述

  • 当 client 端发起 RPC 命令的请求,服务器会收到相应的请求事件,事件名称和 client 请求的 URL 一致。为了保证可靠,client 端的每一次请求都有一个序列号,server 端可以对某个请求进行回复。
/**
 * server.js
 */
server.on('/a/b/c', function (cli, request, payload) {
    
    
  /*
  * do someting and reply
  */
  console.log(JSON.stringify(payload))
  cli.reply(0, request.seqno, {
    
    param:'completed'});
});

/**
 * client.js
 */
client.call('/a/b/c', {
    
     method: vsoa.method.SET }, {
    
    
  param: {
    
     hello: 'hello' }
}, function (error, payload) {
    
    
  if (error) {
    
    
    console.error('RPC call error:', error);
    if (error.status) {
    
    
      console.error('Error status code:', error.status);
    }
  } else {
    
    
    console.log('RPC call OK:', JSON.stringify(payload));
  }
})

④ 全双工流

在这里插入图片描述

  • server 端创建一个流等待 client 端的流连接,这个对象继承自 Stream.Duplex ,每一个 server 包含一个tunid 。client 端流使用这个 tunid 连接 server 端流,完成连接后,此 tunid 置为 0,其他 client 端不能再次使用这个 tunid 进行连接传输数据流。客户端(服务端)可以通过可写流向对端发送消息,通过可读流接收对端消息,两个流内的数据并没有直接的关系。这种全双工方式无需进行读写方向的切换,因此,没有切换操作所产生的时间延迟,这对那些不能有时间延误的交互式应用(例如远程监测和控制系统)十分有利,我们也可以通过这种方式进行文件传输等操作。
/**
 * server.js
 */
server.on('/a/b/c', function (cli, request, payload) {
    
    
  var stream = server.createStream();
  cli.reply(0, request.seqno, stream.tunid);
  
  stream.on('connect', () => {
    
    
    stream.write(Buffer([0, 1, 2, 3, 4, 5, 6]));
    stream.close();
  });
    
  stream.on('timeout', () => {
    
    
    console.log('No client connect stream!');
  });
});

/**
 * client.js
 */
 client.fetch('/a/b/c').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));

四、VSOA 定位服务

  • VSOA 提供一种类似于 DNS 的服务,它将 VSOA 服务器的名字映射到服务器的地址上,可以通过服务器的名字快速找到服务器的地址。当我们未指定位服务的地址时, Position Server 使用 VSOA 服务器的名字在 /etc/vsoa.pos 文件查找 VSOA 服务器的地址。我们也可以使用 vsoa.Position.server 指定定位服务的地址,后续查询操作将使用此地址进行查询。当在服务器的初始化列表找不到的时候,会调用 position.onquery 函数返回。 此外,VSOA 的位置服务提供标准实现模板,⽀持多级位置服务级联查询,冗余服务管理等。
const vsoa = require('vsoa');
const socket = require('socket');

const saddr = {
    
     domain: socket.AF_INET, addr: '127.0.0.1', port: 3200 };
const position = new vsoa.Position([
  {
    
     name: 's1', domain: 2, addr: '127.0.0.1', port: 2050, security: false }
], saddr);

position.start();
vsoa.Position.server(saddr)

position.onquery = function (name, domain, callback) {
    
    
  console.log(`cannot find ${
    
    name} ,call this function`);
  if (name === 's2') {
    
    
    callback({
    
     name: 's2', domain: 2, addr: '192.168.128.100', port: 2049, security: false });
  } else {
    
    
    callback({
    
     name: 'default', domain: 2, addr: '192.168.100.100', port: 3000, security: false });
  }
}

vsoa.lookup('s1', function (error, saddr) {
    
    
  if (error) {
    
    
    console.log(`lookup s1 error: ${
    
    error}`);
  } else {
    
    
    console.log('the ret of lookup s1:', JSON.stringify(saddr));
  }
});

vsoa.lookup('s2', function (error, saddr) {
    
    
  if (error) {
    
    
    console.log(`lookup error: ${
    
    error}`);
  } else {
    
    
    console.log('the ret of lookup s2:', JSON.stringify(saddr));
  }
});

猜你喜欢

转载自blog.csdn.net/Forever_wj/article/details/129661481