- 一、开发配置版本
- 前言
- 应用场景:
- 为什么会放弃uWSGI 使用 gunicorn 的原因?
- 二、 uSWSGI + Nginx +Django 模式配置
- 1. uWSGI配置(保存为uwsgi.ini)
- 2. Nginx配置
- 三、 Django + gunicorn + Nginx 模式配置
- 1. Django settings 配置
- 2. Nginx 配置
- 3. gunicorn 配置(保存为gunicorn.py)
- 总结
一、开发配置版本
前言Liunx Version: CentOS 7.5 64位
Python Version: 3.6.9
Django Version: 2.2.9
Nginx Version: nginx/1.13.7
众所周知 uWSGI + django + nginx 为常用的后端项目配置项,我们来简单理解一下。
uWSGI: 是一个自有uwsgi协议,wsgi协议以及http服务协议的Web服务器。Nginx中HttpUwsgiModule的作用就是与uWSGI服务器进行交换。
Django: 项目是一个Python定制Web框架,它源自一个在线新闻 Web 站点,于 2005年以开源的形式被释放出来。
Django框架的核心组件有:用于创建模型的对象关系映射为最终用户设计的完美管理界面一流的 URL 设计设计者友好的模板语言缓存系统。
Nginx: 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器, 其特点是占有内存少,并发能力强, 稳定性高等优势。
Gunicorn: Gunicorn是⼀个WSGI HTTP Server,是针对Python的、在Unix系统上运⾏的、⽤来解析HTTP请求的⽹关服务。它的特点是:能和⼤多数的Python web框架兼容
应用场景:基于WSGI使用时只能支持不足100人的访问就会导致服务宕机, 从而通过高性能Nginx通过负载均衡对请求进行分流转发到对应的uWSGI服务, 因为UWSGI本身也是可多线程多进程进行请求。
从而让我们整个服务完成一个高性能的运转。
本身在我们的项目中存在websocket 即时消息提醒。 使用uWSGI 进行配置时http请求与wss请求阻塞导致服务挂起状态不做请求处理。
所以最終选用的 gunicorn 中的 gevent 模式, 完美解决卡顿服务挂起的问题。
本文不過多讲解, 带大家看看各自的配置使用方法都是怎样的。
二、 uSWSGI + Nginx +Django 模式配置 1. uWSGI配置(保存为uwsgi.ini)[uwsgi] #使用nginx连接时使用,Django程序所在服务器地址 socket=127.0.0.1:55668 #直接做web服务器使用,Django程序所在服务器地址 #http=127.0.0.1:8282 #项目目录 chdir=项目目录 #项目中wsgi.py文件的目录,相对于项目目录 wsgi-file=项目中wsgi.py文件的目录 # 进程数 processes=2 # 线程数 threads=4 # uwsgi服务器的角色 master=True # 存放进程编号的文件 pidfile=uwsgi.pid # 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的 daemonize=uwsgi.log #设置socket的监听队列大小(默认:100) listen = 2048 #设置用于uwsgi包解析的内部缓存区大小为64k。默认是4k。 buffer-size=5000 #为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏 max-requests = 10000 #设置在平滑的重启(直到接收到的请求处理完才重启)一个工作子进程中,等待这个工作结束的最长秒数。这个配置会使在平滑地重启工作子进程中,如果工作进程结束时间超过了8秒就会被强行结束(忽略之前已经接收到的请求而直接结束) reload-mercy = 10 #启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。 master=true #在每个worker而不是master中加载应用 lazy-apps=true #自动给进程命名 auto-procname = true #为进程指定前缀 procname-prefix-spaced = test-uwsgi # 这个是为了解决websocek使用时服务卡顿问题加的, 也是无法解决相关问题 DJANGO_SETTINGS_MODULE=jianyi.settings WEBSOCKET_FACTORY_CLASS="dwebsocket.backends.uwsgi.factory.uWsgiWebSocketFactory"2. Nginx配置
# 负载均衡使用
upstream test {
server 127.0.0.1:8081;
}
server {
listen 443 ssl;
server_name 域名/公网IP;
root html;
index index.html index.htm;
ssl_certificate 域名证书.pem;
ssl_certificate_key 域名证书.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 100M;
ssl_prefer_server_ciphers on;
include mime.types;
default_type application/octet-stream;
location / {
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
include uwsgi_params;
uwsgi_pass test; # 与upstream一致
}
}
三、 Django + gunicorn + Nginx 模式配置
1. Django settings 配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'gunicorn', # 需要在这里注册它才能正常使用
]
2. Nginx 配置
server {
listen 443 ssl;
server_name 域名/公网IP;
root html;
index index.html index.htm;
ssl_certificate 域名证书.pem;
ssl_certificate_key 域名证书.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 100M;
ssl_prefer_server_ciphers on;
include mime.types;
default_type application/octet-stream;
location / {
proxy_pass http://127.0.0.1:8081; #webScoket的访问地址
proxy_http_version 1.1;
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";
proxy_connect_timeout 4s; #配置点1
proxy_read_timeout 1200s; #配置点2,如果没效,可以考虑这个时间配置长一点
proxy_send_timeout 12s; #配置点3
}
3. gunicorn 配置(保存为gunicorn.py)
# -*- coding: utf-8 -*- # @Time : 2022/3/15 9:16 # @Author : LGL # @File : gunicorn.py import logging import logging.handlers from logging.handlers import WatchedFileHandler import os import multiprocessing # 绑定ip和端口号(与nginx server location中的proxy_pass一致) bind = '127.0.0.1:8081' # 监听队列 backlog = 512 # gunicorn要切换到的目的工作目录 chdir = '要切换到的目的工作目录' # 使用gevent模式,还可以使用sync 模式,默认的是sync模式 worker_class = 'gevent' # 进程数(多进程数据不互通,默认workers为1,单进程模式) 我是根据cpu 核数来的 workers = multiprocessing.cpu_count() # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置 loglevel = 'info' # 错误日志 errorlog = 'gunicorn.error.log' # 访问日志 accesslog = 'gunicorn.access.log' # 程序进程PID存储文件 # pidfile = "gunicorn.pid" # 默认daemon = Flase 这样启动会占用终端,如果只是使用gunicorn而不使用supervisord类似的进程管理工具,该参数设置为true, #使进程成为守护进程,但一旦使用类似supervisord等进程管理工具时,该参数一定不要设置,gunicorn默认该参数为False,否则会出现问题. daemon = False # 最大客户端并发数量,默认情况下这个值为1000。此设置将影响gevent和eventlet工作模式 max_requests = 2000 # 进程名 proc_name = 'gunicorn_test_project' # 设置超时时间120s,默认为30s。按自己的需求进行设置timeout = 120 timeout = 120 # 设置gunicorn访问日志格式,错误日志无法设置 # 如下配置,将打印ip、请求方式、请求url路径、请求http协议、请求状态、请求的user agent、请求耗时 # 示例:[2022-03-25 19:18:19 +0800] [50986]: [INFO] 127.0.0.1 POST /test/v1.0 HTTP/1.1 200 PostmanRuntime/7.26.3 0.088525 access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"' # 在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间。 keepalive = 3 # HTTP请求行的最大大小,此参数用于限制HTTP请求行的允许大小,默认情况下,这个值为4094。 # 值是0~8190的数字。此参数可以防止任何DDOS攻击 limit_request_line = 5120 # 为Ture 是 error 日志中可输出print()函数内容 capture_output = True
至于启动服务我是通过supervisord 进行管理的, 可自行查询使用
总结
在服务器能正常通信后,Werkzeug提供的的WSGI并不适合生产环境。所有我这里选择uWSGI和gunicorn,也不知道是没有寻找的对应的方法或者其他, 所以最终选择了gunicorn,配置也简单。性能也超级棒,好了今天就到这里了, 如果觉得本篇记录文章对你有些许作用, 记得点赞收藏哦!



