上周,我在东京 Node-RED 大会上发表演讲,谈论了该项目的未来。我谈到了项目的高级目标,以及它们在路线图中的技术特性方面的体现。
这篇博客文章是该演讲的书面形式,它提供了仅通过幻灯片无法获得的背景信息。
在我的上一篇文章中,我写了我们如何计划发布时间表——新的主要版本将与 Node.js 的发布时间表保持一致。
那篇文章中我没有提到的是路线图的技术方面。除了跟上 Node.js 的更新,问题是该项目的未来我们有什么计划。
1.0 版本的路线图为我们提供了一个关注点——它为项目设定了一个相当明确的目标。展望 1.0 之后,这是一个更开放的问题——没有一个同等的终点。
我们确实有一套项目目标——我们知道我们想要实现的目标。我们可以利用这些目标来确定和优先安排我们将在未来版本中开发的技术特性。
在这篇文章中,我将分享我们为项目计划的一些技术特性,以及它们如何与我们项目的未来目标相吻合。
但首先我想分享我们认为我们的目标是什么。
我们的用户是谁?
要开始思考项目的技术路线图是什么,我们必须退一步思考我们的用户是谁——我们为谁开发 Node-RED?
我们去年进行的社区调查让我们对社区有了很好的了解。我们的用户来自非常广泛的背景和经验。我们有刚开始学习编程的学生。我们有退休的工程师重新开始建造东西。我们有经验丰富的开发人员,他们欣赏 Node-RED 提供的便利,而不是编写代码。我们还有介于两者之间的所有人。
我们大部分用户是个人,他们在个人设备上运行 Node-RED——笔记本电脑、树莓派或云中的虚拟机。他们正在为自己构建解决方案——无论是家庭自动化、为 Alexa 或 Google Home 添加技能,还是进行 IFTTT 可以提供的在线服务。
主要是这些用户在论坛上花费时间,讨论他们构建了什么,或帮助回答新手的疑问。
另一组用户来自将 Node-RED 集成到自己的产品和服务中的公司。日立、西门子、三星、Particle 等等。他们有不同的需求。他们希望将 Node-RED 集成到他们现有的平台中。他们希望能够为最终用户提供无缝体验——隐藏 Node-RED 如何运行或流程在何处执行的详细信息。
了解这些用户群体的不同需求对于正确确定路线图中的优先级至关重要。
可持续性
我们还需要了解这些不同用户群体的原因还有另一个。我们有责任确保 Node-RED 是一个可持续发展的项目——它拥有继续为用户提供服务所需的资源。开源的可持续性是一个难题。
贡献者通常来自两个地方;选择投入业余时间到项目的个人,以及对项目有商业兴趣并作为日常工作一部分进行贡献的个人。
作为 OpenJS 基金会的成长项目,我们希望扩大我们的贡献者基础——让更多人参与到项目的核心部分。
虽然其中一部分将来自个人,但我们希望增加 Node-RED 的商业采用。这将有助于增加对项目本身的商业投资。
项目目标
在考虑项目的技术路线图时,我们有三个目标
- 改进个人开发者的体验
- 增加 Node-RED 的商业采用
- 改进任何想要使用 Node-RED 的用户的生产路径
正是这些目标将帮助我们优先处理和集中精力向前发展。
如果您关注过论坛或 Slack 中的各种讨论,这些内容很多都将是熟悉的——但将它们整合到一个地方很有用。
改进开发者体验
测试框架
任何软件开发最基本的要求之一就是能够轻松测试代码。无论是单元测试单个组件,还是系统测试更大的部分。
这是 Node-RED 在这方面没有为用户提供太多帮助的整个领域。一些测试可以在编辑器中完成,使用 Inject 节点创建测试消息,并使用 Debug 侧边栏检查结果。但这只是一套非常有限的工具。它完全是手动测试,不适合您想要针对数据库或 Web API 等外部系统进行测试的情况,也不适合您想要在自动化持续集成工作流中自动化测试的情况。
一种方法是在代码中创建传统的测试用例;可以针对流暴露的外部运行的测试。这有两个主要缺点:很难对流的内部组件进行单元测试,并且它与 Node-RED 的“低代码”理念不太契合。
我们希望我们的非传统软件开发人员用户能够像其他人一样轻松地为他们的流程创建测试。
在我们的设计仓库中,关于这个项目已经有一些初步的设计工作。高级概念是能够在编辑器中定义测试用例套件。然后,对于流程中的每个节点,您将能够为每个测试用例定义该节点的预期行为。行为将分为三个阶段
beforeNode
- 此阶段在节点接收到消息但节点尚未获得消息之前触发。这可用于验证到达节点的消息具有预期属性。testNode
- 此阶段可用于定义节点行为以代替实际的运行时节点。这将允许节点被“模拟”,例如写入数据库或与外部系统交互的节点。afterNode
- 此阶段在节点发送消息但下一个节点接收到之前触发。这可用于验证节点的输出。
这些阶段中的任何一个都能够将测试用例标记为通过或失败。这意味着可以创建跨越整个流程的测试用例,或者只关注一个或两个节点的测试用例。
编辑器将有一个新的侧边栏,列出测试用例,可以在那里运行并报告结果。我们还将提供一种仅使用命令行运行测试用例的方法,以便它们可以作为自动化管道的一部分使用。
流检查器
除了测试,还有另一种开发者在现代开发工具中期待并依赖的工具——linter。
Linters 是可以分析代码并根据发现生成建议、警告和错误的工具。从检查基本语法错误到确保代码库中使用一致的格式,Linters 都发挥着重要作用。
我们的日立的朋友已经对 Flow Linter 进行了一些初步工作,我们将在未来几个月内加快这项工作。
Flow Linter 将同时基于命令行和编辑器。命令行版本将允许它作为部署管道的一部分使用,以确保流在集成之前满足所需的 linting 规则。
在编辑器中,它会在用户点击部署按钮之前,向他们提供有关流程中问题的反馈。
它将是一个可插拔的工具,允许编写自定义 linting 规则并与社区共享——因此,如果您的组织有一套特定的要求,或者您可能使用一些必须以非常特定方式连接的自定义节点,linter 将帮助在部署之前捕获错误。
流调试器
我个人最期待开始工作的功能之一是真正的流调试器。
Node-RED 提供调试节点以帮助开发人员了解其流中发生的情况。它们是很有用的工具,但它们有其局限性。您只能在流中添加节点的位置进行调试。当您的流涉及多个分支和定时事件时,很难同时查看消息在每个分支中的流动情况。
流程调试器将允许开发人员在其流程中设置断点。当消息到达断点时,运行时将暂停,消息将停止流动。然后开发人员可以在不同的点检查流程——检查等待传递的消息。
当启用调试器运行时,用户将能够可视化其流程的性能——查看时间花在哪里,或者是否存在可以优化的瓶颈。
可导出子流
我们希望让用户更容易创建自己的节点并与社区共享。目标是允许子流作为适当的节点模块发布,然后可以像库中的任何其他节点一样安装它们。
这方面的工作已经进行得非常顺利——有一个 PR 草案增加了从模块将子流加载到运行时的基本支持。
项目
Node-RED 中很久以前就有了项目功能——直接将版本控制流程引入编辑器。但在这个领域还有更多工作要做。
1.2 版本引入了一种新的简化 Git 工作流——每当单击部署按钮时,更改都会自动提交。这对于不熟悉 Git 版本控制的用户来说非常重要——他们无需了解自己提交更改即可从中受益。
还有其他方面我们需要改进
- 管理项目依赖关系。目前,编辑器允许您自己编辑依赖关系,并尝试提供一些关于需要做什么的提示,但整个用户体验需要改进。
- 访问项目的早期版本。如果不能轻松回溯到早期版本,那么完整的更改历史记录就没有多大用处。在命令行上可以做到——但如果我们想让所有用户在编辑器中都能访问它,那不是正确的答案。
- 将
settings.js
添加到项目中。要使项目成为一个完整的可部署工件,它需要一个设置文件。目前,必须手动创建并将其添加到项目中。编辑器可以为此提供更多帮助——困难的部分是管理项目设置文件与运行时设置文件——但这将在以后讨论。 - 将
Dockerfile
添加到项目中。将项目部署到生产环境的一种常见模式是通过某种形式的容器化。在编辑器中快速轻松地设置它将是一个巨大的进步——尽管这是一个非常可选的功能。
我确信我们可以利用 Projects 功能做更多事情,使其更加强大。与此路线图中的所有内容一样,我们将寻求社区的反馈,以帮助扩展细节。
独立安装程序
我们想要改进的另一个领域是让用户更容易开始使用 Node-RED。目前,要安装 Node-RED,用户必须安装 node.js 和 npm,然后运行一些他们可能不熟悉的命令,并且他们会看到 npm 输出的一整屏内容——其中大部分对他们来说意义不大。
还有一些情况是用户没有良好的互联网连接——或者在他们想要安装 Node-RED 的地方完全没有连接。
为了帮助解决这些问题,我们将为 Node-RED 创建一个独立的安装程序。使用 Electron 构建,为所有常见平台生成本地安装程序,这将是一种将 Node-RED 安装并用作本地桌面应用程序的方法。
目前已经有一些项目实现了这一点——包括斋藤先生的Node-RED 桌面版。我们将在前进的过程中向这些项目寻求合作和灵感。
增加商业采用
项目的一个重要目标是增加其商业采用。通过这种方式,我们可以帮助增加对项目的投资,并帮助增加其长期可持续性。
所有开发者体验项都与此相关,因为 Node-RED 只有在有需求的情况下才会被采用——因此,确保它使用起来令人愉悦并提供用户想要使用的工具至关重要。
但还有一套功能与个人用户的直接相关性较低——但在大规模运行 Node-RED 时将发挥重要作用。
大规模部署 Node-RED
我们经常收到的一个问题是关于多租户——让多个用户共享一个 Node-RED 实例而不互相干扰。
我们长期以来的建议是 Node-RED 运行时不适合多租户。这有几个原因。Node.js 是一个单线程运行时——只有一个事件循环必须在运行时中的所有流之间共享。如果一个用户创建了一个消耗大量资源的流,它可能会对其他流的性能产生负面影响。该流中的任何锁定事件循环的错误都会阻止其他所有内容的运行。同样,我们没有机制来隔离每个流的全局上下文。
这就是为什么我们总是说每个用户的流程都应该放在自己的运行时实例中——我们目前没有立即改变这一建议的计划。
但我们认识到,这将管理多个实例的责任交给了那些希望将 Node-RED 集成到其环境中的人。这可能是采用的很大障碍,而且我们目前没有提供任何关于如何做的指导。
首先,我们想了解 Node-RED 的现有用户是如何大规模部署它的。我们知道目前有许多不同的可能模型和方法。我们想更好地了解诸如使用了哪些堆栈之类的问题——是 Kubernetes、OpenShift、Docker Compose 还是其他编排技术。我们想了解公司采取了哪些方法来管理其用户的流程。用户是在“实时”环境中编辑他们的流程,还是有单独的开发和生产运行时。
这将为我们创建的一套用于大规模部署 Node-RED 的架构模式提供依据。首先,这些模式可能更多地是关于文档而不是运行代码。随着时间的推移,可能会有一些有用的组件可以开发出来,以填补一些空白。
流程的可伸缩性
随着工作负载的增加,我们需要确保 Node-RED 运行时可以扩展以满足需求。
与多租户问题一样,我们传统上将这个问题推迟,说您可以通过运行多个运行时实例并在前面进行某种负载均衡来横向扩展您的流程。
这个答案基本不变,但我们肯定可以做一些事情来帮助提高整体可扩展性。
我们过去多次谈论分布式 Node-RED 架构的想法。这是指在编辑器中绘制的流可以部署到多个运行时和设备上。我们一直在缓慢地朝着这个方向努力,并将继续这样做。
它是一种也可以在可伸缩性上下文中使用的模型。例如,能够在多个运行时上部署流程的多个副本。
在 1.2 中,我们添加了钩子 API 来支持可插拔的消息路由。这将允许在节点之间的消息路由中添加自定义代码。因此,如果一个流程跨越两个不同的运行时,或者不同的部分可以独立扩展,那么该自定义代码可以用于在运行时之间路由消息。
在 1.0 中,我们在编辑器中添加了组功能。计划是在未来的版本中,允许一个组关联自定义元数据。用户可以创建一个流,然后根据节点应该部署到哪里或如何扩展来分组节点。然后,该组元数据可以被消息路由使用,以处理将消息发送到需要的地方。除了组元数据,唯一缺少的部分是跨多个运行时部署流的方法。
我们在 1.2 中引入的用于消息路由的新钩子 API 将在未来的版本中扩展,以支持运行时生命周期其他点的钩子——例如按下部署按钮时。
这里的关键是我们正在添加构建分布式 Node-RED 所需的组件和 API。我们目前不计划生产开箱即用的分布式 Node-RED 版本——但所有组件都将到位。
自定义 Node-RED 流程外观
另一方面是研究自定义 Node-RED 外观的便捷程度。我们已经提供了添加自定义 CSS 和修改编辑器某些方面的方法,但这只能到此为止。
我们偶尔会收到自定义流程本身外观(节点的形状和设计)的请求。
我们计划将流程绘制作为编辑器的一个可插拔组件。目前这只是一个概念——我无法确切说明它将如何运作,但想法是当编辑器需要在给定位置在屏幕上绘制一个节点时,它会调用执行所需工作的自定义代码。
需要明确的是,这并不是允许单个节点改变自身外观——而是以一致的方式自定义整个流程的外观。
反馈
所有这些功能都需要大量的开发工作。作为一个没有大型全职开发团队的开源项目,无法对这项工作的整体确定时间表。这些项目只是未来版本的重点——在编辑器和运行时中还将有无数更小的增强功能和特性。