在AWS上扩展CherryPy Python Web服务器并发请求

4

出于好奇心,我用以下代码组合了一个简单的CherryPy服务器,该服务器会睡眠5秒钟(模拟处理延迟),然后返回一个简单的“hello”。

import cherrypy
import time

class server_runner(object):
  @cherrypy.expose
  def api(self, url):
    time.sleep(5)
    return "hello"

if __name__ == '__main__':
    cherrypy.server.socket_host = '0.0.0.0'
    cherrypy.quickstart(server_runner())

我进行了一项简单的负载测试(结果在此处http://i.imgur.com/LUpEtFL.png),应用程序似乎保持响应时间(蓝色)的一致性,直到第27个活跃用户(绿线显示活跃用户计数):响应时间迅速上升。我有些困惑,如果不能处理27个用户而出现严重延迟,那么CherryPy如何被标记为“生产就绪”服务器。我的实现或理解是否有问题?这是在C3大型Ec2实例上运行的。

server.thread_pool 的配置是什么? - behzad.nouri
感谢您的快速回复Behzad - 在撰写问题时,它是默认值:10。我稍微了解了一下,并将其更改为100,这似乎有所帮助:http://i.imgur.com/H8igGhu.png。您知道线程池配置中存在哪些限制/递减回报吗? - RonniePythonist
我认为在这个答案下的最后一个评论非常好地解释了它。 - behzad.nouri
1个回答

3
在简单情况下,您只需要按照问题评论中提到的方式管理 server.thread_pool 配置参数。
在实际情况下,这取决于许多因素。但我可以确定的是,CherryPy 是一个线程服务器,由于 Python 的 GIL,每次只运行一个线程。对于 I/O 密集型工作负载来说,这可能不是一个大问题,但您仍然可以利用 CPU 核心运行相同应用程序的多个 CherryPy 进程。这可能会决定一些设计决策,例如避免进程内缓存并且通常要遵循共享无状态架构,以便您的进程可以互换使用。
拥有多个应用程序实例会使维护更加复杂,因此您应该考虑利弊。接下来是一个示例,可以为您提供一些线索。 mp.py -- CherryPy 应用程序
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import cherrypy


class App:

  @cherrypy.expose
  def index(self):
    '''Make some traffic'''  
    return ('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean quis laoreet urna. '
      'Integer vitae volutpat neque, et tempor quam. Sed eu massa non libero pretium tempus. '
      'Quisque volutpat aliquam lacinia. Class aptent taciti sociosqu ad litora torquent per '
      'conubia nostra, per inceptos himenaeos. Quisque scelerisque pellentesque purus id '
      'vulputate. Suspendisse potenti. Vestibulum rutrum vehicula magna et varius. Sed in leo'
      ' sit amet massa fringilla aliquet in vitae enim. Donec justo dolor, vestibulum vitae '
      'rhoncus vel, dictum eu neque. Fusce ac ultrices nibh. Mauris accumsan augue vitae justo '
      'tempor, non ullamcorper tortor semper. ')


cherrypy.tree.mount(App(), '/')

srv8080.ini -- 第一个实例配置

[global]
server.socket_host = '127.0.0.1'
server.socket_port = 8080
server.thread_pool = 32

srv8081.ini -- 第二个实例的配置文件

[global]
server.socket_host = '127.0.0.1'
server.socket_port = 8081
server.thread_pool = 32

proxy.conf -- nginx配置文件

upstream app {
  server 127.0.0.1:8080;
  server 127.0.0.1:8081;
}

server {

    listen  80;

    server_name  localhost;

    location / {
      proxy_pass        http://app;
      proxy_set_header  Host             $host;
      proxy_set_header  X-Real-IP        $remote_addr;
      proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

}

mp.py*.ini放在一个目录中。将*.conf添加到nginx的sites-enabled,重新加载。在两个终端中打开带有mp.py的目录。然后在第一个终端中运行cherryd -e production -i mp -c ./srv8080.ini,在第二个终端中运行cherryd -e production -i mp -c ./srv8081.ini
现在您可以尝试它了。我在我的开发机上运行以下命令(Linux Mint 15,Core i5 x2 + HT)。
ab -c 1 -n 12800 -k http://127.0.0.1:8080/ # ~1600 rps
ab -c 16 -n 12800 http://127.0.0.1:8080/   # ~400  rps
ab -c 32 -n 12800 http://127.0.0.1/        # ~1500 rps  

谢谢!这真的很有帮助 :) - RonniePythonist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接