diff --git a/config.toml b/config.toml index 51dfac79886..2512bc848cb 100644 --- a/config.toml +++ b/config.toml @@ -82,7 +82,7 @@ weight = 60 parent = "社区" [[languages.zh.menu.main]] -name = "[new]企业级解决方案" +name = "企业级解决方案" identifier = "business_solution" weight = 45 diff --git a/content/en/_index.html b/content/en/_index.html index 4d8b68fb4a8..f5770d405c3 100644 --- a/content/en/_index.html +++ b/content/en/_index.html @@ -182,7 +182,6 @@

Enterprise Users

  • }}">Kitex
  • }}">Hertz
  • }}">Volo
  • -
  • }}">Netpoll
  • }}">Eino
  • diff --git a/content/en/about/_index.html b/content/en/about/_index.html index 126d074336c..a0be39ec3be 100644 --- a/content/en/about/_index.html +++ b/content/en/about/_index.html @@ -47,7 +47,6 @@

    As of the current date, Kitex & Hertz have been adopted by over 60 external enterprise users, including larger-scale adopters such as: Huaxing Securities, Founder Securities, Semir, Tanwan Games, Holomatic Technology, NEXTDATA and ZHIPU AI. Sonic has also been adopted within China Merchants Bank. Through user feedback, the adoption of CloudWeGo projects has yielded real cost, performance, and stability benefits. - We welcome more enterprise users to join us and connect with the community for additional technical support.

    If you are already using CloudWeGo in production, please register on the corresponding GitHub Issues: diff --git a/content/en/docs/netpoll/Caution/_index.md b/content/en/docs/netpoll/Caution/_index.md deleted file mode 100644 index e715b2ff99d..00000000000 --- a/content/en/docs/netpoll/Caution/_index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: "Caution" -linkTitle: "Caution" -weight: 4 -description: > ---- - -## Wrong setting of NumLoops - -If your server is running on a physical machine, the number of P created by the Go process is equal to the number of -CPUs of the machine. But the server may not use so many cores. In this case, too many pollers will cause performance -degradation. - -There are several solutions: - -1. Use the `taskset` command to limit CPU usage, such as: - -```shell -taskset -c 0-3 $run_your_server -``` - -2. Actively set the number of P, for instance: - -```go -package main - -import ( - "runtime" -) - -func init() { - runtime.GOMAXPROCS(num_you_want) -} -``` - -3. Actively set the number of pollers, e.g: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetNumLoops(num_you_want) -} -``` diff --git a/content/en/docs/netpoll/Common Usage/_index.md b/content/en/docs/netpoll/Common Usage/_index.md deleted file mode 100644 index 6eebab1003b..00000000000 --- a/content/en/docs/netpoll/Common Usage/_index.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -title: "Common Usage" -linkTitle: "Common Usage" -weight: 3 -description: > ---- - -## 1. How to configure the number of pollers ? - -`NumLoops` represents the number of `epoll` created by [Netpoll][Netpoll], which has been automatically adjusted -according to the number of P (`runtime.GOMAXPROCS(0)`) by default, and users generally don't need to care. - -But if your service has heavy I/O, you may need the following configuration: - -```go -package main - -import ( - "runtime" - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetNumLoops(runtime.GOMAXPROCS(0)) -} -``` - -## 2. How to configure poller's connection loadbalance ? - -When there are multiple pollers in Netpoll, the connections in the service process will be loadbalanced to -each poller. - -The following strategies are supported now: - -1. Random - - The new connection will be assigned to a randomly picked poller. -2. RoundRobin - - The new connection will be assigned to the poller in order. - -Netpoll uses `RoundRobin` by default, and users can change it in the following ways: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetLoadBalance(netpoll.Random) - - // or - netpoll.SetLoadBalance(netpoll.RoundRobin) -} -``` - -## 3. How to configure gopool ? - -Netpoll uses gopool as the goroutine pool by default to optimize the `stack growth` problem that -generally occurs in RPC services. - -In the project gopool, it explains how to change its configuration, so won't repeat it here. - -Of course, if your project does not have a `stack growth` problem, it is best to close gopool as follows: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.DisableGopool() -} -``` - -## 4. How to prepare a new connection ? - -There are different ways to prepare a new connection on the client and server. - -1. On the server side, `OnPrepare` is defined to prepare for the new connection, and it also supports returning - a `context`, which can be reused in subsequent business processing. - `WithOnPrepare` provides this registration. When the server accepts a new connection, it will automatically execute - the registered `OnPrepare` function to complete the preparation work. The example is as follows: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - // register OnPrepare - var onPrepare netpoll.OnPrepare = prepare - evl, _ := netpoll.NewEventLoop(handler, netpoll.WithOnPrepare(onPrepare)) - ... -} - -func prepare(connection netpoll.Connection) (ctx context.Context) { - ... prepare connection ... - return -} -``` - -2. On the client side, the connection preparation needs to be completed by the user. Generally speaking, the connection - created by `Dialer` can be controlled by the user, which is different from passively accepting the connection on the - server side. Therefore, the user not relying on the trigger, just prepare a new connection like this: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - conn, err := netpoll.DialConnection(network, address, timeout) - if err != nil { - panic("dial netpoll connection failed") - } - ... prepare here directly ... - prepare(conn) - ... -} - -func prepare(connection netpoll.Connection) (ctx context.Context) { - ... prepare connection ... - return -} -``` - -## 5. How to configure connection timeout ? - -Netpoll now supports two timeout configurations: - -1. `Read Timeout` - - In order to maintain the same operating style as `net.Conn`, `Connection.Reader` is also designed to block - reading. So provide `Read Timeout`. - - `Read Timeout` has no default value(wait infinitely), it can be configured via `Connection` or `EventLoop.Option`, - for example: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // 1. setting by Connection - conn.SetReadTimeout(timeout) - - // or - - // 2. setting with Option - netpoll.NewEventLoop(handler, netpoll.WithReadTimeout(timeout)) - ... -} -``` - -2. `Idle Timeout` - - `Idle Timeout` utilizes the `TCP KeepAlive` mechanism to kick out dead connections and reduce maintenance - overhead. When using Netpoll, there is generally no need to create and close connections frequently, - and idle connections have little effect. When the connection is inactive for a long time, in order to prevent dead - connection caused by suspended animation, hang of the opposite end, abnormal disconnection, etc., the connection - will be actively closed after the `Idle Timeout`. - - The default minimum value of `Idle Timeout` is `10min`, which can be configured through `Connection` API - or `EventLoop.Option`, for example: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // 1. setting by Connection - conn.SetIdleTimeout(timeout) - - // or - - // 2. setting with Option - netpoll.NewEventLoop(handler, netpoll.WithIdleTimeout(timeout)) - ... -} -``` - -## 6. How to configure connection read event callback ? - -`OnRequest` refers to the callback triggered by Netpoll when a read event occurs on the connection. On the -Server side, when creating the `EventLoop`, you can register an `OnRequest`, which will be triggered when each -connection data arrives and perform business processing. On the Client side, there is no `OnRequest` by default, and it -can be set via API when needed. E.g: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - var onRequest netpoll.OnRequest = handler - - // 1. on server side - evl, _ := netpoll.NewEventLoop(onRequest, opts...) - ... - - // 2. on client side - conn, _ := netpoll.DialConnection(network, address, timeout) - conn.SetOnRequest(handler) - ... -} - -func handler(ctx context.Context, connection netpoll.Connection) (err error) { - ... handling ... - return nil -} -``` - -## 7. How to configure the connection close callback ? - -`CloseCallback` refers to the callback triggered by Netpoll when the connection is closed, which is used to -perform additional processing after the connection is closed. -Netpoll is able to perceive the connection status. When the connection is closed by peer or cleaned up by -self, it will actively trigger `CloseCallback` instead of returning an error on the next `Read` or `Write`(the way -of `net.Conn`). -`Connection` provides API for adding `CloseCallback`, callbacks that have been added cannot be removed, and multiple -callbacks are supported. - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // add close callback - var cb netpoll.CloseCallback = callback - conn.AddCloseCallback(cb) - ... -} - -func callback(connection netpoll.Connection) error { - return nil -} -``` diff --git a/content/en/docs/netpoll/Getting started/_index.md b/content/en/docs/netpoll/Getting started/_index.md deleted file mode 100644 index 92b69affc04..00000000000 --- a/content/en/docs/netpoll/Getting started/_index.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -title: "Getting Started" -linkTitle: "Getting Started" -weight: 2 -description: > ---- - -> This tutorial gets you started with [Netpoll][Netpoll] through some simple [examples][Examples], includes how to -> use [Server](#1-use-server), [Client](#2-use-dialer) and [nocopy APIs](#3-use-nocopy-api). - -## 1. Use Server - -[Here][server-example] is a simple server demo, we will explain how it is constructed next. - -### 1.1 Create Listener - -First we need to get a `Listener`, it can be `net.Listener` or `netpoll.Listener`, which is no difference for server -usage. Create a `Listener` as shown below: - -```go -package main - -import "net" - -func main() { - listener, err := net.Listen(network, address) - if err != nil { - panic("create net listener failed") - } - ... -} -``` - -or - -```go -package main - -import "github.com/cloudwego/netpoll" - -func main() { - listener, err := netpoll.CreateListener(network, address) - if err != nil { - panic("create netpoll listener failed") - } - ... -} -``` - -### 1.2 New EventLoop - -`EventLoop` is an event-driven scheduler, a real NIO Server, responsible for connection management, event scheduling, -etc. - -params: - -- `OnRequest` and `OnConnect` are interface that users should implement by themselves to process business logic. [Code Comment][eventloop.go] describes their behavior in detail. -- `Option` is used to customize the configuration when creating `EventLoop`, and the following example shows its usage. - For more details, please refer to [options][netpoll_options.go]. - -The creation process is as follows: - -```go -package main - -import ( - "time" - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - ... - eventLoop, _ := netpoll.NewEventLoop( - handle, - netpoll.WithOnPrepare(prepare), - netpoll.WithOnConnect(connect), - netpoll.WithReadTimeout(time.Second), - ) - ... -} -``` - -### 1.3 Run Server - -`EventLoop` provides services by binding `Listener`, as shown below. -`Serve` function will block until an error occurs, such as a panic or the user actively calls `Shutdown`. - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - ... - // start listen loop ... - eventLoop.Serve(listener) -} -``` - -### 1.4 Shutdown Server - -`EventLoop` provides the `Shutdown` function, which is used to stop the server gracefully. The usage is as follows. - -```go -package main - -import ( - "context" - "time" - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - // stop server ... - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - eventLoop.Shutdown(ctx) -} -``` - -## 2. Use Dialer - -[Netpoll][Netpoll] also has the ability to be used on the Client side. It provides `Dialer`, similar to `net.Dialer`. -Again, [here][client-example] is a simple client demo, and then we introduce it in detail. - -### 2.1 The Fast Way - -Similar to [Net][net], [Netpoll][Netpoll] provides several public functions for directly dialing a connection. such as: - -```go -DialConnection(network, address string, timeout time.Duration) (connection Connection, err error) - -DialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*TCPConnection, error) - -DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConnection, error) -``` - -### 2.2 Create Dialer - -[Netpoll][Netpoll] also defines the `Dialer` interface. The usage is as follows: -(of course, you can usually use the fast way) - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - // Dial a connection with Dialer. - dialer := netpoll.NewDialer() - conn, err := dialer.DialConnection(network, address, timeout) - if err != nil { - panic("dial netpoll connection failed") - } - ... -} -``` - -## 3. Use Nocopy API - -`Connection` provides Nocopy APIs - `Reader` and `Writer`, to avoid frequent copying. Let’s introduce their simple -usage. - -```go -package main - -type Connection interface { - // Recommended nocopy APIs - Reader() Reader - Writer() Writer - ... // see code comments for more details -} -``` - -### 3.1 Simple Usage - -Nocopy APIs is designed as a two-step operation. - -On `Reader`, after reading data through `Next`, `Peek`, `ReadString`, etc., you still have to actively call `Release` to -release the buffer(`Nocopy` reads the original address of the buffer, so you must take the initiative to confirm that -the buffer is no longer used). - -Similarly, on `Writer`, you first need to allocate a buffer to write data, and then call `Flush` to confirm that all -data has been written. -`Writer` also provides rich APIs to allocate buffers, such as `Malloc`, `WriteString` and so on. - -The following shows some simple examples of reading and writing data. For more details, please refer to -the [code comments][nocopy.go]. - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - var reader, writer = conn.Reader(), conn.Writer() - - // reading - buf, _ := reader.Next(n) - ... parse the read data ... - reader.Release() - - // writing - var write_data []byte - ... make the write data ... - alloc, _ := writer.Malloc(len(write_data)) - copy(alloc, write_data) // write data - writer.Flush() -} -``` - -### 3.2 Advanced Usage - -If you want to use the connection to send (or receive) multiple sets of data, then you will face the work of packing and -unpacking the data. - -On [net][net], this kind of work is generally done by copying. An example is as follows: - -```go -package main - -import ( - "net" -) - -func main() { - var conn net.Conn - var buf = make([]byte, 8192) - - // reading - for { - n, _ := conn.Read(buf) - ... unpacking & handling ... - var i int - for i = 0; i <= n-pkgsize; i += pkgsize { - pkg := append([]byte{}, buf[i:i+pkgsize]...) - go func() { - ... handling pkg ... - } - } - buf = append(buf[:0], buf[i:n]...) - } - - // writing - var write_datas <-chan []byte - ... packing write ... - for { - pkg := <-write_datas - conn.Write(pkg) - } -} -``` - -But, this is not necessary in [Netpoll][Netpoll], nocopy APIs supports operations on the original address of the buffer, -and realizes automatic recycling and reuse of resources through reference counting. - -Examples are as follows(use function `Reader.Slice` and `Writer.Append`): - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // reading - reader := conn.Reader() - for { - ... unpacking & handling ... - pkg, _ := reader.Slice(pkgsize) - go func() { - ... handling pkg ... - pkg.Release() - } - } - - // writing - var write_datas <-chan netpoll.Writer - ... packing write ... - writer := conn.Writer() - for { - select { - case pkg := <-write_datas: - writer.Append(pkg) - default: - if writer.MallocLen() > 0 { - writer.Flush() - } - } - } -} -``` - -[Netpoll]: https://github.com/cloudwego/netpoll -[net]: https://github.com/golang/go/tree/master/src/net -[gopool]: https://github.com/bytedance/gopkg/tree/develop/util/gopool -[Examples]: https://github.com/cloudwego/netpoll-examples -[server-example]: https://github.com/cloudwego/netpoll-examples/blob/main/echo/server.go -[client-example]: https://github.com/cloudwego/netpoll-examples/blob/main/echo/client.go -[netpoll_options.go]: https://github.com/cloudwego/netpoll/blob/main/netpoll_options.go -[nocopy.go]: https://github.com/cloudwego/netpoll/blob/main/nocopy.go -[eventloop.go]: https://github.com/cloudwego/netpoll/blob/main/eventloop.go diff --git a/content/en/docs/netpoll/Overview/_index.md b/content/en/docs/netpoll/Overview/_index.md deleted file mode 100644 index f45e8cfee22..00000000000 --- a/content/en/docs/netpoll/Overview/_index.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "Overview" -linkTitle: "Overview" -weight: 1 -description: > ---- - -## Introduction - -[Netpoll][Netpoll] is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by [ByteDance][ByteDance]. - -RPC is usually heavy on processing logic and therefore cannot handle I/O serially. -But Go's standard library [net][net] is designed for blocking I/O APIs, -so that the RPC framework can only follow the One Conn One Goroutine design. -It will waste a lot of cost for context switching, due to a large number of goroutines under high concurrency. -Besides, [net.Conn][net.Conn] has no API to check Alive, so it is difficult to make an efficient connection pool for RPC framework, -because there may be a large number of failed connections in the pool. - -On the other hand, the open source community currently lacks Go network libraries that focus on RPC scenarios. -Similar repositories such as: [evio][evio], [gnet][gnet], etc., are all focus on scenarios like [Redis][Redis], [HAProxy][HAProxy]. - -But now, [Netpoll][Netpoll] was born and solved the above problems. -It draws inspiration from the design of [evio][evio] and [netty][netty], -has excellent [Performance](#performance), and is more suitable for microservice architecture. -Also [Netpoll][Netpoll] provides a number of [Features](#features), -and it is recommended to replace [net][net] in some RPC scenarios. - -We developed the RPC framework [Kitex][Kitex] and HTTP framework [Hertz][Hertz] based on [Netpoll][Netpoll], both with industry-leading performance. - -[Examples][netpoll-example] show how to build RPC client and server using [Netpoll][Netpoll]. - -## Features - -- **Already** - - - [LinkBuffer][LinkBuffer] provides nocopy API for streaming reading and writing - - [gopool][gopool] provides high-performance goroutine pool - - [mcache][mcache] provides efficient memory reuse - - `IsActive` supports checking whether the connection is alive - - `Dialer` supports building clients - - `EventLoop` supports building a server - - TCP, Unix Domain Socket - - Linux, macOS (operating system) - -- **Future** - - - [io_uring][io_uring] - - Shared Memory IPC - - TLS - - UDP - -- **Unsupported** - - Windows (operating system) - -## Performance - -Benchmark should meet the requirements of industrial use. -In the RPC scenario, concurrency and timeout are necessary support items. - -We provide the [netpoll-benchmark][netpoll-benchmark] project to track and compare -the performance of [Netpoll][Netpoll] and other frameworks under different conditions for reference. - -More benchmarks reference [kitex-benchmark][kitex-benchmark] and [hertz-benchmark][hertz-benchmark] - -## Reference - -- [Official Website](/) -- [Getting Started](/docs/netpoll/getting-started/) - -[Netpoll]: https://github.com/cloudwego/netpoll -[net]: https://github.com/golang/go/tree/master/src/net -[net.Conn]: https://github.com/golang/go/blob/master/src/net/net.go -[evio]: https://github.com/tidwall/evio -[gnet]: https://github.com/panjf2000/gnet -[netty]: https://github.com/netty/netty -[Kitex]: https://github.com/cloudwego/kitex -[Hertz]: https://github.com/cloudwego/hertz -[netpoll-example]: https://github.com/cloudwego/netpoll-examples -[netpoll-benchmark]: https://github.com/cloudwego/netpoll-benchmark -[kitex-benchmark]: https://github.com/cloudwego/kitex-benchmark -[hertz-benchmark]: https://github.com/cloudwego/hertz-benchmark -[ByteDance]: https://www.bytedance.com -[Redis]: https://redis.io -[HAProxy]: http://www.haproxy.org -[LinkBuffer]: https://github.com/cloudwego/netpoll/blob/develop/nocopy_linkbuffer.go -[gopool]: https://github.com/bytedance/gopkg/tree/develop/util/gopool -[mcache]: https://github.com/bytedance/gopkg/tree/develop/lang/mcache -[io_uring]: https://github.com/axboe/liburing diff --git a/content/en/docs/netpoll/_index.md b/content/en/docs/netpoll/_index.md deleted file mode 100644 index d31b9e38c27..00000000000 --- a/content/en/docs/netpoll/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Netpoll" -linkTitle: "Netpoll" -weight: 4 -Description: Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance. -menu: - main: - weight: 4 - parent: "Documentation" ---- diff --git a/content/zh/_index.html b/content/zh/_index.html index 8ff8e723351..033a06947c1 100644 --- a/content/zh/_index.html +++ b/content/zh/_index.html @@ -205,7 +205,6 @@

    谁在用

  • }}">Kitex
  • }}">Hertz
  • }}">Volo
  • -
  • }}">Netpoll
  • }}">Eino
  • diff --git a/content/zh/about/_index.html b/content/zh/about/_index.html index f6ce2830071..869933fe44c 100644 --- a/content/zh/about/_index.html +++ b/content/zh/about/_index.html @@ -46,7 +46,6 @@

    截止日前,Kitex & Hertz 落地外部企业用户超过了 60 家,其中较大规模落地的企业用户包括:方正证券、森马、贪玩游戏、禾多科技、数美科技、华兴证券、Construct、智谱 AI等; Sonic 也在招商银行企业内部落地。经过企业用户反馈,落地 CloudWeGo 项目后均获得了真实的成本、性能和稳定性收益。 - 欢迎更多企业用户接入并通过社区与我们建联,以获更多技术专项支持。

    如您已经在生产环境中使用了,欢迎到 GitHub 对应 Issue 进行登记:Kitex ---- - -## 错误设置 NumLoops - -如果你的服务器运行在物理机上,Go 进程创建的 P 个数就等于机器的 CPU 核心数。 但是 Server 可能不会使用这么多核心。在这种情况下,过多的 poller 会导致性能下降。 - -这里提供了以下几种解决方案: - -1. 使用 `taskset` 命令来限制 CPU 个数,例如: - -```shell -taskset -c 0-3 $run_your_server -``` - -2. 主动设置 P 的个数,例如: - -```go -package main - -import ( - "runtime" -) - -func init() { - runtime.GOMAXPROCS(num_you_want) -} -``` - -3. 主动设置 poller 的个数,例如: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetNumLoops(num_you_want) -} -``` diff --git a/content/zh/docs/netpoll/Common Usage/_index.md b/content/zh/docs/netpoll/Common Usage/_index.md deleted file mode 100644 index d90bde0e62a..00000000000 --- a/content/zh/docs/netpoll/Common Usage/_index.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: "常见用法" -linkTitle: "常见用法" -weight: 3 -description: > ---- - -## 1. 如何配置 poller 的数量 ? - -`NumLoops` 表示 [Netpoll][Netpoll] 创建的 `epoll` 的数量,默认已经根据P的数量自动调整(`runtime.GOMAXPROCS(0)`),用户一般不需要关心。 - -但是如果你的服务有大量的 I/O,你可能需要如下配置: - -```go -package main - -import ( - "runtime" - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetNumLoops(runtime.GOMAXPROCS(0)) -} -``` - -## 2. 如何配置 poller 的连接负载均衡 ? - -当 Netpoll 中有多个 poller 时,服务进程中的连接会负载均衡到每个 poller。 - -现在支持以下策略: - -1. Random - - 新连接将分配给随机选择的轮询器。 -2. RoundRobin - - 新连接将按顺序分配给轮询器。 - -Netpoll 默认使用 `RoundRobin`,用户可以通过以下方式更改: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.SetLoadBalance(netpoll.Random) - - // or - netpoll.SetLoadBalance(netpoll.RoundRobin) -} -``` - -## 3. 如何配置 gopool ? - -Netpoll 默认使用 gopool 作为 goroutine 池来优化 `栈扩张` 问题(RPC 服务常见问题)。 - -gopool 项目中已经详细解释了如何自定义配置,这里不再赘述。 - -当然,如果你的项目没有 `栈扩张` 问题,建议最好关闭 gopool,关闭方式如下: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func init() { - netpoll.DisableGopool() -} -``` - -## 4. 如何初始化新的连接 ? - -Client 和 Server 端通过不同的方式初始化新连接。 - -1. 在 Server 端,定义了 `OnPrepare` 来初始化新链接,同时支持返回一个 `context`,可以传递给后续的业务处理并复用。`WithOnPrepare` 提供方法注册。当 Server 接收新连接时,会自动执行注册的 `OnPrepare` 方法来完成准备工作。示例如下: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - // register OnPrepare - var onPrepare netpoll.OnPrepare = prepare - evl, _ := netpoll.NewEventLoop(handler, netpoll.WithOnPrepare(onPrepare)) - ... -} - -func prepare(connection netpoll.Connection) (ctx context.Context) { - ... prepare connection ... - return -} -``` - -2. 在 Client 端,连接初始化需要由用户自行完成。 一般来说,`Dialer` 创建的新连接是可以由用户自行控制的,这与 Server 端被动接收连接不同。因此,用户不需要依赖触发器,可以自行初始化,如下所示: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - conn, err := netpoll.DialConnection(network, address, timeout) - if err != nil { - panic("dial netpoll connection failed") - } - ... prepare here directly ... - prepare(conn) - ... -} - -func prepare(connection netpoll.Connection) (ctx context.Context) { - ... prepare connection ... - return -} -``` - -## 5. 如何配置连接超时 ? - -Netpoll 现在支持两种类型的超时配置: - -1. 读超时(`ReadTimeout`) - - 为了保持与 `net.Conn` 相同的操作风格,`Connection.Reader` 也被设计为阻塞读取。 所以提供了读取超时(`ReadTimeout`)。 - - 读超时(`ReadTimeout`)没有默认值(默认无限等待),可以通过 `Connection` 或 `EventLoop.Option` 进行配置,例如: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // 1. setting by Connection - conn.SetReadTimeout(timeout) - - // or - - // 2. setting with Option - netpoll.NewEventLoop(handler, netpoll.WithReadTimeout(timeout)) - ... -} -``` - -2. 空闲超时(`IdleTimeout`) - - 空闲超时(`IdleTimeout`)利用 `TCP KeepAlive` 机制来踢出死连接并减少维护开销。使用 Netpoll 时,一般不需要频繁创建和关闭连接,所以通常来说,空闲连接影响不大。当连接长时间处于非活动状态时,为了防止出现假死、对端挂起、异常断开等造成的死连接,在空闲超时(`IdleTimeout`)后,netpoll 会主动关闭连接。 - - 空闲超时(`IdleTimeout`)的默认配置为 `10min`,可以通过 `Connection` API 或 `EventLoop.Option` 进行配置,例如: - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // 1. setting by Connection - conn.SetIdleTimeout(timeout) - - // or - - // 2. setting with Option - netpoll.NewEventLoop(handler, netpoll.WithIdleTimeout(timeout)) - ... -} -``` - -## 6. 如何配置连接的读事件回调 ? - -`OnRequest` 是指连接上发生读事件时 Netpoll 触发的回调。在 Server 端,在创建 `EventLoop` 时,可以注册一个`OnRequest`,在每次连接数据到达时触发,进行业务处理。Client端默认没有 `OnRequest`,需要时可以通过 API 设置。例如: - -```go -package main - -import ( - "context" - "github.com/cloudwego/netpoll" -) - -func main() { - var onRequest netpoll.OnRequest = handler - - // 1. on server side - evl, _ := netpoll.NewEventLoop(onRequest, opts...) - ... - - // 2. on client side - conn, _ := netpoll.DialConnection(network, address, timeout) - conn.SetOnRequest(handler) - ... -} - -func handler(ctx context.Context, connection netpoll.Connection) (err error) { - ... handling ... - return nil -} -``` - -## 7. 如何配置连接的关闭回调 ? - -`CloseCallback` 是指连接关闭时 Netpoll 触发的回调,用于在连接关闭后进行额外的处理。 -Netpoll 能够感知连接状态。当连接被对端关闭或被自己清理时,会主动触发 `CloseCallback`,而不是由下一次调用 `Read` 或 `Write` 时返回错误(`net.Conn` 的方式)。 -`Connection` 提供了添加 `CloseCallback` 的 API,已经添加的回调无法删除,支持多个回调。 - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // add close callback - var cb netpoll.CloseCallback = callback - conn.AddCloseCallback(cb) - ... -} - -func callback(connection netpoll.Connection) error { - return nil -} -``` diff --git a/content/zh/docs/netpoll/Getting started/_index.md b/content/zh/docs/netpoll/Getting started/_index.md deleted file mode 100644 index 35143337fae..00000000000 --- a/content/zh/docs/netpoll/Getting started/_index.md +++ /dev/null @@ -1,302 +0,0 @@ ---- -title: "快速开始" -linkTitle: "快速开始" -weight: 2 -description: > ---- - -> 本教程通过一些简单的[示例][Examples]帮助您开始使用 [Netpoll][Netpoll],包括如何使用 [Server](#1-使用-server)、[Client](#2-使用-dialer) 和 [nocopy API](#3-使用-nocopy-api)。 - -## 1. 使用 Server - -[这里][server-example] 是一个简单的 server 例子,接下来我们会解释它是如何构建的。 - -### 1.1 创建 Listener - -首先我们需要一个 `Listener`,它可以是 `net.Listener` 或者 `netpoll.Listener`,两者都可以,依据你的代码情况自由选择。 -创建 `Listener` 的过程如下: - -```go -package main - -import "net" - -func main() { - listener, err := net.Listen(network, address) - if err != nil { - panic("create net listener failed") - } - ... -} -``` - -或者 - -```go -package main - -import "github.com/cloudwego/netpoll" - -func main() { - listener, err := netpoll.CreateListener(network, address) - if err != nil { - panic("create netpoll listener failed") - } - ... -} -``` - -### 1.2 创建 EventLoop - -`EventLoop` 是一个事件驱动的调度器,一个真正的 NIO Server,负责连接管理、事件调度等。 - -参数说明: - -- `OnRequest` 和 `OnConnect` 是用户应该自己实现来处理业务逻辑的接口。 [注释][eventloop.go] 详细描述了它的行为。 -- `Option` 用于自定义 `EventLoop` 创建时的配置,下面的例子展示了它的用法。更多详情请参考 [options][netpoll_options.go] 。 - -创建过程如下: - -```go -package main - -import ( - "time" - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - ... - eventLoop, _ = netpoll.NewEventLoop( - handle, - netpoll.WithOnPrepare(prepare), - netpoll.WithOnConnect(connect), - netpoll.WithReadTimeout(time.Second), - ) - ... -} -``` - -### 1.3 运行 Server - -`EventLoop` 通过绑定 `Listener` 来提供服务,如下所示。`Serve` 方法为阻塞式调用,直到发生 `panic` 等错误,或者由用户主动调用 `Shutdown` 时触发退出。 - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - ... - // start listen loop ... - eventLoop.Serve(listener) -} -``` - -### 1.4 关闭 Server - -`EventLoop` 提供了 `Shutdown` 功能,用于优雅地停止服务器。用法如下: - -```go -package main - -import ( - "context" - "time" - "github.com/cloudwego/netpoll" -) - -var eventLoop netpoll.EventLoop - -func main() { - // stop server ... - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - eventLoop.Shutdown(ctx) -} -``` - -## 2. 使用 Dialer - -[Netpoll][Netpoll] 也支持在 Client 端使用,提供了 `Dialer`,类似于 `net.Dialer`。同样的,[这里][client-example] 展示了一个简单的 Client 端示例,接下来我们详细介绍一下: - -### 2.1 快速方式 - -与 [Net][net] 类似,[Netpoll][Netpoll] 提供了几个用于直接建立连接的公共方法,可以直接调用。 如: - -```go -DialConnection(network, address string, timeout time.Duration) (connection Connection, err error) - -DialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*TCPConnection, error) - -DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConnection, error) -``` - -### 2.2 创建 Dialer - -[Netpoll][Netpoll] 还定义了`Dialer` 接口。 用法如下:(通常推荐使用上一节的快速方式) - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - // Dial a connection with Dialer. - dialer := netpoll.NewDialer() - conn, err := dialer.DialConnection(network, address, timeout) - if err != nil { - panic("dial netpoll connection failed") - } - ... -} -``` - -## 3. 使用 Nocopy API - -`Connection` 提供了 Nocopy API —— `Reader` 和 `Writer`,以避免频繁复制。下面介绍一下它们的简单用法。 - -```go -package main - -type Connection interface { - // Recommended nocopy APIs - Reader() Reader - Writer() Writer - ... // see code comments for more details -} -``` - -### 3.1 简单用法 - -Nocopy API 设计为两步操作。 - -使用 `Reader` 时,通过 `Next`、`Peek`、`ReadString` 等方法读取数据后,还需要主动调用 `Release` 方法释放 buffer(`Nocopy` 读取 buffer 的原地址,所以您必须主动再次确认 buffer 已经不再使用)。 - -同样,使用 `Writer` 时,首先需要分配一个 `[]byte` 来写入数据,然后调用 `Flush` 确认所有数据都已经写入。`Writer` 还提供了丰富的 API 来分配 buffer,例如 `Malloc`、`WriteString` 等。 - -下面是一些简单的读写数据的例子。 更多详情请参考 [说明][nocopy.go] 。 - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - var reader, writer = conn.Reader(), conn.Writer() - - // reading - buf, _ := reader.Next(n) - ... parse the read data ... - reader.Release() - - // writing - var write_data []byte - ... make the write data ... - alloc, _ := writer.Malloc(len(write_data)) - copy(alloc, write_data) // write data - writer.Flush() -} -``` - -### 3.2 高阶用法 - -如果你想使用单个连接来发送(或接收)多组数据(如连接多路复用),那么你将面临数据打包和分包。在 [net][net] 上,这种工作一般都是通过复制来完成的。一个例子如下: - -```go -package main - -import ( - "net" -) - -func main() { - var conn net.Conn - var buf = make([]byte, 8192) - - // reading - for { - n, _ := conn.Read(buf) - ... unpacking & handling ... - var i int - for i = 0; i <= n-pkgsize; i += pkgsize { - pkg := append([]byte{}, buf[i:i+pkgsize]...) - go func() { - ... handling pkg ... - } - } - buf = append(buf[:0], buf[i:n]...) - } - - // writing - var write_datas <-chan []byte - ... packing write ... - for { - pkg := <-write_datas - conn.Write(pkg) - } -} -``` - -但是,[Netpoll][Netpoll] 不需要这样做,nocopy APIs 支持对 buffer 进行原地址操作(原地址组包和分包),并通过引用计数实现资源的自动回收和重用。 - -示例如下(使用方法 `Reader.Slice` 和 `Writer.Append`): - -```go -package main - -import ( - "github.com/cloudwego/netpoll" -) - -func main() { - var conn netpoll.Connection - - // reading - reader := conn.Reader() - for { - ... unpacking & handling ... - pkg, _ := reader.Slice(pkgsize) - go func() { - ... handling pkg ... - pkg.Release() - } - } - - // writing - var write_datas <-chan netpoll.Writer - ... packing write ... - writer := conn.Writer() - for { - select { - case pkg := <-write_datas: - writer.Append(pkg) - default: - if writer.MallocLen() > 0 { - writer.Flush() - } - } - } -} -``` - -[Netpoll]: https://github.com/cloudwego/netpoll -[net]: https://github.com/golang/go/tree/master/src/net -[gopool]: https://github.com/bytedance/gopkg/tree/develop/util/gopool -[Examples]: https://github.com/cloudwego/netpoll-examples -[server-example]: https://github.com/cloudwego/netpoll-examples/blob/main/echo/server.go -[client-example]: https://github.com/cloudwego/netpoll-examples/blob/main/echo/client.go -[netpoll_options.go]: https://github.com/cloudwego/netpoll/blob/main/netpoll_options.go -[nocopy.go]: https://github.com/cloudwego/netpoll/blob/main/nocopy.go -[eventloop.go]: https://github.com/cloudwego/netpoll/blob/main/eventloop.go diff --git a/content/zh/docs/netpoll/Overview/_index.md b/content/zh/docs/netpoll/Overview/_index.md deleted file mode 100644 index b0df478671c..00000000000 --- a/content/zh/docs/netpoll/Overview/_index.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: "概览" -linkTitle: "概览" -weight: 1 -description: > ---- - -## 简介 - -[Netpoll][Netpoll] 是由 [字节跳动][ByteDance] 开发的高性能 NIO(Non-blocking I/O)网络库,专注于 RPC 场景。 - -RPC 通常有较重的处理逻辑,因此无法串行处理 I/O。而 Go 的标准库 [net][net] 设计了 BIO(Blocking I/O) 模式的 -API,使得 RPC 框架设计上只能为每个连接都分配一个 goroutine。 这在高并发下,会产生大量的 -goroutine,大幅增加调度开销。此外,[net.Conn][net.Conn] 没有提供检查连接活性的 API,因此 RPC -框架很难设计出高效的连接池,池中的失效连接无法及时清理。 - -另一方面,开源社区目前缺少专注于 RPC 方案的 Go 网络库。类似的项目如:[evio][evio], [gnet][gnet] 等,均面向 [Redis][Redis], [HAProxy][HAProxy] 这样的场景。 - -因此 [Netpoll][Netpoll] 应运而生,它借鉴了 [evio][evio] 和 [netty][netty] 的优秀设计,具有出色的 [性能](#性能),更适用于微服务架构。 同时,[Netpoll][Netpoll] 还提供了一些 [特性](#特性),推荐在 RPC 设计中替代 -[net][net] 。 - -基于 [Netpoll][Netpoll] 开发的 RPC 框架 [Kitex][Kitex] 和 HTTP 框架 [Hertz][Hertz],其性能均业界领先。 - -[范例][netpoll-example] 展示了如何使用 [Netpoll][Netpoll] 构建 RPC Client 和 Server。 - -## 特性 - -- **已经支持** - - - [LinkBuffer][LinkBuffer] 提供可以流式读写的 nocopy API - - [gopool][gopool] 提供高性能的 goroutine 池 - - [mcache][mcache] 提供高效的内存复用 - - `IsActive` 支持检查连接是否存活 - - `Dialer` 支持构建 client - - `EventLoop` 支持构建 server - - 支持 TCP,Unix Domain Socket - - 支持 Linux,macOS(操作系统) - -- **即将开源** - - - Shared Memory IPC - - 支持 TLS - - 支持 UDP - -- **不被支持** - - Windows(操作系统) - -## 性能 - -性能测试应满足工业级使用要求,在 RPC 场景下,并发请求、等待超时是必要的支持项。 - -我们提供了 [netpoll-benchmark][netpoll-benchmark] 项目用来长期追踪和比较 [Netpoll][Netpoll] 与其他框架在不同情况下的性能数据以供参考。 - -更多测试参考 [kitex-benchmark][kitex-benchmark] 和 [hertz-benchmark][hertz-benchmark] - -## 参考 - -- [官方网站](/zh/) -- [使用文档](/zh/docs/netpoll/getting-started/) - -[Netpoll]: https://github.com/cloudwego/netpoll -[net]: https://github.com/golang/go/tree/master/src/net -[net.Conn]: https://github.com/golang/go/blob/master/src/net/net.go -[evio]: https://github.com/tidwall/evio -[gnet]: https://github.com/panjf2000/gnet -[netty]: https://github.com/netty/netty -[Kitex]: https://github.com/cloudwego/kitex -[Hertz]: https://github.com/cloudwego/hertz -[netpoll-example]: https://github.com/cloudwego/netpoll-examples -[netpoll-benchmark]: https://github.com/cloudwego/netpoll-benchmark -[kitex-benchmark]: https://github.com/cloudwego/kitex-benchmark -[hertz-benchmark]: https://github.com/cloudwego/hertz-benchmark -[ByteDance]: https://www.bytedance.com -[Redis]: https://redis.io -[HAProxy]: http://www.haproxy.org -[LinkBuffer]: https://github.com/cloudwego/netpoll/blob/develop/nocopy_linkbuffer.go -[gopool]: https://github.com/bytedance/gopkg/tree/develop/util/gopool -[mcache]: https://github.com/bytedance/gopkg/tree/develop/lang/mcache -[io_uring]: https://github.com/axboe/liburing diff --git a/content/zh/docs/netpoll/_index.md b/content/zh/docs/netpoll/_index.md deleted file mode 100644 index 05fa3ba681f..00000000000 --- a/content/zh/docs/netpoll/_index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Netpoll" -linkTitle: "Netpoll" -weight: 4 -Description: Netpoll 是由字节跳动开发的高性能 NIO(Non-blocking I/O) 网络库,专注于 RPC 场景。 -menu: - main: - weight: 4 - parent: "文档" ----