Skip to content

Commit

Permalink
refactor: 调整Server-Timing的生成处理
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Feb 9, 2018
1 parent 01bf8e7 commit 18bc448
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 17 deletions.
4 changes: 2 additions & 2 deletions httplog/httplog.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ func Format(ctx *fasthttp.RequestCtx, tags []*Tag, startedAt time.Time) []byte {
case latency:
return []byte(time.Since(startedAt).String())
case latencyMs:
offset := (time.Now().UnixNano() - startedAt.UnixNano()) / (1000 * 1000)
return []byte(strconv.FormatInt(offset, 10))
ms := util.GetTimeConsuming(startedAt)
return []byte(strconv.Itoa(ms))
default:
return tag.data
}
Expand Down
9 changes: 8 additions & 1 deletion proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"crypto/sha1"
"encoding/base64"
"fmt"
"strconv"
"sync/atomic"
"time"

"github.com/valyala/fasthttp"
"github.com/vicanso/pike/util"
"github.com/vicanso/pike/vars"
)

Expand Down Expand Up @@ -44,6 +46,12 @@ func RegisterPolicy(name string, policy func(string) Policy) {

// Do 将当前请求转发至upstream
func Do(ctx *fasthttp.RequestCtx, us *Upstream, config *Config) (*fasthttp.Response, error) {
reqHeader := &ctx.Request.Header
startedAt := time.Now()
defer func() {
ms := util.GetTimeConsuming(startedAt)
reqHeader.SetCanonical(vars.TimingFetch, []byte(strconv.Itoa(ms)))
}()
policy := us.Policy
uh := policy.Select(us.Hosts, ctx)
if uh == nil {
Expand All @@ -54,7 +62,6 @@ func Do(ctx *fasthttp.RequestCtx, us *Upstream, config *Config) (*fasthttp.Respo

// 设置x-forwarded-for
xFor := vars.XForwardedFor
reqHeader := &ctx.Request.Header
orginalXFor := reqHeader.PeekBytes(xFor)

ip := []byte(ctx.RemoteIP().String())
Expand Down
34 changes: 23 additions & 11 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,33 @@ func doProxy(ctx *fasthttp.RequestCtx, us *proxy.Upstream, conf *Config) (*fasth
return resp, header, body, nil
}

func getTimingDesc(ms, name string) []byte {
if len(ms) == 0 {
return nil
}
return []byte("0=" + ms + ";" + name)
}

// 设置响应的 Server-Timing
func setServerTiming(ctx *fasthttp.RequestCtx, startedAt time.Time) {
v := startedAt.UnixNano()
now := time.Now().UnixNano()
use := int((now - v) / 1000000)
desc := []byte("0=" + strconv.Itoa(use) + ";" + string(vars.Name))
header := &ctx.Response.Header
reqHeader := &ctx.Request.Header
ms := util.GetTimeConsuming(startedAt)
totalDesc := getTimingDesc(strconv.Itoa(ms), string(vars.Name))
fetchDesc := getTimingDesc(string(reqHeader.PeekBytes(vars.TimingFetch)), string(vars.Name)+"-fetch")
gzipDesc := getTimingDesc(string(reqHeader.PeekBytes(vars.TimingGzip)), string(vars.Name)+"-gzip")

timing := [][]byte{
totalDesc,
fetchDesc,
gzipDesc,
}

serverTiming := header.PeekBytes(vars.ServerTiming)
if len(serverTiming) == 0 {
header.SetCanonical(vars.ServerTiming, desc)
} else {
header.SetCanonical(vars.ServerTiming, bytes.Join([][]byte{
desc,
serverTiming,
}, []byte(",")))
if len(serverTiming) != 0 {
timing = append(timing, serverTiming)
}
header.SetCanonical(vars.ServerTiming, bytes.Join(timing, []byte(",")))
}

// 增加额外的 Response Header
Expand Down Expand Up @@ -288,7 +298,9 @@ func handler(ctx *fasthttp.RequestCtx, conf *Config) {
// 不可缓存的数据,`dispatch.Response`函数会根据客户端来决定是否压缩
shouldDoCompress := shouldCompress(&resp.Header)
if shouldDoCompress && cacheAge > 0 && len(body) > vars.CompressMinLength {
gzipStartedAt := time.Now()
gzipData, err := util.Gzip(body)
util.SetTimingConsumingHeader(gzipStartedAt, &ctx.Request.Header, vars.TimingGzip)
if err == nil {
body = gzipData
compressType = vars.GzipData
Expand Down
15 changes: 15 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"expvar"
"fmt"
"io/ioutil"
"strconv"
"time"

"github.com/valyala/fasthttp"
"github.com/vicanso/pike/vars"
Expand Down Expand Up @@ -65,3 +67,16 @@ func GetDebugVars() []byte {
w.Flush()
return b.Bytes()
}

// GetTimeConsuming 获取使用耗时(ms)
func GetTimeConsuming(startedAt time.Time) int {
v := startedAt.UnixNano()
now := time.Now().UnixNano()
return int((now - v) / 1000000)
}

// SetTimingConsumingHeader 设置耗时至http头
func SetTimingConsumingHeader(startedAt time.Time, header *fasthttp.RequestHeader, key []byte) {
ms := GetTimeConsuming(startedAt)
header.SetCanonical(key, []byte(strconv.Itoa(ms)))
}
18 changes: 18 additions & 0 deletions util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package util

import (
"testing"
"time"

"github.com/valyala/fasthttp"
)
Expand Down Expand Up @@ -40,3 +41,20 @@ func TestGetDebugVars(t *testing.T) {
t.Fatalf("get the debug vars fail, %v", string(buf))
}
}

func TestGetTimeConsuming(t *testing.T) {
startedAt := time.Now()
time.Sleep(2 * time.Millisecond)
ms := GetTimeConsuming(startedAt)
if ms <= 0 {
t.Fatalf("the time consuming should be gt 0")
}
}

func TestTimingConsumingHeader(t *testing.T) {
header := &fasthttp.RequestHeader{}
startedAt := time.Now()
time.Sleep(2 * time.Millisecond)
key := []byte("Consuming")
SetTimingConsumingHeader(startedAt, header, key)
}
9 changes: 6 additions & 3 deletions vars/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,21 @@ var (

// Gzip gzip compress
Gzip = []byte("gzip")

// Deflate deflate compress
Deflate = []byte("deflate")

// Br brotli compress
Br = []byte("br")

// TimingFetch fecth time
TimingFetch = []byte("Timing-Fetch")
// TimingGzip gzip time
TimingGzip = []byte("Timing-Gzip")

// Get http get method
Get = []byte("GET")

// Head http head method
Head = []byte("HEAD")

// LineBreak 换行符
LineBreak = []byte("\r\n")
// Colon 冒号
Expand Down

0 comments on commit 18bc448

Please sign in to comment.