GVKun编程网logo

Python worker无法重新连接(python无法连接数据库)

29

如果您想了解Pythonworker无法重新连接的相关知识,那么本文是一篇不可错过的文章,我们将对python无法连接数据库进行全面详尽的解释,并且为您提供关于Android/XMPP:连接类型更改后

如果您想了解Python worker无法重新连接的相关知识,那么本文是一篇不可错过的文章,我们将对python无法连接数据库进行全面详尽的解释,并且为您提供关于Android / XMPP:连接类型更改后无法重新连接到服务器、c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常、Corebluetooth 在后台无法重新连接到 BLE 设备、Docker Swarm 无法通过服务名称解析 DNS,Python Celery Workers 连接到 RabbitMQ Broker 导致连接超时的有价值的信息。

本文目录一览:

Python worker无法重新连接(python无法连接数据库)

Python worker无法重新连接(python无法连接数据库)

我是Spark的新生,并尝试完成Spark教程:
指向教程的链接

在本地计算机(Win10 64,Python 3,Spark
2.4.0)上安装它并设置所有环境变量(HADOOP_HOME,SPARK_HOME等)后,我试图通过WordCount.py文件运行一个简单的Spark作业:

from pyspark import SparkContext,SparkConf

if __name__ == "__main__":
    conf = SparkConf().setAppName("word count").setMaster("local[2]")
    sc = SparkContext(conf = conf)

    lines = sc.textFile("C:/Users/mjdbr/Documents/BigData/python-spark-tutorial/in/word_count.text")
    words = lines.flatMap(lambda line: line.split(" "))
    wordCounts = words.countByValue()

    for word,count in wordCounts.items():
        print("{} : {}".format(word,count))

从终端运行后:

spark-submit WordCount.py

我得到以下错误。我检查(逐行注释)它在崩溃

wordCounts = words.countByValue()

知道我应该检查些什么才能使其正常工作吗?

Traceback (most recent call last):
  File "C:\Users\mjdbr\Anaconda3\lib\runpy.py",line 193,in _run_module_as_main
    "__main__",mod_spec)
  File "C:\Users\mjdbr\Anaconda3\lib\runpy.py",line 85,in _run_code
    exec(code,run_globals)
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\worker.py",line 25,in <module>
ModuleNotFoundError: No module named 'resource'
18/11/10 23:16:58 ERROR Executor: Exception in task 0.0 in stage 0.0 (TID 0)
org.apache.spark.SparkException: Python worker failed to connect back.
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:170)
        at org.apache.spark.api.python.PythonWorkerFactory.create(PythonWorkerFactory.scala:97)
        at org.apache.spark.SparkEnv.createPythonWorker(SparkEnv.scala:117)
        at org.apache.spark.api.python.BasePythonRunner.compute(PythonRunner.scala:108)
        at org.apache.spark.api.python.PythonRDD.compute(PythonRDD.scala:65)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:121)
        at org.apache.spark.executor.Executor$TaskRunner$$anonfun$10.apply(Executor.scala:402)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1360)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:408)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: Accept timed out
        at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
        at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
        at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
        at java.net.PlainSocketImpl.accept(Unknown Source)
        at java.net.ServerSocket.implAccept(Unknown Source)
        at java.net.ServerSocket.accept(Unknown Source)
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:164)
        ... 14 more
18/11/10 23:16:58 ERROR TaskSetManager: Task 0 in stage 0.0 failed 1 times; aborting job
Traceback (most recent call last):
  File "C:/Users/mjdbr/Documents/BigData/python-spark-tutorial/rdd/WordCount.py",line 19,in <module>
    wordCounts = words.countByValue()
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\rdd.py",line 1261,in countByValue
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\rdd.py",line 844,in reduce
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\pyspark.zip\pyspark\rdd.py",line 816,in collect
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\py4j-0.10.7-src.zip\py4j\java_gateway.py",line 1257,in __call__
  File "C:\Spark\spark-2.4.0-bin-hadoop2.7\python\lib\py4j-0.10.7-src.zip\py4j\protocol.py",line 328,in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe.
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 1 times,most recent failure:
Lost task 0.0 in stage 0.0 (TID 0,localhost,executor driver): org.apache.spark.SparkException: Python worker failed to connect back.
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:170)
        at org.apache.spark.api.python.PythonWorkerFactory.create(PythonWorkerFactory.scala:97)
        at org.apache.spark.SparkEnv.createPythonWorker(SparkEnv.scala:117)
        at org.apache.spark.api.python.BasePythonRunner.compute(PythonRunner.scala:108)
        at org.apache.spark.api.python.PythonRDD.compute(PythonRDD.scala:65)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:121)
        at org.apache.spark.executor.Executor$TaskRunner$$anonfun$10.apply(Executor.scala:402)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1360)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:408)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: Accept timed out
        at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
        at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
        at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
        at java.net.PlainSocketImpl.accept(Unknown Source)
        at java.net.ServerSocket.implAccept(Unknown Source)
        at java.net.ServerSocket.accept(Unknown Source)
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:164)
        ... 14 more

