測試方式
go run groupcache.go -http=:8081 -groupcache-peers=:8082,:8083 go run groupcache.go -http=:8082 -groupcache-peers=:8081,:8083 go run groupcache.go -http=:8083 -groupcache-peers=:8081,:8082
開啟你的本地瀏覽器 http://localhost:8081/medium.jpg?width=100
這邊是可以看到你目前的狀態 http://localhost:8081/stats
你可以看到以下的資訊
{ "Group": { "Gets": 2, "CacheHits": 1, "PeerLoads": 0, "PeerErrors": 1, "Loads": 1, "LoadsDeduped": 1, "LocalLoads": 1, "LocalLoadErrs": 0, "ServerRequests": 0 }, "Caches": { "Main": { "Bytes": 2762, "Items": 1, "Gets": 3, "Hits": 1, "Evictions": 0 }, "Hot": { "Bytes": 0, "Items": 0, "Gets": 2, "Hits": 0, "Evictions": 0 } } }
需要用到的套件:
- imageserver https://github.com/pierrre/imageserver/blob/master/README.md
以下為 go 的程式碼
// Package advanced provides a groupcache example. // // Run: // go run groupcache.go -http=:8081 -groupcache-peers=:8082,:8083 // go run groupcache.go -http=:8082 -groupcache-peers=:8081,:8083 // go run groupcache.go -http=:8083 -groupcache-peers=:8081,:8082 // // Open http://localhost:8081/medium.jpg?width=100 // // Stats are available on http://localhost:8081/stats package main import ( "crypto/sha256" "encoding/json" "flag" "fmt" "net/http" "net/url" "strings" "github.com/disintegration/gift" "github.com/golang/groupcache" "github.com/pierrre/imageserver" imageserver_cache "github.com/pierrre/imageserver/cache" imageserver_cache_groupcache "github.com/pierrre/imageserver/cache/groupcache" imageserver_http "github.com/pierrre/imageserver/http" imageserver_http_gift "github.com/pierrre/imageserver/http/gift" imageserver_http_image "github.com/pierrre/imageserver/http/image" imageserver_image "github.com/pierrre/imageserver/image" _ "github.com/pierrre/imageserver/image/gif" imageserver_image_gift "github.com/pierrre/imageserver/image/gift" _ "github.com/pierrre/imageserver/image/jpeg" _ "github.com/pierrre/imageserver/image/png" imageserver_testdata "github.com/pierrre/imageserver/testdata" ) const ( groupcacheName = "imageserver" ) var ( flagHTTP = ":8080" flagGroupcache = int64(128 * (1 << 20)) flagGroupcachePeers string ) func main() { parseFlags() startHTTPServer() } func parseFlags() { flag.StringVar(&flagHTTP, "http", flagHTTP, "HTTP") flag.Int64Var(&flagGroupcache, "groupcache", flagGroupcache, "Groupcache") flag.StringVar(&flagGroupcachePeers, "groupcache-peers", flagGroupcachePeers, "Groupcache peers") flag.Parse() } func startHTTPServer() { http.Handle("/", http.StripPrefix("/", newImageHTTPHandler())) http.Handle("/favicon.ico", http.NotFoundHandler()) initGroupcacheHTTPPool() // it automatically registers itself to "/_groupcache" http.HandleFunc("/stats", groupcacheStatsHTTPHandler) err := http.ListenAndServe(flagHTTP, nil) if err != nil { panic(err) } } func newImageHTTPHandler() http.Handler { return &imageserver_http.Handler{ Parser: imageserver_http.ListParser([]imageserver_http.Parser{ &imageserver_http.SourcePathParser{}, &imageserver_http_gift.ResizeParser{}, &imageserver_http_image.FormatParser{}, &imageserver_http_image.QualityParser{}, }), Server: newServer(), } } func newServer() imageserver.Server { srv := imageserver_testdata.Server srv = newServerImage(srv) srv = newServerGroupcache(srv) return srv } func newServerImage(srv imageserver.Server) imageserver.Server { return &imageserver.HandlerServer{ Server: srv, Handler: &imageserver_image.Handler{ Processor: &imageserver_image_gift.ResizeProcessor{ DefaultResampling: gift.LanczosResampling, }, }, } } func newServerGroupcache(srv imageserver.Server) imageserver.Server { if flagGroupcache <= 0 { return srv } return imageserver_cache_groupcache.NewServer( srv, imageserver_cache.NewParamsHashKeyGenerator(sha256.New), groupcacheName, flagGroupcache, ) } func initGroupcacheHTTPPool() { self := (&url.URL{Scheme: "http", Host: flagHTTP}).String() var peers []string peers = append(peers, self) for _, p := range strings.Split(flagGroupcachePeers, ",") { if p == "" { continue } peer := (&url.URL{Scheme: "http", Host: p}).String() peers = append(peers, peer) } pool := groupcache.NewHTTPPool(self) pool.Context = imageserver_cache_groupcache.HTTPPoolContext pool.Transport = imageserver_cache_groupcache.NewHTTPPoolTransport(nil) pool.Set(peers...) } func groupcacheStatsHTTPHandler(w http.ResponseWriter, req *http.Request) { gp := groupcache.GetGroup(groupcacheName) if gp == nil { http.Error(w, fmt.Sprintf("group %s not found", groupcacheName), http.StatusServiceUnavailable) return } type cachesStats struct { Main groupcache.CacheStats Hot groupcache.CacheStats } type stats struct { Group groupcache.Stats Caches cachesStats } data, err := json.MarshalIndent( stats{ Group: gp.Stats, Caches: cachesStats{ Main: gp.CacheStats(groupcache.MainCache), Hot: gp.CacheStats(groupcache.HotCache), }, }, "", " ", ) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } _, _ = w.Write(data) }