【项目总结】c++与go语言基于HTTP 协议的服务注册中心【c++与golang】


前言

服务注册中心是一种用于实现微服务架构的基础设施,用于管理和维护服务的注册、发现、负载均衡等功能。它可以让不同的服务通过一个中心化的方式进行管理,降低了服务之间的耦合性,提高了服务之间的可扩展性和可维护性。使用HTTP通信可以简化注册中心的实现,因为HTTP是一种开放的、标准的协议,很容易被不同的语言和框架支持。自定义Header字段可以传递更多信息,扩展性非常强,可以根据不同的需求设计不同的字段。此外,使用HTTP通信也具有较好的跨平台和跨语言特性,使得不同的服务可以在不同的服务器上运行,提高了应用的可移植性和灵活性。
使用HTTP协议实现服务注册中心具有以下优点:
通用性强:HTTP协议是广泛应用的标准协议,简单易用,可以跨平台、跨语言使用。
易于部署和管理:基于HTTP协议的服务注册中心可以很方便地部署在云端或本地服务器上,并通过监控和管理工具来维护和管理服务。
支持多种传输协议:服务注册中心可以支持多种传输协议,包括HTTP、gRPC等,从而满足不同场景下的需求。

在这里插入图片描述
go语言的基于HTTP 协议的服务注册中心实现已经在之前的文章实现了。
go语言实现的rpc框架
本文章用c++语言实现注册中心,利用go语言作为服务注册者,c++语言最为服务发现者,实现的功能有服务注册,服务发现,心跳机制以及负载均衡。

一、注册中心整体框架

服务注册者可以向注册中心注册服务发送心跳获取可用的服务地址并注销服务。其中,注册和注销操作会修改 ServerList 中的数据,而获取服务地址则只是读取该数据。同时,由于多个线程可能同时访问 ServerList,因此该程序使用了互斥锁来保证数据的安全性。HTTP服务使用httplib库来实现。

1、成员变量以及单例模式

注册中心类Registry使用单例模式来保证只有一个 Registry 对象实例存在,用于管理服务的注册和发现。因为在多个地方需要使用该类时,如果每次都创建一个新的对象,则会导致数据不一致或者资源浪费的问题。
首先,包含了三个私有成员变量 ServerList、ServerFreMap、Mu 和Timeout。其中,ServerList 是一个类似于 Map 的容器,用于存储各个服务名称对应的服务器列表;ServerFreMap 也是一个 Map 类型的变量,用于记录每个服务被调用的次数;Mu 是一个互斥锁。Timeout表示服务超时时间,也就是服务经过这么久没有发送心跳就默认该服务以及宕机了。

  private:
   std::chrono::duration<int, std::milli> Timeout;
   std::mutex Mu;
   std::map<std::string, int> ServerFreMap;
   std::map<std::string, std::vector<ServerItem>> ServerList;
   SelectMode selectmodel;
   explicit Registry(std::chrono::duration<int, std::milli> timeout,
                     SelectMode model)
       : Timeout(timeout),
         selectmodel(model){
   
             // std::cout << "timeout:" << std::ctime(timeout) << std::endl;
         };

  public:
   // 获取 Registry 实例的静态方法
   static Registry& instance(std::chrono::duration<int, std::milli> timeout,
                             SelectMode model) {
   
      static Registry registry(timeout, model);  // 静态局部变量
      return registry;
   }

Instance() 方法返回一个静态的 Registry 对象实例。它定义了一个静态局部变量 instance,该变量在第一次调用 Instance() 方法时被创建,并且只被创建一次,之后每次调用 Instance() 方法都返回该静态变量的引用。

由于构造函数是私有的,所以无法通过外部创建 Registry 类的对象,从而保证只有一个 Registry 实例存在。同时,使用 delete 关键字禁止了拷贝构造函数和赋值运算符的使用,防止非预期的对象复制。

因此,该程序使用单例模式来确保只有一个 Registry 对象实例存在,从而避免了数据不一致或者资源浪费的问题。

2、服务列表的维护

接下来,程序实现了三个公共方法:
PutServer() 方法:用于将一个服务注册到注册中心。在该方法中,程序首先获取该服务对应的服务器列表,如果列表中已经存在相同 IP 地址的服务器,则更新其活跃时间;否则,将新服务器添加到列表中。最后,输出一条日志表示新服务器已经成功注册。


void Registry::PutServer(const std::string& serverName,
                         const std::shared_ptr<ServerItem>& serverItem) {
   
   std::lock_guard<std::mutex> lock(Mu);
   auto& serverList = ServerList[serverName];
   for (auto& item : serverList) {
   
      if (item.Addr == serverItem->Addr) {
   
         item.ActiveTime =
             std::chrono::system_clock::now();  // if exists, update start time
                                                // to keep alive
         return;
      }
   }
   serverItem->ActiveTime =
       std::chrono::system_clock::now();  // if exists, update start time
                                          // to keep alive
   std::cout << "##############server Regist############## " << std::endl;
   std::cout << serverItem->Name << ":" << serverItem->Addr << std::endl;
   serverList.push_back(*serverItem);
}

DestructServer() 方法:用于从注册中心删除某个服务对应的服务器。在该方法中,程序首先获取该服务对应的服务器列表,然后删除相应的服务器信息。如果该服务对应的服务器列表为空,则从 ServerList 中删除该服务。

void Registry::DestructServer(const std::string& serverName,
                              const std::string& addr) {
   
   std::cout << "##############server destruct############## " << std::endl;
   std::cout << serverName << ":" << addr << std::endl;

   auto& serverItemList = ServerList[serverName];
   for (auto it = serverItemList.begin(); it != serverItemList.end();) {
   
      if (it->Addr == addr) {
   
         it = serverItemList.erase(it);  // timeout, remove from server list
         if (serverItemList.empty()) {
   
            ServerList.erase(serverName);
         }
      
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值