c# - 一旦其中一方通过Docker运行,带有PAIR套接字的本地ZeroMQ连接就会遇到端口冲突

标签 c# python .net docker zeromq

最初,我在同一台计算机上运行python脚本和.NET程序,然后我决定将ZeroMQ作为在这两个程序之间共享信息的最便捷方法。

如果我只是正常运行它们,这将完全正常,但是,我最近尝试构建python-script的Docker镜像,尽管它运行得很好,但.NET程序无法绑定(bind)到该套接字,因为它抱怨该地址已被使用,对于应该相互通信的两个套接字来说,这似乎是一个奇怪的抱怨。

为了澄清起见,以相反的顺序运行它们会使Docker抱怨端口已被使用。

相关的python代码:

context = zmq.Context()
socket = context.socket(zmq.PAIR)
socket.connect("tcp://127.0.0.1:6008")

相关的C#代码:
public ClassName(){
        context = ZmqContext.Create();
        sendSocket = context.CreateSocket(SocketType.PAIR);
        sendSocket.Bind("tcp://127.0.0.1:6008");
}

Dockerfile:
FROM python:3
ADD pythonscriptName.py ./
RUN pip install pyzmq
EXPOSE 6008
CMD [ "python", "./pythonscriptName.py" ]

用于创建和运行Docker镜像的命令:
docker build -t pythonscriptName .
docker run -p 6008:6008 -d pythonscriptName

最佳答案

观察:

Docker概念创建了一种抽象视野,以便允许代码以“Dockerized”形式执行,最好不要知道是否在内部保留并运行这样的视野,的抽象。

作为“
下的”,这样的抽象层次对于正在检查的代码来说是很好的,但是“”世界必须以某种方式保持这种抽象,以便在另一个O / S内部共存,在该O / S中资源被映射,分配和使用,而无需与隐藏在抽象视野下的生态系统进行协调。

这意味着,在单层生态系统中,简单的事情(如回送O / S仿真的抽象接口(interface),寻址为TCP / IPv4传递地址 127.0.0.1 )对于“外部” O / S很容易(后者一无所知)在抽象视野的任何“内部”,在那些孤立的,O / S同居宇宙中,其视觉和嗅觉在
之后的越少越好。

ZeroMQ不是魔杖,如果它被指示询问操作系统(真正的主机,虚拟机或抽象在Docker容器内部的“抽象”之后)的O / S, O / S服务的抽象只需交付要求获取的内容-真正的主机O / S使用O / S模拟的环回接口(interface)访问,VM-ed O / S将交付其(特定于VM的)O / S。模拟了环回接口(interface)访问,在此没有人会感到惊讶,即抽象“
后面的”抽象概念将对类似抽象的环回仿真接口(interface)进行类似的设置。

谁会在这里期望,所有这些“非常相同”的 127.0.0.1 地址曾经应该“会见”和“都说”,这三者中的任何一个,主要是“分离”系统抽象仿真?

解决方法

最佳设置ZeroMQ消息传递和信令通信基础设施节点,以真实的物理设备IP地址为基础,可以使用Docker的配置和映射服务来映射,交叉连接和通过
传递“通过”到您的真实主机接口(interface)+使用的寻址。

这样一来,ISO / OSI-Layer3 +服务将在任何类型的抽象视域中得到适当的调解,即“”,同时适当地进行了主机和网络寻址的相应设置和协调,并对不同服务实现了安全规则调解设备允许在它们之间建立和维护此类通信。

最好避免使用像localhost127.0.0.1一样的非“转换后的”抽象,这些抽象视界不需要在“”中相同地工作(顺便说一句,在后面引入分离概念“如此抽象的视野,不是吗?

如果 PAIR 套接字“阻止”提供一个公平的通道“跨越”,否则通过“抽象”正确设置了中介服务来“中介”连接,请首先尝试 PUSH/PULL 测试,以证明“可见性”有效”通过“抽象的视野”。

如果 PUSH/PULL 通道有效,则 PAIR/PAIR 可能不起作用,因为它被证明是一种“实验性”可扩展形式通信原型(prototype)模式,不需要像ZeroMQ原型(prototype)那样支持所有通用服务,就像其他ZeroMQ原型(prototype)那样。自v2.1 +起的本机API

使用PUSH/PULL设置的预防性检查主要是将这一方面与Docker引入的任何问题都跨越任一方向的抽象跨越的问题区分开来,因此有助于在测试PAIR/PAIR设置之前预先测试两个方向以“通过” PASS工作。

最后但并非最不重要的一点是,在那些情况下,如果使用了较差的资源管理实践,并且代码执行被抛出未处理的异常,而某些 Context() -实例仍然可以优雅地非映射,将 channel 终止到 port# (s)。可能会发生这种情况,导致“挂起”或“挂起”其他套接字,无限期地等待一个永远不会到来的事件,直到重新启动该系统为止。因此,如果您在经过某些先前的代码破解后遇到端口无法访问的情况,这可能是拒绝使用此类port#的调用的另一个原因。

欢迎来到的 Realm ,其中 #ASSUME NOTHING 指令因此对于整个分布式系统范围内的系统设计最佳实践更有效。

关于c# - 一旦其中一方通过Docker运行,带有PAIR套接字的本地ZeroMQ连接就会遇到端口冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50451059/

相关文章:

.net - EF 在 linq 查询中比较格式 "YYYYMMDD"的日期字符串?

c# - 对于单个文本输入,对部件使用文本阅读器,对其他部件使用二进制阅读器

c# - 如何从 json 数组创建列表集合?

c# - MSBuild SonarQube 运行程序跳过自动生成的文件?

python - 循环使用 csv 文件行中的数字

python - python 中的切片符号 - 需要对代码片段进行说明

c# - MVC 3,url参数不分开

.net - 即使在Visual Studio中即使编译器有错误也会进行调试

c# - 包装包含 vector 的模板类时如何让 SWIG 应用模板?

python - Verbnet : vn. classids() 返回 2 个列表,但我需要删除其中 1 个