本文只探讨IIS+Python网站的情况,对于asp.net也应该不用这么麻烦。
先上结论:用反向代理: IIS + URL Rewrite + waitress
Waitress是一个纯python编写独立的WSGI服务器,功能比Gunicorn弱一些,但可以运行在windows平台上(Gunicorn 和 uwsgi 不支持windows)。
背景:用django做了个实时监控脚本执行状态的页面。里面用到了SSE技术,在开发环境一切正常,任务脚本执行过程中每个状态输出,web服务器端都会产生一个response推送给客户端,在浏览器中跨域实时看到任务执行状态。但部署到IIS中,web服务器会等全部任务执行完毕,才一次性把中间过程所有状态输出合并成一个response推送给客户端,界面卡住不动,无法实时看到当前状态。
折腾过程:
1、先是尝试了IIS禁用缓存、禁用动态内容压缩,问题依旧。
2、推断可能是wfastcgi导致的,问遍百度谷歌gpt都找不到禁用wfastcgi的buffer的方法
3、巨硬说部署django可以用HTTPPlatformHandler替代wfastcgi,于是折腾HTTPPlatformHandler,发现对于部署django网站HTTPPlatformHandler似乎真的比wfastcgi要简单呢!但无奈HTTPPlatformHandler还是解决不了禁用buffer的问题,并且github上HTTPPlatformHandler的开发者说v1.2确实有这个问题,但v1.2已经是最终版本,HTTPPlatformHandler会迁移到ASP.NET Core去。然后stackoverflow上有人说确实用ASP.NET Core解决了这个问题。
4、接着折腾ASP.NET Core,发现ASP.NET Core+python的部署指引在网上根本找不到。本来尝试肯一下ASP.NET Core的文档的,啃了一轮最后还是放弃了。
5、最终完全放弃IIS了,直接重新买个轻量云装linux,去折腾Nginx+uwsgi+django了,比较顺利地解决了SSE问题了。
6、但对IIS上部署还是有点不死心,于是又继续追着谷歌和gpt折腾这个问题,最后gpt建议试一下IIS反向代理,一试,居然成功了!而且配置并不复杂。嘛的此前折腾死我了!
下面是一个简单的步骤指南来配置IIS作为反向代理:
步骤 1: 安装 IIS 和必要的模块
- 确保安装了IIS。
- 安装URL Rewrite模块,这是一个IIS扩展,提供了URL重写功能。
- 安装Application Request Routing (ARR),ARR是一个IIS扩展,提供了代理功能。
步骤 2: 配置 Application Request Routing
- 打开IIS管理器。
- 选择服务器名称,在“应用程序请求路由缓存”下,打开“服务器代理设置”。
- 勾选“启用代理”,然后应用更改。
步骤 3: 配置web.config
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:8001/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
这个配置假设你的Django应用程序正在监听127.0.0.1
的8001
端口。所有到达IIS的请求将被重写(转发)到这个地址。
在windows系统上怎么启动waitress 我就不写了,网上有很多。备注一下,通过python runserver.py 方式启动waitress的代码如下:
# runserver.py
from waitress import serve
from xxxxxx.wsgi import application #xxxxxx.wsgi 中的xxx是自己项目目录名
serve(
app=application,
host='127.0.0.1', # 如果不用反向代理,直接让waitress对外提供服务,这里就填0.0.0.0,端口填80
port=8001
)
如果通过exe文件启动waitress的命令是:
# 须在虚拟环境下执行,
# ip:port 写0.0.0.0:80 还是写127.0.0.1:8000 请根据实际情况改
# xxxxx.wsgi 中的xxxx是wsgi.py 所在目录,这个文件夹名一般与项目名同名
path\to\waitress-serve.exe --listen=127.0.0.1:8001 xxxxx.wsgi:application
# 这条命令跟runserver.py中每一句的对应关系可以大致着样理解:
# waitress-serve.exe 中的 waitress 对应 from waitress
# waitress-serve.exe 中的 serve 对应 import serve
# listen=127.0.0.1:8001 对应host='127.0.0.1',port=8091
# xxxxx.wsgi 对应 from xxxxx.wsgi
# application 对应 import application
如果折腾ASP.NET Core来部署的话,这条命令可能用得上。