Driver stacktrace:
        at org.apache.spark.scheduler.DAGScheduler.org$apache$spark$scheduler$DAGScheduler$$failJobAndIndependentStages(DAGScheduler.scala:1887)
        at org.apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1875)
        at org.apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1874)
        at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
        at org.apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:1874)
        at org.apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:926)
        at org.apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:926)
        at scala.Option.foreach(Option.scala:257)
        at org.apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:926)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.doOnReceive(DAGScheduler.scala:2108)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2057)
        at org.apache.spark.scheduler.DAGSchedulerEventProcessLoop.onReceive(DAGScheduler.scala:2046)
        at org.apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:49)
        at org.apache.spark.scheduler.DAGScheduler.runJob(DAGScheduler.scala:737)
        at org.apache.spark.SparkContext.runJob(SparkContext.scala:2061)
        at org.apache.spark.SparkContext.runJob(SparkContext.scala:2082)
        at org.apache.spark.SparkContext.runJob(SparkContext.scala:2101)
        at org.apache.spark.SparkContext.runJob(SparkContext.scala:2126)
        at org.apache.spark.rdd.RDD$$anonfun$collect$1.apply(RDD.scala:945)
        at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)
        at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)
        at org.apache.spark.rdd.RDD.withScope(RDD.scala:363)
        at org.apache.spark.rdd.RDD.collect(RDD.scala:944)
        at org.apache.spark.api.python.PythonRDD$.collectAndServe(PythonRDD.scala:166)
        at org.apache.spark.api.python.PythonRDD.collectAndServe(PythonRDD.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
        at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
        at py4j.Gateway.invoke(Gateway.java:282)
        at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
        at py4j.commands.CallCommand.execute(CallCommand.java:79)
        at py4j.GatewayConnection.run(GatewayConnection.java:238)
        at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.spark.SparkException: Python worker failed to connect back.
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:170)
        at org.apache.spark.api.python.PythonWorkerFactory.create(PythonWorkerFactory.scala:97)
        at org.apache.spark.SparkEnv.createPythonWorker(SparkEnv.scala:117)
        at org.apache.spark.api.python.BasePythonRunner.compute(PythonRunner.scala:108)
        at org.apache.spark.api.python.PythonRDD.compute(PythonRDD.scala:65)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:324)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:288)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:121)
        at org.apache.spark.executor.Executor$TaskRunner$$anonfun$10.apply(Executor.scala:402)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1360)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:408)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        ... 1 more
Caused by: java.net.SocketTimeoutException: Accept timed out
        at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
        at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
        at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
        at java.net.PlainSocketImpl.accept(Unknown Source)
        at java.net.ServerSocket.implAccept(Unknown Source)
        at java.net.ServerSocket.accept(Unknown Source)
        at org.apache.spark.api.python.PythonWorkerFactory.createSimpleWorker(PythonWorkerFactory.scala:164)
        ... 14 more

如鸭嘴兽所建议-检查“资源”模块是否可以直接从终端导入-显然不能:

>>> import resource
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
ModuleNotFoundError: No module named 'resource'

在安装资源方面-
我遵循了本教程中的说明:

  1. 从Apache Spark网站下载了spark-2.4.0-bin-hadoop2.7.tgz
  2. 解压缩到我的C盘
  3. 已经安装了Python_3(Anaconda发行版)以及Java
  4. 创建了本地“ C:\ hadoop \ bin”文件夹来存储winutils.exe
  5. 创建了’C:\ tmp \ hive’文件夹,并授予了Spark访问权限
  6. 添加了环境变量(SPARK_HOME,HADOOP_HOME等)

我应该安装任何额外的资源吗?

