服务注册发现

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

你需要在项目的根路径下创建一个 polaris.yaml 文件用于初始化 polaris-cpp SDK。polaris.yaml配置详细

服务注册

SDK实例构建

当初始化好 polaris.yaml 文件之后,你可以直接使用 include polaris/provider.h, 使用polaris::ProviderApi::CreateWithDefaultFile() 方法进行构造一个 ProviderAPI SDK 实例

  1. #include "polaris/provider.h"
  2. int main(int argc, char** argv) {
  3. provider_ = std::unique_ptr<polaris::ProviderApi>(polaris::ProviderApi::CreateWithDefaultFile());
  4. }

注册请求体

  1. // 服务实例注册请求
  2. // 用于向指定命令空间的服务注册服务实例。必须拥有服务token才能进行服务实例注册。
  3. // 服务实例注册成功后,其他服务调用服务发现接口能发现该服务实例,可能会立即向该服务实例发送请求。
  4. // @note 所以必须在服务实例启动完成后才去进行服务注册。
  5. class InstanceRegisterRequest : Noncopyable {
  6. public:
  7. /// @brief 构造服务实例注册请求对象
  8. /// @param service_namespace 服务名所属命名空间
  9. /// @param service_name 服务名
  10. /// @param service_token 服务名对应的token
  11. /// @param host 服务实例监听地址
  12. /// @param port 服务实例监听端口
  13. InstanceRegisterRequest(const std::string& service_namespace, const std::string& service_name,
  14. const std::string& service_token, const std::string& host, int port);
  15. /// @brief 设置请求超时时间。可选,默认为SDK配置的API超时时间
  16. void SetTimeout(uint64_t timeout);
  17. /// @brief 设置服务实例的VPC ID。可选,默认为空
  18. void SetVpcId(const std::string& vpc_id);
  19. /// @brief 设置服务实例协议。可选,默认为空
  20. void SetProtocol(const std::string& protocol);
  21. /// @brief 设置服务实例权重。可选,默认为100
  22. void SetWeight(int weight);
  23. /// @brief 设置服务实例优先级。可选,置默认为0
  24. void SetPriority(int priority);
  25. /// @brief 设置服务实例版本信息。可选,默认为空
  26. void SetVersion(const std::string& version);
  27. /// @brief 设置服务实例的metada数据。可选,默认为空
  28. void SetMetadata(const std::map<std::string, std::string>& metadata);
  29. /// @brief 设置服务实例是否开启健康检查。可选,默认不开启
  30. void SetHealthCheckFlag(bool health_check_flag);
  31. /// @brief 设置健康检查类型。可选,默认为心跳健康检查
  32. void SetHealthCheckType(HealthCheckType health_check_type);
  33. /// @brief 设置心跳健康检查ttl,单位为s,不填默认为5s,
  34. /// 开启了心跳健康检查,客户端必须以TTL间隔上报心跳
  35. /// 健康检查服务器3个TTL未受到心跳则将实例置为不健康
  36. void SetTtl(int ttl);
  37. /// @brief 设置节点的位置信息。可选
  38. /// @param region 节点所在区域
  39. /// @param zone 节点所在城市
  40. /// @param campus 节点所在园区
  41. void SetLocation(const std::string& region, const std::string& zone, const std::string& campus);
  42. };

发起注册请求

你在初始化完 InstanceRegisterRequest 结构体后,需要调用 ProviderAPI.Register 方法完成实例注册, 如果实例开启了心跳上报,则还需要调用 heartbeat 方法定期上报实例心跳

  1. polaris::InstanceRegisterRequest register_req(service_namespace_, service_name_, service_token_, host_, port_);
  2. // 开启健康检查
  3. register_req.SetHealthCheckFlag(true);
  4. register_req.SetHealthCheckType(polaris::kHeartbeatHealthCheck);
  5. register_req.SetTtl(kHeartbeatTtl);
  6. // 注册实例
  7. auto ret_code = provider_->Register(register_req, instance_id_);
  8. if (ret_code != polaris::kReturnOk && ret_code != polaris::kReturnExistedResource) {
  9. std::cout << "register instance with error:" << polaris::ReturnCodeToMsg(ret_code).c_str() << std::endl;
  10. return ret_code;
  11. }
  12. // 启动心跳上报线程
  13. heartbeat_thread_ = std::unique_ptr<std::thread>(new std::thread([=] {
  14. while (!signal_received) { // 循环上报心跳
  15. polaris::InstanceHeartbeatRequest heartbeat_req(service_token_, instance_id_);
  16. auto ret_code = provider_->Heartbeat(heartbeat_req);
  17. if (ret_code != polaris::kReturnOk) {
  18. std::cout << "instance heartbeat with error:" << polaris::ReturnCodeToMsg(ret_code).c_str() << std::endl;
  19. sleep(1);
  20. continue;
  21. }
  22. sleep(kHeartbeatTtl);
  23. }
  24. }));

服务发现

SDK实例构建

当初始化好 polaris.yaml 文件之后,你可以直接使用 include polaris/consumer.h, 使用polaris::ConsumerApi::CreateWithDefaultFile() 方法进行构造一个 ConsumerApi SDK 实例

  1. #include "polaris/consumer.h"
  2. int main(int argc, char** argv) {
  3. consumer_ = std::unique_ptr<polaris::ConsumerApi>(polaris::ConsumerApi::CreateWithDefaultFile());
  4. }

发现服务实例

GetAllInstances

