#1 本地开发 flask 应用程序,里面使用了 websocket,异步模式使用得是 gevent,并在程序刚开始打了 gevent 猴子补丁,s 端主要监听 connect disconnect 两个事件用来做一些前端页面的初始化和离开动作。 启动代码:
socketio.run(app=app, host='0.0.0.0', port=5000, debug=True)
#2 正常在本地 debug 或 run 都没问题,部署到测试环境遇到问题,测试环境采用得是 Nginx+supervisor+gunicorn+flask, nginx 配置:
server {
listen 8000;
listen [::]:8000;
server_name x.x.x.x;
root /root/python/asset;
location / {
proxy_pass http://127.0.0.1:5000;
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;
access_log /var/log/asset/access.log;
error_log /var/log/asset/error.log;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
supervisor 配置:
[program:xx]
directory = /root/python/xx
command = /root/.local/xxx/bin/gunicorn -b 127.0.0.1:5000 -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module:app
user = root
autostart = true
autorestart = true
stopasgroup = true
killasgroup = true
startsecs = 5
startretries = 3
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /var/log/xx/stdout.log
stderr_logfile = /var/log/xx/stderr.log
其中启动 gunicorn 的命令参考自
https://stackoverflow.com/questions/38624447/websockets-proxied-by-nginx-to-gunicorn-over-https-giving-400-bad-request
https://segmentfault.com/q/1010000007495163
https://flask-socketio.readthedocs.io/en/latest/#gunicorn-web-server
gunicorn 也在 pipenv 环境下安装
#3
不使用 gunicorn 的情况下没任何问题,如图:
使用了 gunicorn 的情况,
首先会导致 402 错误,
402 详情,
其次,会一直 pending,一直在发请求,
最后是 402 详情在控制台的信息,
请各位帮帮忙,尝试了好长时间没办法解决,感谢各位。
1
greyli 2018-10-11 12:18:59 +08:00
按照 Flask-SocketIO 的文档,使用 Gunicorn 的时候要使用 eventlet 或 gevent worker,所以启动命令应该是:
``` gunicorn --worker-class eventlet -w 1 module:app ``` 或: ``` gunicorn -k gevent -w 1 module:app ``` |
2
greyli 2018-10-11 12:19:31 +08:00
原来回复不支持 Mardown ……
|
3
hanssx OP 对了,supervisor 有错误日志,一直在尝试连接,如下图:
![image]( http://pgf1p2i0h.bkt.clouddn.com/supervisor%E9%94%99%E8%AF%AF%E6%97%A5%E5%BF%9755.png) |
4
hanssx OP @greyli 辉哥,我改了启动命令了,参考的文档里面
gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module:app |
5
hanssx OP 这是 flask-socketio 官网给的例子,说了一大堆英文,反正就是要用 gunicorn 就要那么写,如果搭配 gevent 的话,
https://flask-socketio.readthedocs.io/en/latest/#gunicorn-web-server 最后命令是这么写的, gunicorn -b 127.0.0.1:5000 -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 module:app |
6
itertools 2018-10-11 13:41:05 +08:00
gunicorn 版本问题
|
7
itertools 2018-10-11 13:42:19 +08:00
使用 gunicorn==19.9.0 这个版本试试。
|
8
FiveDDD 2018-10-11 13:47:20 +08:00
启动命令:gunicorn -b :5000 -w 1 module:app -k eventlet
版本是 19.9.0 没问题 |
9
hanssx OP @itertools 感谢关注,但是测试机上面的 gunicorn 版本就是你说的这个,
(asset-ar0OxIPP) [root@VM asset]# pipenv graph | grep gunicorn gunicorn==19.9.0 |
12
hanssx OP @itertools
supervisorctl stop all find / -name supervisor.sock 后 unlink 掉 再重新启动 supervisord -c /etc/supervisord.conf 还是不行。。。 supervisorctl status,显示 asset STARTING 没 RUNNING 起来。。。 |
13
hanssx OP 看日志,还是那些东西,我去 gg 一下日志相关的东西,
[2018-10-11 13:58:33 +0800] [19707] [INFO] Starting gunicorn 19.9.0 [2018-10-11 13:58:33 +0800] [19707] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:33 +0800] [19707] [ERROR] Retrying in 1 second. [2018-10-11 13:58:34 +0800] [19702] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:34 +0800] [19702] [ERROR] Retrying in 1 second. [2018-10-11 13:58:34 +0800] [19707] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:34 +0800] [19707] [ERROR] Retrying in 1 second. [2018-10-11 13:58:35 +0800] [19702] [ERROR] Can't connect to ('127.0.0.1', 5000) [2018-10-11 13:58:35 +0800] [19707] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:35 +0800] [19707] [ERROR] Retrying in 1 second. [2018-10-11 13:58:36 +0800] [19707] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:36 +0800] [19707] [ERROR] Retrying in 1 second. [2018-10-11 13:58:37 +0800] [19716] [INFO] Starting gunicorn 19.9.0 [2018-10-11 13:58:37 +0800] [19716] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 13:58:37 +0800] [19716] [ERROR] Retrying in 1 second. |
14
hanssx OP @itertools
我根据 https://stackoverflow.com/questions/16756624/gunicorn-connection-in-use-0-0-0-0-5000/40894414 [root@VM asset]# sudo fuser -k 5000/tcp 5000/tcp: 18762 18765 [root@VM asset]# supervisorctl status asset RUNNING pid 20781, uptime 0:00:32 [root@VM asset]# netstat -antlp | grep 5000 tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN 20781/python3.7m tcp 0 0 127.0.0.1:49678 127.0.0.1:5000 TIME_WAIT - tcp 0 0 127.0.0.1:5000 127.0.0.1:49708 ESTABLISHED 20787/python3.7m tcp 0 0 127.0.0.1:49650 127.0.0.1:5000 TIME_WAIT - tcp 0 0 127.0.0.1:5000 127.0.0.1:49706 TIME_WAIT - tcp 0 0 127.0.0.1:49708 127.0.0.1:5000 ESTABLISHED 25344/nginx: worker tcp 0 0 127.0.0.1:5000 127.0.0.1:49680 TIME_WAIT - |
15
so1n 2018-10-11 14:15:33 +08:00
有没有内存不够的可能呢?
|
16
hanssx OP |
17
hanssx OP @itertools 打扰,我已经重新清理了之后使用 sudo kill -9,确认网站访问不了,然后重新 supervisord -c /etc/supervisord.conf
问题依然还在,日志中是这样,请问这是 work 吗?这和我在 supervior conf 中配置的不一样啊,我用了参数-w 1 呀。 [2018-10-11 14:28:36 +0800] [25625] [ERROR] Connection in use: ('127.0.0.1', 5000) [2018-10-11 14:28:36 +0800] [25625] [ERROR] Retrying in 1 second. [2018-10-11 14:28:37 +0800] [25625] [INFO] Listening at: http://127.0.0.1:5000 (25625) [2018-10-11 14:28:37 +0800] [25625] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 14:28:37 +0800] [25635] [INFO] Booting worker with pid: 25635 [2018-10-11 14:32:15 +0800] [26148] [INFO] Starting gunicorn 19.9.0 [2018-10-11 14:32:15 +0800] [26148] [INFO] Listening at: http://127.0.0.1:5000 (26148) [2018-10-11 14:32:15 +0800] [26148] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 14:32:15 +0800] [26151] [INFO] Booting worker with pid: 26151 [2018-10-11 14:33:32 +0800] [26345] [INFO] Starting gunicorn 19.9.0 [2018-10-11 14:33:32 +0800] [26345] [INFO] Listening at: http://127.0.0.1:5000 (26345) [2018-10-11 14:33:32 +0800] [26345] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 14:33:32 +0800] [26348] [INFO] Booting worker with pid: 26348 [2018-10-11 14:37:35 +0800] [26931] [INFO] Starting gunicorn 19.9.0 [2018-10-11 14:37:35 +0800] [26931] [INFO] Listening at: http://127.0.0.1:5000 (26931) [2018-10-11 14:37:35 +0800] [26931] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 14:37:35 +0800] [26934] [INFO] Booting worker with pid: 26934 [2018-10-11 14:39:18 +0800] [27180] [INFO] Starting gunicorn 19.9.0 [2018-10-11 14:39:18 +0800] [27180] [INFO] Listening at: http://127.0.0.1:5000 (27180) [2018-10-11 14:39:18 +0800] [27180] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 14:39:18 +0800] [27183] [INFO] Booting worker with pid: 27183 |
18
hanssx OP 开启了 flask-socketio 的日志,现在重新启动,ps -ef | grep guni 出现 2 行,其中 1 行是 work,work 数应该没错,日志现在报错,继续搜索解决方案,
[2018-10-11 15:19:04 +0800] [697] [INFO] Starting gunicorn 19.9.0 [2018-10-11 15:19:04 +0800] [697] [INFO] Listening at: http://127.0.0.1:5000 (697) [2018-10-11 15:19:04 +0800] [697] [INFO] Using worker: geventwebsocket.gunicorn.workers.GeventWebSocketWorker [2018-10-11 15:19:04 +0800] [700] [INFO] Booting worker with pid: 700 Server initialized for gevent. bae5c5f54be848fcabd9e5cfe8ce59fa: Sending packet OPEN data {'sid': 'bae5c5f54be848fcabd9e5cfe8ce59fa', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000} bae5c5f54be848fcabd9e5cfe8ce59fa: Sending packet MESSAGE data 0 bae5c5f54be848fcabd9e5cfe8ce59fa: Received packet MESSAGE data 0/process_upload_csv bae5c5f54be848fcabd9e5cfe8ce59fa: Sending packet MESSAGE data 0/process_upload_csv Traceback (most recent call last): File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 975, in handle_one_response self.run_application() File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/geventwebsocket/handler.py", line 82, in run_application self.process_result() File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 909, in process_result self.write(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 756, in write self._write_with_headers(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 777, in _write_with_headers self._write(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 741, in _write self._sendall(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 703, in _sendall self.socket.sendall(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/_socket3.py", line 457, in sendall data_memory = _get_memory(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/_socket3.py", line 45, in _get_memory mv = memoryview(data) TypeError: memoryview: a bytes-like object is required, not 'str' 2018-10-11T07:20:48Z {'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '54310', 'HTTP_HOST': '10.26.15.222', (hidden keys: 31)} failed with TypeError bae5c5f54be848fcabd9e5cfe8ce59fa: Client is gone, closing socket bae5c5f54be848fcabd9e5cfe8ce59fa: Client is gone, closing socket ca996671e95d4e54834a745c9129caa8: Sending packet OPEN data {'sid': 'ca996671e95d4e54834a745c9129caa8', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000} ca996671e95d4e54834a745c9129caa8: Sending packet MESSAGE data 0 ca996671e95d4e54834a745c9129caa8: Received packet MESSAGE data 0/process_upload_csv ca996671e95d4e54834a745c9129caa8: Sending packet MESSAGE data 0/process_upload_csv Traceback (most recent call last): File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 975, in handle_one_response self.run_application() File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/geventwebsocket/handler.py", line 82, in run_application self.process_result() File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 909, in process_result self.write(data) File "/root/.local/share/virtualenvs/asset-ar0OxIPP/lib/python3.7/site-packages/gevent/pywsgi.py", line 756, in write |
19
hanssx OP |
20
itertools 2018-10-11 16:21:27 +08:00
@hanssx https://github.com/miguelgrinberg/Flask-SocketIO/issues/272 gevent-websocket 貌似不支持 python3
|
21
hanssx OP 清理了 gunicorn 进程,抛弃了 websocket-gevent,使用了 gevent,gunicorn -b 127.0.0.1:5000 -k gevent -w 1 module:app,不再报 402 错误了,但是程序还是会一直 pending,一直发请求。。。
|
22
hanssx OP @itertools 是的,不支持 py3,真是我的锅,第一次部署花了很多时间,使用了 gevent 之后没有 402 错误了,但是会一直 pending,gunicorn 日志显示好像是心跳包,正在找办法关了它。。。
[2018-10-11 16:40:27 +0800] [12128] [INFO] Shutting down: Master [2018-10-11 16:41:47 +0800] [13014] [INFO] Starting gunicorn 19.9.0 [2018-10-11 16:41:47 +0800] [13014] [INFO] Listening at: http://127.0.0.1:5000 (13014) [2018-10-11 16:41:47 +0800] [13014] [INFO] Using worker: gevent [2018-10-11 16:41:47 +0800] [13017] [INFO] Booting worker with pid: 13017 Server initialized for gevent. 94207eaf37114c118b05480ba12679ef: Sending packet OPEN data {'sid': '94207eaf37114c118b05480ba12679ef', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000} 94207eaf37114c118b05480ba12679ef: Sending packet MESSAGE data 0 94207eaf37114c118b05480ba12679ef: Received packet MESSAGE data 0/process_upload_csv 94207eaf37114c118b05480ba12679ef: Sending packet MESSAGE data 0/process_upload_csv 94207eaf37114c118b05480ba12679ef: Received packet PING data None 94207eaf37114c118b05480ba12679ef: Sending packet PONG data None 94207eaf37114c118b05480ba12679ef: Received packet PING data None 94207eaf37114c118b05480ba12679ef: Sending packet PONG data None 94207eaf37114c118b05480ba12679ef: Received packet PING data None |
23
hanssx OP @itertools 前辈,我这一直发请求,这个有啥好办法解决吗?
![image]( http://pgf1p2i0h.bkt.clouddn.com/%E4%B8%80%E7%9B%B4pending%EF%BC%8C%E4%B8%80%E7%9B%B4%E5%8F%91%E8%AF%B7%E6%B1%82.png) |
24
hanssx OP @itertools 我 flask 应用程序的启动代码:socketio.run(app=app, host='0.0.0.0', port=5000, debug=True)
其中 socketio 初始化时,指定了 async_mode='gevent',是这个原因吗?然后 gunicorn 也使用了 gevent。 |
25
hanssx OP @itertools 我晕,我本地不加 gunicorn,socketio.run(app=app, host='0.0.0.0', port=5000, debug=True),指定 async_mode='gevent',也会一直 pending,一直请求。。。
|
26
itertools 2018-10-11 17:43:29 +08:00 1
@hanssx 目前最解决问题的办法是使用 gunicorn + eventlet 组合跑,卸载 gevent 安装 eventlet 然后把 async_mode="gevent"改成 async_mode="eventlet " 启动命令为 gunicorn --worker-class eventlet -w 1 module:app。
如果一定要用 gevent 请尝试使用 uWSGI + gevent |
27
hanssx OP @itertools 确实,老哥,能加您个 QQ 吗?想感谢您一下,gevent+flask-socketio 就会一直发请求并且 pending,eventlet 则不会,怎么会这样我也不明白,我的扣扣 9614 六 2392,期待老哥,哈哈。
|
28
hanssx OP 已解决,感谢各位的帮助,特别是 itertools。
|
29
daya 2018-10-11 17:53:42 +08:00 via iPhone
怎么解决的?
|
30
hanssx OP @daya 首先清除 gunicorn 多余进程,使用 netstat -antlp | grep port 或者 ps -ef | grep guni,然后 sudo kill -9 pid
然后再把 gevent-websocket 换成 gevetn,因为前者不支持 py3 最后把 flask-socketio 的 async_mode 换成 eventlet 而不是 gevent,gevent 会一直发送类似心跳包的东西,不知道有没有选项可以清除。 |