- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下简单的“Hello World”应用程序:
from gevent import monkey
monkey.patch_all()
from flask import Flask
from gevent import wsgi
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World'
server = wsgi.WSGIServer(('127.0.0.1', 5000), app)
server.serve_forever()
如您所见,它非常简单。
问题是,尽管如此简单,但它仍然非常缓慢/效率低下,如下面的基准测试(使用 Apache Benchmark 制作)所示:
ab -k -n 1000 -c 100 http://127.0.0.1:5000/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 5000
Document Path: /
Document Length: 11 bytes
Concurrency Level: 100
Time taken for tests: 1.515 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 146000 bytes
HTML transferred: 11000 bytes
Requests per second: 660.22 [#/sec] (mean)
Time per request: 151.465 [ms] (mean)
Time per request: 1.515 [ms] (mean, across all concurrent requests)
Transfer rate: 94.13 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.6 0 3
Processing: 1 145 33.5 149 191
Waiting: 1 144 33.5 148 191
Total: 4 145 33.0 149 191
Percentage of the requests served within a certain time (ms)
50% 149
66% 157
75% 165
80% 173
90% 183
95% 185
98% 187
99% 188
100% 191 (longest request)
最终增加连接数和/或并发数并没有带来更好的结果,实际上它变得更糟。
我最担心的是我无法处理超过 700 个每秒请求 和 98 KB/秒的传输速率。
此外,单个每个请求的时间似乎太多了。
我很好奇 Python 和 Gevent 在后台做什么,或者更好的是,操作系统在做什么,所以我使用 strace 来确定最终的系统端问题,结果如下:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
56.46 0.000284 0 1386 close
24.25 0.000122 0 1016 write
10.74 0.000054 0 1000 send
4.17 0.000021 0 3652 3271 open
2.19 0.000011 0 641 read
2.19 0.000011 0 6006 fcntl64
0.00 0.000000 0 1 waitpid
0.00 0.000000 0 1 execve
0.00 0.000000 0 3 time
0.00 0.000000 0 12 12 access
0.00 0.000000 0 32 brk
0.00 0.000000 0 5 1 ioctl
0.00 0.000000 0 5006 gettimeofday
0.00 0.000000 0 4 2 readlink
0.00 0.000000 0 191 munmap
0.00 0.000000 0 1 1 statfs
0.00 0.000000 0 1 1 sigreturn
0.00 0.000000 0 2 clone
0.00 0.000000 0 2 uname
0.00 0.000000 0 21 mprotect
0.00 0.000000 0 69 65 _llseek
0.00 0.000000 0 71 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 3 getcwd
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 243 mmap2
0.00 0.000000 0 1838 748 stat64
0.00 0.000000 0 74 lstat64
0.00 0.000000 0 630 fstat64
0.00 0.000000 0 1 getuid32
0.00 0.000000 0 1 getgid32
0.00 0.000000 0 1 geteuid32
0.00 0.000000 0 1 getegid32
0.00 0.000000 0 4 getdents64
0.00 0.000000 0 3 1 futex
0.00 0.000000 0 1 set_thread_area
0.00 0.000000 0 2 epoll_ctl
0.00 0.000000 0 12 1 epoll_wait
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 26 clock_gettime
0.00 0.000000 0 2 openat
0.00 0.000000 0 1 set_robust_list
0.00 0.000000 0 1 eventfd2
0.00 0.000000 0 1 epoll_create1
0.00 0.000000 0 1 pipe2
0.00 0.000000 0 1 socket
0.00 0.000000 0 1 bind
0.00 0.000000 0 1 listen
0.00 0.000000 0 1000 accept
0.00 0.000000 0 1 getsockname
0.00 0.000000 0 2000 1000 recv
0.00 0.000000 0 1 setsockopt
------ ----------- ----------- --------- --------- ----------------
100.00 0.000503 24977 5103 total
如您所见,有 5103 个错误,最严重的问题是 open syscall,我怀疑这与找不到文件有关 (ENOENT )。令我惊讶的是,epoll 看起来不像是一个麻烦,因为我听说过很多关于它的恐怖故事。
我希望发布完整的 strace,其中包含每个调用的详细信息,但它太大了。
最后一点;我还设置了以下系统参数(这是允许的最大数量),希望它能改变这种情况,但事实并非如此:
echo “32768 61000″ > /proc/sys/net/ipv4/ip_local_port_range
sysctl -w fs.file-max=128000
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.core.somaxconn=61000
sysctl -w net.ipv4.tcp_max_syn_backlog=2500
sysctl -w net.core.netdev_max_backlog=2500
ulimit -n 1024
我的问题是,考虑到我使用的示例无法更改太多来解决这些问题,我应该去哪里纠正它们?
更新我用 Wheezy.web 和 Gevent 制作了以下“Hello World”脚本,每秒收到约 2000 个请求:
from gevent import monkey
monkey.patch_all()
from gevent import pywsgi
from wheezy.http import HTTPResponse
from wheezy.http import WSGIApplication
from wheezy.routing import url
from wheezy.web.handlers import BaseHandler
from wheezy.web.middleware import bootstrap_defaults
from wheezy.web.middleware import path_routing_middleware_factory
def helloworld(request):
response = HTTPResponse()
response.write('hello world')
return response
routes = [
url('hello', helloworld, name='helloworld')
]
options = {}
main = WSGIApplication(
middleware=[
bootstrap_defaults(url_mapping=routes),
path_routing_middleware_factory
],
options=options
)
server = pywsgi.WSGIServer(('127.0.0.1', 5000), main, backlog=128000)
server.serve_forever()
基准测试结果:
ab -k -n 1000 -c 1000 http://127.0.0.1:5000/hello
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 5000
Document Path: /front
Document Length: 11 bytes
Concurrency Level: 1000
Time taken for tests: 0.484 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 170000 bytes
HTML transferred: 11000 bytes
Requests per second: 2067.15 [#/sec] (mean)
Time per request: 483.758 [ms] (mean)
Time per request: 0.484 [ms] (mean, across all concurrent requests)
Transfer rate: 343.18 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 8 10.9 0 28
Processing: 2 78 39.7 56 263
Waiting: 2 78 39.7 56 263
Total: 18 86 42.6 66 263
Percentage of the requests served within a certain time (ms)
50% 66
66% 83
75% 129
80% 131
90% 152
95% 160
98% 178
99% 182
100% 263 (longest request)
我发现 Wheezy.web 的速度很快,但我仍然喜欢使用 Flask,因为它更简单,使用起来更省时。
最佳答案
您使用的是什么 gevent 版本?尝试将您的软件堆栈简化到最低限度,并尝试他们在他们的 github 上的示例。
https://github.com/gevent/gevent/blob/master/examples/wsgiserver.py
您是否将基准测试与非 gevent 版本进行了比较?我已经使用这个库获得了显着的加速,所以我会进一步调查。
关于Python Flask Gevent 堆栈 - 简单的 "Hello World"应用程序在进行基准测试时显示效率低下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23937117/
出于好奇 - 我知道有 LAMP - Linux、Apache、MySQL 和 PHP。但是还有哪些其他 Web 堆栈替代方案的缩写呢?像 LAMR - Linux、Apache、MySQL Ruby
我有以下代码。 var stackMapIn = []; var stackMapOut = []; var stackBack = []; stackMapOut.push("m1"); $scop
我遇到了导致我的堆栈无法恢复的情况,我别无选择,只能将其删除。使用完全相同的模板,我继续创建了另一个同名的堆栈。 The following resource(s) failed to create:
这是我第一次查看 Node 堆栈,自从我学习使用 Ruby on Rails 进行 Web 开发以来,我对一些基本的东西有点困惑。我了解 Rails 目录是什么样的。 demo/ ..../app .
本文实例讲述了C语言使用深度优先搜索算法解决迷宫问题。分享给大家供大家参考,具体如下: 深度优先搜索 伪代码 (Pseudocode)如下: ?
我正在按照指南 here ,它告诉我: The stack setup will download the compiler if necessary in an isolatedlocation (
同时 trying to debug a different question ,我安装了一个似乎与我安装的其他一些软件包冲突的软件包。 我跑了 $ stack install regex-pcre-
我花了几个小时创建了一个方法,该方法将从堆栈 s1 中获取 null 元素,并将它们放入 s2 中。然后该类应该打印堆栈。方法如下 import net.datastructures.ArraySta
我有一个类Floor,它有一个Stack block ,但我不知道如何初始化它。我曾尝试过这样的: public class Floor { private Stack stack;
我知道这个问题已经问过很多次了,但搜索一个小时后我仍然遇到问题。 我想使用一个 lifo 堆栈,它可以存储最大数量的元素。达到最大数量后,首先删除该元素并将其替换为新元素,这样在第一次弹出时我可以获取
我需要编写一个方法,压缩以执行以下操作; 目标compress方法是从栈s1中移除所有null元素。剩余(非空)元素应按其初始顺序保留在 s1 上。辅助堆栈 s2 应用作s1 中元素的临时存储。在该方
我正在尝试验证以下代码发生的顺序。 function square(n) { return n * n; } setTimeout(function(){ console.log("H
我需要一个字符数组,其中包含基于特定文件夹中文件数量的动态数量的字符数组。我能够通过初始化 char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH
我正在编写一些日志逻辑并想要进行一些缩进。了解是否存在任何函数调用或某个函数是否已完成的最简单方法是查看堆栈/帧的当前地址。让我们假设堆栈颠倒增长。然后,如果 log() 调用中的堆栈地址小于前一次调
所以内存分段在x86-64中被放弃了,但是当我们使用汇编时,我们可以在代码中指定.code和.data段/段,并且还有堆栈指针寄存器。 还有堆栈段、数据段和代码段寄存器。 代码/数据/堆栈的划分是如何
void main() { int x = 5; // stack-allocated Console.WriteLine(x); } 我知道 x 是堆栈分配的。但是关于 x 的堆栈中
这是我关于 SO 的第一个问题。这可能是一个愚蠢的问题,但到目前为止我还没弄明白。 考虑下面的程序 Reader.java: public class Reader { public
java中有没有一种快速的方法来获取嵌套/递归级别? 我正在编写一个函数来创建组及其成员的列表。成员也可以是团体。我们最终可能会得到一组循环的组/成员。 我想在某个任意级别停止。 我知道我可以将变量保
考虑以下代码: struct A{...}; A a[100]; A* pa = new A[100]; delete[] pa; a/pa 元素的销毁顺序是由标准定义的还是实现定义的(对于第二种情况
我在下面有一些代码。此代码是一个基本的压入/弹出堆栈类,我将其创建为模板以允许某人压入/弹出堆栈。我有一个家庭作业,我现在要做的是创建一个具有多个值的堆栈。 所以我希望能够创建一个基本上可以发送三个整
我是一名优秀的程序员,十分优秀!