diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml index 6d4b0676c..0aba7465a 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yaml +++ b/.github/ISSUE_TEMPLATE/bug-report.yaml @@ -11,7 +11,7 @@ body: value: | ## Before you go any further - Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally. - - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/gnet-io/gnet). + - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/UyKD7NZcfH). - First of all, visit our [website](https://gnet.host) and [Github Org](https://github.com/gnet-io) for docs and examples. - type: checkboxes id: checklist diff --git a/.github/ISSUE_TEMPLATE/feature-request.yaml b/.github/ISSUE_TEMPLATE/feature-request.yaml index 34e4ed427..8a7342610 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-request.yaml @@ -11,7 +11,7 @@ body: value: | ## Before you go any further - Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally. - - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/gnet-io/gnet). + - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/UyKD7NZcfH). - First of all, visit our [website](https://gnet.host) and [Github Org](https://github.com/gnet-io) for docs and examples. - type: textarea id: feature-request diff --git a/.github/ISSUE_TEMPLATE/question.yaml b/.github/ISSUE_TEMPLATE/question.yaml index b6fc4e0d8..15472f7b7 100644 --- a/.github/ISSUE_TEMPLATE/question.yaml +++ b/.github/ISSUE_TEMPLATE/question.yaml @@ -9,7 +9,7 @@ body: value: | ## Before you go any further - Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally. - - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/gnet-io/gnet). + - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/UyKD7NZcfH). - First of all, visit our [website](https://gnet.host) and [Github Org](https://github.com/gnet-io) for docs and examples. - Make sure what you're looking for here is an issue rather than a [discussion](https://github.com/panjf2000/gnet/discussions/new/choose). - type: checkboxes diff --git a/README.md b/README.md index 49538bc1a..6b6ad1680 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@
- @@ -16,15 +15,19 @@ English | [中文](README_ZH.md) +### 🎉🎉🎉 Feel free to join [the channels about `gnet` on the Discord Server](https://discord.gg/UyKD7NZcfH). + # 📖 Introduction -`gnet` is an event-driven networking framework that is fast and lightweight. It makes direct [epoll](https://en.wikipedia.org/wiki/Epoll) and [kqueue](https://en.wikipedia.org/wiki/Kqueue) syscalls rather than using the standard Go [net](https://golang.org/pkg/net/) package and works in a similar manner as [netty](https://github.com/netty/netty) and [libuv](https://github.com/libuv/libuv), which makes `gnet` achieve a much higher performance than Go [net](https://golang.org/pkg/net/). +`gnet` is an event-driven networking framework that is ultra-fast and lightweight. It is built from scratch by exploiting [epoll](https://man7.org/linux/man-pages/man7/epoll.7.html) and [kqueue](https://en.wikipedia.org/wiki/Kqueue) and it can achieve much higher performance with lower memory consumption than Go [net](https://golang.org/pkg/net/) in many specific scenarios. + +`gnet` and [net](https://golang.org/pkg/net/) don't share the same philosophy about network programming. Thus, building network applications with `gnet` can be significantly different from building them with [net](https://golang.org/pkg/net/), and the philosophies can't be harmonized. There are other similar products written in other programming languages in the community, such as [libevent](https://github.com/libevent/libevent), [libuv](https://github.com/libuv/libuv), [netty](https://github.com/netty/netty), [twisted](https://github.com/twisted/twisted), [tornado](https://github.com/tornadoweb/tornado), etc. which work in a similar pattern as `gnet` under the hood. -`gnet` is not designed to displace the standard Go [net](https://golang.org/pkg/net/) package, but to create a networking client/server framework for Go that performs on par with [Redis](http://redis.io) and [Haproxy](http://www.haproxy.org) for networking packets handling (although it does not limit itself to these areas), therefore, `gnet` is not as comprehensive as Go [net](https://golang.org/pkg/net/), it only provides the core functionalities (by a concise API set) of a networking application and it is not planned on being a full-featured networking framework, as I think [net](https://golang.org/pkg/net/) has done a good enough job in this area. +`gnet` is not designed to displace the Go [net](https://golang.org/pkg/net/), but to create an alternative in the Go ecosystem for building performance-critical network services. As a result of which, `gnet` is not as comprehensive as Go [net](https://golang.org/pkg/net/), it provides only the core functionalities (in a concise API set) required by a network application and it is not planned on being a coverall networking framework, as I think [net](https://golang.org/pkg/net/) has done a good enough job in that area. -`gnet` sells itself as a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go which works on the transport layer with TCP/UDP protocols and Unix Domain Socket, so it allows developers to implement their own protocols(HTTP, RPC, WebSocket, Redis, etc.) of application layer upon `gnet` for building diversified network applications, for instance, you get an HTTP Server or Web Framework if you implement HTTP protocol upon `gnet` while you have a Redis Server done with the implementation of Redis protocol upon `gnet` and so on. +`gnet` sells itself as a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go which works on the transport layer with TCP/UDP protocols and Unix Domain Socket. It enables developers to implement their own protocols(HTTP, RPC, WebSocket, Redis, etc.) of application layer upon `gnet` for building diversified network services. For instance, you get an HTTP Server if you implement HTTP protocol upon `gnet` while you have a Redis Server done with the implementation of Redis protocol upon `gnet` and so on. -**`gnet` derives from the project: `evio` while having a much higher performance and more features.** +**`gnet` derives from the project: `evio` with much higher performance and more features.** # 🚀 Features @@ -73,22 +76,22 @@ If you have `gnet` integrated into projects, feel free to open a pull request re ```bash # Hardware Environment -* 28 HT Cores Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz +* 28 HT Cores Intel(R) Xeon(R) Gold 5120 CPU @ 3.20GHz * 32GB RAM -* Ubuntu 18.04.3 4.15.0-88-generic #88-Ubuntu * Dedicated Cisco 10-gigabit Ethernet switch +* Debian 12 "bookworm" * Go1.19.x linux/amd64 ``` ![](https://raw.githubusercontent.com/panjf2000/illustrations/master/benchmark/techempower-plaintext-top50-light.jpg) -This is a leaderboard of the top ***50*** out of ***499*** frameworks that encompass various programming languages worldwide, in which `gnet` is ranked ***first***. +This is a leaderboard of the top ***50*** out of ***486*** frameworks that encompass various programming languages worldwide, in which `gnet` is ranked ***first***. ![](https://raw.githubusercontent.com/panjf2000/illustrations/master/benchmark/techempower-plaintext-topN-go-light.png) This is the full framework ranking of Go and `gnet` tops all the other frameworks, which makes `gnet` the ***fastest*** networking framework in Go. -To see the full ranking list, visit [TechEmpower Plaintext Benchmark](https://www.techempower.com/benchmarks/#section=test&runid=a07a7117-f861-49b2-a710-94970c5767d0&test=plaintext). +To see the full ranking list, visit [TechEmpower Benchmark **Round 22**](https://www.techempower.com/benchmarks/#hw=ph&test=plaintext§ion=data-r22). ***Note that the HTTP implementation of gnet on TechEmpower is half-baked and fine-tuned for benchmark purposes only and far from production-ready.*** diff --git a/README_ZH.md b/README_ZH.md index 983e1f259..7c42c4d4d 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -6,7 +6,6 @@
- @@ -16,13 +15,17 @@ [英文](README.md) | 中文 +### 🎉🎉🎉 欢迎加入 `gnet` 在 [Discord 服务器上的频道](https://discord.gg/UyKD7NZcfH). + # 📖 简介 -`gnet` 是一个基于事件驱动的高性能和轻量级网络框架。它直接使用 [epoll](https://en.wikipedia.org/wiki/Epoll) 和 [kqueue](https://en.wikipedia.org/wiki/Kqueue) 系统调用而非标准 Go 网络包:[net](https://golang.org/pkg/net/) 来构建网络应用,它的工作原理类似两个开源的网络库:[netty](https://github.com/netty/netty) 和 [libuv](https://github.com/libuv/libuv),这也使得 `gnet` 达到了一个远超 Go [net](https://golang.org/pkg/net/) 的性能表现。 +`gnet` 是一个基于事件驱动的高性能和轻量级网络框架。这个框架是基于 [epoll](https://en.wikipedia.org/wiki/Epoll) 和 [kqueue](https://en.wikipedia.org/wiki/Kqueue) 从零开发的,而且相比 Go [net](https://golang.org/pkg/net/),它能以更低的内存占用实现更高的性能。 + +`gnet` 和 [net](https://golang.org/pkg/net/) 有着不一样的网络编程模式。因此,用 `gnet` 开发网络应用和用 [net](https://golang.org/pkg/net/) 开发区别很大,而且两者之间不可调和。社区里有其他同类的产品像是 [libevent](https://github.com/libevent/libevent), [libuv](https://github.com/libuv/libuv), [netty](https://github.com/netty/netty), [twisted](https://github.com/twisted/twisted), [tornado](https://github.com/tornadoweb/tornado),`gnet` 的底层工作原理和这些框架非常类似。 -`gnet` 设计开发的初衷不是为了取代 Go 的标准网络库:[net](https://golang.org/pkg/net/),而是为了创造出一个类似于 [Redis](http://redis.io)、[Haproxy](http://www.haproxy.org) 能高效处理网络包的 Go 语言网络客户端/服务器框架。因此,`gnet` 在功能上的全面性并不如 [net](https://golang.org/pkg/net/),它只提供网络编程中最核心的功能和最精简的 APIs,而且 `gnet` 也并没有打算变成一个全功能、无所不包的网络库,因为我觉得 Go [net](https://golang.org/pkg/net/) 在这方面已经做得足够好了。 +`gnet` 不是为了取代 [net](https://golang.org/pkg/net/) 而生的,而是在 Go 生态中为开发者提供一个开发性能敏感的网络服务的替代品。也正因如此,`gnet` 在功能全面性上比不了 Go [net](https://golang.org/pkg/net/),它只会提供网络应用所需的最核心的功能和最精简的 APIs,而且 `gnet` 也并没有打算变成一个无所不包的网络框架,因为我觉得 Go [net](https://golang.org/pkg/net/) 在这方面已经做得足够好了。 -`gnet` 的卖点在于它是一个高性能、轻量级、非阻塞的纯 Go 实现的传输层(TCP/UDP/Unix Domain Socket)网络框架,开发者可以使用 `gnet` 来实现自己的应用层网络协议(HTTP、RPC、Redis、WebSocket 等等),从而构建出自己的应用层网络应用:比如在 `gnet` 上实现 HTTP 协议就可以创建出一个 HTTP 服务器 或者 Web 开发框架,实现 Redis 协议就可以创建出自己的 Redis 服务器等等。 +`gnet` 的卖点在于它是一个高性能、轻量级、非阻塞的纯 Go 语言实现的传输层(TCP/UDP/Unix Domain Socket)网络框架。开发者可以使用 `gnet` 来实现自己的应用层网络协议(HTTP、RPC、Redis、WebSocket 等等),从而构建出自己的应用层网络服务。比如在 `gnet` 上实现 HTTP 协议就可以创建出一个 HTTP 服务器 或者 Web 开发框架,实现 Redis 协议就可以创建出自己的 Redis 服务器等等。 **`gnet` 衍生自另一个项目:`evio`,但拥有更丰富的功能特性,且性能远胜之。** @@ -73,22 +76,22 @@ go get -u github.com/panjf2000/gnet ```bash # 硬件环境 -* 28 HT Cores Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz +* 28 HT Cores Intel(R) Xeon(R) Gold 5120 CPU @ 3.20GHz * 32GB RAM -* Ubuntu 18.04.3 4.15.0-88-generic #88-Ubuntu * Dedicated Cisco 10-gigabit Ethernet switch +* Debian 12 "bookworm" * Go1.19.x linux/amd64 ``` ![](https://raw.githubusercontent.com/panjf2000/illustrations/master/benchmark/techempower-plaintext-top50-light.jpg) -这是包含全部编程语言框架的性能排名***前 50*** 的结果,总榜单包含了全世界共计 ***499*** 个框架,其中 `gnet` 排名***第一***。 +这是包含全部编程语言框架的性能排名***前 50*** 的结果,总榜单包含了全世界共计 ***486*** 个框架,其中 `gnet` 排名***第一***。 ![](https://raw.githubusercontent.com/panjf2000/illustrations/master/benchmark/techempower-plaintext-topN-go-light.png) 这是 Go 语言分类下的全部排名,`gnet` 超越了其他所有框架,位列第一,是***最快***的 Go 网络框架。 -完整的排行可以通过 [TechEmpower Plaintext Benchmark](https://www.techempower.com/benchmarks/#section=test&runid=a07a7117-f861-49b2-a710-94970c5767d0&test=plaintext) 查看。 +完整的排行可以通过 [TechEmpower Benchmark **Round 22**](https://www.techempower.com/benchmarks/#hw=ph&test=plaintext§ion=data-r22) 查看。 ***请注意,TechEmpower 上的 gnet 的 HTTP 实现是不完备且针对性调优的,仅仅是用于压测目的,不是生产可用的***。 diff --git a/connection_unix.go b/connection_unix.go index b31234af4..44cd351d4 100644 --- a/connection_unix.go +++ b/connection_unix.go @@ -85,8 +85,6 @@ func newUDPConn(fd int, el *eventloop, localAddr net.Addr, sa unix.Sockaddr, con func (c *conn) release() { c.ctx = nil - c.localAddr = nil - c.remoteAddr = nil c.buffer = nil if addr, ok := c.localAddr.(*net.TCPAddr); ok && c.localAddr != c.loop.ln.addr && len(addr.Zone) > 0 { bsPool.Put(bs.StringToBytes(addr.Zone)) @@ -94,6 +92,14 @@ func (c *conn) release() { if addr, ok := c.remoteAddr.(*net.TCPAddr); ok && len(addr.Zone) > 0 { bsPool.Put(bs.StringToBytes(addr.Zone)) } + if addr, ok := c.localAddr.(*net.UDPAddr); ok && c.localAddr != c.loop.ln.addr && len(addr.Zone) > 0 { + bsPool.Put(bs.StringToBytes(addr.Zone)) + } + if addr, ok := c.remoteAddr.(*net.UDPAddr); ok && len(addr.Zone) > 0 { + bsPool.Put(bs.StringToBytes(addr.Zone)) + } + c.localAddr = nil + c.remoteAddr = nil c.pollAttachment.FD, c.pollAttachment.Callback = 0, nil if !c.isDatagram { c.opened = false