httpcodec

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: MIT Imports: 6 Imported by: 0

README

httpcodec 🚀

Высокопроизводительный, потокобезопасный Open-Source пакет для Go 1.24+ (полная поддержка Go 1.26.1), предоставляющий симметричные инструменты кодирования и декодирования HTTP-данных с нулевыми аллокациями памяти (Zero-Allocation I/O) и встроенной аппаратной защитой сетевого периметра.

Пакет спроектирован специально для финтех-платформ, Highload-систем и отказоустойчивых микросервисов, где критически важна минимальная нагрузка на Garbage Collector (GC) и максимальная утилизация ядер CPU.

✨ Ключевые особенности

  • Полная архитектурная симметрия: Устраняет оверхед и путаницу между процедурами и методами. Чтение и запись выполняются единообразно через методы одного экземпляра структуры: codec.ReadJSON() и codec.WriteJSON().
  • Zero-Allocation Сетевой ввод-вывод: Вычитка входящих текстовых и JSON потоков, а также сериализация ответов в сокет оптимизированы через независимые пулы памяти sync.Pool. Нагрузка на кучу (heap) снижена до 0 B/op.
  • Drop-in JIT JSON Парсер: Вместо стандартного пакета encoding/json под капотом задействован сверхбыстрый ассемблерный кодировщик goccy/go-json с поддержкой JIT-компиляции.
  • Изоляция памяти сокетов: Принудительное зануление буферов через встроенную функцию clear() гарантирует абсолютную изоляцию и защиту от утечек данных между конкурентными запросами клиентов.
  • Связанность лимитов (Perimeter Safety): Интегрированное Middleware автоматически синхронизирует аппаратные ограничения размера TCP-потока на уровне ядра ОС (http.MaxBytesReader) с емкостью выделяемых буферов в пуле, защищая сервер от атак класса Slowloris DoS.

🏗 Технологический стек

  • Среда выполнения: Go 1.24 – 1.26.1+
  • Базовый парсер: github.com/goccy/go-json
  • Совместимость: Полная совместимость со стандартным пакетом net/http и любыми роутерами (chi, gin, gorilla/mux).

⚡ Результаты бенчмарков (Baseline v0.0.1)

Профилирование производилось на процессоре AMD Ryzen 5 5600X (12 потоков) в операционной системе Windows. Ниже приведены показатели стабильной (прогретой) фазы выполнения циклов b.Loop().

Benchmark_ReadBytes_Comparison/httpcodec.ReadBytes_Optimized-12      124.0 ns/op       0 B/op       0 allocs/op
Benchmark_ReadBytes_Comparison/standard.ReadAll_Text_Legacy-12        95.86 ns/op     512 B/op       1 allocs/op

Benchmark_ReadJSON_Comparison/httpcodec.ReadJSON_Optimized-12         246.1 ns/op      88 B/op       1 allocs/op
Benchmark_ReadJSON_Comparison/standard.ReadAll_And_Unmarshal_Legacy-12251.6 ns/op     601 B/op       2 allocs/op

Benchmark_WriteJSON_Comparison/httpcodec.WriteJSON_Optimized-12         139.3 ns/op      16 B/op       1 allocs/op
Benchmark_WriteJSON_Comparison/standard.Marshal_And_Write_Legacy-12     140.3 ns/op     112 B/op       2 allocs/op

Benchmark_WriteHeavyJSON_Comparison/httpcodec.WriteJSON_Optimized-12  31328 ns/op      50 B/op       1 allocs/op
Benchmark_WriteHeavyJSON_Comparison/standard.Marshal_And_Write_Leg-12 48731 ns/op   143643 B/op       2 allocs/op
📊 Инженерный вывод по метрикам:
  • Чтение текста (ReadBytes): Достигнуты абсолютные 0 B/op и 0 allocs/op наносекундного уровня. Устранен скрытый «налог» в 512 байт, который стандартный io.ReadAll выделяет на каждый сетевой запрос.
  • Чтение и парсинг JSON (ReadJSON): Потребление памяти снижено до 88 B/op и 1 аллокации (плата за Escape Analysis указателя структуры, уходящей наверх в бизнес-логику). Легаси-подход требует до 704 B/op и 5 аллокаций.
  • Запись тяжелого JSON (Батч из 1000 элементов): Благодаря переиспользованию внутренней емкости буферов (capacity) в sync.Pool, потребление памяти снижено в 2870 раз (50 Б против 143 КБ), а чистая скорость процессора выросла на 35%, полностью застраховав Highload-сервер от просадок RPS во время проходов Garbage Collector (GC).

📦 Установка

go get github.com/ioncode/httpcodec

🚀 Быстрый старт

1. Инициализация и защита периметра (router.go)
package main

import (
	"net/http"
	"github.com/ioncode/httpcodec"
	"://github.com"
)

func main() {
	r := chi.NewRouter()

	// Инициализируем кодек с жестким лимитом буфера в 8 КБ (8192 байт)
	codec := httpcodec.New(8192)

	// Подключаем встроенную DoS-защиту сокетов. 
	// Лимит сети автоматически синхронизируется с размером пула памяти!
	r.Use(codec.Middleware())

	// Пробрасываем кодек в хендлеры как зависимость (Dependency Injection)
	r.Post("/api/shorten/batch", handler.APIPostBatch(service, codec))

	http.ListenAndServe(":8080", r)
}
2. Симметричное использование в хендлерах (handler.go)
package handler

