这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

C++ 应用开发

1 - 使用 C++ SDK

1.1 - 引入依赖

本文档提供如果编译并在自己的项目中引入Polaris CPP SDK方法

编译安装

下载源码

支持两种方式下载源码:

  1. 使用git clone源码然后切到最新的tag
  2. 直接在polaris cpp仓库的tags页面上下载最新的tag源码

编译打包

注:目前支持make, bazel方式编译。其他编译方式待支持,欢迎贡献。

make方式编译

# 编译
make
# 测试
make test
# 打包,可添加参数package_name指定打包名,默认polaris_cpp_sdk
make package # package_name=polaris_cpp_sdk

执行make package后会在当前目录下生成一个polaris_cpp_sdk.tar.gz压缩文件。该文件的内容如下:

|-- include/polaris  # 头文件
|   |-- consumer.h provider.h limit.h config.h context.h log.h defs.h ...
|-- dlib             # 动态库
|   |-- libpolaris_api.so
`-- slib             # 静态库
    |-- libpolaris_api.a libprotobuf.a

其中include/polaris/为头文件目录。业务程序使用#include "polaris/xxx.h"这种方式包含头文件。

dlib/为动态库目录。libpolaris_api.so为polaris的动态库。注:该动态库已经链接了libprotobuf.a 使用动态库,在发布应用程序时需要将该动态库一起发布,并需要确保能搜到这些动态库。

slib/为静态库目录。用户使用静态编译时需要链接该目录下libpolaris_api.a和libprotobuf.a两个静态库。

自定义PB3版本

目前SDK与北极星Server通信使用的PB3,如果用户使用了PB2,需要升级到PB3,PB3兼容PB2。 且当前为了支持c++98编译,默认集成了protobuf 3.5.1版本。用户可以根据需要使用自己的PB3库

在Makefile中找到protobuf相关路径定义,修改以下三个路径指向自己的PB3即可:

PROTOBUF_INC_DIR =  # 修改成自己的PB3头文件路径
PROTOBUF_LIB =      # 修改成自己的PB3静态库路径
PROTOC =            # 修改成自己的PB3可执行文件protoc路径

兼容其他版本PB

有一些业务使用了其他的PB版本,例如PB2或者与北极星自带的PB3.5.1不同的版本。 如果同时链接两个版本的PB库,会导致符号冲突。 有一种方案可以隐藏北极星使用的PB库符号。该方案只支持业务链接北极星动态库时可用。

具体步骤如下:

  1. 到北极星源码根目录下执行rm -rf third_party/protobuf/build* 删除编译出来的protobuf库

  2. 修改北极星Makefile文件,protobuf的configure命令加上符号隐藏选项"CXXFLAGS=-fvisibility=hidden"。 如下是编译64位库时修改的地方:

$(PROTOBUF_DIR)/build64/libprotobuf.a: $(PROTOBUF_DIR)/configure
	@echo "[PROTOBUF] Preparing protobuf 64bit lib and protoc"
	@cd $(PROTOBUF_DIR); ./configure --with-pic --disable-shared --enable-static "CXXFLAGS=-fvisibility=hidden"

注:编译32位时修改32位PB编译命令的"CXXFLAGS=-m32""CXXFLAGS=-m32 -fvisibility=hidden"即可

  1. 在北极星根目录执行make clean 然后重新make即可

bazel方式编译

sh bazel_build.sh # 编译polaris_api
sh bazel_clean.sh # 编译清理

待补充:
test用例的bazel编译待补充

通过Makefile引入

静态库方式使用

g++ -I./polaris_cpp_sdk/include main.cpp -L./polaris_cpp_sdk/slib  -lpolaris_api -lprotobuf -pthread -lz -lrt -o main

动态库方式使用

g++ -I./polaris_cpp_sdk/include main.cpp -L./polaris_cpp_sdk/dlib -lpolaris_api -pthread -lz -lrt -o main

通过CMake引入

静态库方式使用

set(POLARIS_SDK_DIR /data/example/polaris_cpp_sdk)  # 需要修改polaris_cpp_sdk解压目录

include_directories(${POLARIS_SDK_DIR}/include)

link_directories(${POLARIS_SDK_DIR}/slib)

add_executable(main main.cpp)

target_link_libraries(main libpolaris_api.a libprotobuf.a pthread z rt)

动态库方式使用

set(POLARIS_SDK_DIR /data/example/polaris_cpp_sdk)  # 需要修改polaris_cpp_sdk解压目录

include_directories(${POLARIS_SDK_DIR}/include)

link_directories(${POLARIS_SDK_DIR}/dlib)

add_executable(main main.cpp)

target_link_libraries(main polaris_api pthread z rt)

通过Bazel引入

在WORKSPACE中添加依赖:

    git_repository(
        name = "polaris_cpp",
        remote = "https://github.com/polarismesh/polaris-cpp",
        tag = "v1.1.0",  # 替换成需要依赖的版本
    )

在WORKSPACE中加载北极星依赖:

# 可以放到比较后面,这样如果有自定义其他依赖版本,则会优先使用其他自定义版本
load("//:polaris_deps.bzl", "polaris_deps")
polaris_deps()

在BUILD中设置编译目标添加依赖:

deps = [
        "@polaris_cpp//:polaris_api",
    ],

1.2 - 注册发现

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

服务注册

SDK实例构建

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

#include "polaris/provider.h"

int main(int argc, char** argv) {
    provider_ = std::unique_ptr<polaris::ProviderApi>(polaris::ProviderApi::CreateWithDefaultFile());
}

注册请求体

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

发起注册请求

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

polaris::InstanceRegisterRequest register_req(service_namespace_, service_name_, service_token_, host_, port_);
// 开启健康检查
register_req.SetHealthCheckFlag(true);
register_req.SetHealthCheckType(polaris::kHeartbeatHealthCheck);
register_req.SetTtl(kHeartbeatTtl);

// 注册实例
auto ret_code = provider_->Register(register_req, instance_id_);
if (ret_code != polaris::kReturnOk && ret_code != polaris::kReturnExistedResource) {
  std::cout << "register instance with error:" << polaris::ReturnCodeToMsg(ret_code).c_str() << std::endl;
  return ret_code;
}

// 启动心跳上报线程
heartbeat_thread_ = std::unique_ptr<std::thread>(new std::thread([=] {
  while (!signal_received) {  // 循环上报心跳
    polaris::InstanceHeartbeatRequest heartbeat_req(service_token_, instance_id_);
    auto ret_code = provider_->Heartbeat(heartbeat_req);
    if (ret_code != polaris::kReturnOk) {
      std::cout << "instance heartbeat with error:" << polaris::ReturnCodeToMsg(ret_code).c_str() << std::endl;
      sleep(1);
      continue;
    }
    sleep(kHeartbeatTtl);
  }
}));

服务发现

SDK实例构建

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

#include "polaris/consumer.h"

int main(int argc, char** argv) {
    consumer_ = std::unique_ptr<polaris::ConsumerApi>(polaris::ConsumerApi::CreateWithDefaultFile());
}

发现服务实例

GetAllInstances

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

/// @brief 获取批量服务实例请求
class GetInstancesRequest : Noncopyable {
 public:
  /// @brief 构造获取批量服务实例请求
  /// @param service_key 命名空间和服务名
  explicit GetInstancesRequest(const ServiceKey& service_key);
};

// 调用该方法执行请求
consumer.GetAllInstances()

GetInstances

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

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

/// @brief 获取批量服务实例请求
class GetInstancesRequest : Noncopyable {
 public:
  /// @brief 构造获取批量服务实例请求
  /// @param service_key 命名空间和服务名
  explicit GetInstancesRequest(const ServiceKey& service_key);
  /// @brief 设置服务路由时否包含不健康的服务实例。可选,默认不包含
  /// @note 即使设置不包含的情况下仍然可能降级返回不健康实例
  void SetIncludeUnhealthyInstances(bool include_unhealthy_instances);
  /// @brief 设置服务路由时是否包含熔断的服务实例。可选,默认不包含。
  /// @note 即使设置不包含的情况下仍然可能降级返回熔断实例
  void SetIncludeCircuitBreakInstances(bool include_circuit_breaker_instances);
  /// @brief 设置是否跳过服务路由。可选,默认不跳过服务路由
  void SetSkipRouteFilter(bool skip_route_filter);
  /// @brief 设置源服务信息,用于服务路由计算。可选
  void SetSourceService(const ServiceInfo& source_service);
  /// @brief 设置元数据,用于元数据路由
  void SetMetadata(std::map<std::string, std::string>& metadata);
  /// @brief 设置元数据路由匹配失败时的降级策略,默认不降级
  void SetMetadataFailover(MetadataFailoverType metadata_failover_type);
};

// 调用该方法执行请求
consumer.GetInstances()

GetOneInstances

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

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

/// @brief 获取单个服务实例请求
class GetOneInstanceRequest : Noncopyable {
 public:
  /// @brief 构建获取单个服务实例请求对象
  /// @param service_key 命名空间和服务名
  explicit GetOneInstanceRequest(const ServiceKey& service_key);
  /// @brief 设置hash key,用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  void SetHashKey(uint64_t hash_key);
  /// @brief 设置 hash 字符串, sdk 会用 hash_string 算出一个 uint64_t
  /// 的哈希值用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  void SetHashString(const std::string& hash_string);
  /// @brief 设置是否略过跳过半开探测节点
  /// @note 只在重试业务时设置为true。如果一直设置为true,则熔断节点在网络探测成功后也一直无法恢复
  void SetIgnoreHalfOpen(bool ignore_half_open);
  /// @brief 设置源服务信息,用于服务路由计算。可选
  /// @param source_service 源服务信息,包括源服务命名空间和用于过滤的metadata
  void SetSourceService(const ServiceInfo& source_service);
  /// @brief 设置请求超时时间。可选,默认为全局配置的API超时时间
  void SetTimeout(uint64_t timeout);
  /// @brief 设置请求标签,用于接口级别熔断
  void SetLabels(const std::map<std::string, std::string>& labels);
  /// @brief 设置元数据,用于元数据路由
  void SetMetadata(std::map<std::string, std::string>& metadata);
  /// @brief 设置元数据路由匹配失败时的降级策略,默认不降级
  void SetMetadataFailover(MetadataFailoverType metadata_failover_type);
  /// @brief 设置负载均衡类型。可选,默认使用配置文件中设置的类型
  void SetLoadBalanceType(LoadBalanceType load_balance_type);
  /// @brief 设置用于重试的实例数。可选,默认不返回用于重试的实例
  /// @note 第一个实例由负载均衡器给出,外加backup_instance_num个实例,实例不重复,但不保证数量
  ///       内部的一致性环hash负载均衡返回实例后方相邻的实例,其他返回随机实例
  ///       从GetOneInstance的InstancesResponse获取实例
  /// @param backup_instance_num 重试(备份)实例数
  void SetBackupInstanceNum(uint32_t backup_instance_num);
  /// @param replicate_index 副本索引,默认为0表示当前hash实例本身
  ///                        大于0表示从hash实例后面的第几个副本
  void SetReplicateIndex(int replicate_index);
};

// 调用该方法执行请求
consumer->GetOneInstance(request, instance)

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

1.3 - 动态路由

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

SDK实例构建

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

#include "polaris/consumer.h"

int main(int argc, char** argv) {
    consumer_ = std::unique_ptr<polaris::ConsumerApi>(polaris::ConsumerApi::CreateWithDefaultFile());
}

服务路由

GetInstances

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

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

/// @brief 获取批量服务实例请求
class GetInstancesRequest : Noncopyable {
 public:
  /// @brief 构造获取批量服务实例请求
  /// @param service_key 命名空间和服务名
  explicit GetInstancesRequest(const ServiceKey& service_key);
  /// @brief 设置服务路由时否包含不健康的服务实例。可选,默认不包含
  /// @note 即使设置不包含的情况下仍然可能降级返回不健康实例
  void SetIncludeUnhealthyInstances(bool include_unhealthy_instances);
  /// @brief 设置服务路由时是否包含熔断的服务实例。可选,默认不包含。
  /// @note 即使设置不包含的情况下仍然可能降级返回熔断实例
  void SetIncludeCircuitBreakInstances(bool include_circuit_breaker_instances);
  /// @brief 设置是否跳过服务路由。可选,默认不跳过服务路由
  void SetSkipRouteFilter(bool skip_route_filter);
  /// @brief 设置源服务信息,用于服务路由计算。可选
  void SetSourceService(const ServiceInfo& source_service);
  /// @brief 设置元数据,用于元数据路由
  void SetMetadata(std::map<std::string, std::string>& metadata);
  /// @brief 设置元数据路由匹配失败时的降级策略,默认不降级
  void SetMetadataFailover(MetadataFailoverType metadata_failover_type);
};

// 调用该方法执行请求
consumer->GetInstances(request, instance)

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

1.4 - 负载均衡

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

SDK实例构建

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

#include "polaris/consumer.h"

int main(int argc, char** argv) {
    consumer_ = std::unique_ptr<polaris::ConsumerApi>(polaris::ConsumerApi::CreateWithDefaultFile());
}

服务路由

GetInstances

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

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

/// @brief 获取单个服务实例请求
class GetOneInstanceRequest : Noncopyable {
 public:
  /// @brief 构建获取单个服务实例请求对象
  /// @param service_key 命名空间和服务名
  explicit GetOneInstanceRequest(const ServiceKey& service_key);
  /// @brief 设置hash key,用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  void SetHashKey(uint64_t hash_key);
  /// @brief 设置 hash 字符串, sdk 会用 hash_string 算出一个 uint64_t
  /// 的哈希值用于一致性哈希负载均衡算法选择服务实例。其他负载均衡算法不用设置
  void SetHashString(const std::string& hash_string);
  /// @brief 设置负载均衡类型。可选,默认使用配置文件中设置的类型
  /// LoadBalanceType可取值如下:
  /// - kLoadBalanceTypeWeightedRandom // 权重随机
  /// - kLoadBalanceTypeRingHash // 一致性hash负载均衡
  /// - kLoadBalanceTypeMaglevHash // 一致性Hash: maglev算法
  /// - kLoadBalanceTypeL5CstHash // 兼容L5的一致性Hash
  /// - kLoadBalanceTypeSimpleHash // hash_key%总实例数 选择服务实例
  /// - kLoadBalanceTypeDefaultConfig // 使用全局配置的负载均衡算法,默认值
  void SetLoadBalanceType(LoadBalanceType load_balance_type);
  /// @brief 设置用于重试的实例数。可选,默认不返回用于重试的实例
  /// @note 第一个实例由负载均衡器给出,外加backup_instance_num个实例,实例不重复,但不保证数量
  ///       内部的一致性环hash负载均衡返回实例后方相邻的实例,其他返回随机实例
  ///       从GetOneInstance的InstancesResponse获取实例
  /// @param backup_instance_num 重试(备份)实例数
  void SetBackupInstanceNum(uint32_t backup_instance_num);
  /// @param replicate_index 副本索引,默认为0表示当前hash实例本身
  ///                        大于0表示从hash实例后面的第几个副本
  void SetReplicateIndex(int replicate_index);
};

// 调用该方法执行请求
consumer->GetOneInstance(request, instance)

如何基于 polaris-cpp 客户端完成一个负载均衡的程序

1.5 - 节点熔断

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

SDK实例构建

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

#include "polaris/consumer.h"

int main(int argc, char** argv) {
    consumer_ = std::unique_ptr<polaris::ConsumerApi>(polaris::ConsumerApi::CreateWithDefaultFile());
}

上报调用情况

/// @brief 服务实例调用结果上报
class ServiceCallResult : Noncopyable {
 public:
  /// @brief 设置服务实例的服务名
  void SetServiceName(const std::string& service_name);
  /// @brief 设置服务实例的命名空间
  void SetServiceNamespace(const std::string& service_namespace);
  /// @brief 设置服务实例ID
  void SetInstanceId(const std::string& instance_id);
  /// @brief 设置服务实例Host和Port,可选,如果设置了服务实例ID,则这个可不设置,优先使用服务实例ID
  /// @param host 服务实例Host
  /// @param port 服务实例Port
  void SetInstanceHostAndPort(const std::string& host, int port);
  /// @brief 设置调用返回状态码
  void SetRetStatus(CallRetStatus ret_status);
  /// @brief 设置调用返回码。可选,用于支持根据返回码实现自己的插件
  void SetRetCode(int ret_code);
  /// @brief 设置服务实例调用时延
  void SetDelay(uint64_t delay);
  /// @brief 设置主调服务ServiceKey
  void SetSource(const ServiceKey& source);
  /// @brief 设置被调服务labels信息
  void SetLabels(const std::map<std::string, std::string>& labels);
};

上报请求调用结果

你在根据请求调用情况对 ServiceCallResult 结构体完成初始化后,只需要调用 ConsumerAPI.UpdateServiceCallResult 方法即可完成请求调用结果上报。SDK 内部会根据上报的调用结果信息,对实例进行信息统计并计算是否需要对实例进行熔断

consumer_->UpdateServiceCallResult(result)

如何基于 polaris-go 客户端完成一个节点熔断的程序

1.6 - 访问限流

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

SDK实例构建

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

#include "polaris/limit.h"

int main(int argc, char** argv) {
    polaris::LimitApi* limit_api = polaris::LimitApi::CreateWithDefaultFile();
}

请求配额

/// @brief 限流配额请求
class QuotaRequest {
 public:
  /// @brief 设置服务命名空间
  void SetServiceNamespace(const std::string& service_namespace);
  /// @brief 设置服务名
  void SetServiceName(const std::string& service_name);
  /// @brief 设置标签用于选择限流配置
  void SetLabels(const std::map<std::string, std::string>& labels);
  /// @brief 设置请求需要分配的配额数量,可选,默认为1
  void SetAcquireAmount(int amount);
  /// @brief 设置请求超时时间,可选,单位ms,默认1000ms
  void SetTimeout(uint64_t timeout);
  /// @brief 设置请求所属的接口名,可选
  void SetMethod(const std::string& method);
};

发起请求配额申请

你在接收到请求之后对 QuotaRequest 结构体完成初始化后,只需要调用 LimitAPI.GetQuota 方法即可完成本次请求配额的申请。

ret = limit_api->GetQuota(quota_request, response)

对于请求配额结果的结构体如下。

/// @brief 配额获取结果
enum QuotaResultCode {
  kQuotaResultOk = 0,   // 配额正常
  kQuotaResultLimited,  // 配额被限流
  kQuotaResultWait      // 需求需要等待重试
};

/// @brief 配额分配信息,sidecar模式下暂时不支持获取这些信息
struct QuotaResultInfo {
  int64_t left_quota_;  // 剩余配额
  int64_t all_quota_;   // 配置的配额
  uint64_t duration_;   // 配置周期
  bool is_degrade_;     // 是否降级
};

/// @brief 限流配额应答
class QuotaResponse {
 public:
  /// @brief 获取限流配额结果
  QuotaResultCode GetResultCode() const;
  /// @brief 获取配额分配信息
  const QuotaResultInfo& GetQuotaResultInfo() const;
  /// @brief 请求需要获取多长时间才能使用配额
  uint64_t GetWaitTime() const;
};

分布式限流使用

如果要使用分布式限流,请先确保已经部署了北极星分布式限流 server

部署完后确认北极星控制台存在服务 命名空间: Polaris, 服务名: polaris.limiter

确认完毕后,调整 polaris.yaml 配置文件,在控制台配置分布式限流规则,SDK 仍然使用 ret = limit_api->GetQuota(quota_request, response) 即可。

# 描述:限流相关配置
rateLimiter:
  # 分布式限流时用于发现限流服务器,当规则中未配置限流集群时使用该配置
  rateLimitCluster:
    # 限流服务器集群所在命名空间
    namespace: Polaris
    # 限流服务器集群名字
    service: polaris.limiter

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

1.7 - 二次寻址

引入依赖

参考文档:依赖引入

初始化 polaris.yaml

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

修改 polaris.yaml 开启二次寻址

global:
  #描述系统相关配置
  system:
    # 服务发现集群,用于二次寻址,非二次寻址场景无需配置
    discoverCluster:
      namespace: Polaris
      service: polaris.discover
      # 可选:服务刷新间隔
      refreshInterval: 10m
    # 健康检查集群,用于二次寻址,非二次寻址场景无需配置
    healthCheckCluster:
      namespace: Polaris
      service: polaris.healthcheck
      # 可选:服务刷新间隔
      refreshInterval: 10m

2 - 使用 L5Agent

环境准备

部署polaris

如果已经部署好了polaris,可忽略这一步。

polaris支持在kubernetes环境中进行部署,注意必须保证暴露HTTP端口为8090,gRPC端口为8091。具体部署方案请参考:

开启服务端的 L5 接入能力

编辑 polaris-server.yaml 配置文件

# apiserver配置
apiservers:
  ...
  # - name: service-l5
  #   option:
  #     listenIP: 0.0.0.0
  #     listenPort: 7779
  #     clusterName: cl5.discover

将相关注释移除

# apiserver配置
apiservers:
  ...
  - name: service-l5
    option:
      listenIP: 0.0.0.0
      listenPort: 7779
      clusterName: cl5.discover

重启 polaris-server

bash tool/stop.sh
bash tool/start.sh

bash tool/stop.cmd
bash tool/start.cmd

修改 L5Agent 配置

修改 L5Agent 安装目录下的 conf/l5_config.ini 配置文件

[L5CONFIG]
ServerIp={北极星服务端IP}
ServerPort=7779

修改完上述配置之后,重启 L5Agent。在重启前需要删除 /data/L5Backup/l5server_list.backup

验证

SID 规范以及注意

  • L5 SDI 的格式:ModID:CmdID
  • 强烈建议用户命名空间选择 default 或者 Production,ModID 取值范围为: [2, 192,000,000]
  • 如果用户确实有需要使用其他命名空间,请按照以下方式进行其他命名空间的换算:ModID 数值右移6位,如果结果 >= 3000001,则需要计算 ModID & 63 的结果值,根据结果值对应的命名空间信息如下,否则会出现L5寻址失败的问题:
    {
        1: "Production",
        2: "Development",
        3: "Pre-release",
        4: "Test",
        5: "Polaris",
        6: "default",
    }
    

创建测试服务以及SID

由于 l5api 仅支持访问 L5 SID,因此访问非 L5 SID 格式的服务名,需要创建 CL5 SID 格式的服务别名指向该服务

执行

➜  bin ./L5GetRoute1 192002625 487373 3 
ip is :127.0.0.1 port is : 8091, usec=153,avg_usec=153=========================
ip is :127.0.0.1 port is : 8091, usec=2,avg_usec=77=========================
ip is :127.0.0.1 port is : 8091, usec=111,avg_usec=88=========================