Android / XMPP:连接类型更改后无法重新连接到服务器

Android / XMPP:连接类型更改后无法重新连接到服务器

我目前正在研究我的大学项目,这是一个Android-App,它应该向服务器提供数据.

为此,我需要通过XMPP与服务器建立或多或少的一致连接.连接在100%的时间内并不是很重要,但是因为系统应该或多或少地对用户不可见,所以用户交互应该是最小的.

服务器和客户端都是xmpp-clients.我使用jabber.org作为xmpp服务器.

我有一个Android服务,它建立与服务器的连接并提供数据,这很好.

现在我尝试在连接丢失或从Wifi更改为GSM时重新连接服务.我想尝试使用收听NETWORK_STATE_CHANGED_ACTION的广播接收器来完成这项工作.但我甚至没有这么做.

这是问题:我尝试运行应用程序,然后只是禁用我的WiFi.我的电话比自动切换到GSM,我失去了我的连接(我预期).但是当我尝试手动重新连接(例如重新启动服务)时,我从服务器收到错误.我的状态仍然“可用”.从那一刻起,它需要太长时间,直到我再次连接.

@H_301_14@06-29 18:12:14.888: WARN/System.err(14246): resource-constraint(500) 06-29 18:12:14.890: WARN/System.err(14246): at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:110) 06-29 18:12:14.890: WARN/System.err(14246): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:404) 06-29 18:12:14.890: WARN/System.err(14246): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349) ....

我实际连接到xmpp服务器,但它不传递我的消息:

@H_301_14@06-29 18:12:14.882: INFO/System.out(14246): 06:12:14 nachm. RCV (1079704816): <iq type='error' id='7rhk4-70'><error code='500' type='wait'><resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>

有时我没有收到错误,但仍然没有传递消息.

所以我认为服务器不允许我连接,因为在尝试重新连接之前我没有断开连接.我发现这很奇怪,因为我认为你甚至可以从多个客户端连接到一个帐户.

我发布了一些我认为可能相关的代码:

@H_301_14@public void connectToServer() throws XMPPException { ConnectionConfiguration config = new ConnectionConfiguration( serverADD, port, service); connection = new XMPPConnection(config); connection.connect(); SASLAuthentication.supportSASLMechanism("PLAIN", 0); connection.login(user_JID,password); Presence presence = new Presence(Presence.Type.available); presence.setStatus("available"); presence.setPriority(24); presence.setMode(Presence.Mode.available); connection.sendPacket(presence); }

这是我发送消息的方式:

@H_301_14@public void sendMessage(String message, String recipient) throws XMPPException { chat = connection.getChatManager().createChat(recipient, this); chat.sendMessage(message); }

有谁有想法如何解决这个问题?只要我的消息传递到服务器,我甚至会使用“脏”技巧.

顺便说一下:发件人和收件人的jids总是一样的(初始设置后).万一有人认为这可能很重要.

解决方法:

Smack断开连接时的死锁

正如Airsource有限公司在他的评论中提到的那样:Smack正在遭遇断开连接的僵局(),这个僵局已经为SMACK-278.我有made a commit that fixes this in my smack fork.

Android重新连接处理

对于网络失败转移,请查看GTalkSMS receiver.它将发出ACTION_NETWORK_CHANGED意图,其中布尔额外的“可用”和“失败转移”.当“available = false”和“fallover = false”时,您的服务应该“停止”连接.你如何“停止”连接取决于你.有时即使使用SMACK-278的修复程序,disconnect()也需要很长时间,这就是为什么我们执行disconnect in an thread that will abort after x seconds然后创建一个新的Connection实例.当收到“available = true”的意图时,我们重新连接.

您将在GTalkSMS源代码中找到其他示例.我让应用程序永久运行,它实现了稳定但不是100%可用的连接(因为WLAN< - > GSM交换机).

c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常

c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常

我正在为WCF调用(使用BackgroundWorker)编写某种包装器,以便在调用正在进行时保持GUI不冻结.它主要是按预期工作,但是当WCF调用抛出异常时,我遇到了BackgroundWorker的问题.如果在DoWork中发生异常,我可以在RunWorkCompleted中检测到它,但是将其重新抛出到GUI不起作用.我已经读了很多线程,人们提到这应该有效.

包装器的代码(注意WCF调用由抛出的异常表示):

