【问题标题】:is there a deadlock in my simple loop code我的简单循环代码中是否有死锁
【发布时间】:2020-03-26 21:25:42
【问题描述】:

我有一个微服务,它的工作只有在另一台服务器启动时才需要执行。 几个星期以来它工作得很好,如果服务器关闭,微服务会在没有完成工作的情况下休眠一点(应该),如果服务器启动 - 工作就完成了。 服务器永远不会关闭超过几分钟(当然!服务器受到高度监控),因此该作业被跳过 2-3 次。

今天我进入我的 Docker 容器,并在日志中注意到该作业现在甚至没有尝试继续几个星期(我知道不监控的错误选择),这表明,我认为发生了某种死锁。 我还假设问题出在我的异常处理上,可以使用我独自工作的一些建议。

def is_server_healthy():
    url = "url" #correct url for health check path
    try:
        res = requests.get(url)
    except Exception as ex:
        LOGGER.error(f"Can't health check!{ex}")
    finally:
        pass

    return res

def init():
    while True:
        LOGGER.info(f"Sleeping for {SLEEP_TIME} Minutes")
        time.sleep(SLEEP_TIME*ONE_MINUTE)

        res = is_server_healthy()

        if res.status_code == 200:
            my_api.DoJob()
            LOGGER.info(f"Server is: {res.text}")
        else:
            LOGGER.info(f"Server is down... {res.status_code}")

(为了简化问题,更改了变量的名称)

运行状况检查很简单——如果正常则返回“up”。其他任何东西都被认为已关闭,因此除非状态 200 和“up”返回,否则我认为服务器已关闭。

【问题讨论】:

  • 你不应该缩进return res更多吗?
  • @alex 是的,我没有很好地复制。请忽略错误编辑
  • 在没有while True: 循环的情况下,您不应该在检查脚本的每一分钟执行一次 cron-tab 吗?或者尝试what-is-the-best-way-to-repeatedly-execute-a-function中的其他一些方法
  • 唯一可能导致未处理异常的行是my_api.DoJob()。所有其他行都不会导致异常,并且可以通过 try except 处理的行。
  • @TinNguyes - 有。请参阅下面的答案。

标签: python while-loop microservices deadlock docker-container


【解决方案1】:

如果您的服务器出现故障,您会收到未捕获的错误:

NameError: name 'res' is not defined

为什么?见:

def is_server_healthy():
    url = "don't care"
    try:
        raise Exception()  # simulate fail
    except Exception as ex:
        print(f"Can't health check!{ex}")
    finally:
        pass

    return res   ## name is not known ;o)

res = is_server_healthy()
if res.status_code == 200:   # here, next exception bound to happen
    my_api.DoJob()
    LOGGER.info(f"Server is: {res.text}")
else:
    LOGGER.info(f"Server is down... {res.status_code}")

即使您声明了名称,它也会尝试访问一些不存在的属性:

if res.status_code == 200:   # here - object has no attribute 'status_code'   
    my_api.DoJob()
    LOGGER.info(f"Server is: {res.text}")
else:
    LOGGER.info(f"Server is down... {res.status_code}")

会尝试访问一个根本不存在的成员 => 异常,并且进程消失了。


您最好使用某种特定于系统的方式每分钟调用一次脚本(Cron 作业、任务计划程序),然后在 while True: 中闲置并休眠。

【讨论】:

  • 我想我刚刚意识到你所说的 - 我将那行改为:if hasattr(res, "status_code") and res.status_code == 200:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多