目录
前言
这个月我想学一下go语言,于是决定学习一个go实现的缓存服务。
首先本文基于golang的http包实现一个简单http的缓存服务,因为用golang自带的http包实现一个处理请求的服务端十分便利,我们只需要写一个简单的map保存数据,写一个http的handler处理请求即可,你不需要考虑任何复杂的并发问题,因为golang的http服务框架会帮你处理好底层的一切。
cache
缓存服务接口
本文实现的简单缓存具备三种基本接口 : SET
GET
DEL
分别通过http协议的PUT
、GET
、DELETE
、操作进行。
put
PUT /cache/<key>
content
<value>
GET
GET /cache/<key>
content
<value>
DELETE
DELETE /cache/<key>
cache包实现
本缓存服务里面通过一个cache包实现缓存功能。
cache包接口定义
:
package cache
type Cache interface {
Set(string, []byte) error
Get(string) ([]byte, error)
Del(string) error
GetStat() Stat
}
cache 接口实现
Cache 结构很简单,一张map,另加一把锁保护即可.
package cache
import "sync"
type SimpleCache struct {
c map[string][]byte
mutex sync.RWMutex
Stat
}
func (c *SimpleCache) Set(k string, v []byte) error {
c.mutex.Lock()
defer c.mutex.Unlock()
tmp, exist := c.c[k]
if exist {
c.del(k, tmp)
}
c.c[k] = v
c.add(k, v)
return nil
}
func (c *SimpleCache) Get(k string) ([]byte, error) {
c.mutex.RLock()
defer c.mutex.RUnlock()
return c.c[k], nil
}
func (c *SimpleCache) Del(k string) error {
c.mutex.Lock()
defer c.mutex.Unlock()
v, exist := c.c[k]
if exist {
delete(c.c, k)
c.del(k, v)
}
return nil
}
func (c *SimpleCache) GetStat() Stat {
return c.Stat
}
func newInMemoryCache() *SimpleCache {
return &SimpleCache{make(map[string][]byte), sync.RWMutex{}, Stat{}}
}
cache包测试:
package main
import (
"./cache"
"fmt"
)
func main() {
c := cache.New("inmemory")
k, v := "sola", []byte{'a','i','l','u','m','i','y','a'}
c.Set(k, v)
tmp, _ := c.Get(k)
fmt.Println("key: ", k, " value: ", tmp)
c.Del(k)
tmp, _ = c.Get(k)
fmt.Println("key: ", k, " value: ", tmp)
}
sola@sola:~/Coder/GitHub/go-cache/http-cache/server$ go run main.go
2019/02/10 00:07:15 inmemory ready to serve
key: sola value: [97 105 108 117 109 105 121 97]
sola@sola:~/Coder/GitHub/go-cache/http-cache/server$ go run main.go
2019/02/10 00:07:28 inmemory ready to serve
key: sola value: [97 105 108 117 109 105 121 97]
key: sola value: []
golang http包使用介绍
Golang自带的http包已经实现了htpp客户端和服务端,我们可以利用它更为快速的开发http服务。本章仅介绍一下http包服务端的使用。
Golang中处理 HTTP 请求主要跟两个东西相关:ServeMux 和 Handler。
ServrMux 本质上是一个 HTTP 请求路由器(或者叫多路复用器,Multiplexor)。它把收到的请求与一组预先定义的 URL 路径列表做对比,然后在匹配到路径的时候调用关联的处理器(Handler)。
处理器(Handler)负责输出HTTP响应的头和正文。任何满足了http.Handler接口的对象都可作为一个处理器。通俗的说,对象只要有个如下签名的ServeHTTP方法即可:
ServeHTTP(http.ResponseWriter, *http.Request)
Golang的 HTTP 包自带了几个函数用作常用处理器,比如NotFoundHandler 和 RedirectHandler。
NotFoundHandler
返回一个简单的请求处理器,该处理器会对每个请求都回复"404 page not found"。
RedirectHandler
返回一个请求处理器,该处理器会对每个请求都使用状态码code重定向到网址url。
接着,我们来看两个简单的样例:
hello.go
package main
import (
"io"
"log"
"net/http"
)
func HelloGoServer(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, this is a GoServer")
}
func main() {
http.HandleFunc("/", HelloGoServer)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServer ", err)
}
}
浏览器看看我们的hello程序:
1、 http.HandleF