1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-elton

Клонировать/Скачать
custom_compress.md 5.3 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 04.06.2025 23:59 7f2703a
description
Пользовательская компрессия

Большинство клиентов поддерживают несколько методов компрессии, и для различных сценариев требуется выбор подходящего алгоритма компрессии. При взаимодействии микросервисов можно использовать высокопроизводительные методы компрессии. Ниже приведены основные моменты, которые следует учесть при создании пользовательского компрессионного middleware:

  • Определение поддерживаемых клиентом методов компрессии на основе заголовка запроса Accept-Encoding
  • Установка минимального размера для компрессии, чтобы избежать потери производительности при компрессии небольших данных
  • Компрессия только текстовых данных на основе заголовка ответа Content-Type
  • Балансировка между коэффициентом компрессии и производительностью в зависимости от сценария, например, для внутренней сети можно использовать эффективные алгоритмы компрессии, такие как snappy и lz4

Middleware elton-compress предоставляет несколько других часто используемых методов компрессии, включая zstd и snappy. Для добавления нового метода компрессии необходимо реализовать три функции интерфейса Compressor.

// Compressor интерфейс компрессора
type Compressor interface {
	// Accept функция проверки поддержки компрессии
	Accept(c *elton.Context, bodySize int) (acceptable bool, encoding string)
	// Compress функция компрессии
	Compress([]byte) (*bytes.Buffer, error)
	// Pipe функция передачи данных
	Pipe(*elton.Context) error
}
```Пример реализации компрессии lz4 в middleware elton-compress:

```go
package compress

import (
	"bytes"
	"io"

	"github.com/pierrec/lz4"
	"github.com/vicanso/elton"
)

const (
	// Lz4Encoding кодировка lz4
	Lz4Encoding = "lz4"
)

type (
	// Lz4Compressor компрессор lz4
	Lz4Compressor struct {
		Level     int
		MinLength int
	}
)

func (l *Lz4Compressor) getMinLength() int {
	if l.MinLength == 0 {
		return defaultCompressMinLength
	}
	return l.MinLength
}

// Accept проверка поддержки кодировки
func (l *Lz4Compressor) Accept(c *elton.Context, bodySize int) (acceptable bool, encoding string) {
	// Если размер данных меньше минимального размера для компрессии, то не компрессировать
	if bodySize >= 0 && bodySize < l.getMinLength() {
		return
	}
	return AcceptEncoding(c, Lz4Encoding)
}

// Compress lz4 компрессия
func (l *Lz4Compressor) Compress(buf []byte) (*bytes.Buffer, error) {
	buffer := new(bytes.Buffer)
	w := lz4.NewWriter(buffer)
	defer w.Close()
	w.Header.CompressionLevel = l.Level
	_, err := w.Write(buf)
	if err != nil {
		return nil, err
	}
	return buffer, nil
}

// Pipe lz4 pipe компрессия
func (l *Lz4Compressor) Pipe(c *elton.Context) (err error) {
	r := c.Body.(io.Reader)
	closer, ok := c.Body.(io.Closer)
	if ok {
		defer closer.Close()
	}
	w := lz4.NewWriter(c.Response)
	w.Header.CompressionLevel = l.Level
	defer w.Close()
	_, err = io.Copy(w, r)
	return
}

Пример вызова:

package main

import (
	"bytes"

	"github.com/vicanso/elton"
	compress "github.com/vicanso/elton-compress"
	"github.com/vicanso/elton/middleware"
)

func main() {
	d := elton.New()

	conf := middleware.CompressConfig{}
	lz4 := &compress.Lz4Compressor{
		Level:     2,
		MinLength: 1024,
	}
	conf.AddCompressor(lz4)
	d.Use(middleware.NewCompress(conf))

	d.GET("/", func(c *elton.Context) (err error) {
		b := new(bytes.Buffer)
		for i := 0; i < 1000; i++ {
			b.WriteString("Привет, мир!\n")
		}
		c.SetHeader(elton.HeaderContentType, "text/plain; charset=utf-8")
		c.BodyBuffer = b
		return
	})

	err := d.ListenAndServe(":3000")
	if err != nil {
		panic(err)
	}
}

curl -H 'Accept-Encoding: lz4' -v 'http://127.0.0.1:3000'

  • Rebuilt URL to: http://127.0.0.1:3000/
  • Trying 127.0.0.1...
  • TCP_NODELAY set
  • Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)

GET / HTTP/1.1 Host: 127.0.0.1:3000 User-Agent: curl/7.54.0 Accept: / Accept-Encoding: lz4

< HTTP/1.1 200 OK < Content-Encoding: lz4 < Content-Length: 103 < Content-Type: text/plain; charset=utf-8 < Vary: Accept-Encoding ...


Из заголовков ответа видно, что данные были сжаты в формате `lz4`, а размер данных составил всего 103 байта, что позволило сэкономить полосу пропускания.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-elton.git
git@api.gitlife.ru:oschina-mirror/mirrors-elton.git
oschina-mirror
mirrors-elton
mirrors-elton
master