1. 程式人生 > 實用技巧 >savsgio/kratgo 基於fasthttp 開發的一個cache proxy 服務

savsgio/kratgo 基於fasthttp 開發的一個cache proxy 服務

savsgio/kratgo 基於fasthttp 開發的web cache 服務,包含以下特性

支援的特性

  • cache proxy
  • lb (順序,然後輪轉模式,沒有權重)
  • 配置cache 規則
  • 配置http 請求頭
  • 管理api 支援,基於管理api 我們可以進行cache 清理

參考使用

  • docker-compose 檔案
version: "3"
services:
 proxy: 
  image: savsgio/kratgo
  command: -config /etc/config.yaml
  ports:
  - "6081:6081"
  volumes: 
   - "./config.yaml:/etc/config.yaml"
  • 配置
###########################
#  KRATGO CONFIGURATION
###########################
# IMPORTANT: Be careful with the tabulation indentation
# --- Variables ---
# $(method) : request method
# $(host) : request host
# $(path) : request path
# $(contentType) : response backend's content type
# $(statusCode) : response backend's status code
# $(req.header::<NAME>) : request header name
# $(resp.header::<NAME>) : response header name
# $(cookie::<NAME>) : request cookie name
# --- Operators ---
# Modifiers: + - / * & | ^ ** % >> <<
# Comparators: > >= < <= == != =~ !~
# Logical ops: || &&
# Numeric constants, as 64-bit floating point (12345.678)
# String constants (single quotes: 'foobar')
# Date constants (single quotes, using any permutation of RFC3339, ISO8601, ruby date, or unix date; date parsing is automatically tried with any string constant)
# Boolean constants: true false
# Parenthesis to control order of evaluation ( )
# Arrays (anything separated by , within parenthesis: (1, 2, 'foo'))
# Prefixes: ! - ~
# Ternary conditional: ? :
# Null coalescence: ??
# --- Log ---
# Log level: fatal | error | warning | info | debug
# Log output:
#  - console: Write output in standard error
#  - <file path>: Write output in log file
logLevel: debug
logOutput: ./kratgo.log
# --- Cache ---
# ttl: Cache expiration in minutes
# cleanFrequency: Interval in minutes between removing expired entries (clean up)
# maxEntries: Max number of entries in cache. Used only to calculate initial size for cache
# maxEntrySize: Max size of entry in bytes
# hardMaxCacheSize: Limit for cache size in MB (Default value is 0 which means unlimited size)
cache:
 ttl: 10
 cleanFrequency: 1
 maxEntries: 600000
 maxEntrySize: 500
 hardMaxCacheSize: 0
# --- Invalidator ---
# maxWorkers: Maximum workers to execute invalidations
invalidator:
 maxWorkers: 5
# --- Proxy ---
# addr: IP and Port of Kratgo
# backendAddrs: Array with "addr:port" of the backends
# response: Configuration to manipulate reponse (Optional)
#  headers:
#   set: Configuration to SET headers from response (Optional)
#    - name: Header name
#     value: Value of header
#     if: Condition to set this header (Optional)
#
#   unset: Configuration to UNSET headers from response (Optional)
#    - name: Header name
#     if: Condition to unset this header (Optional)
#
# nocache: Conditions to not save in cache the backend response (Optional)
proxy:
 addr: 0.0.0.0:6081
 backendAddrs:
   [
    <address>
   ]
 response:
  headers:
   set:
    - name: X-Kratgo
     value: true
   unset:
    - name: Set-Cookie
     if: $(req.header::X-Requested-With) != 'XMLHttpRequest'
 nocache:
  - $(req.header::X-Requested-With) == 'XMLHttpRequest'
# --- Admin ---
# addr: IP and Port of admin api
admin:
 addr: 0.0.0.0:6082
  • 效果

同時,如果斷開網路連結,你會發現網站依然還能訪問(因為cache了)

基於fasthttp 開發一個自己proxy 的簡單程式碼

package main
import (
 "flag"
 "fmt"
 "log"
 "github.com/valyala/fasthttp"
)
var (
 add = flag.String("add", "localhost", "proxy address")
)
type myLog struct {
 add string
}
func (l myLog) Printf(format string, args ...interface{}) {
 log.Printf(format, args...)
}
func (l myLog) myhandler(ctx *fasthttp.RequestCtx) {
 backend := fasthttp.HostClient{
  Addr: l.add,
  }
 backend.Do(&ctx.Request, &ctx.Response)
}
func main() {
 flag.Parse()
 fmt.Println(*add)
 log := myLog{
  add: *add,
  }
 s := fasthttp.Server{
  Handler:   log.myhandler,
  LogAllErrors: true,
  Logger:    log,
  }
 s.ListenAndServe(":8000")
}

原始碼簡單說明

savsgio/kratgo 的原始碼並不難,對於cache proxy 基於fasthttp 的Server提供,對於cache 部分基於bigcache
Server handler 使用了fasthttp 的fasthttp.HostClient,配置解析部分基於yaml,指定語法解析(配置自定義引數)
使用Knetic/govaluate,同時為了效能作者很多地方使用了sync.Pool ,lb 部分實現很簡單,就是資料索引的移動
當超過資料最大值得時候,重置索引為0,同時對於cache 管理,作者基於channel 實現了一個校驗任務,實際可以
看看原始碼,實際上以後也分享過gregjones/httpcache的開源實現,也是一個不錯的選擇

參考資料

https://github.com/savsgio/kratgo
https://github.com/Knetic/govaluate
https://github.com/valyala/fasthttp
https://github.com/allegro/bigcache
https://github.com/gregjones/httpcache