我在ubuntu机器(16.04)上以相同的设置托管了两个python应用程序(app1和app2),并使用了不同的python版本(2.7和3.7),两者均基于Flask框架,使用Flask-SocketIO,并在uWSGI上运行( 2.0.17.1)在Nginx代理之后。 我已经能够在2.7版中成功实现对websocket的支持,但是我在3.7版上却做不到。 Nginx的配置和uwsgi相同,只是uwsgi的插件不同(Python版本) 在这两种情况下,我都使用带redis队列的uwsgi websocket服务器(通过SocketIO)。 除了websocket问题,app2可以正常工作。
Python 2.7库:
烧瓶== 0.12.2
Flask-SocketIO == 2.9.4
gevent == 1.2.2
greenlet == 0.4.13
Python 3.7库:
烧瓶== 1.0.2
Flask-Script == 2.0.6
gevent == 1.3.7
greenlet == 0.4.15
uWSGI -2.0.17.1
app = Flask(__name__)
# SocketIO
try: # This step is required only for version deployed on UWSGI
import uwsgi
socketio = SocketIO(app, message_queue=app.config['REDIS_QUEUE_URL'])
except ImportError:
print 'Application runs outside of uWSGI context'
socketio = SocketIO(app)
from flask-script import Manager
from app1 import app
@manager.command
def runserver(host = None, port = None, socket = True):
if not host:
host = 'localhost'
if not port:
port = 5000
if socket:
socketio.run(app)
else:
app.run(host, port, debug=False)
[uwsgi]
plugins-dir = /usr/local/lib/uwsgi
plugins = python27
#application's base folder
base = /home/ubuntu/app1
#python module to import
app = manage
module = %(app)
home = %(base)/venv
virtualenv = %(base)/venv
pythonpath = %(base)
#socket file's location
socket = %(base)/app1.sock
#permissions for the socket file
chmod-socket = 666
callable = app
logto = /var/log/uwsgi/%n.log
processes = 20
http-websockets = true
gevent = 500
vacuum = true
die-on-term = true
enable-threads = true
master = true
server {
listen 1014 ssl default_server;
server_name server_name_1;
access_log /var/log/nginx/app1_access_log;
error_log /var/log/nginx/app1_error_log;
auth_basic off;
# SSL only
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location /socket.io/ {
include uwsgi_params;
uwsgi_pass unix:/home/ubuntu/app1/app1.sock;
proxy_http_version 1.1;
proxy_read_timeout 180s;
proxy_buffering on;
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 X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {deny all;}
location = /app1{ rewrite ^ /app1/; }
location /app1{
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 X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://server:8080 https://server_name_1:1014/app1;
try_files $uri @app1; }
location @app1{
include uwsgi_params;
uwsgi_param SCRIPT_NAME /app1;
uwsgi_modifier1 30;
uwsgi_read_timeout 180s;
uwsgi_send_timeout 180s;
proxy_read_timeout 180s;
uwsgi_pass unix:/home/ubuntu/app1/app1.sock;
}}
def create_app():
...
app = Flask(__name__)
socket_io.init_app(app, message_queue = app.config['REDIS_URL'])
...
return app
import uwsgi
from gevent.monkey import patch_all
patch_all()
print('Patching all!')
from app2 import create_app
application = create_app()
[uwsgi]
plugins-dir = /usr/local/lib/uwsgi
plugins = python37
#application's base folder
base = /home/ubuntu/app2
home = %(base)/venv
virtualenv = %(base)/venv
pythonpath = %(base)
mount = /app2=%(base)/wsgi.py
callable = application
socket = %(base)/app2.sock
chmod-socket = 666
chdir = %(base)
attach-daemon = %(virtualenv)/bin/celery -A celery_worker.celery worker
attach-daemon = %(virtualenv)/bin/celery -A celery_worker.celery beat
logto = /var/log/uwsgi/%n.log
processes = 20
vacuum = true
die-on-term = true
enable-threads = true
master = true
manage-script-name = true
http-websockets = true
gevent = 5000
#Workaround for flask send_file() failing on python 3 and uwsgi
wsgi-disable-file-wrapper = true
server {
listen 1015 ssl default_server;
server_name server_name_2;
access_log /var/log/nginx/app2_access_log;
error_log /var/log/nginx/app2_error_log;
auth_basic off;
# SSL only
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location /socket.io/ {
include uwsgi_params;
uwsgi_buffering off;
uwsgi_pass unix:/home/ubuntu/app2/app2.sock;
proxy_http_version 1.1;
proxy_read_timeout 180s;
proxy_buffering on;
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 X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {deny all;}
location = /app2 { rewrite ^ /app2/; }
location /app2/ {
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 X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://server_name_2:1015/app2;
try_files $uri @app2; }
location @app2 {
include uwsgi_params;
uwsgi_read_timeout 180s;
uwsgi_send_timeout 180s;
proxy_read_timeout 180s;
uwsgi_pass unix:/home/ubuntu/app2/app2.sock;
}}
基于我的研究问题是uWSGI中的问题,由于某种原因,它没有收到任何wss调用。从客户端的角度来看,套接字连接是完成,而不是 101待处理。
无论我使用的是哪个客户端,问题始终存在。
在app1中,我可以在nginx和uwsgi(vassal)日志文件中看到套接字连接的每个尝试和错误,在app2的情况下,每次套接字连接尝试我只能看到499错误,而在vassal日志中没有匹配的条目。
最初,我指责uwsgi websocket服务器只能容纳1个应用程序,但是我可以在不同的vassal和nginx站点下随意复制app1任意多次,因此websocket连接很好。
python 3.7&uwsgi&SocketIO集成是否存在任何已知问题?我没主意了。