Go分布式缓存 使用 Protobuf 通信(day7)
admin
2024-01-31 12:21:11
0

Go分布式缓存 使用 Protobuf 通信(day7)

  • 为什么要使用 protobuf?
  • 使用 protobuf 进行节点间通信,编码报文,提高效率。代码约50行

1 为什么要使用 protobuf

protobuf 即 Protocol Buffers,Google 开发的一种数据描述语言,是一种轻便高效的结构化数据存储格式,与语言、平台无关,可扩展可序列化。protobuf 以二进制方式存储,占用空间小。

protobuf 的安装和使用教程请移步 Go Protobuf 简明教程,这篇文章就不再赘述了。protobuf 广泛地应用于远程过程调用(RPC) 的二进制传输,使用 protobuf 的目的非常简单,为了获得更高的性能。传输前使用 protobuf 编码,接收方再进行解码,可以显著地降低二进制传输的大小。另外一方面,protobuf 可非常适合传输结构化数据,便于通信字段的扩展。

使用 protobuf 一般分为以下 2 步:

  • 按照 protobuf 的语法,在 .proto 文件中定义数据结构,并使用 protoc 生成 Go 代码(.proto 文件是跨平台的,还可以生成 C、Java 等其他源码文件)。
  • 在项目代码中引用生成的 Go 代码。

2 使用 protobuf 通信

新建 package geecachepb,定义 geecachepb.proto

day7-proto-buf/geecache/geecachepb/geecachepb.proto - github

syntax = "proto3";package geecachepb;message Request {string group = 1;string key = 2;
}message Response {bytes value = 1;
}service GroupCache {rpc Get(Request) returns (Response);
}
  • Request 包含 2 个字段, group 和 cache,这与我们之前定义的接口 /_geecache// 所需的参数吻合。
  • Response 包含 1 个字段,bytes,类型为 byte 数组,与之前吻合。

生成 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 接口,参数使用 geecachepb.pb.go 中的数据类型。

day7-proto-buf/geecache/peers.go - github

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

最后,修改 geecache.gohttp.go 中使用了 PeerGetter 接口的地方。

day7-proto-buf/geecache/geecache.go - github

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
}

day7-proto-buf/geecache/http.go - github

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
}
  • ServeHTTP() 中使用 proto.Marshal() 编码 HTTP 响应。
  • Get() 中使用 proto.Unmarshal() 解码 HTTP 响应。

至此,我们已经将 HTTP 通信的中间载体替换成了 protobuf。运行 run.sh 即可以测试 GeeCache 能否正常工作。

3 总结

到这一篇为止,7 天用 Go 动手写/从零实现分布式缓存 GeeCache 这个系列就完成了。简单回顾下。第一天,为了解决资源限制的问题,实现了 LRU 缓存淘汰算法;第二天实现了单机并发,并给用户提供了自定义数据源的回调函数;第三天实现了 HTTP 服务端;第四天实现了一致性哈希算法,解决远程节点的挑选问题;第五天创建 HTTP 客户端,实现了多节点间的通信;第六天实现了 singleflight 解决缓存击穿的问题;第七天,使用 protobuf 库,优化了节点间通信的性能。如果看到这里,还没有动手写的话呢,赶紧动手写起来吧。一天差不多只需要实现 100 行代码呢。

4 参考文章

传送门

相关内容

热门资讯

专业师傅教你“海港玩十三张到底... 专业师傅教你“海港玩十三张到底有挂吗?其实是有挂(揭秘手机上必赢技巧)是一款可以让一直输的玩家,快速...
专业师傅教你“心悦麻将到底有挂... 您好:心悦麻将确实真的有挂,软件请加QQ群客服咨询:1075075785确实是有挂的,很多玩家在这款...
专业师傅教你“福建十三道到底有... 专业师傅教你“福建十三道到底有挂吗?其实是有挂(揭秘手机上必赢技巧)一、福建十三道AI软件牌型概率发...
专业师傅教你“启航竞技到底有挂... 您好,启航竞技这款游戏可以开挂的,确实是有挂的,需要了解{请加QQ群客服咨询:1075075785}...
专业师傅教你“边锋陕西麻将到底... 专业师傅教你“边锋陕西麻将到底有挂吗?其实是有挂(揭秘手机上必赢技巧)1、让任何用户在无需AI插件第...
专业师傅教你“旺旺冲击麻将到底... 你好旺旺冲击麻将这个游戏其实有挂的,确实是有挂的,需要了解【请加QQ群客服咨询:1075075785...
专业师傅教你“老牌人到底有挂吗... 亲,老牌人这款游戏可以开挂的,确实是有挂的,。但是开挂要下载第三方辅助软件,老牌人的开挂软件,名称叫...
专业师傅教你“皮皮湖南跑胡子到... 自定义皮皮湖南跑胡子系统规律,只需要输入自己想要的开挂功能,一键便可以生成出微扑克专用辅助器,不管你...
专业师傅教你“好友圈到底有挂吗... 亲,好友圈这款游戏可以开挂的,确实是有挂的,。但是开挂要下载第三方辅助软件,好友圈的开挂软件,名称叫...
专业师傅教你“心悦众娱到底有挂... 您好,心悦众娱这款游戏可以开挂的,确实是有挂的,需要了解{请加QQ群客服咨询:1075075785}...
专业师傅教你“德州牛仔到底有挂... 亲,德州牛仔这款游戏可以开挂的,确实是有挂的,。但是开挂要下载第三方辅助软件,德州牛仔的开挂软件,名...
专业师傅教你“口袋二人麻将到底... 你好口袋二人麻将这个游戏其实有挂的,确实是有挂的,需要了解【请加QQ群客服咨询:1075075785...
专业师傅教你“欢乐四喜到底有挂... 您好:欢乐四喜确实真的有挂,软件请加QQ群客服咨询:1075075785确实是有挂的,很多玩家在这款...
专业师傅教你“大唐麻将全集到底... 专业师傅教你“大唐麻将全集到底有挂吗?其实是有挂(揭秘手机上必赢技巧)一、大唐麻将全集AI软件牌型概...
专业师傅教你“PPPoker到... 自定义PPPoker系统规律,只需要输入自己想要的开挂功能,一键便可以生成出微扑克专用辅助器,不管你...
专业师傅教你“追梦到底有挂吗?... 专业师傅教你“追梦到底有挂吗?其实是有挂(揭秘手机上必赢技巧)一、追梦AI软件牌型概率发牌机制”必胜...
专业师傅教你“奕福麻将到底有挂... 你好奕福麻将这个游戏其实有挂的,确实是有挂的,需要了解【请加QQ群客服咨询:1075075785】,...
专业师傅教你“丁丁麻将到底有挂... 亲,丁丁麻将这款游戏可以开挂的,确实是有挂的,。但是开挂要下载第三方辅助软件,丁丁麻将的开挂软件,名...
专业师傅教你“万盛竞技到底有挂... 专业师傅教你“万盛竞技到底有挂吗?其实是有挂(揭秘手机上必赢技巧)是一款可以让一直输的玩家,快速成为...
专业师傅教你“君临天下到底有挂... 您好,君临天下这款游戏可以开挂的,确实是有挂的,需要了解{请加QQ群客服咨询:1075075785}...