c++使用ppconsul库实现Consul服务注册与发现集成

安装与配置consul服务端

安装

在这里我直接使用docker安装了,简单许多

docker pull consul

docker配置启动consul

#1.启动consul服务器
docker run --hostname consulsvul --name consul_node_1 -d -p 8500:8500 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect 2 -ui -bind=0.0.0.0 -client=0.0.0.0
#2.查看分配的ip地址
docker inspect --format '{{.NetworkSettings.IPAddress}}' consul_node_1
#3.启动另外两个节点,加入集群
docker run --hostname consulsvu2 --name consul_node_2 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 填写第二步显示分配的ip地址

docker run --hostname consulsvu3 --name consul_node_3 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 填写第二步显示分配的ip地址
#查看集群状态
docker exec -t consul_node_1 consul members

网页后台

浏览器打开即可

127.0.0.1:8500

这就是后台界面了,可以看见我们配置的集群的三个节点.由于我之前在主节点中注册了两个服务,但是没有做健康处理,所以这里主节点是红色的,你们应该都是绿色的.

image-20240304102613453

进入services服务界面,consul是自带的,显示的是集群中三个节点的健康状态,

signupService1是我测试代码产生的,等后续执行了我写的代码也会这样,由于consul有健康检测,需要定时给服务端发送健康心跳,所以超时后就会如图显示变成红色,表示不健康

image-20240304103702829

image-20240304104244743

使用c++ ppconsul库实现Consul集成

简介

Consul是一个用于服务发现、健康检查和动态配置的工具,使得分布式系统中的服务能够轻松地相互发现和通信。ppconsul是一个用于C++的库,为开发者提供了与Consul进行交互的简单而强大的接口。

安装

首先,你需要获取ppconsul库的源代码,并将其集成到你的C++项目中。你可以通过以下步骤来完成:

git clone https://github.com/oliora/ppconsul.git
cd ppconsul
mkdir build && cd build
cmake ..
make
sudo make install

确保你的系统上已经安装了CMakelibcurl,json11

头文件header-only

#include <ppconsul/consul.h>

链接

g++ ppconsul_test.cpp -o ppconsul -lppconsul -lcurl -ljson11#添加这个参数链接ppconsul

服务注册

让我们通过一个简单的示例来展示如何使用ppconsul进行服务注册和发现。

由于这里的定时提交健康服务的代码,我使用了workflow框架的定时器来编写的代码,读者可以将这部分的代码删除后学习,或者替换成其他的库

#include <ppconsul/consul.h>
#include "workflow/WFTaskFactory.h"
//维持节点健康
void timerCallback(WFTimertask* timerTask){
    ppconsul::agent::Agent *pagent = static_cast<ppconsul::agent::Agent*>(timerTask->user_data);
    pagent->servicePass("SignupServicel");
    auto nextTask = WFTaskFactory::create_timer_task(5000000,timerCallback);
    nextTask->user = pagent;
    service_of(timerTask)->push_back(nextTask);
}

int main()
{
    //将本服务注册到consul之中
    //找到dc1注册中心
    ppconsul::Consul consul("127.0.0.1:8500",ppconsul::kw::dc = "dc1");
    //创建一个用来访问注册中心的agent
    ppconsul::agent::Agent agent(consul);
    agent.reisterService(
    	ppconsul::agent::kw::name = "SignupServicel",
        ppconsul::agent::kw::address = "127.0.0.1",
        ppconsul::agent::kw::id = "SignupServicel",
        ppconsul::agent::kw::port = 1412,
        ppconsul::agent::kw::check = ppconsul::agent::Ttlcheck{std::chrono::seconds(10)}
   	);
    agent.servicePass("SignupServicel");//设置健康服务(心跳)
    auto timerTask = WFTaskFactory::create_timer_task(5,timerCallback);
    timerTask->user_data = &agent;
    timerTask->start();
}

服务发现

服务发现作为客户端,我们可以直接使用http访问,在解析返回的json

我在consul中注册了一个名为SignupServicel的服务,其下有SignupServicel和SignupService2(在之前的代码执行后再将ppconsul::agent::kw::id =xxx这一行改为SignupService2即可和我一致)

查看所有的服务

http://127.0.0.1:8500/v1/agent/services

