当前位置: 首页 > news >正文

广东建设工程招标网站深圳华汇设计

广东建设工程招标网站,深圳华汇设计,电商运营年终总结ppt,同城信息网站建设本文目录 1.序2.引入etcd缓存流程项目结构 3.gocachepb.proto4.服务注册register.go5.服务发现discover.go6.gRPC客户端client.gopeers.goclient.go 7.gRPC服务端实现server.go一些问题缓存获取流程缓存设置流程为什么要带超时的上下文#xff1f; 1.序 GeeCache项目并没有引… 本文目录 1.序2.引入etcd缓存流程项目结构 3.gocachepb.proto4.服务注册register.go5.服务发现discover.go6.gRPC客户端client.gopeers.goclient.go 7.gRPC服务端实现server.go一些问题缓存获取流程缓存设置流程为什么要带超时的上下文 1.序 GeeCache项目并没有引入服务发现对于现代分布缓存系统服务发现和节点间通信是两个重要环节所以可以引入etcd和gRPC来使得系统更加健壮和高效。 etcd作为一个高可用的分布式键值存储系统扮演着服务注册与发现的角色。通过etcd缓存节点可以动态地注册自己的存在同时发现其他节点的位置。这种机制使得系统能够自动适应节点的加入和退出无需手动配置。 而且etcd的租约机制提供了节点健康检查的能力当某个节点宕机时系统能够及时感知并进行相应调整保证整个缓存集群的可用性。 gRPC则解决了节点间高效通信的问题。相比传统的HTTP/JSON通信方式gRPC基于HTTP/2协议和Protocol Buffers序列化格式提供了更高的性能和更低的延迟。传输前使用 protobuf 编码接收方再进行解码可以显著地降低二进制传输的大小。另外一方面protobuf 可非常适合传输结构化数据便于通信字段的扩展。GeeCache中只是单纯用了protobuf进行通信。 在缓存系统中节点间需要频繁交换数据如缓存查询、更新等操作gRPC的高效通信能力显著提升了系统的吞吐量。 本文所参考的部分实现代码是Github上的cache项目原地址https://github.com/Spr1n9/springcache 2.引入etcd 缓存流程 当一个节点需要获取不在本地缓存的数据时它会通过一致性哈希算法选择一个节点使用 etcd 进行服务发现获取该节点的地址建立 gRPC 连接并调用远程节点的 Get 方法获取数据如果远程节点也没有缓存该数据它会从数据源获取并返回 项目结构 这里我们需要编写几个新的文件分别是 cachepb.proto Protocol Buffers定义文件用于定义gRPC服务接口和消息格式。 定义了 SpringCache 服务包含 Get 和 Set 两个RPC方法定义了请求和响应的消息结构 GetRequest 、 GetResponse 、 SetRequest 和 SetResponse这个文件是gRPC通信的基础通过protoc工具生成Go代码 server.go 服务端核心实现负责处理来自其他节点的缓存请求。 实现了gRPC服务接口处理 Get 和 Set 请求管理节点间的通信和缓存数据的分发使用一致性哈希算法选择节点启动gRPC服务器接收来自其他节点的请求 client.go 客户端实现负责向其他节点发送请求。 封装了gRPC客户端调用逻辑实现了 PeerGetter 接口用于从远程节点获取或设置缓存处理与远程节点的连接和通信 discover.go 服务发现相关功能负责发现和连接其他节点。 提供 DialPeer 函数用于建立与其他节点的gRPC连接提供 GetAddrByName 函数通过etcd查询服务名对应的地址使用etcd的服务发现机制获取节点信息 register.go 服务注册相关功能负责将节点注册到etcd。 提供 Etcd 结构体封装etcd客户端操作实现租约创建、绑定和续约功能提供 RegisterServer 方法将服务注册到etcd 3.gocachepb.proto 首先来看看proto文件定义了整个系统的RPC接口和消息格式。 跟GeeCache一样有两个GetRequest、GetResponse是用来Get获取缓存的请求和响应。 value 缓存的值使用 bytes 类型可以存储任意二进制数据。 SetRequest 和 SetResponse 是设置缓存的请求消息和响应消息。 这里请求消息有group 缓存组名、key 缓存键、 value 缓存值、expire 过期时间戳Unix时间戳格式、ishot 是否为热点数据。 设置缓存的响应消息有ok 返回bool格式操作是否成功。 service SpringCache {rpc Get(GetRequest) returns (GetResponse);rpc Set(SetRequest) returns (SetResponse); }Get 获取缓存接收 GetRequest 参数返回 GetResponse Set 设置缓存接收 SetRequest 参数返回 SetResponse 使用protoc工具生成对应的两个代码如下生成的代码将被服务端和客户端使用服务端 server.go 实现了 SpringCacheServer 接口处理 Get 和 Set 请求客户端 client.go 使用 SpringCacheClient 接口向远程节点发送请求。 springcachepb.pb.go 包含消息类型的定义和序列化/反序列化代码springcachepb_grpc.pb.go 包含 gRPC 客户端和服务端接口代码 4.服务注册register.go Etcd 结构体是对 etcd 客户端的封装包含了与 etcd 交互所需的核心组件。其中 EtcdCli 是 etcd 的客户端实例用于执行各种 etcd 操作 leaseId 存储租约 ID用于后续的租约管理 ctx 和 cancel 则用于控制上下文和超时处理。将 etcd 的操作封装在一个结构体中便于统一管理和使用。 NewEtcd 函数负责初始化 etcd 客户端连接。它接收 etcd 服务器的地址列表创建一个新的 etcd 客户端实例并设置连接超时时间。这里使用了 clientv3.New 方法创建客户端这是 etcd v3 API 的标准做法。还创建一个带超时的上下文用于控制后续操作的超时行为。这是与分布式系统交互的常见模式可以避免因网络问题导致的长时间阻塞。 DialTimeout 是客户端尝试连接到 etcd 服务时的超时时间。如果在指定时间内无法建立连接客户端会返回错误。 CreateLease 为注册在etcd上的节点创建租约。 由于服务端无法保证自身是一直可用的可能会宕机所以与etcd的租约是有时间期限的租约一旦过期服务端存储在etcd上的服务地址信息就会消失。 如果服务端是正常运行的etcd中的地址信息又必须存在因此发送心跳检测一旦发现etcd上没有自己的服务地址时请求重新添加续租。 CreateLease 函数实现了 etcd 的租约创建机制。在分布式系统中租约是一种重要的机制用于表示节点的存活状态。该函数调用 Grant 方法向 etcd 申请一个指定过期时间的租约并将获得的租约 ID 保存在 Etcd 结构体中。租约机制是 etcd 实现服务健康检查的基础一旦租约过期与之关联的键值对会被自动删除这样就能自动清理已经宕机的节点信息。 BindLease 函数将服务信息与租约绑定。它使用 Put 方法将服务名称和地址作为键值对存储到 etcd 中并通过 clientv3.WithLease 选项将这个键值对与之前创建的租约关联起来。这样当租约过期时这个服务信息也会被自动删除。这种机制确保了 etcd 中只保存活跃节点的信息是实现服务自动注册和注销的关键。 KeepAlive 函数实现了租约的续约机制。它调用 etcd 的 KeepAlive 方法定期向 etcd 发送心跳以延长租约的有效期。该函数启动一个 goroutine 持续监听续约响应通道如果收到 nil 响应表示续约失败服务可能已经与 etcd 断开连接。这种心跳机制是分布式系统中保持节点活跃状态的标准做法确保了只要服务正常运行其信息就会一直保存在 etcd 中。 RegisterServer 函数是服务注册的入口它整合了前面几个函数的功能完成服务的完整注册流程。首先创建租约然后将服务信息与租约绑定接着启动心跳保持租约活跃最后使用 etcd 的 endpoints 管理器注册服务端点。 使用 endpoints.NewManager 创建一个管理器用于管理同一服务的所有实例。通过 AddEndpoint 方法将当前实例的信息添加到服务组织中并使用之前的租约进行关联。 em 会将所有 UserService 的实例组织在一起以 UserService/ 为前缀存储在 etcd 中。通过 AddEndpoint可以动态地添加服务实例。如果后续有更多实例如 192.168.1.2:8080 和 192.168.1.3:8080可以继续调用 AddEndpoint 将它们添加到 etcd 中。比如下面的。 /CacheService/instance1:8001 (leaseID: 123)/instance2:8002 (leaseID: 456)/instance3:8003 (leaseID: 789)每个实例都有自己的租约保证存活而 Manager 则负责将这些实例组织在一起方便 gRPC 客户端进行服务发现和负载均衡。 5.服务发现discover.go DialPeer 函数负责建立与远程服务节点的 gRPC 连接。它接收 etcd 客户端和服务名称作为参数返回一个 gRPC 连接。函数首先创建一个 etcd resolver 构建器这是 gRPC 服务发现的核心组件。然后设置一个带超时的上下文确保连接操作不会无限期阻塞。最后使用 grpc.DialContext 方法建立连接其中 etcd:///service 表示使用 etcd 作为服务发现机制并指定要连接的服务名称。 在 DialPeer 函数中 resolver.NewBuilder(c) 创建了一个 etcd resolver 构建器。这个构建器实现了 gRPC 的 resolver.Builder 接口能够解析 etcd 中存储的服务信息。当使用 etcd:///service 作为目标地址时gRPC 会使用这个 resolver 从 etcd 中查找所有注册在该服务名下的实例地址。这种机制使得客户端可以通过服务名而非具体 IP 地址进行通信实现了服务发现的解耦。 GetAddrByName 函数提供了一种更直接的服务发现方式。它接收 etcd 客户端和服务名称作为参数直接从 etcd 中查询该服务名对应的地址。函数首先创建一个带超时的上下文然后使用 etcd 的 Get 方法查询指定键服务名的值服务地址。这种方式适用于简单的键值查询不依赖 gRPC 的 resolver 机制。 这两种方式分别满足不同场景的需求。例如 DialPeer 用于建立 gRPC 连接进行缓存操作而 GetAddrByName 则用于服务器启动时发现其他节点。 两个函数都使用了 context.WithTimeout 创建带超时的上下文这是 Go 语言中处理超时的标准模式。在分布式系统中网络延迟和服务不可用是常见问题设置适当的超时可以避免长时间阻塞提高系统的可用性和响应速度。在这个文件中超时时间设置为 2 秒这是一个较为合理的值既能容忍一定的网络延迟又不会因等待过长而影响用户体验。 6.gRPC客户端client.go peers.go client.go Client 结构体是对远程节点通信客户端的封装包含两个关键字段 Name 表示目标服务节点的名称用于在 etcd 中查找对应的服务地址 Etcd 是 etcd 客户端的引用用于进行服务发现。 Get 函数实现了从远程节点获取缓存数据的功能。它首先通过 DialPeer 函数利用 etcd 进行服务发现获取目标节点的 gRPC 连接。然后创建 gRPC 客户端构造请求参数并设置超时上下文最后发起 RPC 调用并处理响应。这个函数展示了 gRPC 客户端的标准使用模式以及如何将 etcd 服务发现与 gRPC 调用结合起来。 Set 函数实现了向远程节点设置缓存数据的功能。它的流程与 Get 函数类似也是先通过 etcd 获取连接然后创建 gRPC 客户端发起调用。不同的是它需要处理更多的参数包括缓存值、过期时间和热点标记。这个函数展示了如何处理复杂的 RPC 参数以及如何处理 RPC 调用的错误和响应。 var _ PeerGetter (*Client)(nil)通过这种方式验证 Client 结构体是否实现了 PeerGetter 接口。 这是 Go 语言中常用的接口实现检查技巧如果 Client 没有完全实现 PeerGetter 接口编译器会报错。这种静态检查可以早期发现接口实现的问题提高代码质量。 7.gRPC服务端实现server.go Server 结构体是 分布式缓存系统的服务端核心组件它实现了 gRPC 服务接口和节点选择功能。结构体中包含多个重要字段 status 标记服务运行状态 self 记录自身 IP 地址 peers 是一致性哈希环用于节点选择 etcd 是 etcd 客户端实例用于服务发现 clients 存储了所有远程节点的客户端实例。 NewServer 函数负责创建并初始化一个 Server 实例。它接收服务名称、自身地址和 etcd 客户端作为参数初始化一致性哈希环和客户端映射。 Get 和 Set 方法实现了 gRPC 服务接口分别用于处理远程缓存获取和设置请求。当其他节点通过 gRPC 调用这些方法时服务器会从本地缓存组中获取或设置数据并返回相应的结果。这两个方法是分布式缓存系统中节点间数据交换的核心实现它们将 gRPC 请求转换为本地缓存操作实现了远程调用与本地存储的桥接。 SetPeers 方法是服务发现和节点管理的关键。它接收一组节点名称通过 etcd 查找每个节点的 IP 地址然后将这些地址添加到一致性哈希环中并创建对应的客户端实例。这个方法展示了如何使用 etcd 进行服务发现通过 GetAddrByName 函数查询 etcd 中存储的服务地址信息。 PickPeer 方法实现了 connect.PeerPicker 接口用于根据键选择合适的远程节点。它使用一致性哈希算法确定键应该存储在哪个节点上然后返回该节点的客户端实例。这个方法是分布式缓存系统中数据分片的核心实现它确保了相同的键总是被路由到相同的节点提高了缓存的命中率和一致性。 StartServer 方法负责启动 gRPC 服务器。它首先检查服务是否已经启动然后初始化 TCP 监听器创建 gRPC 服务器实例注册服务处理器最后开始监听和处理请求。这个方法是服务器组件的入口点它将所有组件组合在一起形成一个完整的服务节点。 一些问题 缓存获取流程 当客户端通过 API 请求获取缓存数据时 HTTP 服务器接收请求调用 group.Get 方法获取数据。 group.Get 首先尝试从本地缓存获取数据如果命中则直接返回。 如果本地缓存未命中 group.Get 会调用 group.load 方法加载数据。 group.load 会先检查是否有远程节点负责存储该键的数据 如果有则通过 PeerPicker.PickPeer 选择合适的节点然后通过 PeerGetter.Get 从远程节点获取数据这个过程涉及 gRPC 调用由 Client.Get 方法实现 如果远程节点获取失败或没有远程节点负责该键则调用回调函数从数据源获取数据。 获取到数据后将其存储到本地缓存并返回给客户端。 缓存设置流程 当客户端通过 API 请求设置缓存数据时 HTTP 服务器接收请求解析参数调用 group.Set 方法设置数据。 group.Set 会根据键选择合适的节点 如果是本地节点则直接设置本地缓存如果是远程节点则通过 PeerGetter.Set 设置远程节点的缓存这个过程也涉及 gRPC 调用由 Client.Set 方法实现 设置成功后返回成功响应给客户端。 为什么要带超时的上下文 可以看到这里我们经常使用上下文并且还要加入超时的设定。 使用带超时的上下文context.WithTimeout是一种非常重要的编程实践它能有效防止系统因为某些操作卡住而导致资源耗尽。 ctx, cancel : context.WithTimeout(context.Background(), 2*time.Second) defer cancel()创建一个新的上下文它会在2秒后自动超时。同时返回一个cancel函数可以手动取消这个上下文。defer cancel() 确保无论函数如何返回都会调用cancel函数释放资源。 打个比方假设我们去餐厅点餐如果没有超时控制 你告诉服务员我要一份牛排然后一直等不管厨房是否忙碌、是否缺货你可能会一直等下去。 有超时控制 你告诉服务员我要一份牛排但我只能等15分钟。如果15分钟内上菜了太好了如果没有你就可以取消订单离开不用无限期等待。 如果没有超时控制当目标节点宕机或网络异常时请求可能会一直阻塞有了2秒的超时控制即使目标节点无响应最多也只会等待2秒就返回错误。
http://www.pierceye.com/news/638275/

