一台服务器,俩“房客”互不打扰?用Nginx + uWSGI同时跑Django和Flask,真没你想的那么难
兄弟们,咱们搞IT的,谁没遇到过这种事儿:
公司创业初期,就一台服务器,配置还不错。结果呢,产品部说要上Django写个后台管理系统,市场部那边又急着用Flask搭个活动落地页。需求都急,老板一拍板:就用那台唯一的服务器,俩都给跑起来!
你心里当时就咯噔一下:这俩玩意儿跑一块儿,端口冲突了咋整?环境乱了咋整?一个崩了另一个还活不活?
别慌,这事儿我干过好几回了。今天就用大白话,跟你们聊聊我是怎么在一台服务器上,用Nginx + uWSGI把这俩“房客”伺候得服服帖帖的,保证它们各过各的日子,谁也不碍着谁。
核心思想:其实就是多开几个“厨房”
你要理解一个事儿,无论是Django还是Flask,Python应用本身跑起来,就好比一个小厨房。它自己有个锅(应用进程),能炒菜(处理请求),但客人得直接跟厨房点菜,挺不方便的,而且厨房一多,来客人都找不着北了。
Nginx呢,就是酒店大堂的前台。所有客人进来,先到前台问:“我找Django那个房(后台系统)。” 前台一看,Django在101,Flask在202,就指引客人去对应的房间。
而uWSGI,是给你每个“厨房”配的专属传菜员。它把咱Python“厨房”做好的菜(HTTP响应),稳稳当当地端到前台去。
所以,一台服务器跑多个应用,思路特简单:多开几个uWSGI实例,每个监听不同的内部端口,然后用Nginx当“前台”,按请求的域名或者URL路径,把流量分发到不同的房间去。
第一步:给俩“厨房”分好锅灶(uWSGI配置)
咱们得给Django和Flask各自准备一套独立的uWSGI配置,相当于给它们各开一档“灶台”。我用的是文件 .ini 配置,特别清爽,像个菜谱一样。
比如,给Django整一个 django_app.ini:
[uwsgi]
# 这个厨房专门服务Django
socket = 127.0.0.1:8001
chdir = /data/www/my_django_project
module = my_django_project.wsgi:application
master = true
processes = 4 ; 多配几个厨师(进程)
threads = 2
vacuum = true
给它配个内部的“门牌号” 8001 端口。
然后给Flask整一个 flask_app.ini:
[uwsgi]
# 这个厨房专门服务Flask
socket = 127.0.0.1:8002
chdir = /data/www/my_flask_app
module = my_flask_app:app
master = true
processes = 2
threads = 2
vacuum = true
看见了没?端口不一样(一个是8001,一个是8002),这就是决定它们互不影响的关键。哪怕你两个都用Django,只要端口分开,配置文件里指向的代码路径分开,它们就是两个独立的世界。
你用 uwsgi --ini django_app.ini 和 uwsgi --ini flask_app.ini 把这两个“厨房”点着火,它们就在后台默默地各练各的功了。
第二步:调教“前台”(Nginx配置)
现在该让Nginx这个“前台”干活了。它要会认人。
场景一:用域名区分
假设 admin.mycompany.com 找Django,event.mycompany.com 找Flask。
server {
listen 80;
server_name admin.mycompany.com; # 来了个找Django的
location / {
uwsgi_pass 127.0.0.1:8001; # 你就往Django那屋带
include uwsgi_params;
}
}
server {
listen 80;
server_name event.mycompany.com; # 来了个找Flask的
location / {
uwsgi_pass 127.0.0.1:8002; # 直接带去Flask那屋
include uwsgi_params;
}
}
场景二:用路径区分(一个小技巧)
如果只有一个域名 mycompany.com,你可以配置 mycompany.com/django/ 和 mycompany.com/flask/,但这样改动代码里URL前缀很麻烦。我更推荐用第一个方法,专门买两个域名或者子域名,也就是10块钱的事儿,省心。
配好Nginx后,nginx -s reload 让它即刻生效。你看,就是这么简单,前台认得路了,客人就不会走错门。
真遇到事儿了,你就知道这有多香了
上次市场部那哥们儿,为了整那个Flask活动页,用了个特别新的第三方库,结果包依赖跟老系统起冲突了。搁以前,那肯定得把整个服务器环境搞乱。现在呢?我直接给那个Flask的uWSGI进程单独建了个虚拟环境,它在里面怎么折腾都行。就算它崩了,我重启一下Flask的uWSGI进程,Django那边的订单系统稳如老狗,一点都不会受到牵连。
再比如,Django那边发版,需要重启uWSGI加载新代码。你就在那儿重启 django_app.ini 就完事儿了,绝对不影响市场部还在用着的Flask活动页。它们俩压根就不知道对方的存在。
最后说几句掏心窝子的
这种多应用共存的部署方案,对于咱们这种资源有限的公司来说,真的是救命的。它没啥高深莫测的魔法,就是把职责分清楚:Nginx管流量入口,uWSGI管各个应用进程,各司其职。
如果你不想手写配置文件,嫌麻烦,现在也有很多像Supervisor或者Docker这样的工具来管理这些进程。但核心的“端口隔离 + 反向代理”这个思路,你只要懂了,以后不管换成啥工具,心里都有底。
这两行配置,能给你省下买第二台服务器的钱,还能让你在领导面前显得特专业:“小意思,一台服务器多应用部署嘛,基础操作。”
如果你们公司也遇到类似情况,或者你想了解更详细的配置参数坑点(比如静态文件怎么处理,开机自启怎么设),赶紧收藏这篇文章。更多现成的部署方案,可以访问 itfangan.com 去翻翻,很多老哥的经验比我这写得更全。行了,今天先聊到这儿,我得去看看我那俩“房客”今天有没有打架。