项目组件框架介绍[etcd]

文章目录

  • 前言
  • etcd安装
    • Ubuntu 上通过包管理器安装
    • 通过源码安装
    • 配置
  • 客户端开发包
    • 开发包的安装
    • 接口介绍
      • 添加一个键值对
      • 获取一个键值对
      • 租约保活机制
      • 监听
  • 封装服务注册与发现
    • 服务注册
    • 服务发现


前言

    Etcd 是一个 golang 编写的分布式、高可用的一致性键值存储系统,用于配置共享和服务发现等

etcd安装

Ubuntu 上通过包管理器安装

# 直接安装
sudo apt-get install etcd
# 启动
sudo systemctl start etcd
# 设置开机自启
sudo systemctl enable etcd

验证安装

$ etcd --version
etcd Version: 3.2.26
Git SHA: Not provided (use ./build instead of go build)
Go Version: go1.13.8
Go OS/Arch: linux/amd64

可见已经安装成功

通过源码安装

    etcd是使用Go语言编写的, 根据官网描述的教程, 需要Go1.2+的版本

# 克隆仓库
$ git clone -b v3.5.16 https://github.com/etcd-io/etcd.git
$ cd etcd
# 运行构建脚本:
$ ./build.sh
# 二进制文件位于 directory/bin
# 设置环境变量, 假如你的二进制文件位于/bin
$ export PATH="$PATH:`pwd`/bin"
# 验证安装
$ etcd --version

配置

    默认 etcd 的集群节点通信端口为 2380, 客户端访问端口为 2379, 如果需要更改可以修改/etc/default/etcd文件
修改配置

客户端开发包

开发包的安装

    官方只维护了 go 语言版本的 client 库, 因此需要使用 C/C++ 非官方的 client 开发库, etcd-cpp-apiv3是一个不错的选择, etcd-cpp-apiv3 是一个 etcd 的 C++版本客户端 API。它依赖于 mipsasm, boost, protobuf, gRPC, cpprestsdk 等库
所有首先需要安装依赖

# 建议先看看是否已经用其他方式安装这些, 否则出现版本冲突问题很难受
# 比如up就在项目中途把protobuf版本更新了, 就导致所有依赖protobuf编译安装的第三方库都用不了
# 比如这个, brpc等等都用不了,最后重新编译安装了它们才解决, 还出现了莫名其妙的库找不到的问题
sudo apt-get install libboost-all-dev libssl-dev
sudo apt-get install libprotobuf-dev protobuf-compiler-grpc
sudo apt-get install libgrpc-dev libgrpc++-dev 
sudo apt-get install libcpprest-dev

使用源码安装即可

git clone https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3.git
cd etcd-cpp-apiv3
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
make -j$(nproc) && sudo make install

接口介绍

    项目中主要使用etcd进行服务注册和发现, 我们重点介绍这些接口, 其他介绍可参考官方介绍

添加一个键值对

#include<etcd/Client.hpp>//构造一个etcd::Client 对象, 用etcd服务端的url构造
etcd::Client etcd("http://127.0.0.1:2379");
//使用put方法添加一个键值对, etcd.put() 方法是非阻塞的,返回一个异步任务pplx::task
pplx::task<etcd::Response> response_task = etcd.put("/test/1", "111");
// 等待异步任务完成并获取结果
try 
{etcd::Response response = response_task.get();if (response.is_ok()) {std::cout << "Put: " << response.key() << " : " << response.value() << std::endl;} else {std::cerr << "Error: " << response.error_message() << std::endl;}
} 
catch (const std::exception &e) 
{std::cerr << e.what() << std::endl;
}

获取一个键值对

etcd::Client etcd("http://127.0.0.1:2379");
//使用get方法获取一个键值对, 这个也是非阻塞的, 返回一个异步任务
pplx::task<etcd::Response> response_task = etcd.get("/test/1");
try
{etcd::Response response = response_task.get();if (response.is_ok()){std::cout << "获取成功" << response.value().as_string();}else{std::cout << "获取失败: " << response.error_message();}
}
catch (std::exception const & ex)
{std::cerr << ex.what() <<std::endl;
}