private void GetSomething(Action<IEnumerable<int>> completedAction)
{
    BackgroundWorker b = new BackgroundWorker();

    b.DoWork += (s,evt) => { throw new Exception(); evt.Result = new List<int> { 1,2,3 }; };

    b.RunWorkerCompleted += (s,evt) =>
    {
        if (evt.Error == null && completedAction != null)
        {
           completedAction((IEnumerable<int>)evt.Result);
        }
        else if(evt.Error != null)
        {
           throw evt.Error;
        }
    };

    b.RunWorkerAsync();
}

在Windows窗体中调用代码:

private void button3_Click(object sender,EventArgs e)
{
    try
    {
        GetSomething(list =>
        {
           foreach (int i in list)
           {
              listView1.Items.Add(new ListViewItem(i.ToString()));
           }
        });
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

在调试时,我得到:

  1. “Exception of type ‘System.Exception’ was thrown” in DoWork
  2. “Exception of type ‘System.Exception’ was thrown” at throw evt.Error
  3. “TargetInvocationException was unhandled” at Application.Run(new Form1()) in the Main method

我究竟做错了什么?我想在Windows窗体中捕获异常.

解决方法

事件b.RunWorkerCompleted是您应该进行错误处理的地方.您可以传递一个Action< Exception>做错误处理就像

private void GetSomething(Action<IEnumerable<int>> completedAction,Action<Exception> exceptionAction)
{
    BackgroundWorker b = new BackgroundWorker();

    b.DoWork += (s,evt) =>
    {
        if (evt.Error == null && completedAction != null)
            completedAction((IEnumerable<int>)evt.Result);
        else if(evt.Error != null)
            exceptionAction(evt.Error);
    };

    b.RunWorkerAsync();
}

然而,这往往会变得丑陋.如果您使用.Net 4或4.5,则可以使用“任务”.任务< TResult>是为了这种情况而创建的:

Task<IEnumerable<int>> GetSomething()
{
    return Task.Factory.StartNew(() => { 
        Thread.Sleep(2000);
        throw new Exception(); 
        return (new List<int> { 1,3 }).AsEnumerable(); 
        });
}

任务基本上是一个信号构造

> a.结果财产
> .Exception属性
> a .ContinueWith()方法

在ContinueWith()中,您可以检查Task是否处于故障状态(Exception被抛出).

你可以像使用它一样

private void button3_Click(object sender,EventArgs e)
    {
        GetSomething()
            .ContinueWith(task =>
                {
                    if (task.IsCanceled)
                    {
                    }
                    else if (task.IsFaulted)
                    {
                        var ex = task.Exception.InnerException;
                        MessageBox.Show(ex.Message);
                    }
                    else if (task.IsCompleted)
                    {
                        var list = task.Result;
                        foreach (int i in list)
                        {
                            listView1.Items.Add(new ListViewItem(i.ToString()));
                        }
                    }
                });
    }

如果您使用.Net 4.5和C#5(您需要VS2012或VS2010和Async CTP),您甚至可以使用异步并等待

private async void button3_Click(object sender,EventArgs e)
    {
        try
        {
            var list = await GetSomething();
            foreach (int i in list)
            {
                listView1.Items.Add(new ListViewItem(i.ToString()));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

……所有的魔力都是由编译器完成的.请注意,您可以像以前一样使用try catch.

Corebluetooth 在后台无法重新连接到 BLE 设备

Corebluetooth 在后台无法重新连接到 BLE 设备

如何解决Corebluetooth 在后台无法重新连接到 BLE 设备?

我正在尝试在后台模式下使用 corebluetooth 连接到 BLE 设备。我已经有后台模式工作,目前在后台接收断开连接回调。

我像这样创建经理

centralManager = CBCentralManager(delegate: self,queue: nil,options: [CBCentralManagerOptionRestoreIdentifierKey: "myCentralManagerIdentifier"])

然后我用

执行扫描
centralManager.scanForperipherals(withServices: nil,options: [CBCentralManagerScanoptionAllowDuplicatesKey: true])

然后我在扫描后连接到设备

func centralManager(_ central: CBCentralManager,diddiscover peripheral: CBPeripheral,advertisementData: [String: Any],RSSi RSSI: NSNumber) {

        if peripheral.name == "My BLE" {
            self.peripheral = peripheral
            self.peripheral.delegate = self
            centralManager.stopScan()
            // Connect!
            centralManager.connect(self.peripheral,options: nil)
        }
    }

现在当应用程序进入后台,并且 BLE 断开连接时,我收到了这个回调(这很好,它表明后台模式和状态恢复正在工作)

    func centralManager(_ central: CBCentralManager,diddisconnectPeripheral peripheral: CBPeripheral,error: Error?)
        {
            print("disconnected")
            peripheral.delegate = self
            centralManager.connect(peripheral,options: nil)
        }

我立即尝试重新连接。但即使设备重新上线,我也从未收到任何回电。 我的印象是,这个 API 的工作方式是操作系统会在我的应用程序处于后台时为我尝试连接,当 BLE 重新上线时,我会收到通知?

我有以下委托方法让我知道它何时连接

func centralManager(_ central: CBCentralManager,didConnect peripheral: CBPeripheral) {
        //send some user notifications and logs
        alert()
    }

didConnect 在第一次连接时被调用,但当 BLE 设备在后台重新上线时不会被第二次调用

据苹果documentation

当用户离开家时,iOS 设备可能最终会出现故障 锁的范围,导致与锁的连接丢失。在 此时,应用程序可以简单地调用 connectPeripheral:options: CBCentralManager 类的方法,并且因为连接请求 不要超时,iOS 设备会在用户返回时重新连接 家。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

Docker Swarm 无法通过服务名称解析 DNS,Python Celery Workers 连接到 RabbitMQ Broker 导致连接超时

Docker Swarm 无法通过服务名称解析 DNS,Python Celery Workers 连接到 RabbitMQ Broker 导致连接超时

如何解决Docker Swarm 无法通过服务名称解析 DNS,Python Celery Workers 连接到 RabbitMQ Broker 导致连接超时?

设置

我使用 Docker swarm 安装并连接了 9 台机器、1 个管理器和 8 个工作节点。这种安排已经在我们的开发服务器中使用了大约 5 年。

我正在使用它来启动一个使用 Celery for Python 的任务队列。 Celery 使用 RabbitMQ 作为代理,Redis 作为结果后端。

我在 Docker 中创建了一个覆盖网络,以便我所有由 Docker swarm 启动的 Celery worker 可以通过名称引用他们的代理和结果后端;即,rabbitmq 或 redis,而不是 IP 地址。网络是通过运行以下命令创建的:

docker network create -d overlay <network_name>

使用以下命令在该覆盖网络下的管理器节点上启动RabbitMQ服务和Redis服务:

docker service create --network <my_overlay_network> --name redis --constraint "node.hostname==manager" redis

docker service create --network <my_overlay_network> --name rabbitmq --constraint "node.hostname==manager" rabbitmq

一旦这两个都启动,我会使用以下命令在同一个覆盖网络上部署我的 Celery 工作器,每个 Docker swarm 工作器节点一个:

docker service create --network <my_overlay_network> --name celery-worker --constraint "node.hostname!=manager" --replicas 8 --replicas-max-per-node 1 <my_celery_worker_image>

在有人建议之前,是的,我知道我应该使用 Docker 撰写文件来启动所有这些。我目前正在测试中,待一切正常后我会写一篇。

问题

Celery worker 被配置为通过容器名称引用他们的代理和后端:

app = Celery(''tasks'',backend=''redis://redis'',broker=''pyamqp://guest@rabbitmq//'')

一旦所有服务都启动并由 Docker 验证,8 个中的 3 个成功启动,连接到代理和后端,并允许我开始在它们上运行任务。其他5个尝试连接RabbitMQ时连续超时,报如下信息:

consumer: Cannot connect to amqp://guest:**@rabbitmq:5672//: timed out.

我不知道为什么只有 3 个工作节点允许连接发生,而其他 5 个导致连续超时。所有启动的服务都通过同一个覆盖网络连接。

当我尝试使用 RabbitMQ 以外的代理时,问题仍然存在,使我认为它不是特定于任何一个代理。当在报告超时的机器上时,我可能会遇到按名称连接到覆盖网络上的任何服务的问题。停止服务并再次启动总是会产生相同的结果 - 相同的 3 个节点工作,而其他 5 个超时。

所有节点都运行相同版本的 Docker (19.03.4,build 9013bf583a),并且这些机器是从相同的镜像创建的。它们几乎相同。它们之间唯一的区别是它们的主机名,例如 manager、worker1、worker2 等。

在我的个人计算机上开发我的应用程序时,我已经能够通过使用桥接网络而不是覆盖在 Docker swarm 之外复制这个设置(全部在一台机器上)。直到我在我们的开发服务器上启动所有内容后,我才遇到问题,使用上面详述的步骤,在将其推送到生产之前对其进行测试。

关于为什么会发生这种情况以及我该如何补救的任何想法?从 Docker swarm 切换到 Kubernetes 目前对我来说不是一个选择。

解决方法

这不是我想要的答案,但这似乎是 Docker swarm 中的一个持续错误。对于任何感兴趣的人,我将包括问题页面。

https://github.com/docker/swarmkit/issues/1429

有一个用户在那里列出的解决方法可能会唤醒一些人,但您的里程可能会有所不同。它对我不起作用。解决方法列在下面的项目符号中:

  • 不要尝试使用 docker for Windows 来运行多节点网状网络(swarm)。它根本不(还)受支持。如果你用谷歌搜索,你会发现一些微软博客讲述了它。 docker 文档也在某处提到了它。如果 docker cmd 本身在尝试在 Windows 下设置某些内容时会打印错误/警告,那就太好了 - 这根本行不通。不过,它确实适用于单个节点。
  • 不要尝试在 Windows 下的 Virtualbox 中使用 Linux 并希望解决它。当然,它不起作用,因为它与底层 Windows 具有相同的限制。
  • 确保您至少为工作节点打开 7946 tcp/udp 和 4789 udp 端口​​。对于 master 也是 2377 tcp。使用例如netcat -vz -u 用于 udp 检查。 tcp 没有 -u。
  • 确保在执行 join swarm 命令时在 docker 工作节点 (!) 上传递 --advertise-addr。此处放置已打开上述端口的工作节点的外部 IP 地址。仔细检查端口是否真的打开!
  • 使用 ping 检查容器名称的 DNS 解析是否有效。如果您忘记 --advertise-addr 或未打开端口 7946 会导致 DNS 解析在工作节点上不起作用!

如果您遇到相同的问题,我建议您先尝试以上所有操作。为了澄清上述要点中的一些事情,在将工作节点加入群时,应在工作节点上使用 --advertise-addr 标志。如果您的工作节点没有静态 IP 地址,您可以使用该接口连接它。运行 ifconfig 以查看您的界面。您需要使用具有面向外部的 IP 地址的接口。对于大多数人来说,这可能是 eth0,但您仍然应该在运行命令之前进行检查。这样做,您将向工作人员发出的命令是:

docker swarm join --advertise-addr eth0:2377 --token <your_token> <manager_ip>:2377

2377 是 Docker 使用的端口。通过进入管理器节点并运行以下命令来验证您是否使用正确的 IP 地址加入:

docker node inspect <your_node_name>

如果你不知道你的节点名称,它应该是你作为工作节点加入的机器的主机名。您可以通过运行来查看它:

docker node ls

如果你在右侧界面加入,运行inspect时你会在返回的底部看到这个:

{
    "Status": "ready","Addr": <your_workers_external_ip_addr>
}

如果您确认一切都已正确加入,但问题仍然存在,您可以尝试在运行 Docker swarm create 时使用 --dns-option use-vc 的附加标志启动您的服务:

docker swarm create --dns-option use-vc --network <my_overlay> ...

最后,如果以上所有方法对您来说都像我一样失败,那么您可以在 swarm 中公开您希望连接的正在运行的服务的端口。对我来说,我希望将我的工作节点上的服务连接到我的管理器节点上的 RabbitMQ 和 Redis。我通过公开服务端口来做到这一点。您可以在创建时运行:

docker swarm create -p <port>:<port> ...

或者在通过运行启动服务之后

docker service update --publish-add <port>:<port> <service_name>

此后,您的工作节点服务可以通过工作节点主机的 IP 地址和您暴露的端口连接到管理节点服务。例如,使用 RabbitMQ,这将是:

pyamqp://<user>:<pass>@<worker_host_ip_addr>:<port>/<vhost>

希望这能帮助那些偶然发现这篇文章的人。

关于Python worker无法重新连接python无法连接数据库的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android / XMPP:连接类型更改后无法重新连接到服务器、c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常、Corebluetooth 在后台无法重新连接到 BLE 设备、Docker Swarm 无法通过服务名称解析 DNS,Python Celery Workers 连接到 RabbitMQ Broker 导致连接超时等相关知识的信息别忘了在本站进行查找喔。

本文标签: