【go项目-geecache】动手写分布式缓存 - day7 - 使用 Protobuf 通信

索引

【go项目-geecache】动手写分布式缓存 - day1 - 实现LRU算法
【go项目-geecache】动手写分布式缓存 - day2 - 单机并发缓存
【go项目-geecache】动手写分布式缓存 - day3 - HTTP 服务端
【go项目-geecache】动手写分布式缓存 - day4 - 一致性哈希(hash)
【go项目-geecache】动手写分布式缓存 - day5 - 分布式节点
【go项目-geecache】动手写分布式缓存 - day6 - 防止缓存击穿
【go项目-geecache】动手写分布式缓存 - day7 - 使用 Protobuf 通信

收获:

  1. 了解节点之间通信的方式
  2. 如何使用Protobuf通信

基本介绍 protobuf 和 安装方法

详情看这篇博客[【go】protobuf 基本介绍和window安装说明](【go】protobuf 基本介绍和window安装说明_CCSU__LRF的博客-CSDN博客)

使用 protobuf 通信 geecachepb.proto

syntax = "proto3";  
  
package geecachepb;  
  
message Request {  
  string group = 1;  
  string key = 2;  
}  
  
message Response {  
  bytes value = 1;  
}  
  
service GroupCache {  
  rpc Get(Request) returns (Response);  
}

新建 package geecachepb,定义 geecachepb.proto

  • Requset为信息类型:包含group和key满足/_geecache//所需要的参数
  • Response为信息类型 : 包含一个value为bytes, 表示回复的内容

生成 geecache.pb.go

$ protoc --go_out=. *.proto  
$ ls  
geecachepb.pb.go  geecachepb.proto  

可以看到 geecachepb.pb.go 中有如下数据类型:


type Request struct {  
	Group string   `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"`  
    Key   string   `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`  
    ...  
}  
type Response struct {  
	Value []byte   `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`  
}

修改 peers.go 中的 PeerGetter 接口

import pb "geecache/geecachepb"  
type PeerGetter interface {  
	Get(in *pb.Request, out *pb.Response) error  
}

修改 group.go

import (  
    // ...  
    pb "geecache/geecachepb"  
)  
  
func (g *Group) getFromPeer(peer PeerGetter, key string) (ByteView, error) {  
	req := &pb.Request{  
		Group: g.name,  
		Key:   key,  
	}  
	res := &pb.Response{}  
	err := peer.Get(req, res)  
	if err != nil {  
		return ByteView
, err  
	}  
	return ByteView{b: res.Value}, nil  
}

修改 http.go

import (  
    // ...  
	pb "geecache/geecachepb"  
	"github.com/golang/protobuf/proto"  
)  
  
func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {  
    // ...  
	// Write the value to the response body as a proto message.  
	body, err := proto.Marshal(&pb.Response{Value: view.ByteSlice()})  
	if err != nil {  
		http.Error(w, err.Error(), http.StatusInternalServerError)  
		return  
	}  
	w.Header().Set("Content-Type", "application/octet-stream")  
	w.Write(body)  
}  
  
func (h *httpGetter) Get(in *pb.Request, out *pb.Response) error {  
	u := fmt.Sprintf(  
		"%v%v/%v",  
		h.baseURL,  
		url.QueryEscape(in.GetGroup()),  
		url.QueryEscape(in.GetKey()),  
	)  
    res, err := http.Get(u)  
	// ...  
	if err = proto.Unmarshal(bytes, out); err != nil {  
		return fmt.Errorf("decoding response body: %v", err)  
	}  
  
	return nil  
}

你可能感兴趣的:(golang项目,-,geecache,golang,分布式,缓存)