https://github.com/s00inx/goserver
high-performance HTTP Web server using Linux epoll API and raw syscalls.
https://github.com/s00inx/goserver
Last synced: 2 months ago
JSON representation
high-performance HTTP Web server using Linux epoll API and raw syscalls.
- Host: GitHub
- URL: https://github.com/s00inx/goserver
- Owner: s00inx
- License: mit
- Created: 2026-02-15T18:08:27.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-04-17T15:19:54.000Z (2 months ago)
- Last Synced: 2026-04-17T17:28:56.061Z (2 months ago)
- Language: Go
- Homepage:
- Size: 110 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# goserver
goserver — это реализация HTTP-сервера с нуля (без использования стандартной библиотеки `net/http`).
Проект создавался как образовательный: мне хотелось спуститься на уровень ниже и на практике разобраться, как работают сетевые сокеты, событийные циклы (event loops) и как писать код с минимальным влиянием на Garbage Collector.
### Что было реализовано и изучено
Основной фокус в разработке был сделан на производительность и оптимизацию потребления памяти.
* **Свой Event Loop на epoll:** Отказался от стандартной модели "горутина на каждое соединение". Реализовал асинхронную обработку соединений через системные вызовы Linux (`epoll`), чтобы понять, как серверы держат тысячи подключений.
* **Минимизация аллокаций (Zero-Allocation Hot Path):** Жизненный цикл HTTP-запроса спроектирован так, чтобы не выделять память в куче (heap). Для этого активно используется `sync.Pool` и переиспользование байтовых буферов.
* **No-Copy парсинг:** Чтение заголовков и роутинг работают напрямую с индексами в сыром `[]byte`. Я избегал конвертации срезов в `string` без крайней необходимости, чтобы не копировать данные в памяти.
* **Оптимизация конкурентности:** При управлении состоянием соединений постарался уйти от "тяжелых" блокировок (`sync.Mutex`), заменив их на атомарные операции (`sync/atomic`). Это заметно снизило contention (борьбу за ресурсы) при тестировании на многоядерном процессоре.
* **Профилирование:** В процессе разработки активно использовал `pprof` (CPU и Heap профили), чтобы находить узкие места в парсере и устранять лишние выделения памяти.
### Технический стек
* **Язык**: Go (с использованием пакета `unsafe` для конвертаций без копирования).
* **ОС**: Только Linux (так как ядро сети завязано на Linux syscalls).
### Результаты (Бенчмарки)
Сервер тестировался на машине с Intel Core Ultra 5 125H (18 потоков) с помощью `wrk`.
* **Пропускная способность**: ~980k RPS.
* **Latency**: Среднее время отклика ~1.13 мс.
* **Память**: 0 B/op на горячем пути (подтверждено Go-бенчмарками `Benchmark_... -benchmem`).
> **Важное примечание:** Проект является пет-проектом для глубокого изучения языка и системного программирования. В угоду производительности и простоты экспериментов здесь опущены некоторые проверки безопасности (например, таймауты медленных клиентов) и кроссплатформенность, обязательные для production-решений.
### Запуск и тестирование
*(Требуется Linux или WSL)*
```bash
make run # Запуск сервера
make bmem # Запуск внутренних бенчмарков памяти
make testwrk # Нагрузочное тестирование (потребуется утилита wrk)
```
### Пример использования
```go
func main() {
srv := server.New()
// Определение роутов
api := srv.Group("/api/v1")
api.Get("/hello", func(c *server.Context) {
c.String(200, "Hello World")
})
// Парсинг IP пока реализован на низком уровне массивом байт
srv.Run([4]byte{127, 0, 0, 1}, 8080)
}
```