{
    "signupService1": {
        "ID": "signupService1",
        "Service": "signupService1",
        "Tags": [],
        "Meta": {},
        "Port": 1412,
        "Address": "127.0.0.1",
        "TaggedAddresses": {
            "lan_ipv4": {
                "Address": "127.0.0.1",
                "Port": 1412
            },
            "wan_ipv4": {
                "Address": "127.0.0.1",
                "Port": 1412
            }
        },
        "Weights": {
            "Passing": 1,
            "Warning": 1
        },
        "EnableTagOverride": false,
        "Datacenter": "dc1"
    },
    "signupService2": {
        "ID": "signupService2",
        "Service": "signupService1",
        "Tags": [],
        "Meta": {},
        "Port": 1412,
        "Address": "127.0.0.1",
        "TaggedAddresses": {
            "lan_ipv4": {
                "Address": "127.0.0.1",
                "Port": 1412
            },
            "wan_ipv4": {
                "Address": "127.0.0.1",
                "Port": 1412
            }
        },
        "Weights": {
            "Passing": 1,
            "Warning": 1
        },
        "EnableTagOverride": false,
        "Datacenter": "dc1"
    }
}

查看指定的服务

http://127.0.0.1::8500/v1/agent/service/signupService1

{
    "ID": "signupService1",
    "Service": "signupService1",
    "Tags": [],
    "Meta": {},
    "Port": 1412,
    "Address": "127.0.0.1",
    "TaggedAddresses": {
        "lan_ipv4": {
            "Address": "127.0.0.1",
            "Port": 1412
        },
        "wan_ipv4": {
            "Address": "127.0.0.1",
            "Port": 1412
        }
    },
    "Weights": {
        "Passing": 1,
        "Warning": 1
    },
    "EnableTagOverride": false,
    "ContentHash": "1ff72835f53fe7d",
    "Datacenter": "dc1"
}

查看健康服务

http://127.0.0.1:8500/v1/health/service/signupService1

此时先执行代码使SignupService2处于健康状态,对比SignupServicel和SignupService2

可以看出json[0]是SignupServicel的信息,json[1]是SignupServicel的信息

由于我们事先让SignupService2处于健康状态,SignupServicel处于不健康状态

可以看见json[0][“Checks”][1]==critical,json[1][“Checks”][1]==passing

也就是说passing是健康的,critical是不健康的

