书接上回,之前一篇:Win10环境下使用Flask配合Celery异步推送实时定时消息(Socket。io)2020年最新攻略,阐述了如何使用Celery异步推送Websocket消息,现在我们利用Docker将这个完整项目部署起来,为什么用Docker呢?原因很简单,这种容器技术可以将整个项目用单个容器装起来,仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器,甚至把这个过程自动化,部署流程就会变得简单、方便。 简单理解就是Docker的镜像就类似《精灵宝可梦》中小智手里的精灵球,我们的项目就类似那些宠物小精灵,当我们开发完毕就可以利用DockerFile对项目进行打包制作成镜像(小精灵被吸入精灵球),部署时就可以理解为小精灵被释放出来进行战斗(通过打包好的镜像运行容器),而Docker的仓库则提高了镜像的便捷性,可以让我们随时随地只要联网就可以使用自己的镜像(相当于小智不用随身携带精灵球,而是通过网络随时下载需要的精灵球)。 同时Docker其强大的跨平台特性,可以让我们在任何系统下部署项目,包括经常令人诟病的Windows,值得一提的是本次在Win10下部署项目的流程同样适用于Centos、Macos、Ubuntu等系统,其兼容性可见一斑。 关于Win10如何折腾和配置Docker,请参照这篇文章:win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑) 首先简单看一下项目结构: manage。py是项目的入口文件,这里我们利用Sockert。io让Flask支持WebsocketfromflaskimportFlaskfromflasksqlalchemyimportSQLAlchemyimportpymysqlfromflaskimportrequest,jsonifyfromflaskcorsimportCORSfromflasksocketioimportSocketIO,send,emit,joinroom,leaveroomimporturllib。parseimportuserviewfromceleryimportCeleryfromdatetimeimporttimedeltapymysql。installasMySQLdb()appFlask(name)app。config〔SQLALCHEMYDATABASEURI〕mysql:root:rootlocalhost:3306mdapp。config〔SQLALCHEMYCOMMITONTEARDOWN〕Trueapp。config〔SQLALCHEMYTRACKMODIFICATIONS〕Trueapp。config〔BROKERURL〕redis:localhost:6379app。config〔CELERYRESULTBACKEND〕redis:localhost:6379app。config〔CELERYACCEPTCONTENT〕〔json,pickle〕app。config〔REDISURL〕redis:localhost:6379app。config〔JSONASASCII〕FalseCORS(app,corsallowedorigins)app。registerblueprint(userview。user)dbSQLAlchemy(app)socketioSocketIO(app,corsallowedorigins,asyncmodethreading,messagequeueapp。config〔CELERYRESULTBACKEND〕)celeryCelery(app。name)celery。conf。update(app。config)celery。conf。CELERYBEATSCHEDULE{test:{task:getcron,schedule:timedelta(seconds10)}}celery。task(namegetcron)defgetcron():getsendback。delay()celery。task()defgetsendback():socketio。emit(sendback,message,broadcastTrue)app。route(task)defstartbackgroundtask():getsendback。delay()return开始app。route(,methods〔GET,POST,PUT,DELETE〕)defhelloworld():resdb。session。execute(insertintouser(username)values(123))resdb。session。execute(selectid,usernamefromuser)。fetchall()datarequest。args。get(id)datarequest。form。get(id)print(data)print(res)returnHelloFlaskreturnjsonify({result:〔dict(row)forrowinres〕})returnjsonify({message:你好,Docker})socketio。on(join)defonjoin(data):usernameuser1roomroom1joinroom(room)send(usernamehasenteredtheroom。,roomroom)socketio。on(message)defhandlemessage(message):messageurllib。parse。unquote(message)print(message)send(message,broadcastTrue)socketio。on(connect,namespacechat)deftestconnect():emit(myresponse,{data:Connected})socketio。on(disconnect,namespacechat)deftestdisconnect():print(Clientdisconnected)app。route(sendback,methods〔GET〕)defsendback():socketio。emit(sendback,message)returnokifnamemain:socketio。run(app,debugTrue,host0。0。0。0,port5000) 接下来使用Gunicorngevent来运行Flask项目,Gunicorn服务器作为wsgiapp的容器,能够与各种Web框架兼容(flask,django等),得益于gevent等技术,使用Gunicorn能够在基本不改变wsgiapp代码的前提下,大幅度提高wsgiapp的性能。那到底怎么提升性能?说简单点,Gunicorn默认的网络模型是select,当我们把worker替换成gevent后,则改为epoll监听模型,关于select、poll、epoll请参照这篇文章:关于Tornado:真实的异步和虚假的异步,这里不再赘述。 安装相应的库pipinstallgunicorngeventuser 编辑项目目录下的gunicorn。conf。pyworkers3进程数workerclassgevent异步模式bind0。0。0。0:5000 由于Gunicorn并不支持Windows环境,所以只需要写好配置,不需要运行。 编辑项目目录下的requirements。txt文件,这里面都是我们项目所依赖的库flask1。0。2flaskcorsflasksocketioflasksqlalchemypymysqlcelerygunicorngeventredis3。3。11 随后在项目目录下创建一个Dockerfile文件,这个文件可以理解为打包镜像的脚本,你需要这个镜像做什么,就把任务写到脚本中,Docker通过执行这个脚本来打包镜像FROMpython:3。6WORKDIRProjectmyflaskCOPYrequirements。txt。RUNpipinstallrrequirements。txtihttps:pypi。tuna。tsinghua。edu。cnsimpleCOPY。。ENVLANGC。UTF8CMD〔gunicorn,manage:app,c,。gunicorn。conf。py〕 可以看到,我们项目的镜像首先基于python3。6这个基础镜像,然后声明项目目录在Projectmyflask中,拷贝依赖表,之后安装相应的依赖,这里在安装过程中我们指定了国内的源用来提高打包速度,最后利用gunicorn运行项目,值得一提的是,ENVLANGC。UTF8是为了声明Docker内部环境中的编码,防止中文乱码问题。 最后我们就可以愉快的打包整个项目了,在项目根目录下执行dockerbuildtmyflask。 此时看到Docker通过读取Dockerfile文件来下载所需的基础镜像和依赖库,这里一定要指定Docker的下载源,否则速度会非常缓慢,打包好的镜像文件大概有1g左右。 下载结束之后,可以看到myflask这个镜像已经静静躺在镜像库中了,运行dockerimages 命令来查看 然后我们就可以利用这个镜像来通过容器跑Flask项目了,运行命令dockerrunitrmp5000:5000myflask 这里的命令是通过端口映射把docker内部的端口5000映射到宿主机的5000端口上,后面的参数是镜像名称。我们看到,在Win10下,已经不可思议的通过Gunicorn把Flask跑起来了,这在之前没有Docker技术之前是不可想象的。 通过网址访问一下,这里注意一点,就是Windows系统下,访问Docker容器需要通过分配的ip来访问,而不是我们常用的localhost。 完全没有任何问题。 结语:到这里我们的DockerFlaskGunicorn就部署完毕了,将这个镜像上传Dockerhub仓库,在任何时间、任何地点、任何系统上,只要连着网、只要我们想,就都可以在短短1分钟之内部署好我们的项目,这就是Docker技术对开发人员最好的馈赠。最后奉上项目地址:https:gitee。comQiHanXiBeimyflask