聊天室项目开发——etcd的安装和使用

1.etcd的安装

这里也是比较简单我就直接放步骤了,一般是没有问题的,如果有问题欢迎在评论区指出

bash 复制代码
sudo apt-get install etcd   //安装etcd
sudo systemctl start etcd   //启动etcd服务
sudo systemctl enable etcd  //设置etcd开机自启动

2.介绍etcd讲解一些有关etcd的概念

2.1 介绍etcd

Etcd 是一个 golang 编写的分布式、高可用的一致性键值存储系统,用于配置共享和服 务发现等。它使用 Raft 一致性算法来保持集群数据的一致性,且客户端通过长连接 watch 功能,能够及时收到数据变化通知,相较于 Zookeeper 框架更加轻量化。

扯了半天其实我们可以把etcd理解为一个 redis,置于为什么可以这么理解就要看我后面的讲解了。

2.2 etcd的一些概念

这里我先讲讲etcd是怎么进行使用的,首先我们得有一个能提供服务的服务端,然后在服务端向etcd server注册自己的信息,包括地址(ip和端口)和服务名称,在注册前我们需要先向etcd server申请一个租约(这个概念我后面讲)。

我们还要有一个需要访问我们服务端的客户端,在这个客户端一开始肯定是不知道我们服务的地址的,但是我们可以通过etcd的ls接口获取所有已经在etcd注册的服务,接着我们就可以通过服务的名称来获取我们需要服务的地址,进而进行访问。在客户端我们还可以通过定义监控对象,来感知服务的上下线。

上面提到的租约类似redis中数据的有效时间,一旦服务下线那么等待租约的时间一过,那么etcd就会通过回调函数通知监控对象有哪些服务下线,,但并不是说服务没有下线租约就没有作用,在服务正常的时候租约会每隔一段时间向etcd服务器发送信息,告诉etcd服务器我这个服务还在。

3.etcd的使用

服务发现测试程序

cpp 复制代码
//discoverer.cc
#include <etcd/Client.hpp>
#include <etcd/Watcher.hpp>

void watcherCallback(etcd::Response const &resp)
{
    if (resp.error_code())
    {
        std::cout << "Watcher Error:" << resp.error_code();
        std::cout << "-" << resp.error_message() << std::endl;
    }
    else
    {
        for(auto const &ev:resp.events())
        if (ev.event_type() == etcd::Event::EventType::PUT)
        {
            // 如果是新增值,则通过当前值来查看新增的是什么值
            std::cout << "服务" << ev.kv().key() << "新增主机:";
            std::cout << ev.kv().as_string() << std::endl;
        }
        else if (ev.event_type() == etcd::Event::EventType::DELETE_)
        {
            // 如果是值被删除,则需要通过发生事件之前的值来了解哪个值被删除了
            std::cout << "服务" << ev.kv().key() << "下线主机:";
            std::cout<< ev.prev_kv().as_string() << std::endl;
        }
    }
}


int main()
{
    std::string registry_host = "http://127.0.0.1:2379";
    std::string service_key = "/service/user/";

    etcd::Client etcd(registry_host);      
    // 初次先用 ls 获取所有能够提供指定服务的实例信息
    etcd::Response resp = etcd.ls(service_key).get();
    if (resp.is_ok())
    {
        for (int i = 0; i < resp.keys().size(); i++)
        {
            std::cout << resp.key(i) << "=" << resp.value(i).as_string() << std::endl;
        }
    }
    else std::cout << "Get Service Error:" << resp.error_code();
    std::cout << "-" << resp.error_message() << std::endl;
    // 获取之后,然后定义监控对象,监控目录内容变化,通过目录变化来感知服务的上线与下线
    etcd::Watcher watcher(registry_host, service_key, watcherCallback, true);
    getchar();
    watcher.Cancel();
    return 0;
}

服务注册程序

cpp 复制代码
//registry.cc
#include <etcd/Client.hpp>
#include <etcd/Response.hpp>
#include <etcd/KeepAlive.hpp>
#include <thread>


int main()
{
    std::string registry_host = "http://127.0.0.1:2379";
    //为了防止多主机注册相同服务时,信息覆盖,因此每个主机在服务名后加入自己的实例名称,相当于各有各的服务-主机键值对
    std::string service_key = "/service/user/instance";
    std::string service_host = "112.23.23.120:9090";
     std::string service_key2 = "/service/user/test";
    std::string service_host2 = "112.23.23.120:9091";
    etcd::Client etcd(registry_host);     //可以理解为连接服务器

        //对客户端创建一个指定时长的租约,若租约到期则创建的键值将被撤销
        //通过租约进行保活探测,若服务提供端掉线,则租约到期后etcd会给服务发现者发送服务下线通知
        // etcd::Response resp = etcd.leasegrant(3).get();   //设置一个3s的租约
        // auto lease_id = resp.value().lease();   //获取租约ID

    //创建客户端的同时,创建一个保活的3s租约 保活对象 -- 也就是一旦断开连接,3s租约失效
    std::shared_ptr<etcd::KeepAlive> keepalive = etcd.leasekeepalive(3).get();
    auto lease_id = keepalive->Lease();
    std::shared_ptr<etcd::KeepAlive> keepalive2 = etcd.leasekeepalive(10).get();
    auto lease_id2 = keepalive2->Lease();
    auto resp_task = etcd.put(service_key,service_host,lease_id);  //注册服务
    auto resp_task2 = etcd.put(service_key2,service_host2,lease_id2);  //注册服务
    auto resp = resp_task.get();
    if(resp.is_ok() == false)
    {
        std::cout << resp.error_message() << std::endl;
        return -1;
    }
    std::cout << "添加数据成功!" << std::endl;
    getchar();//回车后撤销租约
    // //租约的撤销
    etcd.leaserevoke(lease_id);
    return 0;
}

make文件

cpp 复制代码
all: registry discoverer
registry: registry.cc
    g++ -std=c++17 $^ -o $@ -letcd-cpp-api -lcpprest
discoverer: discoverer.cc
    g++ -std=c++17 $^ -o $@ -letcd-cpp-api -lcpprest
clean:
    rm -rf registry discoverer
相关推荐
siriuuus2 小时前
Linux Tomcat 简单使用及 Nginx 反向代理
linux·nginx·tomcat
new coder3 小时前
[c++语法学习]Day10:c++引用
开发语言·c++·学习
呱呱巨基3 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
哼?~4 小时前
C++11标准 上 (万字解析)
开发语言·c++
竹等寒4 小时前
Linux-网络安全私房菜(二)
linux·服务器·web安全
YuCaiH4 小时前
Linux文件处理
linux·笔记·嵌入式
给大佬递杯卡布奇诺4 小时前
FFmpeg 基本API avformat_alloc_context 函数内部调用流程分析
c++·ffmpeg·音视频
早睡冠军候选人4 小时前
Ansible学习----Ansible Playbook
运维·服务器·学习·云原生·容器·ansible
sulikey4 小时前
从实验出发深入理解Linux目录权限:r、w、x分别控制什么?能否进入目录到底由谁决定?
linux·运维·服务器·ubuntu·centos