作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
接上一篇:http 中使用 gzip 输出内容时,如何预先压缩前一半页面?
经过实测,对线上一个输出 html 的服务进行了改造,通过预先压缩页面前半部分的方法,此接口的性能提升了 20%.
对比项无 gzip 压缩gzip 压缩+前半部分预压缩输出字节数43992246每核 qps14052.6316924.75具体的写法如下:
1.获取改造后的库- go get github.com/ahfuzhang/compress@v1.17.2
复制代码 2.在 go.mod 中修改:- replace (
- github.com/klauspost/compress => github.com/ahfuzhang/compress v1.17.2
- )
- require (
- github.com/klauspost/compress v1.16.3
- github.com/valyala/bytebufferpool v1.0.0
- github.com/valyala/fasthttp v1.50.0
- )
复制代码 3.代码:- package main
- import (
- "bytes"
- _ "embed"
- "fmt"
- "log"
- "os"
- "github.com/klauspost/compress/gzip"
- "github.com/valyala/bytebufferpool"
- "github.com/valyala/fasthttp"
- )
- //go:embed raw.html
- var html string
- //go:embed raw.js
- var js string
- func testGzipedHttp() {
- topHalf, digest := gzip.GetGzipedData([]byte(html)) // cache 页面的前一半, digest 是这些内容的 crc32 的校验和
- requestHandler := func(ctx *fasthttp.RequestCtx) {
- ctx.Response.Header.Add("Content-Type", "text/plain")
- ctx.Response.Header.Add("Content-Encoding", "gzip")
- switch string(ctx.Request.URI().RequestURI()) {
- case "/1": // direct output
- w, _ := gzip.NewWriterLevel(ctx, gzip.BestCompression)
- w.Write([]byte(html))
- w.Write([]byte(js))
- w.Close()
- case "/2":
- w := gzip.GetWriter(ctx) // 使用对象池
- w.WriteHeader() // 写 gzip 的头部信息,10 字节
- w.WriteGzipedData([]byte(html), topHalf, digest)
- // 当这个缓存是第一次输出的时候,可以传入 digest 值,这样可以少算一次 crc32
- // 当不是第一次输出的时候, 第三个参数 digest 填 0
- w.Write([]byte(js))
- gzip.PutWriter(w) // 必须调用,写入尾部信息,并放回对象池
- }
- }
- s := &fasthttp.Server{
- Handler: requestHandler,
- }
- if err := s.ListenAndServe(":8080"); err != nil {
- log.Fatalf("error in ListenAndServe: %v", err)
- }
- }
- func main() {
- testGzipedHttp()
- }
复制代码 希望对你有用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |