写点什么

借助基于模块的软件工程方法征战物联网丛林

  • 2017-08-16
  • 本文字数:8545 字

    阅读完需:约 28 分钟

主要结论

  • 从软件工程的观点来看,物联网应用有两个特征。首先,包含大范围分布的处理节点;其次,处理节点以及通信协议存在极高异构性。
  • ThingML(Internet of Things Modeling Language,物联网建模语言)方法旨在促进服务开发者与平台专家之间的协作,帮助双方联手使用建模语言、一系列工具,以及相应的方法论开发基于物联网的增值服务。
  • ThingML 的主要目的是物联网软件建模,通过将现有代码融入 ThingML 模型,为复杂事件的处理和新传感器的发现提供支持,可简化这一过程的实现,同时还可针对异构平台生成代码。
  • 在商用医疗解决方案中运用 ThingML 已可证明其效果,但在部署和更新等方面,这种方法依然面临重要的挑战。

本文首发于 IEEE Software 杂志。 IEEE Software 针对当今世界的主要战略性技术问题提供了坚实的同行审阅信息。为了应对企业在可靠性、灵活性等方面提出的挑战,IT 经理和技术主管必须依赖 IT 专业人员才能获得最先进的解决方案。

在 UML 启发下诞生的 ThingML 方法解决了物联网在分布和异构两方面遇到的挑战。这种模块驱动的生成式方法还在不断演进,已在不同领域获得了广泛应用,包括商业化的数字医疗解决方案。

编写、部署、演化物联网软件的过程中面临的挑战往往被人们低估 [footnote1]。从软件工程的观点来看,物联网应用有两个特征。首先,包含大范围分布的处理节点;其次,处理节点以及通信协议存在极高异构性。对于上述每个特征,都有大量围绕软件工程的文献,然而很少有研究结果能同时解决这两个问题,进而会产生三个挑战。

首先,在大规模物联网应用中,往往包含大量异构节点,在距离数据源较近的位置处理数据,以及通过去中心化的方式做出响应的过程中,这些节点通常扮演了不同的角色。分布式系统、远程通信,甚至传感器网络领域的大量研究都专注于伸缩至极大数量的节点,但对于这些节点的类型和角色(例如客户端 - 服务器、对端追踪器、传感器网关服务器等)往往涉足甚少 [1] 。这种同质性的特征使得我们可以针对大量节点开发并部署类似的代码,确保软件不会变得过于复杂。但物联网软件的情况截然不同,物联网不仅需要对节点数量进行伸缩,而且需要对节点和平台的类型数量进行伸缩,例如从微控制器扩展至云端。

其次,为了让物联网系统发挥全部潜力,开发者必须充分利用异构节点锁提供的多样化资源和去中心化计算能力。很多工具和技术会隐藏这种异构性,借此帮助开发者编写能在不同平台(操作系统、Web 浏览器、移动设备等)上以相同方式执行的应用 [2] 。在物联网应用中,这种异构性从部分方面来说并非出于偶然,开发者必须明确这种特性并能加以利用。例如只有这样,开发者才能利用物联网节点的深度睡眠模式省电,而不同平台在这种模式的实现上往往存在差异。

第三,按照物联网的愿景,应用程序不再是相互隔离的专有设备和软件组成的“竖井” [3] ,而是在整个环境中相互结合唾手可得的真实物件:有共性,也有面向具体应用的个性,甚至可能还有遗留的物件。因此物联网应用必须能在共享的硬件上运行,开发者也需要密切注意,以避免应用之间产生不必要的交互。

因此工业化的物联网应用会在开发过程的不同阶段面临挑战,开发者团队需要在电子、微处理云计算,以及数据挖掘等领域有着全面的资质。ThingML(Internet of Things Modeling Language,物联网建模语言)方法旨在促进服务开发者与平台专家之间的协作,帮助双方联手使用建模语言、一系列工具,以及相应的方法论开发基于物联网的增值服务。过去六年来,这个方法在不断演进,已在不同领域获得了广泛应用,包括商业化的数字医疗解决方案。

ThingML 方法

ThingML 方法的发展历程

ThingML(Internet of Things Modeling Language)方法意在将学术界有关基于模型的软件开发技术带到相关行业内。

过去六年来,ThingML 语言和工具经历过三次重大变革。

