Go - 单机版缓存

工程目录树

$ tree cache-servercache-server├── caches│   └── cache.go├── go.mod├── go.sum├── main.go├── servers│   ├── http.go│   └── IServer.go└── utils    └── byte.go

utils

// byte.gopackage utilsfunc Copy(src []byte) []byte{    dst := make([]byte, len(src))    copy(dst, src)    return dst}

caches

// cache.gopackage cachesimport(    "sync"    "cache-server/utils")// cache data structtype Cache struct{    data map[string][]byte    count int64    lock *sync.RWMutex}func Newcache() *Cache{    return &Cache{        data: make(map[string][]byte, 256),        count:0,        lock: &sync.RWMutex{},    }}// cache's crud methods// create method & update methodfunc (c *Cache) Set(k string, v []byte){    c.lock.Lock()    _, ok := c.data[k]    if !ok {        // c.data[k] = v        c.count++    }    c.data[k] = utils.Copy(v)    c.lock.Unlock()}//  read methodfunc (c *Cache) Get(k string) ([]byte, bool){    c.lock.RLock()    defer c.lock.RUnlock()    v, ok := c.data[k]    return v,ok}//  delete methodfunc (c *Cache) Delete(k string){    c.lock.Lock()    _, ok := c.data[k]    if ok {        delete(c.data, k)        c.count--    }    c.lock.Unlock()}//  count methodfunc (c *Cache) Count() int64 {    c.lock.RLock()    defer c.lock.RUnlock()    return c.count    }

servers

// IServer.gopackage serverstype Server interface{    Run(ipAddress string)error}
// http.gopackage serversimport(    "net/http"    "encoding/json"    "io/ioutil"        "cache-server/caches"    "github.com/julienschmidt/httprouter")type HttpServer struct {    cache *caches.Cache}// 返回一个对于cache的新HTTP服务器func NewHttpServer(cache *caches.Cache) *HttpServer{    return &HttpServer{        cache: cache,    }}func (this *HttpServer) Run(ipAddress string) error{    return http.ListenAndServe(ipAddress, this.routerHandler())}// register routersfunc (this *HttpServer) routerHandler() http.Handler{    // github.com/julienschmidt/httprouter    r := httprouter.New()    // get cache by key    r.GET("/cache/:key", this.getHandler)     // set cache by key    r.PUT("/cache/:key", this.setHandler)     // delete cache by key    r.DELETE("/cache/:key", this.deleteHandler)     // get cache's data count     r.GET("/counts", this.countHandler)     return r}func (this *HttpServer) getHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {    key := params.ByName("key")    value, ok := this.cache.Get(key)    if ok {        w.Write(value)    }else{        w.WriteHeader(http.StatusNotFound)        return     }}func (this *HttpServer) setHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {    key := params.ByName("key")    value, err := ioutil.ReadAll(r.Body)    if err != nil {        w.WriteHeader(http.StatusInternalServerError)        return    }    this.cache.Set(key, value)    w.Write([]byte("set success"))}func (this *HttpServer) deleteHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {    key := params.ByName("key")    _, ok := this.cache.Get(key)    if !ok {        w.WriteHeader(http.StatusNotFound)    }    this.cache.Delete(key)}func (this *HttpServer) countHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params) {    counts, err := json.Marshal(map[string]interface{}{        "count": this.cache.Count()})    if err != nil{        w.WriteHeader(http.StatusInternalServerError)        return     }    w.Write(counts)}

main

// main.gopackage mainimport(    "cache-server/caches"    "cache-server/servers")func main(){    c := caches.Newcache()    err := servers.NewHttpServer(c).Run(":8080")    if err != nil {        panic(err)    }}

启动

$ cd ./cache-server && go mod init cache-server$ go get github.com/julienschmidt/httprouter$ go run main.go

测试

$ curl http://127.0.0.1:8080/cache/k  $ curl http://127.0.0.1:8080/cache/k -X PUT -d 'v'  set success%                                                                      $ curl http://127.0.0.1:8080/cache/k  v%                                                                                $ curl http://127.0.0.1:8080/cache/k -X DELETE      $ curl http://127.0.0.1:8080/cache/k              $ curl http://127.0.0.1:8080/counts              {"count":0}%$ curl http://127.0.0.1:8080/cache/k -X PUT -d 'v'set success%                                                                      $ curl http://127.0.0.1:8080/counts              {"count":1}