相关文章:

  • 网站开发学习步骤网站开发合同要注意哪些
  • 制作网站要花多少钱如何装饰设计公司哪个好
  • vue做网站的优缺点番禺最新发布
  • 免费模板素材网站有哪些免费中文网站模板html
  • 本地建设多个网站链接平安保险网站
  • wordpress安装主题后无法查看媒体seo内容优化
  • 广告在线制作图片外贸推广建站蓝颜seo牛
  • 成都网站创建wordpress 未找到
  • 网站seo链接购买长宁广州网站建设
  • 网站分类导航代码wordpress笔记主题
  • 网站常用代码阿里云 全国网站建设
  • 盗取dede系统做的网站模板深圳建设工程信息网站
  • 百度SEO网站江门网站建设公司哪家好
  • 成都网站建设 四川冠辰科技php响应式网站
  • 大连网站建设辽icp备阿里云 网站
  • 网站开发前期准备做网站渠道
  • 网站根目录是哪里没有面板的服务器怎么建设网站
  • 济南市住房城乡建设网无锡优化网站公司
  • 公司网站设计好河南比较出名的外贸公司
  • 清除网站黑链湖州市住房和城乡建设局官方网站
  • 凡科网的网站建设好用吗网站开发过程的数据交互
  • 郑州做商城网站公司开发微信小程序流程
  • 宝安电子厂做网站外包app开发多少钱
  • 箱包 东莞网站建设公司网站建设与设计制作
  • 网站如何做点击链接地址直播平台排行榜前十名
  • 万网域名指向网站wordpress 下载媒体库
  • 小店网站制作php做的网站首页是什么文件
  • i深建官方网站淮南网络营销哪家强
  • 网上网站怎么做织梦网站模块
  • 怎么新建自己的网站百度广告推广费用