第一次迭代主要基于原有 UML 工具。我们开发了一种极简化语言,用来描述基于传感器的架构,实现了商用状态机工具生成的代码与现有 API 的集成。但大规模传感器网络的开发(与油气行业合作)受到了难用的图形规范(几个“玩具示例”除外)、资源有限的平台对代码要求严苛,以及重要的遗留和第三方组件等问题阻碍。

第二次迭代为状态机引入了一种文本语法(Textual syntax)以及以及一种一流的动作语言(Action language)。我们还分别针对微处理器、Posix C 和 Java 提供了三个独立的编译器。我们通过 CORBYS(Cognitive Control Framework for Robotic Systems:corbys.eu)项目开发了一种医疗康复机器人,并通过 Arrowhead 项目(arrowhead.eu)开发了一种智能家居网关,借此证明了这种文本语言的用途。同时也证明了固定的整体式编译器(Monolithic compiler)所存在的局限,必须对其进行必要的调整才能满足项目需求。

借此我们也意识到,真正重要的还是代码本身。基于模型的技术不应试图替代或隐藏实际代码,而是应该支持从业者以更系统化,也更有效的方式生成所需代码。

第三次迭代主要围绕 HEADS 项目(heads-project.eu),通过以往获得的经验,我们为医疗和数字健康领域提供了两个几乎完全实现的商用产品。该项目的主要贡献在于代码生成框架,并通过相关方法论让从业者可以全面控制代码,根据需求灵活定制编译器。第三次迭代同时还为 ThingML 语言扩展出更多概念,例如复杂事件处理以及动态会话(见下文)。

我们所提出的方法是与行业合作伙伴和从业者不断联手完善,根据反馈进行改进的产物。

ThingML 方法包含一个建模语言,一系列工具,以及一个方法论。该语言(ThingML)包含与 UML(状态图 [Statechart] 和组件)相符并获得证实的软件建模构造,一种必须采用的平台独立动作语言,以及围绕物联网应用制定的构造。工具包括编辑器、转换器(例如导出至 UML),以及一个可支持多种目标编程语言的高级多平台代码生成框架 [4] 。方法论规定了物联网服务开发者和平台专家的开发流程和所用工具。语言、工具、方法论,均以开源形式包含在 HEADS IDE 中发布。

物联网软件建模

ThingML 方法的首要目标是对异构平台和物联网设备进行抽象,借此为所需的物联网系统架构进行建模。在实践中,平台和设备,以及软件组件的最终分布通常在早期设计阶段是不确定的。架构模型可包含组件、端口、连接器,以及异步消息。

常规架构定义完毕后,我们的方法可以通过平台独立的方法使用状态图和动作语言确定组件的业务逻辑规范。ThingML 状态图包含合成器、并行区域,以及历史状态。状态机通常会对组件端口传入的消息所对应的事件做出响应。动作语言可以让开发者在组件中指定保护措施、动作、变量,以及函数,并让状态机通过组件端口收发消息。

促进应用程序的开发

ThingML 方法还集成了三个可以促进物联网应用开发的功能。首先是一种可以通过将 ThingML 代码融入目标代码,快速封装现有库的机制。其次是通过复杂事件处理(CEP)处理复杂反应模式的能力。第三是可以动态发现传感器的动态会话功能。

ThingML 与原生代码的融合。平台独立的规范有助于促进早期开发工作,以及不直接依赖底层系统或硬件功能的组件开发工作。然而一旦开发者选定了具体平台,必须以足够高效的方式实现某些组件,并且要能充分利用硬件功能以及任何可用的软件库。为提供所需灵活性,我们的方法可以自由地将模型动作与目标语言动作结合在一起。这种机制使得开发者可以轻松地双向共享变量并实现调用和回调。

图 1 展示了将一个组件链接至现有 JavaScript Z-Wave 库的实现。蓝色代码是纯粹的 JavaScript 代码,借此我们初始化了 Z-Wave 驱动并注册了回调。我们将 ThingML 代码融入这些回调中,借此可在调用回调时发出 ThingML 事件。通过这种方式,网关依然可以实现平台独立,只要针对 ThingML 事件做出回应即可。

(点击放大图像)

图1:ThingML 中平台独立和平台特定的组件。蓝色代码是纯粹的JavaScript 代码,借此我们初始化了Z-Wave 驱动并注册了回调。这些回调包含的ThingML 代码可在调用回调时发出ThingML 事件。