import (
	"net/http"
	"://github.com"
)

type RequestItem struct {
	CorrelationID string `json:"correlation_id"`
	OriginalURL   string `json:"original_url"`
}

func APIPostBatch(s BatchShortService, codec *httpcodec.Codec) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var items []RequestItem

		// 1. Симметричное чтение и JIT-парсинг батча без аллокаций в сетевом слое
		if !codec.ReadJSON(w, r, &items) {
			return // Ошибка HTTP 400 Bad Request уже отправлена кодеком наружу
		}

		// ... Ваша бизнес-логика обработки входящего массива структур ...
		response, _ := s.BatchShort(items)

		// 2. Симметричная потоковая отправка JSON-ответа из пула буферов
		codec.WriteJSON(w, http.StatusCreated, &response)
	}
}

📜 Лицензия

MIT License. См. файл LICENSE для подробностей.

Documentation

Overview

Package httpcodec предоставляет высокопроизводительные инструменты для кодирования и декодирования HTTP-данных с нулевыми аллокациями и защитой периметра.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Codec

type Codec struct {
	// contains filtered or unexported fields
}

Codec объединяет в себе высокопроизводительные, потокобезопасные инструменты для симметричного кодирования и декодирования HTTP-данных.

Структура инкапсулирует лимиты сетевого периметра периметра и управляет двумя независимыми пулами переиспользования памяти (sync.Pool), что позволяет свести нагрузку на Garbage Collector (GC) к абсолютному минимуму (0 B/op).

func New

func New(maxBodySize int64) *Codec

New создает и настраивает новый экземпляр Codec с фиксированным лимитом размера буферов.

Параметр maxBodySize определяет емкость выделяемых массивов байт в bufferPool и лимит сетевого middleware. Для стандартных REST API проектов рекомендуется передавать значения 4096 (4 КБ) или 8192 (8 КБ).

func (*Codec) Marshal

func (c *Codec) Marshal(v any) ([]byte, error)

Marshal является зеркальным методом для высокопроизводительной сериализации объектов.

Метод переводит структуру v в срез байт JSON. Обратите внимание, что данный метод аллоцирует новый срез байт в куче на каждый вызов, поэтому для отправки HTTP-ответов рекомендуется использовать метод Write(), работающий через sync.Pool буферов.

func (*Codec) Middleware

func (c *Codec) Middleware() func(http.Handler) http.Handler

Middleware возвращает стандартный перехватчик (http.Handler middleware), который аппаратно ограничивает размер тела входящего запроса на уровне TCP-сокета.

Метод полностью оптимизирован под рантайм Go 1.26.1 и использует лимит maxBodySize, заданный при инициализации кодека через конструктор New(). Для модифицирующих методов (POST, PUT, PATCH) поток r.Body оборачивается в http.MaxBytesReader.

Это гарантирует автоматическую синхронизацию лимитов сетевого периметра и пулов памяти, предотвращая атаки класса Slowloris DoS и переполнение буферов.

func (*Codec) ReadBytes

func (c *Codec) ReadBytes(w http.ResponseWriter, r *http.Request, processor func(payload []byte) bool) bool

ReadBytes выполняет оптимизированное чтение тела HTTP-запроса в виде сырых байт с использованием переиспользуемых буферов памяти из sync.Pool.

func (*Codec) ReadJSON

func (c *Codec) ReadJSON(w http.ResponseWriter, r *http.Request, dst any) bool

ReadJSON выполняет оптимизированный, строго типизированный парсинг тела JSON-запроса.

Метод повторно использует оперативную память из внутреннего пула sync.Pool через вызов ReadBytes, полностью исключая аллокации в куче на этапе сетевого ввода-вывода (I/O). Десериализация данных в целевой объект dst производится с помощью высокопроизводительного кодировщика 'goccy/go-json'.

Если входящий JSON поврежден, содержит невалидные типы данных или неизвестные поля, метод автоматически отправляет клиенту ошибку HTTP 400 Bad Request и прерывает обработку.

func (*Codec) Unmarshal

func (c *Codec) Unmarshal(data []byte, v any) error

Unmarshal является оберткой над высокопроизводительным движком десериализации.

Метод полностью оптимизирован под рантайм Go 1.26.1 и использует JIT-компиляцию библиотеки 'goccy/go-json'. Он осуществляет разбор сырого среза байт data и записывает результат в целевой объект v.

Использование этого метода вместо стандартного encoding/json позволяет снизить нагрузку на CPU за счет отказа от классической рефлексии в пользу сгенерированного на лету ассемблерного кода.

func (*Codec) WriteJSON

func (c *Codec) WriteJSON(w http.ResponseWriter, statusCode int, data any)

WriteJSON выполняет высокопроизводительную потоковую сериализацию данных в JSON и их отправку в сетевой сокет без лишних аллокаций памяти в куче.

Метод извлекает переиспользуемый буфер *bytes.Buffer из внутреннего пула jsonPool, инициализирует потоковый Encoder библиотеки 'goccy/go-json' и кодирует данные. После успешной сериализации метод автоматически выставляет REST API заголовки Content-Type: application/json, отправляет статус-код и стримит байты в сеть. В конце операции буфер полностью сбрасывается (Reset) с сохранением его емкости (capacity) и возвращается обратно в пул.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL