开发者

http通过StreamingHttpResponse完成连续的数据传输长链接方式

开发者 https://www.devze.com 2022-12-10 13:07 出处:网络 作者: Hayley-L
目录http通过StreamingHttpResponse完成连续的数据传输长链接问题输出输入StreamingHttpResponse和HttpResponsehttp通过StreamingHttpResponse完成连续的数据传输长链接
目录
  • http通过StreamingHttpResponse完成连续的数据传输长链接
    • 问题
    • 输出
    • 输入
  • StreamingHttpResponse和HttpResponse

    http通过StreamingHttpResponse完成连续的数据传输长链接

    问题

    http服务之间传递结果流

    一个由flask封装起http://www.cppcns.com来的算法,一个由django封装的后台,我希望在django里通过requests调用flask的算法接口,flask可以分析一帧www.cppcns.com返回一帧结果,追求分析结果的实时返回,而不是完全分析完再完整返回结果

    为了能完整返回结果,暂时想到的模式有以下三种:

    • 一问一答:等待完整的分析结果,然后返回,最不济就用这种
    • 我要你给(长链接):flask返回一个generator,django取next就得到下一个的结果
    • 你有你给(理想,长链接):建立长链接,flask每分析出一帧结果,就返回

    一次结果,直到分析结束,关闭连接

    看到flask中有个flask_socketio建立socket连接,还没有实验

    暂时用StreamingHttpResponse,generater能实现实时分析的感觉,属于第三种模式(你有你给)

    django的StreamingHttpResponse可以返回generater,request调用返回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)  www.cppcns.com     
          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 http://www.cppcns.comrange(10):          
          print(i)             
          yield 'hi ' + str(i)
         print('sleep 3')         
          time.sleep(1)
      return flask.Response(generate())

    输入

    不区分flask,django,都可以通过request,contextlib 实现

    #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

    在修改以前的文件下载功能时,发现一个文件有5G,用HttpResponse实现时,服务器返回502错误,查看nginx log时,发现nginx log记录的是: upstream prematurely closed connection while reading response header from upstream。应该是nginx服务器从上游获取数据时超时了。

    查了很多办法,修改了nginx的配置,但是仍然超时。

    绝望之下,查了一下Django的文档,发现了StreamingHttpResponse,试了一下效率提高了很多。

    后来仔细查了一下发现HttpResponse在使用文件迭代器时:

    HttpResponse will consume the iterator immediately, store its content as a string, and discard it.

    HttpResponse会直接使用迭代器对象,将迭代器对象的内容存储城字符串,然后返回给客户端,同时释放内存。可以当文件变大看出这是一个非常耗费时间和内存的过程。

    而StreamingHttpResponse是将文件内容进行流式传输,

    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.

    这是一种非常省时省内存的方法。但是因为StreamingHttpResponse的文件传输过程持续在整个response的过程中,所以这有可能会降低服务器的性能。

    参考文档

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号