Домашняя страница проекта
Github.com/ Pan Jianfeng 2000 / месяц ...
Добро пожаловать всем на просмотр ~~, он все еще постоянно обновляется, если вам интересно, вы можете пометить его звездочкой и тайно наблюдать за ним.
Введение
gnet
Это высокопроизводительная и легкая сетевая библиотека, основанная на событийном цикле событий. Эта библиотека используется напрямуюepollиkqueueСистемные вызовы вместо стандартных сетевых пакетов Golang:netдля создания веб-приложений он работает как две веб-библиотеки с открытым исходным кодом:libuvиlibevent.
Ценность существования этого проекта заключается в обеспеченииRedis,HaproxyЭти два проекта имеют фреймворки веб-сервера на языке Go с одинаковой производительностью.
gnet
Изюминкой является то, что это высокопроизводительная, легкая, неблокирующая чистая реализация Go сетевой библиотеки транспортного уровня (TCP/UDP/Unix-Socket), которую разработчики могут использоватьgnet
реализовать собственный сетевой протокол прикладного уровня, чтобы создать собственное сетевое приложение прикладного уровня: например, вgnet
Реализуя протокол HTTP, вы можете создать HTTP-сервер или среду веб-разработки, а реализовав протокол Redis, вы можете создать свой собственный сервер Redis и так далее.
gnet
Взято из другого проекта:evio
, но с лучшей производительностью.
Функции
- высокая производительностьEvent-Loop, управляемый событиями, на основе многопоточной модели
- Встроенный алгоритм балансировки нагрузки Round-Robin
- Лаконичные API
- Эффективное использование памяти на основе кольцевого буфера
- Поддержка нескольких сетевых протоколов: TCP, UDP, Unix Sockets
- Поддерживаются два механизма управления событиями: epoll в Linux и kqueue во FreeBSD.
- Поддержка асинхронных операций записи
- Позволяет привязать несколько сетевых адресов прослушивания к Event-Loop.
- Гибкий таймер событий
- Повторное использование порта SO_REUSEPORT
Основной дизайн
многопоточная модель
gnet
Переработана и разработана новая встроенная модель многопоточности: «многопоточность master-slave Reactor», которая такжеnetty
Модель многопоточности по умолчанию. Ниже приведена схема этой модели:
Процесс его работы выглядит следующим образом:
сейчас яgnet
Разработайте новую модель многопоточности: «Многопоточность master-slave Reactors с пулом процессов thread/go», и она будет завершена в ближайшее время.Архитектурная схема этой модели выглядит следующим образом:
Процесс его работы выглядит следующим образом:
Механизм связи
gnet
Модель «Master-Slave Reactors Multithreading» основана на горутинах в Golang.Один реактор монтируется на один горутин, поэтому вgnet
В этой сетевой модели главный Reactor/Go-процедура и подчиненные Reactor/Go-процедуры имеют огромные требования к связи, поэтомуgnet
Должен быть механизм для эффективной связи между горутинами Я не выбрал основное решение в Golang: модель CSP на основе Channel, а выбрал решение Disruptor с большей производительностью и на основе Ring-Buffer.
Так что в итоге я выбралgo-disruptor: Golang реализация высокопроизводительной очереди распределения сообщений LMAX Disruptor.
Автоматически расширяющийся кольцевой буфер
gnet
Используйте кольцевой буфер для кэширования данных потока TCP и управления использованием памяти.
начать использовать
Установить
$ go get -u github.com/panjf2000/gnet
Пример использования
// ======================== Echo Server implemented with gnet ===========================
package main
import (
"flag"
"fmt"
"log"
"strings"
"github.com/panjf2000/gnet"
"github.com/panjf2000/gnet/ringbuffer"
)
func main() {
var port int
var loops int
var udp bool
var trace bool
var reuseport bool
flag.IntVar(&port, "port", 5000, "server port")
flag.BoolVar(&udp, "udp", false, "listen on udp")
flag.BoolVar(&reuseport, "reuseport", false, "reuseport (SO_REUSEPORT)")
flag.BoolVar(&trace, "trace", false, "print packets to console")
flag.IntVar(&loops, "loops", 0, "num loops")
flag.Parse()
var events gnet.Events
events.NumLoops = loops
events.OnInitComplete = func(srv gnet.Server) (action gnet.Action) {
log.Printf("echo server started on port %d (loops: %d)", port, srv.NumLoops)
if reuseport {
log.Printf("reuseport")
}
return
}
events.React = func(c gnet.Conn, inBuf *ringbuffer.RingBuffer) (out []byte, action gnet.Action) {
top, tail := inBuf.PreReadAll()
out = append(top, tail...)
inBuf.Reset()
if trace {
log.Printf("%s", strings.TrimSpace(string(top)+string(tail)))
}
return
}
scheme := "tcp"
if udp {
scheme = "udp"
}
log.Fatal(gnet.Serve(events, fmt.Sprintf("%s://:%d", scheme, port)))
}
события ввода/вывода
gnet
В настоящее время поддерживаются следующие события ввода-вывода:
-
OnInitComplete
Вызывается после завершения инициализации сервера. -
OnOpened
Когда соединение открывается, оно вызывается. -
OnClosed
Вызывается при закрытии соединения. -
OnDetached
Вызывается при активном отключении соединения. -
React
Вызывается, когда серверная сторона получает данные, отправленные с клиентской стороны. (Ваш основной бизнес-код обычно пишется с помощью этого метода) -
Tick
Когда сервер запустится, он будет вызываться один раз, а затем будет вызываться один раз через заданный интервал времени, это метод таймера. -
PreWrite
Метод предварительной записи данных вызывается перед тем, как серверная сторона записывает данные обратно на клиентскую сторону.
Тестирование производительности
Linux (epoll)
Системные параметры
Go Version: go1.12.9 linux/amd64
OS: Ubuntu 18.04
CPU: 8 Virtual CPUs
Memory: 16.0 GiB
Echo Server
HTTP Server
FreeBSD (kqueue)
Системные параметры
Go Version: go version go1.12.9 darwin/amd64
OS: macOS Mojave 10.14.6
CPU: 4 CPUs
Memory: 8.0 GiB
Echo Server
HTTP Server
Сертификат
gnet
Исходный код позволяет пользователям следовать MITСертификат с открытым исходным кодомиспользуется по правилам.
сделать
gnet все еще находится в процессе непрерывной разработки, поэтому код и документация этого репозитория будут постоянно обновляться.Если вы заинтересованы в gnet, вы можете внести свой код в эту библиотеку с открытым исходным кодом~~