上一篇,在windows下尝试使用ASGI部署django3.1,部署失败一半,为什么说失败一半呢?因为按照官方文档, Gunicorn是在生产环境中运行和管理Uvicorn的最简单方法, 但是比如用 gunicorn -w 4 -k uvicorn.workers.UvicornWorker 以四个工作进程启动Gunicorn的时候,
UvicornWorker的
实现使用uvloop
和httptools, uvloop模块并不支持windows. 如果不用Gunicorn, 仅仅使用uvicorn是成功的,但这与生产环境的要求就不符了.
在docker下部署, 并不能真正用于生产,查查坑而已:
docker pull centos
docker run centos cat /etc/centos-release # 查看pull下来的centos版本 CentOS Linux release 8.3.2011 # 8.3版
docker run centos -it /bin/bash # 进入容器的命令行模式
yum install net-tools # 先安装网络工具,好使用ifconfig之类的工具
centos8.3 发行版默认有Python3,但centos的镜像默认没有python,需要安装一个.
yum install python3
结果默认安装的是python3.6.8 ,我又给删除了, 因为Python 3.9 对异步编程(asyncio)和多进程库进行了优化, 能更好发挥ASGI的能力.
yum install wget wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo # 更换成阿里云的源 sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo # 非阿里云运行这行
yum makecache # 老版本有个fast参数, 已经失效了.
yum list python* # 遗憾,只支持到3.8
源码方式安装试试.
yum -y update yum groupinstall "Development Tools" -y # 必要的工具,包括gcc yum install openssl-devel libffi-devel bzip2-devel -y gcc --version # 看看gcc的版本 ,结果是3.8.1 wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz cd /home tar xvf Python-3.9.2.tgz cd Python-3.9.2/ ./configure --enable-optimizations make altinstall # 我用2核8G的虚拟机的docker容器, 好慢.
添加python的国内源
python.exe -m pip install --upgrade pip pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip3.9 install django # 安装django 最新版本是3.1.7
python3.9 -m pip install uvicorn gunicorn
创建和激活虚拟环境
mkdir hello_async cd hello_async python3.9 -m venv env source env/bin/activate
创建个django项目并用官方方法运行
(env)$ django-admin.py startproject hello_async
(env)$ cd hello_async
(env)$ gunicorn hello_async.asgi:application -k uvicorn.workers.UvicornWorker #Django官方手册的方法
报错了
[2021-03-13 19:00:17 +0000] [13110] [INFO] Starting gunicorn 20.0.4 [2021-03-13 19:00:17 +0000] [13110] [INFO] Listening at: http://127.0.0.1:8000 (13110) [2021-03-13 19:00:17 +0000] [13110] [INFO] Using worker: uvicorn.workers.UvicornWorker [2021-03-13 19:00:17 +0000] [13111] [INFO] Booting worker with pid: 13111 [2021-03-13 19:00:17 +0000] [13111] [ERROR] Exception in worker process Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker worker.init_process() File "/usr/local/lib/python3.9/site-packages/uvicorn/workers.py", line 62, in init_process self.config.setup_event_loop() File "/usr/local/lib/python3.9/site-packages/uvicorn/config.py", line 354, in setup_event_loop loop_setup = import_from_string(LOOP_SETUPS[self.loop]) File "/usr/local/lib/python3.9/site-packages/uvicorn/importer.py", line 23, in import_from_string raise exc from None File "/usr/local/lib/python3.9/site-packages/uvicorn/importer.py", line 20, in import_from_string module = importlib.import_module(module_str) File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 680, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 790, in exec_module File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "/usr/local/lib/python3.9/site-packages/uvicorn/loops/uvloop.py", line 3, in <module> import uvloop ModuleNotFoundError: No module named 'uvloop' [2021-03-13 19:00:17 +0000] [13111] [INFO] Worker exiting (pid: 13111) [2021-03-13 19:00:17 +0000] [13110] [INFO] Shutting down: Master [2021-03-13 19:00:17 +0000] [13110] [INFO] Reason: Worker failed to boot.
提示,缺少uvloop.
deactivate # 必须退出虚拟环境
pip3.9 install uvloop
source env/bin/activate
再次运行
gunicorn hello_async.asgi:application -k uvicorn.workers.UvicornWorker
报错
File "/usr/local/lib/python3.9/sqlite3/dbapi2.py", line 27, in <module> from _sqlite3 import * ModuleNotFoundError: No module named '_sqlite3'
退出虚拟环境
yum install sqlite-devel # 也会自动安装sqlite
重新编译python,此处不重复写命令行了
pip3.9 install httptools # 趁退出了虚拟环境,安装httptools模块,别问我是怎么知道的.
重新创建虚拟环境,并进入对应带manage.py的文件夹,再次运行,
gunicorn hello_async.asgi:application -k uvicorn.workers.UvicornWorker
(env) [root@4f64ace0cb0b hello_async]# gunicorn hello_async.asgi:application -k uvicorn.workers.UvicornWorker [2021-03-13 19:34:43 +0000] [24570] [INFO] Starting gunicorn 20.0.4 [2021-03-13 19:34:43 +0000] [24570] [INFO] Listening at: http://127.0.0.1:8000 (24570) [2021-03-13 19:34:43 +0000] [24570] [INFO] Using worker: uvicorn.workers.UvicornWorker [2021-03-13 19:34:43 +0000] [24571] [INFO] Booting worker with pid: 24571 [2021-03-13 19:34:43 +0000] [24571] [INFO] Started server process [24571] [2021-03-13 19:34:43 +0000] [24571] [INFO] Waiting for application startup. [2021-03-13 19:34:43 +0000] [24571] [INFO] ASGI 'lifespan' protocol appears unsupported. [2021-03-13 19:34:43 +0000] [24571] [INFO] Application startup complete.
终于运行起来了.
通过在centos下的部署测试说明, 缺少uvloop模块对windows的支持, uvicorn.workers.UvicornWorker是不能工作的, 兄弟们我觉得可以暂时放弃在windows server下部署异步模式的django项目了.
退出容器, 看看宿主机防火墙状态
firewall-cmd --state # 查看防火墙状态. firewall-cmd --list-ports #查看所有打开的端口,ssh默认不显示 firewall-cmd --permanent --add-port=8000/tcp # 添加一个规则,暴露8000端口用于在宿主机外访问容器内的django网站
firewall-cmd --reload # reload,使规则生效.
先commint一个容器镜像,回头再补充 与nginx的联合使用.
docker commit -a "x****@foxmail.com" -m "centos83+python39+django3.1.7+ ASGI" 4f64ace0 centos_python_django_asgi:0.1