nginx+gunicorn+django+dwebsocket部署过程

记录本次部署的艰难过程

uwsgi启动项目(弃用)

了解到uwsgi也是支持websocket的,所以便使用这种熟悉的支持wsgi协议的web服务器来部署。
访问网页测试时,出现了报错

Internal Server Error

查看了uwsgi.log后,发现提示:

— no python application found, check your startup logs for errors —

报错有两个可能的原因:

  • uwsgi配置文件中的项目目录设置错误。
  • 使用的uwsgi版本可能是python2的,没有到进入到虚拟环境,建议推出重进一下

成功启动nginx与uwsgi后,再次访问网页进行测试, 出现报错:

WebSocket connection to 'xxx‘ failed:

然后websocket连接就关闭了。

查询代码后,发现网络请求是到@accept_websocket时停止的,猜测是因为websocket连接无法成功连接。请教了身边的同事后,了解到可能是因为nginx配置不支持websocket连接。

在网上一番搜索后,在项目nginx下的配置文件中加入了支持websocket的连接。

在location中加入了websocket配置。

location / {
    	# uwsgi启动
                uwsgi_send_timeout 600;        # 指定向uWSGI传送请求的超时时间,完成握手后向uWSGI传送请求的超时时间。
                uwsgi_connect_timeout 600;
                uwsgi_read_timeout 600;

                include     /usr/local/nginx/conf/uwsgi_params;
                uwsgi_pass  127.0.0.1:9997;

                # websocket的匹配
                proxy_redirect off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
}

将nginx重启应用新的配置文件。

nginx -s reload -c /路径/nginx.conf

成功重启nginx与,再次访问网页进行测试, 出现报错:

WebSocket connection to 'xxx‘ failed:

一样的报错,这让我不能理解了,遇到不能理解的事情时,只能期待google能够为我解释。于是在网上继续搜索,发现了dwebsocket的github,通过readme文件中的操作,尝试验证了一番。

Change websocket backends

Currently supports two kinds of backends, they are default and uwsgi.

Django develop server, eventlent, gevent, gunicore are supported by default.

If you want to use the uwsgi backend, add WEBSOCKET_FACTORY_CLASS in the settings.py file:

WEBSOCKET_FACTORY_CLASS = 'dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory'

Run uwsgi:

uwsgi --http :8080 --http-websockets --processes 1 --wsgi-file wsgi.py --async 30 --ugreen --http-timeout 300

这段话的意思是,dwebsocket目前支持两种类型的后端,default与uwsgi。ps: default我认为就是在开发时使用的runserver命令。默认支持django开发服务器,eventlent,gevent,gunicore。eventlent与gevent都是python中支持协程第三方库。ps:不知道是不是作者敲错字了,我理解的gunicore应该是gunicorn,一个wsgi的容器,支持wsgi的应用服务器。

如果想使用uwsgi作为后端,应该在项目的settings.py中配置

WEBSOCKET_FACTORY_CLASS = 'dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory'

启动uwsgi时使用命令

uwsgi --http :8080 --http-websockets --processes 1 --wsgi-file wsgi.py --async 30 --ugreen --http-timeout 300

github中的这一串命令应该是打错了,官网中wsgi.py与–async中间没有空格,导致运行时会报错。

用此命令启动uwsgi,由于此时是用uwsgi启动的,没有经过nginx,直接访问8080端口。打开网页进行测试,css样式全部消失了,一按F12,发现原来都找不到静态文件。确定路径都没有问题后,google一下。原来是命令中没有配置静态文件的路径,于是将命令更新为:

uwsgi --http :8080 --http-websockets --processes 1 --wsgi-file wsgi.py --async 30 --ugreen --http-timeout 300 --static-map /static=/路径/static

成功运行项目。ps:运行此命令时,建议在项目根路径下,与manage.py同级。将命令中wsgi.py替换成“项目名/wsgi.py",否则可能会报错no application,或者no module named ”项目名“的错误。

此处参考https://note.qidong.name/2017/07/uwsgi-serve-django-static/。

而且一行命令太长了,所以将其写成一个配置文件xxx_uwsgi.ini在后台,启动或配置更方便。

# xxx_uwsgi.ini
[uwsgi]
http=:8080
http-websockets=True
processes=1
wsgi-file=xxx/wsgi.py
async=30
ugreen=True
http_timeout=300
static-map=/static=/路径/static

; 设置日志目录
daemonize=/路径/log/uwsgi.log
; 停止时自动删除进程号文件
vacuum = true
pidfile=/路径/test_train.pid

虽然使用uwsgi启动项目成功了,但是通过测试项目发现,当有一个用户进行websocket长连接后,另一个用户便无法连接了,原因是uwsgi配置文件中的processes进程只配置了一个,websocket长连接占据了这个进程,导致了阻塞。