租约保活机制

    在项目中我们需要监控一个服务的在线情况, 如果异常退出, 有时候就不能很好的检测到, etcd提供了租约保活机制, 服务如果没有续约, 就可以认为该服务已下线

    etcd::Client etcd("http://127.0.0.1:2379");//获取一个三秒的租约保活对象 std::shared_ptr<etcd::KeepAlive> keep(etcd.leasekeepalive(3).get());//获取租约IDint64 lease_id=keep->Lease();etcd.put("/test/2", "222",lease_id);

监听

    项目中需要对服务的上线与下线进行监控, 再结合其他组件, 比如bprc, 就可通过这个服务获取相对应的通信对象

    //构造一个监控对象, 第二个参数可以是一个目录, 比如/test, 那么就会监控/test下比如/test/1 /test/2, 第三个是一个回调函数, 当被监控的对象发送改变时就会触发回调etcd::Watcher watcher("http://127.0.0.1:2379", "/test", CallBack);//etcd::Response是一个容器, 可以通过遍历的方式获取, 比如void CallBack(const etcd::Response& re){if(!re.is_ok()){LOG_ROOT_ERROR<<re.error_message();return;}for(const auto& ev: re.events()){//通过etcd::EVent::EventType 可得知具体情况if(ev.event_type()==etcd::Event::EventType::PUT){LOG_ROOT_INFO<<"新增服务: "<<ev.kv().key()<<" : "<<ev.kv().as_string();}if(ev.event_type()==etcd::Event::EventType::DELETE_){LOG_ROOT_INFO<<"服务下线: "<<ev.prev_kv().key()<<" : "<<ev.prev_kv().as_string();}}}

封装服务注册与发现

    有了上面了了解, 我们就能完成一个简单的服务注册与发现模块

服务注册

#include<etcd/Client.hpp>
#include<etcd/KeepAlive.hpp>
#include<etcd/Response.hpp>
#include<etcd/Value.hpp>
#include<etcd/Watcher.hpp>
#include"log.hpp"
namespace MindbniM
{class Registry{public:using ptr=std::shared_ptr<Registry>;//这里默认使用3秒保活了, 也可以手动传入Registry(const std::string& host):_client(std::make_unique<etcd::Client>(host)),_ka(_client->leasekeepalive(3).get()),_lease_id(_ka->Lease()){}bool registry(const std::string& key,const std::string& value){etcd::Response re=_client->put(key,value,_lease_id).get();if(!re.is_ok()){LOG_ROOT_ERROR<<"服务注册失败"<<":"<<re.error_message();return false;}LOG_ROOT_DEBUG<<"服务注册:"<<key<<" : "<<value;return true;}private:std::unique_ptr<etcd::Client> _client;std::shared_ptr<etcd::KeepAlive> _ka;int64_t _lease_id;};
}

服务发现

