在生产中的Web服务器中使用sleep()是不好的做法吗?

时间:2018-02-20 21:29:50

标签: python django

我正在使用Django1.8和Python2.7。

在项目的某个部分,我打开一个套接字并通过它发送一些数据。由于另一端的工作方式,我需要在发送的每个数据之间留出一些时间(比如说10毫秒):

   while True:
       send(data)
       sleep(0.01)

所以我的问题是:仅仅使用sleep()来创建暂停是不是很糟糕?还有其他更有效的方法吗?

更新: 我需要创建该暂停的原因是因为套接字的另一端是外部服务,需要一些时间来处理我发送的数据块。我还应该指出,在收到或者更不用说处理数据之后,它不会返回任何内容。留下那个短暂的暂停可确保我发送的每个数据块都得到接收方的正确处理。

编辑:将睡眠时间改为0.01。

2 个答案:

答案 0 :(得分:3)

是的,这是不好的做法和反模式。您将在未知的时间段内处理正在处理此请求的“工作人员”,这将使其无法提供其他请求。 Web应用程序的经典模式是尽可能快地为请求提供服务,因为通常有固定或最大数量的并发工作程序。虽然这名工作人员不断sleep,但它实际上是在游泳池之外。如果多个请求到达此端点,则会捆绑多个工作人员,因此应用程序的其余部分将遇到瓶颈。除此之外,您还可能遇到数据库锁定或竞争条件的问题。

处理您的情况的标准方法是使用像 Celery 这样的任务队列。您的Web应用程序将告诉 Celery 启动任务,然后快速完成请求逻辑。然后 Celery 将处理与第三方服务器的通信。 Django 非常适合 Celery ,并且有许多教程可以帮助您解决此问题。

如果您需要向最终用户提供信息,则可以为任务生成唯一ID,并通过让客户端每隔一段时间刷新URL来轮询结果后端以进行更新。 (我认为 Celery 会自动生成一个guid,但我通常会指定一个。)

答案 1 :(得分:2)

像大多数事情一样,简短的回答:这取决于。

答案稍长: 如果您在与Web服务器有很多(例如50个)连接的环境中运行它,所有这些连接都会触发睡眠代码,那么您真的不会喜欢这种行为。我强烈建议使用像celery / rabbitmq这样的东西,这样Django就可以把时间延迟部分转移到其他东西上,然后快速响应一个"任务开始"消息。

如果这是生产,但你是唯一一个点击网络服务器的人,它仍然不是很好的设计,但如果它有效,那么很难证明额外的复杂性上面提到的任务队列方法。