CEP。物联网业务逻辑通常需要对不同来源和设备的事件流做出回应。根据我们的经验,当时用传统状态机(或直接使用目标语言)实现这种逻辑时,会不必要地增加事件缓冲集地复杂度,并会将不同来源的事件混合在一起。CEP 语言以及诸如 ReactiveX 等库 [5] 提供了一种陈述式(Declarative)的方式,可以指定如何处理来自不同流的事件,并将其结合成一个新的事件流。

我们的方法在与状态机相同的层面上定义了 CEP 查询。与状态机类似,CEP 查询可处理一系列输入消息并生成输出消息。然而 CEP 查询的规范完全是陈述式的。ThingML CEP 包含的运算符可联接(Join)并合并(Merge)消息流,并可在通过时间或消息数量定义的窗口内处理消息。下文我们将通过之前提到的数字医疗应用介绍 CEP 查询。

会话。物联网网关组件可动态地处理连接,与通过网关网络往来的设备交互。此类动态环境的处理与 Web 应用中用户会话的处理极为类似。为了实现此类行为,我们本可使用即席(Ad hoc)解决方案,但为了提供系统化的解决方案并杜绝内存管理方面的问题,ThingML 状态机也使用了会话的概念。

“会话”是对并行区域(Parallel region)进行动态实例化的产物,会在初始化时包含其父项上下文(一组属性)在 Fork 时的副本。会话可执行自己的行为(状态机、CEP,或函数),并且只能访问和修改自己的上下文。与其他组件一样,父项和会话只能通过异步消息通信。会话到达最终状态后将会终止。下文将在数字医疗应用中展示会话的使用。

为异构平台生成代码

与从业者通过基于模型的方式进行开发,我们最大的收获是:代码真的很重要。尽管很多架构师与管理者通常更愿意使用模型和系统化的代码生成技术,但有经验的开发者往往更关注通过模型生成的代码的质量、可管理性,以及集成。所有重要项目对 ThingML 方法的成功运用都要求对代码生成器进行调整,不仅是为了满足目标平台的需求,同时也是为了满足整个项目对代码风格、库、API,以及遗留组件等方面的要求。

考虑到这些情况,ThingML 代码生成框架可以帮助开发者适应并扩展代码生成器,以满足自己领域和项目的独特需求。该框架包含一个抽象框架以及针对三种语言(C/C++、Java、JavaScript)现成可用的代码生成器,以及多个库和开放平台(Arduino、Raspberry Pi、Intel Edison、Linux 等)。在物联网应用中,ThingML 组件可分布在不同的异构平台中,因此需要使用不同的代码生成器。此外还可通过特定的代码生成器插件为不同平台上多个组件生成通信并交换消息。

为了能高效地定制所生成代码的任何内容,该框架还提供了大约 10 个扩展点,每个都可生成特定类型的源代码。例如用一个生成器发布 API,用另一个生成器实现组件。在物联网系统中,每个组件都可以用不同组合方式使用众多代码生成器插件。

在使用、扩展、定制代码生成器过程中,还有一个重要问题:必须确保它们都能为 ThingML 构造提供相同的执行语义。为了帮助开发者做到这一点,我们提供了一个包含上百种测试用例以及一系列测试装置(Test harness)的测试框架(还可针对新的目标平台进行扩展),借此可对任何代码生成器进行自动化的诊断。该测试框架可针对所有测试用例生成代码,在目标平台上执行代码,收集执行过程追踪信息,并将其与一系列参考记录进行对比。

实际运用中可定制的范围非常广泛,从现有生成器的简单调整,到针对新平台或目标编程语言开发全新的生成器,均可实现。下文将简单介绍三个例子以及大致的工作量。

首先,可对特定动作进行定制,例如让 ThingML 将输出结果保存到日志文件,而非在控制台中显示文字,这大约需要 5 行 -50 行代码。

另一个常见的定制是更改所生成项目的具体构造并进行构建,例如从默认的 Maven 改为 Gradle,以管理并构建 Java 项目,这大约需要 100 行代码。

最后说一个略微复杂的定制,该框架可通过构建插件处理不同平台上组件之间的消息交换。例如可以让任何 Java 组件与任何 C 组件通过 MQTT(Message Queuing Telemetry Transport)通信,这大约需要 800 行代码,其中 Java 需要约 400 行,C 也需要约 400 行。在这 400 行代码中,大约有一半负责消息的编组(Marshaling)和解组(Unmarshaling),另一半负责处理使用 MQTT 库进行的载荷传输。默认情况下,对于受支持的语言可以使用二进制序列化 [6] 和 JSON(JavaScript Object Notation)序列化,以及 MQTT、WebSocket,以及序列传输协议。

