diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 00000000000..c9fd3dbc5ec --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,28 @@ +name: CLA Assistant + +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +permissions: + actions: write + contents: write + pull-requests: write + statuses: write + +jobs: + CLAssistant: + runs-on: ubuntu-latest + steps: + - name: CLA Assistant + uses: contributor-assistant/github-action@v2.6.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + with: + path-to-signatures: signatures/version1/cla.json + path-to-document: https://cla-assistant.io/cloudwego/cloudwego.github.io + branch: main + allowlist: bot diff --git a/content/en/_index.html b/content/en/_index.html index 4d8b68fb4a8..8e42b185bc4 100644 --- a/content/en/_index.html +++ b/content/en/_index.html @@ -182,7 +182,6 @@

Enterprise Users

  • }}">Kitex
  • }}">Hertz
  • }}">Volo
  • -
  • }}">Netpoll
  • }}">Eino
  • @@ -192,7 +191,6 @@

    Enterprise Users

  • Kitex
  • Hertz
  • Volo
  • -
  • Netpoll
  • Sonic
  • Eino
  • 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..a220763c5d2 100644 --- a/content/zh/_index.html +++ b/content/zh/_index.html @@ -205,7 +205,6 @@

    谁在用

  • }}">Kitex
  • }}">Hertz
  • }}">Volo
  • -
  • }}">Netpoll
  • }}">Eino
  • @@ -215,7 +214,6 @@

    谁在用

  • Kitex
  • Hertz
  • Volo
  • -
  • Netpoll
  • Sonic
  • Eino
  • diff --git a/content/zh/docs/netpoll/Caution/_index.md b/content/zh/docs/netpoll/Caution/_index.md deleted file mode 100644 index 7027e4bbb00..00000000000 --- a/content/zh/docs/netpoll/Caution/_index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "注意事项" -linkTitle: "注意事项" -weight: 4 -description: > ---- - -## 错误设置 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: "文档" ---- diff --git a/signatures/version1/cla.json b/signatures/version1/cla.json new file mode 100644 index 00000000000..780c4992616 --- /dev/null +++ b/signatures/version1/cla.json @@ -0,0 +1 @@ +{ "signedContributors": [] }