gunicorn多进程不死_WEB,gunicorn - 无论是多进程、多线程、协程模式,同一个浏览器窗口多个标签页访问同一个url,看上去不会并发的问题...
TL;DR
其實(shí)是瀏覽器同一個(gè)窗口下限制了對(duì)同一個(gè)url會(huì)執(zhí)行串行操作。
1.參考
2.現(xiàn)象
我有一個(gè)WSGI APP,每次處理request都睡眠5秒。不管多進(jìn)程、多線程、協(xié)程跑WSGI APP,同一個(gè)瀏覽器窗口,不同的標(biāo)簽頁(yè),同一個(gè)url,都是串行執(zhí)行(一個(gè)接一個(gè)完成,不管gunicorn是多進(jìn)程、多線程、協(xié)程的并發(fā)模式)。例如同一個(gè)瀏覽器窗口,3個(gè)標(biāo)簽頁(yè),都是花費(fèi)15秒。
import time
from datetime import datetime
from wsgiref.validate import validator
from gunicorn import __version__
@validator
def app(environ, start_response):
"""Simplest possible application object"""
time_begin = datetime.now()
# time_being = time.time()
data = '{time_begin}{time_end}'
status = '200 OK'
response_headers = [
('Content-type', 'text/plain'),
('Content-Length', str(len(data))),
('X-Gunicorn-Version', __version__),
('Foo', 'B\u00e5r'), # Foo: B?r
]
time.sleep(5) # 關(guān)鍵在這。
# time_end = time.time() - time_begin
time_end = datetime.now() - time_begin
data = data.format(time_begin=time_begin, time_end='x')
data = bytes(data, encoding='utf-8')
start_response(status, response_headers)
return iter([data])
無(wú)論哪種模式,都是15秒。
gunicorn --workers=1 --threads=3 test1:app -b 0:9999 --log-level debug # 多線程
gunicorn --workers=3 --threads=1 test1:app -b 0:9999 --log-level debug # 多進(jìn)程
gunicorn --workers=3 --threads=3 test1:app -b 0:9999 --log-level debug # 多進(jìn)程 + 多線程
gunicorn --workers=1 --threads=1 test1:app -b 0:9999 --log-level debug # 協(xié)程
gunicorn --workers=3 --threads=3 test1:app -b 0:9999 --log-level debug -k gevent # 多進(jìn)程 + 多線程 + 協(xié)程
3.疑問(wèn)
這看上去不就不能并發(fā)嘛?說(shuō)好的多進(jìn)程、多線程、協(xié)程、Non-blocking I/O的并發(fā)模式呢?
4.本質(zhì)
通過(guò)第一點(diǎn)“參考”,可以看出,這其實(shí)是瀏覽器的鍋。瀏覽器同一個(gè)窗口(有不同標(biāo)簽頁(yè))對(duì)同一個(gè)url會(huì)串行化訪問(wèn);其實(shí)瀏覽器還有另外一個(gè)限制(對(duì)同一個(gè)域名的資源有并發(fā)限制),這是另外一個(gè)問(wèn)題了。
5.解決辦法
方法一,瀏覽器同一個(gè)窗口,不同標(biāo)簽頁(yè),給同一個(gè)url加上一些冗余的query params就行了。例如,同一個(gè)窗口不同標(biāo)簽頁(yè)同時(shí)訪問(wèn)一下三個(gè)url,返回的請(qǐng)求時(shí)間差不多在同一時(shí)間完成。
http://127.0.0.1:9999/?a=1
http://127.0.0.1:9999/?a=2
http://127.0.0.1:9999/?a=3
方法二,在瀏覽器不同窗口,或者不同瀏覽器訪問(wèn)同一個(gè)url,也可以“并發(fā)”。這是非常合理的。因?yàn)檫@繞過(guò)了瀏覽器的限制,而且代表了不同的client的request。
6.總結(jié)
其實(shí)這個(gè)看上去是問(wèn)題的問(wèn)題不是問(wèn)題,因?yàn)榫€上真正的請(qǐng)求一般不會(huì)出現(xiàn)這些情況。因?yàn)榫€上的請(qǐng)求是來(lái)自不同的瀏覽器、不同的curl,或者說(shuō),不同的http client,那就沒(méi)有瀏覽器這個(gè)小小的限制啦!
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的gunicorn多进程不死_WEB,gunicorn - 无论是多进程、多线程、协程模式,同一个浏览器窗口多个标签页访问同一个url,看上去不会并发的问题...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: cbow word2vec 损失_wor
- 下一篇: linux安装tightvnc_tigh