在不使用现有插件的情况下全新实现一个编译器,大约需要 10,000 行代码。这个过程较为困难,但对大部分开发者,至少企业中的开发者来说,依然是可行的。

打造数字医疗跌倒检测系统

挪威 IT 公司 Tellu 开发的 SmartTracker 是一种物联网平台,可以让用户注册传感器,存储数,并使用云服务器中运行的 JBoss Drools 定义业务规则。该公司适用于物品和人员的地理围栏和监视应用已正式商用。虽然这种集中化的方式在某些领域已有成功的先例,但 Tellu 发现在数字医疗服务的开发方面存在局限,因为这个领域对数据吞吐量、延迟、时间要求,以及可靠的反应等方面有更高要求。这种情况下,业务逻辑必须分布在整个物联网架构中,而所建立的系统必须能在不依赖互联网连接或云服务的情况下实现关键功能。

Tellu 数字健康解决方案的核心是一种基于气压的跌倒检测系统。该系统的表现远超竞争对手,并使用了可穿戴的惯性传感器。然而除了可穿戴传感器,该系统还要求环境中具备固定式压力传感器集群 [7] 。这个额外的基础架构同时可以充当精确的室内定位系统,可触发家庭范围内的各种自动化任务,如在无需运动传感器的情况下自动打开房间内的灯光。该应用的逻辑和软件必须针对具体的住宅、用户以及设备进行调整。

固定式传感器会以分布式的方法,通过处理可穿戴传感器借助 BLE(Bluetooth low energy,也叫做 Bluetooth Smart)发送的数据检测跌倒。固定式传感器需要连接至一个 Wi-Fi 网络,借此通过点对点通信检测跌倒,并使用 MQTT 代理(Broker)与网关通信。

Tellu 使用 ThingML 在传感器和网关处实现所需逻辑。图 2 展示了这种基础架构在家庭中部署后的概况,此外图中还展示了一个部署在网关上的状态机。

(点击放大图像)

图 2:Tellu 数字健康和家具自动化解决方案。(a) 基础架构和部署方式概况;(b) 网关所用状态机的部分内容,网关会使用动态会话实现设备的动态发现与管理工作。BLE 是指 Bluetooth low energy,MQTT 是指 Message Queuing Telemetry Transport。

该系统包含超过 25 个 ThingML 组件,共运行在四种类型的嵌入式节点上:

  • 基于 ARM Cortex M3 微处理器的可穿戴传感器,
  • 基于 Intel Edison 的固定式压力传感器节点,
  • 一个基于树莓派网关搭建的初代系统原型,以及
  • 一个基于 MIPS,适用于生产系统的专有网关。

在协议方面,该系统主要使用 BLE、MQTT(通过 Wi-Fi 和以太网)以及 Z-Wave。

为了实现动态的设备发现和管理,网关会使用会话(图 2)。当系统发现新设备(Z-Wave?nodeAdded)后,网关会 Fork 一个设备会话(fork device),并提供及时更新的 ID,借此处理与该设备有关的消息。

传感器会利用 CEP 以优雅的方式实现并轻松调整精确度量所需的压力补偿算法(图 3)。当系统同时收到未经处理的原始温度和压力数据后,会触发一个流。用户可通过输入注解的方式自定义可联接的两个事件间的时间间隔。这个流还可以将最后三个补偿压力合并在一起进行计算。为了计算最终的补偿压力,可通过 compensate 函数应用为缓冲区中最新的补偿值,以及当前压力和温度应用多项式函数。

(点击放大图像)

图3:以ThingML CEP(复杂事件处理)流的方式表示的压力补偿算法。压力传感器会利用CEP 实现并调整精确度量所需的压力补偿算法。

虽然Tellu 数字健康系统依然在开发中,但ThingML 方法已开始显现出四个重要收益。首先,ThingML 组件及其严格的异步消息传递通信语义使得系统能够发现组件之间的所有交互。这一点极大地简化了系统集成和测试工作,因为现在可以用更简单的方法模拟不同组件。

其次,用于处理缓冲区和计时器分配与管理的大部分代码已经可以通过ThingML 或其他目标语言来表达,因此可以直接从模型中移出,并在引入CEP 和会话后交给编译器处理。