可是当我将processes进程数量设为2后,虽然可以两个用户连接了,但是并不能三个用户同时连接,这显然是不合理的。并且用户与用户之间的进程不通信,所以协同的功能就没有了。

经过一番搜寻后,没有找到好的解决方案,所以就弃用了uwsgi作为Web服务器的方案。

gunicorn启动项目(弃用)

舍弃了uwsgi作为web服务器方案后,尝试github中给出的第二种Web服务器gunicorn。

首先需要在Django项目下settings.py中的installed_apps加入gunicorn:

INSTALLED_APPS=[
    ...
   	...
    'gunicorn', # 部署用
]

在项目目录下,gunicorn启动语法:

gunicorn --worker-class=gevent 项目名.wsgi:application -b 127.0.0.1:8000&
  • -worker-class指定工作方式,如果运行提示you need gevent installed to use this worker.则使用pip install gevent安装即可。
  • 项目名.wsgi:application指定项目下的wsgi文件。
  • -b 指定地址和端口号。
  • & 表示在后台运行。

如果出现下面的报错:

 ModuleNotFoundError: No module named 'uwsgi'

回到settings.py文件中将WEBSOCKET_FACTORY_CLASS配置项注释掉,重新运行命令即可。

使用gunicorn启动时发现一个问题,当第二个客户端连接进入的时候,会找不到静态文件,暂时不知道为什么。

nginx+gunicorn启动项目(成功)

使用gunicorn启动项目时,第二个客户端连接上去找不到静态文件,猜测可能是因为静态文件占用问题。所以使用nginx作为静态文件服务器,并转发网络请求。

nginx文件配置:


location /static {
alias /home/xxx/static;
}

location / {
 #gunicorn配置
 proxy_pass http://127.0.0.1:9997;
 proxy_http_version 1.1;
 proxy_redirect off;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 # 协议升级
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection "upgrade";
}


为了方便gunicorn文件的配置,将其写到gunicorn.py文件中。

bind = '127.0.0.1:9997'  # 绑定ip与端口号
backlog = 512  # 监听队列
chdir = '/home/xxx/项目名'

# 使用gevent模式,还可以使用sync 模式,默认的是sync模式
worker_class = 'gevent'
loglevel = 'info'  # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
errorlog = '/home/xxx/logs/gunicorn.error.log'  #错误日志
accesslog = '/home/xxx/logs/gunicorn.access.log' #访问日志

daemon = True  # 后台运行

启动nginx:

nginx -c "/绝对路径/xxx_nginx.conf"

以nohup将gunicorn在后台保持运行:

nohup gunicorn -c gunicorn.py 项目名.wsgi:application

到这里,成功的将项目部署好了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是一个基本的 NginxGunicornDjango 和 DRF 示例,涵盖了常见的配置和设置: 1. 安装和配置 Nginx 在服务器上安装 Nginx,并创建一个新的站点配置文件。以下是一个示例配置文件,将所有请求转发到 Gunicorn: ``` server { listen 80; server_name yourdomain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` 2. 安装和配置 GunicornDjango 项目的虚拟环境中安装 Gunicorn: ``` pip install gunicorn ``` 创建一个 Gunicorn 配置文件(比如 gunicorn_config.py),指定项目的 WSGI 应用程序和其他选项: ``` import multiprocessing bind = "127.0.0.1:8000" workers = multiprocessing.cpu_count() * 2 + 1 ``` 3. 安装和配置 Django 和 DRF 在 Django 项目的虚拟环境中安装 Django 和 DRF: ``` pip install django djangorestframework ``` 创建一个 Django 项目,并在 settings.py 中添加 DRF 的应用程序: ``` INSTALLED_APPS = [ ... 'rest_framework', ... ] ``` 在 urls.py 中添加 DRF 的路由: ``` from django.urls import path, include urlpatterns = [ ... path('api/', include('rest_framework.urls')), ... ] ``` 创建一个 DRF 视图(比如 views.py),实现一个简单的 API: ``` from rest_framework.views import APIView from rest_framework.response import Response class HelloWorldView(APIView): def get(self, request): return Response("Hello, World!") ``` 在 urls.py 中添加一个路由,将视图映射到 URL: ``` from django.urls import path from .views import HelloWorldView urlpatterns = [ ... path('api/hello/', HelloWorldView.as_view()), ... ] ``` 4. 启动应用程序 使用 Gunicorn 启动 Django 项目: ``` gunicorn myproject.wsgi:application -c gunicorn_config.py ``` 访问 http://yourdomain.com/api/hello/,应该会看到 "Hello, World!" 的响应。如果您遇到任何问题,请参阅 NginxGunicornDjango 和 DRF 的文档和教程,以获取更详细的说明和指导。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值