在 http 连接的 erlang 集群之间共享原子

Sharing atoms between http-connected erlang clusters

我们的基础设施中有一些非 erlang 连接的集群,目前使用 term_to_binary 为集群之间的消息编码 erlang 术语。在接收方,我们使用 binary_to_term(Bin, [safe]) 仅转换为现有原子(如果消息中有的话)。

偶尔(尤其是在开始一个新的cluster/stack之后),我们会遇到这样的问题,即消息中编码了部分已知的原子,即发送集群知道这个原子,但接收集群不知道。这可能有多种原因,最常见的是接收节点根本没有加载包含某些记录定义的模块。我们目前采用了一些令人讨厌的变通办法,这些变通办法基本上相当于维护一个可能使用的原子的简短列表,但我们对这种容易出错的方法不太满意。

有没有一种聪明的方法可以在这些集群之间共享原子?还是建议不要将二进制格式用于此类目的?

期待您的见解。

我会认真思考为什么非 Erlang 节点首先要发送原子值。最有可能的是可以对用于通信的协议进行一些调整——或者最常见的是根本没有定义真正的协议,实际使用的协议随着时间的推移而有机地演变。

不知道具体情况,有两种解决方法:

  • 深入使用抽象序列化技术,如 ASN.1 或 JSON 或其他任何技术,使用二进制字符串而不是原子。当您要发送大量易于理解的结构化数据(可能包含非结构化或不透明数据)时,这最有意义。
  • 保持肤浅,而是为 processes/modules 编写一个功能性 API 接口,您将首先发送 to/calling,以确保您完全理解您的协议实际是什么,然后通过使每个接口调用对应于匹配的网络消息来支持这一点,当接收到该消息时,将调度与 API 函数调用相同的过程。

基本问题是非 Erlang 节点能够生成集群可能不知道的原子的想法。这是一个有点棘手的问题。在许多情况下,您可以在使用原子的地方使用二进制文件来达到类似的效果并保留相同的语义,而不会混淆运行时。就是{<<"new_message">>, Data}{new_message, Data}的区别;函数头内的匹配以相同的方式工作,只是在语法上稍微嘈杂。