description |
---|
Пользовательская компрессия |
Большинство клиентов поддерживают несколько методов компрессии, и для различных сценариев требуется выбор подходящего алгоритма компрессии. При взаимодействии микросервисов можно использовать высокопроизводительные методы компрессии. Ниже приведены основные моменты, которые следует учесть при создании пользовательского компрессионного middleware:
Accept-Encoding
Content-Type
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'
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 )