Ngxin:HTTP响应发送-上游网速优先

在这里插入图片描述

一、READ阶段

  • preread_bufs
    预读取的响应包体,在读响应头时获取到,存放在u->buffer;

  • 接收空间的分配

    • 从free_raw_bufs中获取。
      single_buf:为1时只获取一个chain,为0时获取所有chain。
    • 重新分配。
      (1)申请的内存块数量和大小受p->bufs(proxy_buffers指令大小)的限制;
      (2)分配ngx_chain_t、ngx_buf_t、b->start三块空间。
    • 在上述两种方式都无法分配接收空间的情况下,如果下游可写(p->downstream->write->ready),则设置p->upstream_blocked标志位,阻塞上游读操作,优先下游写操作,等待free_raw_bufs有内存块可用。
    • 在包体可缓存情况下(p->cacheable),将部分已接收包体写入文件,再使用清空的free_raw_bufs进行上游接收。
  • 接收
    以申请到的ngx_chain_t为参数,调用p->upstream->recv_chain接收,返回接收到的字节数。

  • 发送

    • 对于已经写满的ngx_chain_t,直接调用p->input_filter发送;
      (1)从p->free分配新的ngx_chain_t和ngx_buf_t;
      (2)将传入的ngx_buf_t拷贝入新分配的ngx_buf_t,两者互为shadow;
      (3)将新分配的ngx_chain_t挂入p->in队尾;
      (4)对原ngx_chain_t(保存ngx_buf_t本体)进行释放。
      此时未释放的内存包括:in队列的ngx_chain_t,两个ngx_buf_t(互为shadow),一份数据(buf->start)。
    • 对于未写满的ngx_chain_t,重新挂在p->free_raw_bufs队头,用于继续接收。

二、WRITE阶段

ngx_chain_t *out
p->in:内存中需要发送的ngx_buf_t;
p->out:文件中需要发送的buf;
p->busy:上一次未发送的ngx_buf_t;

  • 发送
    调用p->output_filter。

  • chain更新

  1. 对于已经发送成功的ngx_chain_t,放在p->free;
  2. 对于没有发送完成的ngx_chain_t,放入p->busy;
  3. 对于p->free中的ngx_buf_t,都存在一个shadow,并且shadow中存在用于保存数据的空间(buf->start)。这里,重新分配ngx_chain_t,用于装在shadow,并将其重新挂在p->free_raw_bufs用于接收。之后p->free中保存的只有ngx_chain_t和ngx_buf_t,不包含保存数据的空间。

三、文件缓存

  • 通过该接口,将p->in中的内容全部写入文件:
    n = ngx_write_chain_to_temp_file(p->temp_file, out);
  • 分配ngx_chain_t、ngx_buf_t,用于保存文件信息,其中b->inf_file=1,b->temp_file=1。
  • 同上述“chain更新”,对p->in中的空间进行释放,回归内存到p->free_raw_bufs用于接收。

p->free_raw_bufs——》p->in(里面的buf都是shadow) input_filter——》p->free(已发送的chain+buf,这里的buf是shadow) ngx_chain_update_chains/p->busy(未发送的chain+buf,这里的buf是shadow)——》p->free_raw_bufs(将p->free中保存的非shadow的buf拿出,重新放入free_raw_bufs用于接收)

猜你喜欢

转载自blog.csdn.net/u013032097/article/details/91418210