    为了和其他组件相互结合, 我们设置两个回调, 分别对应服务上线与下线的操作

#include<etcd/Client.hpp>
#include<etcd/Response.hpp>
#include<etcd/Value.hpp>
#include<etcd/Watcher.hpp>
#include"log.hpp"
namespace MindbniM
{class Discovery{public:using ptr=std::shared_ptr<Discovery>;//对应key和valueusing CallBack=std::function<void(const std::string&,const std::string&)>;Discovery(const std::string& host,const CallBack& put=nullptr,const CallBack& del=nullptr):_client(std::make_unique<etcd::Client>(host)),_put(put),_del(del){}bool discover(const std::string& dir){etcd::Response re=_client->ls(dir).get();if(!re.is_ok()){LOG_ROOT_ERROR<<"服务发现错误"<<re.error_message();return false;}int n=re.keys().size();if(_put!=nullptr){for(int i=0;i<n;i++){_put(re.key(i),re.value(i).as_string());}}//开始监听_watch=std::make_unique<etcd::Watcher>(*_client,dir,std::bind(&Discovery::_CallBack,this,std::placeholders::_1),true);return true;}bool wait(){return _watch->Wait();}private:void _CallBack(const etcd::Response& re){if(!re.is_ok()){LOG_ROOT_ERROR<<re.error_message();return;}for(const auto& ev: re.events()){if(ev.event_type()==etcd::Event::EventType::PUT){if(_put) _put(ev.kv().key(),ev.kv().as_string());LOG_ROOT_INFO<<"新增服务: "<<ev.kv().key()<<" : "<<ev.kv().as_string();}if(ev.event_type()==etcd::Event::EventType::DELETE_){if(_del) _del(ev.prev_kv().key(),ev.prev_ky().as_string());LOG_ROOT_INFO<<"服务下线: "<<ev.prev_kv().key()<<" : "<<ev.prev_kv().as_string();}}}CallBack _put;CallBack _del;std::unique_ptr<etcd::Client> _client;std::unique_ptr<etcd::Watcher> _watch;};
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Windows 10中使用SSH远程连接服务器(附花生壳操作方法)

SSH 在 linux 中是一种重要的系统组件&#xff0c;用户可以使用 SSH 来远程连接 linux 系统的计算机&#xff0c;或者传输文件。不过在 win10 以前&#xff0c;windows 并不原生支持 SSH&#xff0c;需要借助第三方工具来使用 SSH 功能。而实际上&#xff0c;微软在 2015 年就曾…

【环境搭建】Jeecg-Boot v3.5.0 Docker搭建

前言 最近需要复现JeecgBoot的SQL注入漏洞&#xff0c;必须要搭建JeecgBoot v3.5.0这个版本才行&#xff0c;DockerHub没人push这个版本的&#xff0c;相关博客也比较少&#xff0c;所以自己来搭建&#xff0c;记录一下过程。 前置环境 Ubuntu 20.04Docker version 27.3.1do…

【人工智能基础06】人工神经网络(练习题):神经网络的计算、激活函数的选择与神经网络的退化

文章目录 1. 基于神经网络计算心理健康程度2. 添加激活函数的神经网络计算3. 使用神经网络预测小胖是否会变胖4. 激活函数选择的讨论5. 神经网络的设计6. 深度线性模型的表达能力线性模型7. 神经网络退化 主要讨论的内容 什么是人工神经网络&#xff0c;相关计算反向传播算法的…

STM32 串口收发文本数据包

单片机学习&#xff01; 目录 前言 一、文本数据包格式 二、串口收发文本数据包代码 三、代码解析 3.1 标志位清除 3.2 数据包接收 四、代码问题改进 总结 前言 本文介绍了串口收发文本数据包程序设计的思路并详解代码作用。 一、文本数据包格式 文本数据包的格式的定义…

预言机调研

预言机 1. 概述 预言机主要承担两个工作&#xff0c;一是验证信息可靠性&#xff0c;二是传递信息。 如果没有预言机&#xff0c;区块链的信息来源将仅限于其内部数据&#xff0c;其广泛使用的潜力和可能性将会大大降低。 区块链预言机是区块链与外部世界之间的桥梁。它们使区…

【1211更新】腾讯混元Hunyuan3D-1文/图生3D模型云端镜像一键运行

目录 项目介绍 显存占用 11月21 新增纹理烘焙模块Dust3R 烘焙相关参数&#xff1a; AutoDL云端镜像 启动说明 标准模型下载 项目介绍 https://github.com/Tencent/Hunyuan3D-1 腾讯混元 3D 生成模型,支持文本和图像条件生成(对于文生3D&#xff0c;支持中/英双语生成)…

【前端】HTML标签汇总

目录 展示用户信息的标签 1.文本标签 span 2.标题标签 h1~h6 3.竖着布局的标签 div 4.段落标签 p 5.超链接标签 a 5.1跳转至网上的资源 5.2锚点 6.列表标签 6.1有序列表 ol 6.2无序列表 ul 7.图片标签 img 7.1相对路径 7.1.1兄弟关系 7.1.2叔侄关系 7.1.3表兄弟…

今天你学C++了吗?——C++中的类与对象(日期类的实现)——实践与知识的碰撞❤

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…

负载均衡和tomcat

一、负载均衡 1.相关概念 nginx的反向代理<-->负载均衡 负载均衡 将四层或者是七层的请求分配到多台后端的服务器上&#xff0c;从而分担整个业务的负载。提高系统的稳定性&#xff0c;也可以提供高可用&#xff08;备灾&#xff0c;其中的一台后端服务器如果发生故障…

【蓝桥杯每日一题】推导部分和——带权并查集

推导部分和 2024-12-11 蓝桥杯每日一题 推导部分和 带权并查集 题目大意 对于一个长度为 ( N ) 的整数数列 ( A 1 , A 2 , ⋯ , A N A_1, A_2, \cdots, A_N A1​,A2​,⋯,AN​ )&#xff0c;小蓝想知道下标 ( l ) 到 ( r ) 的部分和 ∑ i l r A i A l A l 1 ⋯ A r \su…

【C++】判断能否被 3, 5, 7 整除问题解析与优化

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;老师代码实现与分析老师代码逻辑分析优点缺点 &#x1f4af;学生代码实现与分析学生代码逻辑分析优点缺点 &#x1f4af;改进与优化优化代码实现优化…

[计算机网络]IP地址推行的“书同文,车同轨”

硬件地址无法直接转换的故事 在很久很久以前&#xff0c;网络世界就像一个庞大的帝国&#xff0c;各个村落&#xff08;网络&#xff09;都有自己的语言&#xff08;硬件地址&#xff09;。每个村落都有自己的规则和习惯&#xff0c;村里的每户人家&#xff08;设备&#xff0…

深度优先搜索(DFS)与回溯法:从全排列到子集问题的决策树与剪枝优化

文章目录 前言&#x1f384;一、全排列✨核心思路✨实现步骤✨代码✨时间和空间复杂度&#x1f381;1. 时间复杂度&#x1f381;2. 空间复杂度 &#x1f384;二、子集✨解法一&#xff1a;逐位置决策法&#x1f381;步骤分析&#x1f381;运行示例&#x1f381;代码 ✨解法二&a…

egg初始搭建

前言 egg.js 是由阿里开源的面向企业级开发的 Node.js 服务端框架&#xff0c;它的底层是由 Koa2 搭建。 Github&#xff1a;https://github.com/eggjs/egg&#xff0c;目前 14.8K Star&#xff0c;egg 很适合做中台。 安装 首先&#xff0c;你要 确保 Node 已经配置环境变量…

Python中的all/any函数和操作符and/or

操作符直观易读适用简单逻辑&#xff0c;函数紧凑方便适宜多条件处理。 (笔记模板由python脚本于2024年12月12日 22:19:10创建&#xff0c;本篇笔记适合有一定编程基础的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff…

论文学习——多种变化环境下基于多种群进化的动态约束多目标优化

论文题目&#xff1a;Multipopulation Evolution-Based Dynamic Constrained Multiobjective Optimization Under Diverse Changing Environments 多种变化环境下基于多种群进化的动态约束多目标优化&#xff08;Qingda Chen , Member, IEEE, Jinliang Ding , Senior Member, …

2025年山东省职业院校技能大赛“信息安全管理与评估”(山东省) 任务书

2025年山东省职业院校技能大赛“信息安全管理与评估”(山东省 任务书 模块一网络平台搭建与设备安全防护任务1&#xff1a;网络平台搭建 &#xff08;50分&#xff09;任务2&#xff1a;网络安全设备配置与防护&#xff08;250分&#xff09; 模块二网络安全事件响应、数字取证…

国标GB28181-2022平台EasyGBS如何实现无插件也能让RTSP在网页端播放?

在流媒体技术日新月异的今天&#xff0c;实时流传输协议&#xff08;RTSP&#xff09;作为视频监控、在线直播等领域的重要支撑&#xff0c;正经历着前所未有的变革。曾经&#xff0c;RTSP在网页端播放面临着诸多挑战&#xff0c;如浏览器兼容性问题、安全性考量以及视频流处理…

EXCEL 关于plot 折线图--频度折线图的一些细节

目录 0 折线图有很多 1 频度折线图 1.1 直接用原始数据做的频度折线图 2 将原始数据生成数据透视表 3 这样可以做出了&#xff0c;频度plot 4 做按某字段汇总&#xff0c;成为累计plot分布 5 修改上面显示效果&#xff0c;做成百分比累计plot频度分布 0 折线图有很多 这…

MATLAB四种逻辑运算

MATLAB中的四种逻辑运算包括逻辑与用&或 a n d 表示 ( 全为 1 时才为 1 &#xff0c;否则为 0 ) and表示(全为1时才为1&#xff0c;否则为0) and表示(全为1时才为1&#xff0c;否则为0)&#xff0c;逻辑或用|或 o r 表示 ( 有 1 就为 1 &#xff0c;都为 0 才为 0 ) or表示…