第三,ThingML 方法大幅简化了从原型到生产系统的过度。正如上文所述,除了最初使用的,基于树莓派的家庭网关,这个系统现在还可以使用专有的MIPS 网关。虽然这样的网关包含与某些特定平台有关的组件(图1),但可以很简单地迁移至新平台,因为所有与特定平台有关的引用都可以在ThingML 模型中清楚明确地表达。对于Tellu 这样的软件公司来说,快速更改平台的能力很重要,可以避免自己被任何硬件解决方案锁定。

最后,开发者只要将现有库封装至ThingML,并使用ThingML 框架定制代码生成器,即可为自己的目标平台和协议提供支持,甚至可支持ARM Cortex M3 微处理器。

Tellu 数字健康系统的开发很好地诠释了商用物联网系统开发的流程和可能遇到的问题:异构、资源有限、分布式、可靠性、隐私需求,以及软硬件的代码开发。在这种情况下,ThingML 方法是应对系统复杂性以及在底层物联网平台的丛林中顺利发展的第一步。我们围绕数字健康、机器人、传感器网络、媒体,以及家具自动化等领域获得的经验也可以应用在更多领域,让更多从业人员获益。

然而软件工程领域的重要挑战依然存在,尤其是在软件部署和更新,以及以可靠可预测的方式在不同物联网应用之间共享计算资源和设备等方面更是如此。在云计算的环境中,诸如 Docker [8] 或 LXC(Linux 容器)等方法可将组件和应用程序实现容器化,借此应对共生(Mutualized)服务器上的部署和“沙箱”执行环境等需求。在物联网方面,Docker 和 LXC 已经可以移植到树莓派这样资源极为有限的平台 [9] ,使其可充当中介作用的物联网节点。然而规模更小的物联网节点需要不同的方式。对于资源有限的平台,可通过调度算法处理相互混合的关键性系统 [10] ,借此为计算工作执行过程建立可预测的基准线。模型所提供的抽象为行为分析提供了可行、有效的基础。

致谢

本次研究得到了 EU FP7 HEADS 项目(611337 项目)的支持。

关于本文作者

Brice Morin是芬兰奥斯陆 SINTEF 信息与通信技术中心的研究员,他的研究通过 ThingML 语言为物联网技术提供了强大、实用的建模功能。Morin 在法国雷恩大学(University of Rennes)获得了博士学位。他的联系方式:brice.morin@sintef.no。

Nicolas Harrand是芬兰奥斯陆 SINTEF 信息与通信技术中心的工程师,他的研究致力于通过模型驱动的工程技术打造异构分布式系统。Harrand 在法国圣马丹代雷研究生院(école Nationale Supérieure D’informatique et de Mathématiques Appliquées de Grenoble)获得工程学学士学位。他的联系方式:nicolas.harrand@sintef.no。

Franck Fleurey是芬兰奥斯陆 SINTEF 信息与通信技术中心的资深研究员,他的研究方向包括模型驱动的软件工程、嵌入式系统,以及动态自适应系统。Fleurey 在法国雷恩大学获得了计算机科学博士学位。他的联系方式:franck.fleurey@sintef.no。

作者 Brice Morin Nicolas Harrand Franck Fleurey 阅读英文原文 Model-Based Software Engineering to Tame the IoT Jungle


[1] I. Stoica et al., “Chord: A Scalable Peer-to-Peer Lookup Service for Internet Applications”, ACM SIGCOMM Computer Communication Rev., vol. 4, no. 31, 2001, pp. 149-160. [2] P. Grace, G. Blair, and S. Samuel, “A Reflective Framework for Discovery and Interaction in Heterogeneous Mobile Environments”, ACM SIGMOBILE Mobile Computing and Communications Rev., vol. 1, no. 9, 2005, pp. 2–14.

[3] A. Marinos and G. Briscoe, “Community Cloud Computing”, Cloud Computing, LNCS 5931, Springer, 2009, pp. 472-484.

[4] N. Harrand et al., “ThingML: A Language and Code Generation Framework for Heterogeneous Targets”, Proc. ACM/IEEE 19th Int’l Conf. Model-Driven Eng. Languages and Systems (MODELS 16), 2016, pp. 125–135.

[5] E. Meijer, “Reactive Extensions (Rx): Curing Your Asynchronous Programming Blues”, Proc. 2010 ACM SIGPLAN Workshop Commercial Users of Functional Programming (CUFP 10), 2010, article 11.

