主要内容:
Go语言可以很轻松地实现一个HTTP服务端,示例如下,下例创建了一个在19326端口接收任何HTTP请求的HTTP服务端。
gopackage main
import (
"log"
"net/http"
)
type server int // server类 所有要传到http包里作为Handler的类必须实现ServeHTTP方法
func main() {
var s server
http.ListenAndServe("127.0.0.1:19326", &s)
}
// ServeHTTP 自己实现的ServeHTTP方法 在这个类中记录了HTTP请求的路径 并且响应Hello World
func (h *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL.Path)
_, err := w.Write([]byte("Hello World!"))
if err != nil {
return
}
}
效果如下:
得益于已经对缓存进行了有效的并发保护,在HTTP服务端这里直接调用函数即可。
go// src/geecache/http.go
package geecache
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"strings"
)
const defaultBasePath = "/_geecache/" // 默认资源地址
// HTTPPool 一个缓存对应一个HTTP池 记录自身的地址和URL
type HTTPPool struct {
selfAddr string // 记录缓存自身的地址 包括端口
basePath string // 记录URL
}
// NewHTTPPool HTTPPool的构造方法
func NewHTTPPool(selfAddr string) (result *HTTPPool) {
result = &HTTPPool{
selfAddr: selfAddr,
basePath: defaultBasePath,
}
return
}
// Log 记录信息 参数v可传多个值 这些值会按format来进行格式化 再进入log
func (pool *HTTPPool) Log(format string, v ...interface{}) {
log.Printf("[Server %s] %s", pool.selfAddr, fmt.Sprintf(format, v...))
}
// ServeHTTP HTTP服务端的Handler方法 对有效的缓存请求进行响应
func (pool *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.URL.Path, pool.basePath) { // 检查请求是否有效
panic("HTTPPool is serving unexpected path: " + r.URL.Path)
}
pool.Log("%s %s", r.Method, r.URL.Path) // log记录该次请求的信息
parts := strings.SplitN(r.URL.Path[len(pool.basePath):], "/", 2) // 切片 按'/'切两段
if len(parts) != 2 { // 检查请求是否有效
http.Error(w, "bad request", http.StatusBadRequest) // 400
return
}
groupName := parts[0]
key := parts[1]
group := GetGroup(groupName)
if group == nil { // 请求的缓存不存在
http.Error(w, "no such group:" + groupName, http.StatusNotFound) // 404
return
}
view, err := group.GetFromCache(key)
if err != nil { // 缓存请求失败
http.Error(w, err.Error(), http.StatusInternalServerError) // 500
return
}
w.Header().Set("Content-Type", "application/octet-stream")
_, err = w.Write(view.GetByteCopy())
if err != nil { // 写入响应失败
http.Error(w, "write into responseWriter error: " + err.Error(), http.StatusInternalServerError) // 500
return
}
}
gopackage main
import (
"GeeCache/src/geecache"
"fmt"
"log"
"net/http"
)
var db1 = map[string]string{
"Tom": "630",
"Jack": "589",
"Sam": "567",
}
func main() {
geecache.NewGroup("scores", 2<<10, geecache.GetterFunc(
func(key string) ([]byte, error) {
log.Println("[SlowDB] search key", key)
if v, ok := db1[key]; ok {
return []byte(v), nil
}
return nil, fmt.Errorf("%s not exist", key)
}))
addr := "localhost:9999"
peers := geecache.NewHTTPPool(addr)
log.Println("geecache is running at", addr)
log.Fatal(http.ListenAndServe(addr, peers))
}
测试效果:
本文作者:御坂19327号
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!