[
    {
        "Node": {
            "ID": "41557981-708b-5e95-a80d-4a0ae866346b",
            "Node": "consulsvul",
            "Address": "172.17.0.2",
            "Datacenter": "dc1",
            "TaggedAddresses": {
                "lan": "172.17.0.2",
                "lan_ipv4": "172.17.0.2",
                "wan": "172.17.0.2",
                "wan_ipv4": "172.17.0.2"
            },
            "Meta": {
                "consul-network-segment": ""
            },
            "CreateIndex": 5,
            "ModifyIndex": 9
        },
        "Service": {
            "ID": "signupService1",
            "Service": "signupService1",
            "Tags": [],
            "Address": "127.0.0.1",
            "TaggedAddresses": {
                "lan_ipv4": {
                    "Address": "127.0.0.1",
                    "Port": 1412
                },
                "wan_ipv4": {
                    "Address": "127.0.0.1",
                    "Port": 1412
                }
            },
            "Meta": {},
            "Port": 1412,
            "Weights": {
                "Passing": 1,
                "Warning": 1
            },
            "EnableTagOverride": false,
            "Proxy": {
                "Mode": "",
                "MeshGateway": {},
                "Expose": {}
            },
            "Connect": {},
            "CreateIndex": 928,
            "ModifyIndex": 928
        },
        "Checks": [
            {
                "Node": "consulsvul",
                "CheckID": "serfHealth",
                "Name": "Serf Health Status",
                "Status": "passing",
                "Notes": "",
                "Output": "Agent alive and reachable",
                "ServiceID": "",
                "ServiceName": "",
                "ServiceTags": [],
                "Type": "",
                "Interval": "",
                "Timeout": "",
                "ExposedPort": 0,
                "Definition": {},
                "CreateIndex": 5,
                "ModifyIndex": 5
            },
            {
                "Node": "consulsvul",
                "CheckID": "service:signupService1",
                "Name": "Service 'signupService1' check",
                "Status": "critical",
                "Notes": "",
                "Output": "TTL expired",
                "ServiceID": "signupService1",
                "ServiceName": "signupService1",
                "ServiceTags": [],
                "Type": "ttl",
                "Interval": "",
                "Timeout": "",
                "ExposedPort": 0,
                "Definition": {},
                "CreateIndex": 928,
                "ModifyIndex": 1172
            }
        ]
    },
    {
        "Node": {
            "ID": "41557981-708b-5e95-a80d-4a0ae866346b",
            "Node": "consulsvul",
            "Address": "172.17.0.2",
            "Datacenter": "dc1",
            "TaggedAddresses": {
                "lan": "172.17.0.2",
                "lan_ipv4": "172.17.0.2",
                "wan": "172.17.0.2",
                "wan_ipv4": "172.17.0.2"
            },
            "Meta": {
                "consul-network-segment": ""
            },
            "CreateIndex": 5,
            "ModifyIndex": 9
        },
        "Service": {
            "ID": "signupService2",
            "Service": "signupService1",
            "Tags": [],
            "Address": "127.0.0.1",
            "TaggedAddresses": {
                "lan_ipv4": {
                    "Address": "127.0.0.1",
                    "Port": 1412
                },
                "wan_ipv4": {
                    "Address": "127.0.0.1",
                    "Port": 1412
                }
            },
            "Meta": {},
            "Port": 1412,
            "Weights": {
                "Passing": 1,
                "Warning": 1
            },
            "EnableTagOverride": false,
            "Proxy": {
                "Mode": "",
                "MeshGateway": {},
                "Expose": {}
            },
            "Connect": {},
            "CreateIndex": 1167,
            "ModifyIndex": 1167
        },
        "Checks": [
            {
                "Node": "consulsvul",
                "CheckID": "serfHealth",
                "Name": "Serf Health Status",
                "Status": "passing",
                "Notes": "",
                "Output": "Agent alive and reachable",
                "ServiceID": "",
                "ServiceName": "",
                "ServiceTags": [],
                "Type": "",
                "Interval": "",
                "Timeout": "",
                "ExposedPort": 0,
                "Definition": {},
                "CreateIndex": 5,
                "ModifyIndex": 5
            },
            {
                "Node": "consulsvul",
                "CheckID": "service:signupService2",
                "Name": "Service 'signupService1' check",
                "Status": "passing",
                "Notes": "",
                "Output": "",
                "ServiceID": "signupService2",
                "ServiceName": "signupService1",
                "ServiceTags": [],
                "Type": "ttl",
                "Interval": "",
                "Timeout": "",
                "ExposedPort": 0,
                "Definition": {},
                "CreateIndex": 1167,
                "ModifyIndex": 9231
            }
        ]
    }
]

使用consul kv存储

consul的kv存储可以用来编写配置文件,程序启动后从kv存储中读取配置信息在进行配置,可以进行集中配置管理,一般使用json格式

#include "ppconsul/kv.h"

using ppconsul::Consul;
using ppconsul::Consistency;
using namespace ppconsul::kv;

int main(){
    Consul consul("127.0.0.1:8500",ppconsul::kw::dc="dc1");

    Kv kv(consul);

    // 设置一个key-value
    kv.set("settings.something", "new-value");


    // 从存储器中读取键的值
    std::string something = kv.get("settings.something", "default-value");
    std::cout << something << std::endl;

    // 从consul kv存储中通过key删除
    kv.erase("settings.something");
    return 0;
}
root@VM-16-3-ubuntu:~/projects/test# g++ consul.cpp -o consul -lppconsul -lcurl -ljson11
root@VM-16-3-ubuntu:~/projects/test# ./consul 
new-value

也可以在后台管理界面直接编写,点击右边的create按钮即可

image-20240304113941140

高级功能

ppconsul库不仅仅局限于服务注册和发现,它还提供了许多其他功能,如健康检查、KV存储等。你可以根据自己的需求深入了解和使用这些高级功能。

结论

ppconsul是一个强大而灵活的C++库,用于简化与Consul的集成。通过它,你可以轻松地在你的应用程序中实现服务发现、健康检查等功能,使得你的分布式系统更加强大和可靠。

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@马云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值