Flask自带的web服务器是Werkzeug,更准确地说,是Werkzeug库里的开发服务器,通过flask run或app.run()启动,适合本地调试,不适合直接扛线上流量。
flask自带的是什么web服务器?先认识Werkzeug
你第一次运行Flask时,终端会出现一行提示Running on http://127.0.0.1:5000,这个给你提供服务的东西并不是Flask本人,而是它的老朋友Werkzeug,Werkzeug是一个WSGI工具集,里面附带一个简单的HTTP服务器,Flask官方文档称它为“development server”。
业内专家指出,很多初学者误以为Flask内置了一个完整的企业级服务器,实际上Flask只是把Werkzeug的run_simple函数封装成了app.run(),让你少写几行代码,你可以打开终端执行pip show werkzeug,看看它的体积和依赖,会发现它正大光明地独立运行着。
Werkzeug开发服务器的特点可以归纳成三条:
- 自动检测代码变化并重启,省去手动按Ctrl+C的麻烦。
- 自带交互式调试器,页面报错时能直接看到堆栈,并可以在浏览器里执行代码片段。
- 默认监听127.0.0.1,只允许本机访问,避免你在调试时被局域网内其他人打扰。
WSGI全称Web Server Gateway Interface,是Python Web框架和服务器之间的标准沟通协议,Flask负责生成响应,Werkzeug负责把响应装进HTTP消息里发出去,当你调用app.run()时,默认使用Werkzeug的服务器处理请求,这就是标题答案的由来。
flask自带的开发服务器与gunicorn等生产服务器有什么区别?
很多人在搜索“flask自带的是什么web服务器”之后,紧接着就会问“flask和gunicorn区别”,这里需要先明确一个概念:Werkzeug开发服务器和gunicorn、uWSGI、waitress这些生产级WSGI服务器,目标完全不同。
flask内置服务器和gunicorn的区别可以从下表看出:
| 对比项 | Werkzeug开发服务器 | gunicorn等生产服务器 |
|---|---|---|
| 启动方式 | flask run 或 app.run() | gunicorn -w 4 app:app |
| 并发模型 | 单进程,默认多线程能力有限 | 多进程多Worker,支持预派生 |
| 静态文件处理 | 能跑但效率低 | 通常交给Nginx等反向代理 |
| 安全防护 | 几乎为零 | 有基本的请求头限制和超时控制 |
| 官方建议 | 仅用于开发 | 生产环境标配 |
这个表格很直观,开发服务器就像一个随身携带的测试工具,方便你快速验证代码逻辑,gunicorn则像一辆运货卡车,为线上流量设计,还会配合进程管理工具实现崩溃后的自动拉起,行业共识认为,把Werkzeug开发服务器直接暴露到公网,是一个相当危险的做法,不仅性能不够,还容易因为调试模式泄露源码。
另一个经常被拿来做对比的问题是“flask和django自带服务器哪个更顺手”,Django自带服务器也是开发服务器,基于django.core.servers,实现逻辑和Werkzeug不同,两者都只适合本地调试,如果你问哪个更适合入门,答案取决于你选哪个框架,而不是服务器本身。
flask自带的服务器怎么改端口?调试模式怎么关?
拆开聊一下实际操作,新手最常见的困惑是“flask自带服务器端口怎么改”,你只要在启动时带上--port参数就行:
- 改成8080端口:
flask run --port 8080 - 同时允许局域网访问:
flask run --host=0.0.0.0 --port=8080 - 关闭重启功能和调试器:
flask run --no-reload --no-debugger
如果你更喜欢用代码启动,app.run里也能控制:
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080, debug=False)
这里要提醒你,debug=True时Werkzeug会开启调试器,浏览器报错页面会出现一个控制台图标,生产环境切莫这样做,因为它允许远程执行Python代码,你可以用环境变量FLASK_ENV=production配合flask run,从根上避免误开调试模式。

设置环境变量的具体步骤
在项目目录里打开终端:
- Linux或macOS:
export FLASK_APP=app.py,再执行flask run - Windows PowerShell:
$env:FLASK_APP="app.py",再执行flask run
如果你的文件名不叫app.py,这里就需要改成真实文件名,比如main.py就要写成export FLASK_APP=main.py。
端口被占用时怎么办
当你在5000端口上看到Address already in use,说明已经有一个进程占用了它。
- Linux或macOS:执行
lsof -i:5000,记住PID,然后kill 你看到的PID - Windows:打开命令提示符,执行
netstat -ano | findstr :5000,再执行taskkill /PID 占用端口号 /F
解决完端口冲突后,再运行flask run,情况就恢复了。
什么时候该换掉flask自带服务器?生产环境的实战选择
假设你做了一个个人博客,跑在树莓派或一台低配置云服务器上,刚开始用flask run,访问量不高,一切正常,后来文章被推荐了,同一秒涌进来几十个请求,自带服务器开始出现明显的卡顿,甚至报出Connection Refused,这时候你需要思考一个百度上被反复搜索的问题:flask生产环境用什么服务器?
常用的替换方案有以下几类:
- gunicorn:类Unix系统下最主流的选择,配置简单,内置多Worker,配合Nginx使用效果很好。
- uWSGI:比gunicorn更底层,支持更多协议,但配置稍显复杂,适合需要更精细化控制的场景。
- waitress:纯Python实现的WSGI服务器,能在Windows上稳定运行,弥补了gunicorn不支持Windows的短板。
替换过程并不复杂,先安装gunicorn,再在项目目录执行gunicorn -w 4 app:app,把原来的app.run()留作本地调试用,生产服务器前通常还会架一层Nginx,负责静态资源和负载均衡,这个组合是社区里最常见的Flask部署架构。

一个标准的部署步骤可以这样写:
- 在项目根目录创建wsgi.py,内容为
from app import app - 执行
pip install gunicorn - 启动服务:
gunicorn -w 4 -b 0.0.0.0:8000 wsgi:app - 配置Nginx反向代理,把80端口转发到8000端口
当你使用生产服务器时,app.run()里的host和port参数就变得无关紧要了,真正决定监听地址的是gunicorn的--bind参数,比如gunicorn -w 4 --bind 0.0.0.0:8000 wsgi:app,公网访问就会通过Nginx转进来。
关于flask自带web服务器的常见问题解答
flask自带的服务器到底算不算一个真正的web服务器?
它算一个Web服务器,但不是完整意义上的生产级服务器,Werkzeug实现了HTTP/1.1协议,能处理请求和响应,也支持WebSocket扩展,由于它的设计目标聚焦在开发体验上,稳定性、并发能力和安全防护都弱于专业服务器,你可以把它理解为“功能齐全的玩具车”,能开能停,但上不了高速。
使用flask自带服务器时,静态文件访问总是404怎么办?
这是开发初期的高频问题,默认情况下flask run并不会自动扫描根目录下的static文件夹,需要在Flask实例化对象时显式指定静态文件夹路径,检查你的初始化代码,看看有没有写Flask(__name__, static_folder='static'),路径写对后,访问/static/css/style.css就能正常返回了。
flask自带的服务器和gunicorn能共用吗?
不建议,你不需要同时启动app.run()和gunicorn,否则会造成端口冲突和请求处理混乱,开发时用flask run,上线时用gunicorn,两者之间通过环境变量切换即可,运行gunicorn时设置环境变量FLASK_ENV=production,Flask代码里就可以根据这个环境变量决定是否调用app.run()。
Flask自带服务器是Werkzeug的化身,方便、直接、贴心,但你得记住它的边界,等到项目要见公网,换个更结实的服务器,Flask不会怪你,反而会跑得更稳。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/890485.html