直接返回目标服务下的所有实例,包括不健康、隔离、权重为0、被熔断的实例,也会在返回的实例列表中。

  1. /// @brief 获取批量服务实例请求
  2. class GetInstancesRequest : Noncopyable {
  3. public:
  4. /// @brief 构造获取批量服务实例请求
  5. /// @param service_key 命名空间和服务名
  6. explicit GetInstancesRequest(const ServiceKey& service_key);
  7. };
  8. // 调用该方法执行请求
  9. consumer.GetAllInstances()

GetInstances

每次获取一批可用服务提供者实例,该方法会执行路由流程。

该方法默认会过滤掉不健康、隔离、权重为0、被熔断的实例。

说明:

执行路由流程的条件

  • 配置了 GetInstancesRequest.SourceService.Metadata 属性,会触发自定义路由流程
  • 设置了 GetInstancesRequest.Metadata 属性,会触发元数据路由流程
  1. /// @brief 获取批量服务实例请求
  2. class GetInstancesRequest : Noncopyable {
  3. public:
  4. /// @brief 构造获取批量服务实例请求
  5. /// @param service_key 命名空间和服务名
  6. explicit GetInstancesRequest(const ServiceKey& service_key);
  7. /// @brief 设置服务路由时否包含不健康的服务实例。可选,默认不包含
  8. /// @note 即使设置不包含的情况下仍然可能降级返回不健康实例
  9. void SetIncludeUnhealthyInstances(bool include_unhealthy_instances);
  10. /// @brief 设置服务路由时是否包含熔断的服务实例。可选,默认不包含。
  11. /// @note 即使设置不包含的情况下仍然可能降级返回熔断实例
  12. void SetIncludeCircuitBreakInstances(bool include_circuit_breaker_instances);
  13. /// @brief 设置是否跳过服务路由。可选,默认不跳过服务路由
  14. void SetSkipRouteFilter(bool skip_route_filter);
  15. /// @brief 设置源服务信息,用于服务路由计算。可选
  16. void SetSourceService(const ServiceInfo& source_service);
  17. /// @brief 设置元数据,用于元数据路由
  18. void SetMetadata(std::map<std::string, std::string>& metadata);
  19. /// @brief 设置元数据路由匹配失败时的降级策略,默认不降级
  20. void SetMetadataFailover(MetadataFailoverType metadata_failover_type);
  21. };
  22. // 调用该方法执行请求
  23. consumer.GetInstances()

GetOneInstances

每次仅获取一个可用服务提供者实例,该方法会依次执行路由、负载均衡流程。

该方法默认会过滤掉不健康、隔离、权重为0、被熔断的实例。

说明:

执行路由流程的条件

  • 配置了 GetOneInstanceRequest.SourceService.Metadata 属性,会触发自定义路由流程
  • 设置了 GetOneInstanceRequest.Metadata 属性,会触发元数据路由流程
  1. /// @brief 获取单个服务实例请求
  2. class GetOneInstanceRequest : Noncopyable {
  3. public:
  4. /// @brief 构建获取单个服务实例请求对象
  5. /// @param service_key 命名空间和服务名
  6. explicit GetOneInstanceRequest(const ServiceKey& service_key);
  7. /// @brief 设置hash key,用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  8. void SetHashKey(uint64_t hash_key);
  9. /// @brief 设置 hash 字符串, sdk 会用 hash_string 算出一个 uint64_t
  10. /// 的哈希值用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  11. void SetHashString(const std::string& hash_string);
  12. /// @brief 设置是否略过跳过半开探测节点
  13. /// @note 只在重试业务时设置为true。如果一直设置为true,则熔断节点在网络探测成功后也一直无法恢复
  14. void SetIgnoreHalfOpen(bool ignore_half_open);
  15. /// @brief 设置源服务信息,用于服务路由计算。可选
  16. /// @param source_service 源服务信息,包括源服务命名空间和用于过滤的metadata
  17. void SetSourceService(const ServiceInfo& source_service);
  18. /// @brief 设置请求超时时间。可选,默认为全局配置的API超时时间
  19. void SetTimeout(uint64_t timeout);
  20. /// @brief 设置请求标签,用于接口级别熔断
  21. void SetLabels(const std::map<std::string, std::string>& labels);
  22. /// @brief 设置元数据,用于元数据路由
  23. void SetMetadata(std::map<std::string, std::string>& metadata);
  24. /// @brief 设置元数据路由匹配失败时的降级策略,默认不降级
  25. void SetMetadataFailover(MetadataFailoverType metadata_failover_type);
  26. /// @brief 设置负载均衡类型。可选,默认使用配置文件中设置的类型
  27. void SetLoadBalanceType(LoadBalanceType load_balance_type);
  28. /// @brief 设置用于重试的实例数。可选,默认不返回用于重试的实例
  29. /// @note 第一个实例由负载均衡器给出,外加backup_instance_num个实例,实例不重复,但不保证数量
  30. /// 内部的一致性环hash负载均衡返回实例后方相邻的实例,其他返回随机实例
  31. /// 从GetOneInstance的InstancesResponse获取实例
  32. /// @param backup_instance_num 重试(备份)实例数
  33. void SetBackupInstanceNum(uint32_t backup_instance_num);
  34. /// @param replicate_index 副本索引,默认为0表示当前hash实例本身
  35. /// 大于0表示从hash实例后面的第几个副本
  36. void SetReplicateIndex(int replicate_index);
  37. };
  38. // 调用该方法执行请求
  39. consumer->GetOneInstance(request, instance)

如何基于 polaris-cpp 客户端完成一个服务发现的程序