【问题标题】:Variable will be instantiated more than once变量将被多次实例化
【发布时间】:2011-12-20 03:27:04
【问题描述】:

我在使用 Python2.7+Apache+mod_wsgi 开发小型 Web 服务器时遇到了一些不寻常的事情。该服务器的主要用途是:

  1. 从另一个服务器(服务器A)接收定期请求,并将请求正文放入数据库。
  2. 使用一些后台线程解析DB中的请求体,并将解析后的信息发送到第三台服务器(服务器B)。

Apache 配置为 Windows 'winnt' MPM 模式。作为入口点的 dispatch.py​​ 的代码如下:

from urlparse import parse_qs

pool = MyThreadClass() # A customized thread class to parse request body in DB
pool.start()

def application(environ, start_response):
    # Receiving regular request from server A and put request body into BD
    output = 'OK'
    start_response('200OK', [('Content-Type', 'text/plain')])
    return [output]

一开始,线程类是在服务器启动时创建的,它运行完美。然而,几个小时后,我发现线程类(MyThreadClass)将再次实例化,这意味着此时将有两个 MyThreadClass 实例在后台运行。
我不知道在Apache启动时创建这样的实例是否正确。你有什么想法吗?

[edit1]下面是apache中wsgi部分的配置:

WSGIScriptAlias / "E:/eclipse workspace/SubscriptionServer/src/business/dispatcher.py"
WSGIPythonPath "E:/eclipse workspace/SubscriptionServer/src"

<Directory "E:/eclipse workspace/SubscriptionServer">
    Order deny,allow
    Allow from all
</Directory>

[edit2] 我已按照@Graham 给出的指令将 LogLevel 设置为“信息”。我想我找到了原因,但无法解释原因!
以下是访问日志和错误日志的日志。我的服务器正在监听 8080。error.log 的前三行在服务器启动时记录。但是,在 16:36:18 2011 的访问日志中,有来自 124.237.78.181 的呼叫请求http://g.ha99y.com/R.asp?P=123.157.218.85:8080。就在那个时候,在错误日志中,服务器再次加载了 dispatcher.py。我无法解释该调用来自何处以及为什么它会创建两个解释器“myhost.com:8080|”和“myhost.com|”。

access.log:

124.237.78.181 - - [20/Dec/2011:16:36:18 +0800] "GET http://g.ha99y.com/R.asp?P=123.157.218.85:8080 HTTP/1.1" 404 29

error.log:

[Tue Dec 20 15:50:14 2011] [info] mod_wsgi (pid=1008): Create interpreter 'myhost.com:8080|'.
[Tue Dec 20 15:50:14 2011] [info] mod_wsgi (pid=1008): Adding 'E:/eclipse workspace/SubscriptionServer/src' to path.
[Tue Dec 20 15:50:14 2011] [info] [client 66.220.151.121] mod_wsgi (pid=1008, process='', application='myhost.com:8080|'): Loading WSGI script 'E:/eclipse workspace/SubscriptionServer/src/business/dispatcher.py'.
[Tue Dec 20 16:36:19 2011] [info] mod_wsgi (pid=1008): Create interpreter 'myhost.com|'.
[Tue Dec 20 16:36:19 2011] [info] mod_wsgi (pid=1008): Adding 'E:/eclipse workspace/SubscriptionServer/src' to path.
[Tue Dec 20 16:36:19 2011] [info] [client 124.237.78.181] mod_wsgi (pid=1008, process='', application='myhost.com|'): Loading WSGI script 'E:/eclipse workspace/SubscriptionServer/src/business/dispatcher.py'.

【问题讨论】:

    标签: python apache mod-wsgi


    【解决方案1】:

    您可能修改了导致 mod_wsgi 重新加载的 WSGI 脚本文件。

    使用以下命令关闭重新加载:

    WSGIScriptReloading Off
    

    每当您进行代码更改时,请确保重新启动 Apache。

    阅读:

    http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Reloading_In_Embedded_Mode http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIScriptReloading

    【讨论】:

    • 感谢您的回复。但我百分百确定我没有对代码进行任何更改。因为我让代码在周末运行而没有更改它并通过日志发现问题。
    • 然后发布 Apache 配置的 mod_wsgi 部分。我唯一能想到的另一件事是,您以某种方式对同一个脚本进行了多重别名,以使其可能被加载到不同的子解释器中。此实例中的线程类将位于不同的子解释器中。您可以通过确保在 Apache 配置中将 LogLevel 设置为“信息”来了解是否是这种情况。这样 mod_wsgi 将记录何时加载/重新加载 WSGI 脚本以及进入哪个子解释器。
    • WSGIScriptAlias / "E:/eclipse workspace/SubscriptionServer/src/business/dispatcher.py" WSGIPythonPath "E:/eclipse workspace/SubscriptionServer/src" 订单拒绝,允许所有 允许
    • 嗨@Graham,我有一些发现!
    • 您的服务器仍在侦听端口 80 和端口 8080。因为您没有明确停止此操作并且没有为端口 80 定义 VirtualHost,所以 Apache 将回退到使用第一个 VirtualHost它在配置中找到的定义。但它使用不同的子解释器,因为 mod_wsgi 默认情况下会将针对不同端口的请求分离到不同的子解释器中,但 80/443 情况除外。注释掉 Apache 配置中端口 80 的 Listen 指令。可以探测请求以查看您的网站是否容易受到某些攻击。
    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多