Skip to content

Commit

Permalink
docs: delete stream.md && supplement stream description to client (#752)
Browse files Browse the repository at this point in the history
Co-authored-by: copy rogers <40619032+rogerogers@users.noreply.github.com>
  • Loading branch information
chaoranz758 and rogerogers committed Sep 7, 2023
1 parent d96c179 commit 622a693
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 94 deletions.
14 changes: 13 additions & 1 deletion content/en/docs/hertz/tutorials/basic-feature/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,15 @@ func main() {

## Streaming Read Response Content

Hertz's client supports streaming read HTTP response content. For more information, please refer to [Client](/docs/hertz/tutorials/basic-feature/stream/#client).
Hertz's client supports streaming read HTTP response content.

Since the client has the problem of multiplexing connections, if streaming is used, the connection will be handled by the user(`resp.BodyStream()` is encapsulated by connection) once streaming is used. There are some differences in the management of connections in the above case:

1. If the user doesn't close the connection, the connection will eventually be closed by the GC without causing a connection leak. However, due to the need to wait for 2 Round-Trip Time to close the connection, in the case of high concurrency, the consequence is that there will be too many open files and creating a new connection will be impossible.

2. Users can recycle the connection by calling the relevant interface. After recycling, the connection will be put into the connection pool for reuse, so as to achieve higher resource utilization and better performance. The following methods will recycle the connection. Warning: Recycling can only be done once.
1. Explicit call: `protocol.ReleaseResponse(), resp.Reset(), resp.ResetBody()`.
1. Implicit call: The server side will also recycle the response. If the client and server use the same response, there is no need to explicitly call the recycling method

Sample Code:

Expand All @@ -541,6 +549,10 @@ func main() {
c, _ := client.NewClient(client.WithResponseBodyStream(true))
req := &protocol.Request{}
resp := &protocol.Response{}
defer func() {
protocol.ReleaseRequest(req)
protocol.ReleaseResponse(resp)
}()
req.SetMethod(consts.MethodGet)
req.SetRequestURI("http://127.0.0.1:8080/streamWrite")
err := c.Do(context.Background(), req, resp)
Expand Down
46 changes: 0 additions & 46 deletions content/en/docs/hertz/tutorials/basic-feature/stream.md

This file was deleted.

2 changes: 1 addition & 1 deletion content/zh/blog/news/Go_HTTP_Hertz_Design/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Server 和 Client 的中间件实现方式并不相同。对于 Server 来说,

[Hertz][Hertz] 提供 Server 和 Client 的流式处理能力。HTTP 的文件场景是十分常见的场景,除了 Server 侧的上传场景之外,Client 的下载场景也十分常见。
为此,[Hertz][Hertz] 支持了 Server 和 Client 的流式处理。在内部网关场景中,从 Gin 迁移到 [Hertz][Hertz] 后,CPU 使用量随流量大小不同可节省 30%—60% 不等,服务压力越大,收益越大。
[Hertz][Hertz] 开启流式功能的方式也很容易,只需要在 Server 上或 Client 上添加一个配置即可,可参考 CloudWeGo 官网 Hertz 文档的[流式处理](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/stream/)部分。
[Hertz][Hertz] 开启流式功能的方式也很容易,只需要在 Server 上或 Client 上添加一个配置即可,可参考 CloudWeGo 官网 Hertz 文档的 [Server 流式处理](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/engine/#流式处理) 部分和 [Client 流式处理](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/client/#流式读响应内容) 部分。

由于 [Netpoll][Netpoll] 采用 LT 的触发模式,由网络库主动将将数据从 TCP 缓冲区读到用户态,并存储到 buffer 中,否则 epoll 事件会持续触发。
因此 Server 在超大请求的场景下,由于 [Netpoll][Netpoll] 持续将数据读到用户态内存中,可能会有 OOM 的风险。HTTP 文件上传场景就是一个典型的场景,但 HTTP 上传服务又是很常见的场景,
Expand Down
13 changes: 12 additions & 1 deletion content/zh/docs/hertz/tutorials/basic-feature/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,14 @@ func main() {

## 流式读响应内容

Hertz 客户端支持流式读取 HTTP 响应内容。(更多内容请参考 [Client](/zh/docs/hertz/tutorials/basic-feature/stream/#client)
Hertz 客户端支持流式读取 HTTP 响应内容。

client 有复用连接的问题,如果使用了流式,那连接就会交由用户处理 (`resp.BodyStream()` 底层是对 connection 的封装),这个时候对连接的管理会有一些不同:

1. 如果用户不关闭连接,连接最终会被 GC 关掉,不会造成连接泄漏。但是,由于关闭连接需要等待 2RTT,在高并发情况下可能会出现 fd 被打满导致无法新建连接的情况。
2. 用户可以调用相关接口回收连接,回收后,该连接会放入连接池中复用,资源使用率更好,性能更高。以下几种方式都会回收连接,注意回收只能回收一次。
1. 显式调用 `protocol.ReleaseResponse(), resp.Reset(), resp.ResetBody()`
2. 非显式调用:server 侧也会有回收 resp 的逻辑。如果 client 与 server 使用同一个 response 的情况下就不需要显式调用回收的方法了。

示例代码:

Expand All @@ -539,6 +546,10 @@ func main() {
c, _ := client.NewClient(client.WithResponseBodyStream(true))
req := &protocol.Request{}
resp := &protocol.Response{}
defer func() {
protocol.ReleaseRequest(req)
protocol.ReleaseResponse(resp)
}()
req.SetMethod(consts.MethodGet)
req.SetRequestURI("http://127.0.0.1:8080/streamWrite")
err := c.Do(context.Background(), req, resp)
Expand Down
45 changes: 0 additions & 45 deletions content/zh/docs/hertz/tutorials/basic-feature/stream.md

This file was deleted.

1 comment on commit 622a693

@vercel
Copy link

@vercel vercel bot commented on 622a693 Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.