在工作中,我们时不时地要求返回那么久,当它们完成时,前端(nginx)已经杀死了连接,因此用户将看不到输出(无论是好还是坏)。
最糟糕的是,平衡器(haproxy)也将终止连接,然后假设服务器可以自由处理另一个请求,这意味着当服务器仍在处理旧请求时,新的请求会进入并争取资源。
理想情况下,服务器应该一次只处理一个请求,以尽可能多地重用与ZEO数据库的连接线程,因此同时运行两个请求会使服务器更慢,然后我们的一个监控系统正确地重新启动因为假人证明它发送的时间很长。
那么给出一些逻辑(可能重用我们已经使用的Products.LongRequestLogger)有没有办法告诉线程处理请求停止这样做?
答案 0 :(得分:1)
恕我直言,手动中止请求是一个坏主意。你以某种方式干扰冲突解决,这是恕我直言,不是一个非常好的行为。
我正在运行一些大型plone网站,每天有200到400位作者发布/修改1000 - 3000个对象。通常负载是在一天中分散的,因此也会在合理的时间内处理更长的请求。
例如在晚上,长期要求(30s-60s)表现良好。没有理由中止他们。
在Plone中我们有一些经典的长请求,比如重命名/移动一棵大树,更改权限,复制很多对象。然后通常冲突发生在目录中的某个地方,并在3次重试后中止事务。
通过中止长请求,您只需从Plone中删除一些功能。您可以考虑为重命名/移动/复制操作添加条件,因此如果您在容器中有1000个对象,则它们不再存在。
到目前为止我尝试/做过的事情:
缩短请求时间(哈哈,我现在简单地说但很难实现:-)) - >例如,检查此package's copy/move patch:它不再执行重命名和移动的uncatalog /目录,而只更新必要的索引。我们用这个实现了很多。
队列:我使用redis来排队和处理已知的长动作。当然你需要提前知道,这是一个潜在的长期请求,但我想你已经在你的环境中知道了这一点。如果请求完成,您可以通过电子邮件或某种Flash消息联系用户。
保持目录尽可能小,将所有内容委托给solr / elasticsearch(删除SearchableText会给你很多...)
硬件:我知道听起来很傻,但这通常是一个快速的胜利。尝试至少加载RAM中的所有目录对象。在快速cpu / ssd(通用I / O)中投入几美元。这不是我喜欢的方式,但它发生了,在2016年,它可以给你一些时间来解决长期请求问题。
未来:
嗯......首先我只发表评论,但我超出了人物限制; - )