1

我对 Python 和 Django 还很陌生,所以如果有更好的方法,请告诉我。我想做的是让每个设备(继承自models.Model)启动一个长时间运行的后台线程,不断检查该设备的健康状况。但是,当我运行我的代码时,它似乎不像守护进程那样执行,因为服务器运行缓慢并且不断超时。这个后台线程将(在大多数情况下)运行程序的生命周期。

以下是我的代码的简化版本:

class Device(models.Model):
    active = models.BooleanField(default=True)
    is_healthy = models.BooleanField(default=True)
    last_heartbeat = models.DateTimeField(null=True, blank=True)

    def __init__(self, *args, **kwargs):
        super(Device, self).__init__(*args, **kwargs)
        # start daemon thread that polls device's health
        thread = Thread(name='device_health_checker', target=self.health_checker())
        thread.daemon = True
        thread.start()


    def health_checker(self):
        while self.active:
            if self.last_heartbeat is not None:
                time_since_last_heartbeat = timezone.now() - self.last_heartbeat
                self.is_healthy = False if time_since_last_heartbeat.total_seconds() >= 60 else True
                self.save()
                time.sleep(10)

这似乎是一个非常简单的线程使用,但每次我寻找解决方案时,建议的方法是使用 celery,这对我来说似乎有点过头了。有没有办法让这个工作而不需要像芹菜这样的东西?

4

2 回答 2

1

正如@knbk 在评论中提到的那样,“每次查询设备时,都会为每个返回的设备创建一个新线程”。这是我最初忽略的事情。

但是,我能够使用作为 Django 应用程序启动的单个后台线程来解决我的问题。这是一种比添加 3rd 方库(如 Celery)更简单的方法。

class DeviceApp(AppConfig):
    name = 'device_app'

    def ready(self):
        # start daemon thread that polls device's health
        thread = Thread(name='device_health_checker', target=self.device_health_check)
        thread.daemon = True
        thread.start()

def device_health_check(self):
    while (true):
        for device in Device.objects.get_queryset():
            if device.last_heartbeat is not None:
                time_since_last_heartbeat = timezone.now() - device.last_heartbeat
                device.is_healthy = False if time_since_last_heartbeat.total_seconds() >= 60 else True
                device.save()
        time.sleep(10)
于 2017-07-17T19:21:37.467 回答
0

当您在开发环境中开始时,设备的数量可能非常少。因此,当您进行测试时,线程数可能是两位数。

但是,即使您让代码正常工作,随着设备数量的增加,这个线程问题也会迅速变得站不住脚。因此,使用带有芹菜节拍的芹菜是更好的方法。

还要考虑到您是 Django 和 Python 的新手,尝试在此基础上掌握线程会增加更多复杂性。最后使用芹菜会更简单,更整洁。

于 2017-07-10T20:44:27.123 回答