http通過StreamingHttpResponse完成連續(xù)的數(shù)據(jù)傳輸長鏈接方式
http通過StreamingHttpResponse完成連續(xù)的數(shù)據(jù)傳輸長鏈接
問題
http服務(wù)之間傳遞結(jié)果流
一個由flask封裝起來的算法,一個由django封裝的后臺,我希望在django里通過requests調(diào)用flask的算法接口,flask可以分析一幀返回一幀結(jié)果,追求分析結(jié)果的實時返回,而不是完全分析完再完整返回結(jié)果
為了能完整返回結(jié)果,暫時想到的模式有以下三種:
- 一問一答:等待完整的分析結(jié)果,然后返回,最不濟就用這種
- 我要你給(長鏈接):flask返回一個generator,django取next就得到下一個的結(jié)果
- 你有你給(理想,長鏈接):建立長鏈接,flask每分析出一幀結(jié)果,就返回
一次結(jié)果,直到分析結(jié)束,關(guān)閉連接
看到flask中有個flask_socketio建立socket連接,還沒有實驗
暫時用StreamingHttpResponse,generater能實現(xiàn)實時分析的感覺,屬于第三種模式(你有你給)
django的StreamingHttpResponse可以返回generater,request調(diào)用返回generate的接口的時候,通過contextlib 的closing對流進行處理:
輸出
#django 算法端,輸出流 from django.http import StreamingHttpResponse def stream_response(request): ? ? ? ? ? ? ? ? ? ? ? def generate(): ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? for i in range(10): ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? print(i) ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? yield 'hi ' + str(i) ? ? ? ? ? ? ?? ? ? ? ? ? ? print('sleep 3') ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? time.sleep(1) ? ? ? ? ? ? ? ? ? ? ? ? ? return StreamingHttpResponse(generate(), )?
#flask 算法端,輸出流 @app.route('/re', methods=('POST', )) def re(): ? ? @flask.stream_with_context ? ? def generate(): ? ? ?? ?for i in range(10): ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? print(i) ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? yield 'hi ' + str(i) ? ? ? ? ?? ?print('sleep 3') ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? time.sleep(1) ? ? return flask.Response(generate())
輸入
不區(qū)分flask,django,都可以通過request,contextlib 實現(xiàn)
#flask 算法端 @app.route('/test', methods=['POST', 'GET']) def test(): ? ? url = 'http://172.16.68.151:8000/test2' ? ? from contextlib import closing ? ? with closing(requests.get(url, stream=True)) as r1: ? ? ? ? for i in r1.iter_content(): ? ? ? ? ? ? print(i)
StreamingHttpResponse和HttpResponse
在修改以前的文件下載功能時,發(fā)現(xiàn)一個文件有5G,用HttpResponse實現(xiàn)時,服務(wù)器返回502錯誤,查看nginx log時,發(fā)現(xiàn)nginx log記錄的是: upstream prematurely closed connection while reading response header from upstream。應(yīng)該是nginx服務(wù)器從上游獲取數(shù)據(jù)時超時了。
查了很多辦法,修改了nginx的配置,但是仍然超時。
絕望之下,查了一下Django的文檔,發(fā)現(xiàn)了StreamingHttpResponse,試了一下效率提高了很多。
后來仔細(xì)查了一下發(fā)現(xiàn)HttpResponse在使用文件迭代器時:
HttpResponse will consume the iterator immediately, store its content as a string, and discard it.
HttpResponse會直接使用迭代器對象,將迭代器對象的內(nèi)容存儲城字符串,然后返回給客戶端,同時釋放內(nèi)存??梢援?dāng)文件變大看出這是一個非常耗費時間和內(nèi)存的過程。
而StreamingHttpResponse是將文件內(nèi)容進行流式傳輸,
StreamingHttpResponse在官方文檔的解釋是:
The StreamingHttpResponse class is used to stream a response from Django to the browser. You might want to do this if generating the response takes too long or uses too much memory.
這是一種非常省時省內(nèi)存的方法。但是因為StreamingHttpResponse的文件傳輸過程持續(xù)在整個response的過程中,所以這有可能會降低服務(wù)器的性能。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Sentry的安裝、配置、使用教程(Sentry日志手機系統(tǒng))
Sentry?是一個實時事件日志記錄和聚合平臺,由于ExceptionLess官方提供的客戶端只有.Net/.NetCore平臺和js的,本文繼續(xù)介紹另一個日志收集系統(tǒng)Sentry,感興趣的朋友一起看看吧2022-07-07python爬蟲MeterSphere平臺執(zhí)行報告流程解析
這篇文章主要為大家介紹了python爬蟲MeterSphere平臺執(zhí)行報告流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12openCV入門學(xué)習(xí)基礎(chǔ)教程第二篇
人臉識別,物體檢測,OpenCV是基石,下面這篇文章主要給大家介紹了關(guān)于openCV入門學(xué)習(xí)基礎(chǔ)教程的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11對Python中Iterator和Iterable的區(qū)別詳解
今天小編就為大家分享一篇對Python中Iterator和Iterable的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10