[6] F. Fleurey et al., “MDE to Manage Communications with and between Resource-Constrained Systems”, Model Driven Engineering Languages and Systems, LNCS 6981, Springer, 2011, pp. 349–363.

[7] A. Liverud, “ New Sensor Will Make Life Safer for the Elderly ”, Gemini, 9 Feb. 2016;

[8] F. Fouquet et al., “Dissemination of Reconfi guration Policies on Mesh Networks”, Distributed Applications and Interoperable Systems, LNCS 7272, Springer, 2016, pp. 16–30.

[9] F.P. Tso et al. “The Glasgow Raspberry Pi Cloud: A Scale Model for Cloud Computing Infrastructures”, Proc. 33rd Int’l Conf. Distributed Computing Systems Workshops, 2013, pp. 108–112.

[10] S. Baruah, H. Li, and L. Stougie, “Towards the Design of Certifi able Mixed-Criticality Systems”, Proc. 16th IEEE Real-Time and Embedded Technology and Applications Symp. (RTAS 10), 2010, pp. 13–22.

2017-08-16 17:241360
用户头像

发布了 283 篇内容, 共 106.0 次阅读, 收获喜欢 62 次。

关注

评论

发布
暂无评论
发现更多内容

亚马逊云科技推出五项Amazon SageMaker新功能

财见

大模型数据集:构建、挑战与未来趋势

来自四九城儿

DAPP算力挖矿系统开发丨合约技术开发

l8l259l3365

云图说 | 图解制品仓库服务CodeArts Artifact

华为云开发者联盟

华为云 华为云开发者联盟 华为云CodeArts 华为云云图说

常用的企业加速公司内部大文件传输速度方法

镭速

大文件传输 传输大文件 内部大文件传输

【写作训练营打卡|02】

终身学习 #学习

XPET宠物游戏系统开发技术

薇電13242772558

gamefi

FPS和SFTP的速度哪个更快?区别在哪里?

镭速

ftp sftp 传输大文件

直播预告丨电商内容营销的AIGC式进化

京东科技开发者

电商 大模型 AIGC

最大Prompt模板库助力AI应用

百度开发者中心

大模型 #人工智能 Prompt

分布式数据库 GaiaDB-X 金融应用实践

Baidu AICLOUD

分布式数据库

小程序中添加用户隐私保护的操作方法

Geek_2305a8

离散元分析有什么用?仿真软件介绍

智造软件

CAE CAE软件 离散元

掌握Prompt工程,开启AI大模型新时代

百度开发者中心

大模型 #人工智能

异常追踪与 JIRA 实现双向联动

观测云

Jira 异常追踪

身为 Go 程序员,我为啥更喜欢用 Zig?

树上有只程序猿

Go 编译器 Zig语言

社交泛娱乐出海,市场 & 赛道、投放 & 变现的最新干货分享

融云 RongCloud

社交 泛娱乐 市场 变现 梳理

大模型数据集:突破边界,探索未来

来自四九城儿

Prompt创新引领对话系统未来

百度开发者中心

大模型 Prompt

Upgrading from WiFi 5 to WiFi 6 with IPQ5018

wallyslilly

ipq5018

生产环境的质量监控实践和思考

老张

监控 质量保障 高可用架构 稳定性保障

如何在组织中有效地使用低代码工具?

互联网工科生

企业 低代码平台 企业管理软件

大模型数据集:构建、挑战与未来发展

来自四九城儿

公有云频繁宕机,从上云到下云备份如何实现?

财见

B 站基于 StarRocks 构建大数据元仓

StarRocks

数据库 StarRocks 数据分析、

行外人提问:CST软件仿真能够解决哪些问题?

思茂信息

cst cst电磁仿真 cst仿真软件

免费SSL,阿里云免费SSL证书申请及如何宝塔更换SSL证书

JaneYork

阿里云 ssl 宝塔面板 免费SSL证书 宝塔

过去 100 天,发生了啥?丨 RTE 开发者日报 Vol.100

声网

从全托管到Serverless,腾讯云大数据Elasticsearch开启云原生新范式

腾讯云大数据

ES

云原生技术的发展与实践 主赛道:技术人的 2023 总结

Echo_Wish

容器 云原生 个人总结 年度

借助基于模块的软件工程方法征战物联网丛林_移动_Brice Morin_InfoQ精选文章