1 - 使用 Java SDK
1.1 - 注册发现
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
服务注册
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.factory.api.DiscoveryAPIFactory, 使用 DiscoveryAPIFactory 中的方法进行构造一个 ProviderAPI SDK 实例
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
public static void main(String[] args) throws Exception {
ProviderAPI providerAPI = DiscoveryAPIFactory.createProviderAPI();
}
注册请求体
InstanceRegisterRequest request = new InstanceRegisterRequest();
// 设置实例所属服务信息
request.setService(service);
// 设置实例所属服务的命名空间信息
request.setNamespace(namespace);
// 设置实例的 host 信息
request.setHost(host);
// 设置实例的端口信息
request.setPort(port);
// 可选,资源访问Token,即用户/用户组访问凭据,仅当服务端开启客户端鉴权时才需配置
request.setToken(token);
// 设置实例版本
request.setVersion(version);
// 设置实例的协议
request.setProtocol(protocol);
// 设置实例权重
request.setWeight(weight);
// 设置实例的标签
request.setMetadata(metadata);
// 设置实例地理位置 zone 信息
request.setZone(zone);
// 设置实例地理位置 region 信息
request.setRegion(region);
// 设置实例地理位置 campus 信息
request.setCampus(campus);
// 设置心跳健康检查ttl,单位为s,不填默认为5s,TTL的取值范围为 (0s, 60s]
// 开启了心跳健康检查,客户端必须以TTL间隔上报心跳
// 健康检查服务器3个TTL未受到心跳则将实例置为不健康
request.setTtl(ttl);
发起注册请求
你在初始化完 InstanceRegisterRequest 结构体后,只需要调用 ProviderAPI.RegisterInstance 方法即可完成实例注册,并且 RegisterInstance 方法内部会自动维护实例的心跳上报。
InstanceRegisterResponse registerResp = providerAPI.registerInstance(registerRequest)
服务发现
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.factory.api.DiscoveryAPIFactory, 使用 DiscoveryAPIFactory 中的方法进行构造一个 ConsumerAPI SDK 实例
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
public static void main(String[] args) throws Exception {
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPI();
}
发现服务实例
GetAllInstances
直接返回目标服务下的所有实例,包括不健康、隔离、权重为0、被熔断的实例,也会在返回的实例列表中。
GetAllInstancesRequest request = new GetAllInstancesRequest();
// 设置服务命名空间
request.setNamespace(String namespace);
// 设置服务名称
request.setService(String service);
// 设置超时时间
request.setTimeoutMs(long timeoutMs);
// 调用 ConsumerAPI 执行该请求
consumerAPI.getAllInstance(request);
GetHealthyInstances
每次获取一批可用服务提供者实例。
该方法默认会过滤掉不健康、隔离、权重为0、被熔断的实例。
GetInstancesRequest request = new GetInstancesRequest();
// 设置服务命名空间
request.setNamespace(String namespace);
// 设置服务名称
request.setService(String service);
// 可选,设置主调服务信息,只用于路由规则匹配
SourceService serviceInfo = new SourceService();
// 设置主调服务命名空间
serviceInfo.setNamespace(String namespace);
// 设置主调服务名称
serviceInfo.setService(String service);
// 设置主调方的请求标签信息
serviceInfo.setArguments(Set<RouteArgument> arguments);
request.setServiceInfo(serviceInfo);
// 设置超时时间
request.setTimeoutMs(long timeoutMs);
// 调用 ConsumerAPI 执行该请求
consumerAPI.getInstances(request);
GetOneInstances
每次仅获取一个可用服务提供者实例,该方法会依次执行路由、负载均衡流程。
该方法默认会过滤掉不健康、隔离、权重为0、被熔断的实例。
执行路由流程的条件
- 配置了 GetOneInstanceRequest.ServiceInfo.Metadata 属性,会触发自定义路由流程
- 设置了 GetOneInstanceRequest.Metadata 属性,会触发元数据路由流程
public class Criteria {
/**
* 指定负载均衡策略
*/
private String lbPolicy;
/**
* 一致性hash的key
*/
private String hashKey;
}
GetOneInstanceRequest request = new GetOneInstanceRequest();
// 设置服务命名空间
request.setNamespace(String namespace);
// 设置服务名称
request.setService(String service);
// 可选,元数据信息,仅用于dstMetadata路由插件的过滤
request.setMetadata(Map<String, String> metadata);
// 可选,设置元数据路由兜底措施
// 当前支持的元数据路由兜底措施如下
// - 默认不降级: METADATAFAILOVERNONE("metadataFailoverNone")
// - 降级返回所有节点: METADATAFAILOVERALL("metadataFailoverAll")
// - 返回不包含元数据路由key的节点: METADATAFAILOVERNOTKEY("metadataFailoverNoKey")
request.setMetadataFailoverType();
// 可选,对应自定义路由规则中请求标签中的方法(Method)
request.setMethod(String method);
// 如果需要走 Hash 负载均衡的话,需要设置
Criteria criteria = new Criteria();
request.setCriteria(criteria);
// 可选,设置主调服务信息,只用于路由规则匹配
SourceService serviceInfo = new SourceService();
// 设置主调服务命名空间
serviceInfo.setNamespace(String namespace);
// 设置主调服务名称
serviceInfo.setService(String service);
// 设置主调方的请求标签信息
serviceInfo.setArguments(Set<RouteArgument> arguments);
request.setServiceInfo(serviceInfo);
// 设置超时时间
request.setTimeoutMs(long timeoutMs);
// 调用 ConsumerAPI 执行该请求
consumerAPI.getOneInstance(request);
如何基于 polaris-java 客户端完成一个服务发现的程序
1.2 - 动态路由
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
服务注册
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.factory.api.RouterAPIFactory, 使用 RouterAPIFactory 中的方法进行构造一个 RouterAPI SDK 实例
import com.tencent.polaris.factory.api.RouterAPIFactory;
public static void main(String[] args) throws Exception {
RouterAPI routerAPI = RouterAPIFactory.createRouterAPI();
}
注册请求体
ProcessRoutersRequest request = new ProcessRoutersRequest();/
// 被调服务命名空间
request.setNamespace();
// 被调服务名称
request.setService();
// 可选,对应自定义路由规则中请求标签中的方法(Method)
request.setMethod();
// 可选,设置主调服务信息,只用于路由规则匹配
SourceService serviceInfo = new SourceService();
// 设置主调服务命名空间
serviceInfo.setNamespace(String namespace);
// 设置主调服务名称
serviceInfo.setService(String service);
// 设置主调方的请求标签信息
serviceInfo.setArguments(Set<RouteArgument> arguments);
request.setSourceService(serviceInfo);
// 设置待参与路由的目标实例
request.setDstInstances();
ProcessRoutersRequest.RouterNamesGroup group = new ProcessRoutersRequest.RouterNamesGroup();
// 设置前置路由
group.setBeforeRouters();
// 设置业务路由
group.setCoreRouters();
// 设置后置路由
group.setAfterRouters();
// 可选,设置路由插件执行链
// 当前支持的路由插件类型如下
// - 就近路由: nearByRoute
// - 自定义路由: ruleRouter
// - 元数据路由: metadataRoute
request.setRouters();
如果当前 ProcessRoutersRequest 还不支持 putRouterArgument 方法,或者不存在 class SourceService, 同时服务端版本 >= 1.12.0,请求标签对应的 key 名称如下:
- 路径: $path
- 方法: $method
- 请求头: $header.{标签键}
- 请求参数: $query.{标签键}
- 请求COOKIE: $cookie.{标签键}
- 主调IP: $caller_ip
- 自定义: {标签键}
执行服务路由
你在初始化完 ProcessRoutersRequest 结构体后,只需要调用 RouterAPI.processRouters 方法即可完成服务路由
ProcessRoutersResponse resp = routerAPI.processRouters(registerRequest)
如何基于 polaris-java 客户端完成一个服务路由的程序
1.3 - 负载均衡
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
服务注册
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.factory.api.RouterAPIFactory, 使用 RouterAPIFactory 中的方法进行构造一个 RouterAPI SDK 实例
import com.tencent.polaris.factory.api.RouterAPIFactory;
public static void main(String[] args) throws Exception {
RouterAPI routerAPI = RouterAPIFactory.createRouterAPI();
}
负载均衡
public class Criteria {
// 一致性hash的key
private String hashKey;
}
ProcessLoadBalanceRequest request = new ProcessLoadBalanceRequest();
// 设置需要参与负载均衡的服务实例
request.setDstInstances(ServiceInstances dstInstances);
// 设置负载均衡策略
// 当前支持的负载均衡策略如下
// - 权重随机负载均衡: weightedRandom
// - 权重一致性负载均衡: ringHash
request.setLbPolicy(String lbPolicy);
// 如果需要走 Hash 负载均衡的话,需要设置
Criteria criteria = new Criteria();
request.setCriteria(criteria);
执行服务负载均衡
你在使用 ConsumerAPI.getAllInstances 或者 ConsumerAPI.getInstances 获取到服务实例列表后,完成 ProcessLoadBalanceRequest 初始化,只需要调用 RouterAPI.processLoadBalance 方法即可完成负载均衡
ProcessLoadBalanceResponse resp = routerAPI.processLoadBalance(request)
如何基于 polaris-java 客户端完成一个服务负载均衡的程序
1.4 - 熔断降级
熔断整个服务
配置熔断规则
配置服务熔断规则,针对default命名空间下所有的服务,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对服务进行熔断。
使用SDK进行熔断判断
方法说明
北极星Java SDK提供以下熔断相关的方法,所有的方法都在com.tencent.polaris.circuitbreak.api.CircuitBreakAPI接口中提供。
- check:检查资源是否可被调用,并对资源获取调用申请。对于半开的资源,如果半开的调用配额申请成功,返回true,否则返回false。
- report:该方法供用户在资源调用完成后,上报调用的结果,包括返回码、时延等信息,供熔断逻辑判断。
- makeFunctionalDecorator:创建一个函数调用装饰器
FunctionalDecorator,装饰器可以对Java的函数接口进行装饰。装饰后的逻辑,会在函数逻辑调用前,先通过check方法检查资源是否可被调用,如果不能被调用,会抛出资源熔断异常(CallAbortedException)。调用完成后,会通过report接口上报本次调用结果。FunctionalDecorator包含以下方法:- decorateSupplier:对函数接口Supplier进行封装。
- decorateConsumer:对函数接口Consumer进行封装。
- decorateFunction:对函数Function进行封装。
- decoratePredicate:对函数接口Predicate进行封装。
使用示例
// 创建CircuitBreakAPI实例
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
// 通过传入服务名(testService1)和命名空间(default),创建FunctionalDecorator
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
// 封装函数接口
Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
@Override
public void accept(Integer object) {
// 执行服务调用...
}
});
// 通过执行函数接口,进行服务调用
// 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
for (int i = 0; i < 500; i++) {
try {
integerConsumer.accept(i);
} catch(CallAbortedException e) {
e.printStackTrace();
}
}
样例地址
熔断单个接口
配置熔断规则
配置接口熔断规则,针对default命名空间所有服务的foo接口,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对接口进行熔断。
使用SDK进行熔断判断
熔断所使用的SDK接口及方法与服务级熔断相同,这里不再重复介绍。
使用示例
// 创建CircuitBreakAPI实例
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
// 通过传入服务名(testService1)、命名空间(default)和方法名(foo),创建FunctionalDecorator
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
makeDecoratorRequest.setMethod("foo");
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
// 封装函数接口
Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
@Override
public void accept(Integer object) {
// 执行服务接口调用...
}
});
// 通过执行函数接口,进行服务调用
// 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
for (int i = 0; i < 500; i++) {
try {
integerConsumer.accept(i);
} catch(CallAbortedException e) {
e.printStackTrace();
}
}
样例地址
熔断单个实例
配置熔断规则
配置实例熔断规则,针对default命名空间下所有的服务实例,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,每个实例的错误率是单独统计的,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对被调实例(IP:PORT)进行熔断。
使用SDK进行熔断判断
当实例被熔断时,该实例会暂时不接收请求,原本路由到该实例的请求会路由到其他实例。这个过程在服务路由过程中自动完成,用户无需进行额外的熔断状态判断等操作。
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
配置北极星服务端地址
用户需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。
global:
serverConnector:
# 北极星服务端地址,端口为8091
addresses:
- 127.0.0.1:8091
执行服务路由
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
public static void main(String[] args) throws Exception {
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPI();
// 执行服务路由,筛选出单个实例,在这个过程中,会自动剔除熔断的实例
GetOneInstanceRequest getOneInstanceRequest = new GetOneInstanceRequest();
getOneInstanceRequest.setNamespace("default");
getOneInstanceRequest.setService("testService1");
InstancesResponse oneInstance = consumerAPI.getOneInstance(getOneInstanceRequest);
Instance targetInstance = oneInstance.getInstances()[0];
// 执行服务调用 --- 伪代码
httpResult, delay = rpc(targetInstance.host, targetInstance.port, body);
// invoke rpc call with targetInstance
InstanceResource instanceResource = new InstanceResource(new ServiceKey(namespace, service),
targetInstance.getHost(), targetInstance.getPort(), sourceService.getServiceKey());
circuitBreakAPI.report(new ResourceStat(instanceResource, httpResult.code, delay));
}
样例地址
启用主动探测
业务往往会存在高峰期和低峰期,低峰期流量比较少,不足以触发熔断,会出现当部分实例出现数据不可达的问题时,没法及时发现,导致高峰期到来时出现故障。
主动探测可以解决这个问题,启用主动探测后,主调方会定时根据探测规则,对被调实例进行探测,探测结果可作为熔断的判断依据,可实现对故障资源的快速熔断。
配置主动探测规则
配置一个主动探测规则,对服务(名为testService1,命名空间为default)进行探测。探测使用的协议是HTTP协议,由于服务开启了鉴权,因此探测时需要传入鉴权头。
注意:主动探测的规则,服务名可以选择全部服务,则规则针对全部服务生效。如果需要针对只接口进行探测,则可以在接口字段中填入对应的接口名。
在熔断规则中开启主动探测
需要在熔断规则中开启探测,这样才可以把探测结果用于熔断。
1.5 - 访问限流
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.ratelimit.factory, 使用 LimitAPIFactory 中的方法进行构造一个 ProviderAPI SDK 实例
import com.tencent.polaris.ratelimit.factory.LimitAPIFactory;
public static void main(String[] args) throws Exception {
LimitAPI limitAPI = LimitAPIFactory.createLimitAPI();
}
请求配额
QuotaRequest quotaRequest = new QuotaRequest();
// 设置需要进行限流的服务信息:设置命名空间信息
quotaRequest.setNamespace(String namespace);
// 设置需要进行限流的服务信息:设置服务名称信息
quotaRequest.setService(String service);
// 设置本次被调用的方法信息
quotaRequest.setMethod(String method);
// 设置本次的请求标签
quotaRequest.setArguments(Set<Argument> arguments)
// 设置需要申请的请求配额数量
quotaRequest.setCount(1);
如果当前 QuotaRequest 还不支持 setArguments 方法,同时服务端版本 >= 1.11.0,SetLabels 对应的 key 名称如下:
- 路径: $path
- 方法: $method
- 请求头: $header.{标签键}
- 请求参数: $query.{标签键}
- 主调服务: $caller_service
- 主调IP: $caller_ip
- 自定义: {标签键}
发起配额申请请求
你在初始化完 QuotaRequest 结构体后,只需要调用 LimitAPI.getQuota 方法即可完成服务限流
QuotaResponse resp = limitAPI.getQuota(registerRequest)
分布式限流使用
如果要使用分布式限流,请先确保已经部署了北极星分布式限流 server
部署完后确认北极星控制台存在服务 命名空间: Polaris, 服务名: polaris.limiter。
确认完毕后,调整 polaris.yml 配置文件,在控制台配置分布式限流规则,SDK 仍然使用 QuotaResponse resp = limitAPI.getQuota(registerRequest) 即可。
provider:
rateLimit:
enable: true
limiterNamespace: Polaris
limiterService: polaris.limiter
如何基于 polaris-java 客户端完成一个服务限流的程序
1.6 - 配置管理
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.configuration.factory, 使用 ConfigFileServiceFactory 中的方法进行构造一个 ConfigFileService SDK 实例
import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory;
public static void main(String[] args) throws Exception {
ConfigFileService configFileService = ConfigFileServiceFactory.createConfigFileService();
}
配置文件读取操作
// 获取特定远程的配置文件
ConfigFile configFile = configFileService.getConfigFile(String namespace, String fileGroup, String fileName);
System.out.println(configFile.getContent());
对配置文件发起监听
//获取配置文件
ConfigFile configFile = configFileService.getConfigFile(namespace, fileGroup, fileName);
//添加变更监听器
configFile.addChangeListener(new ConfigFileChangeListener() {
@Override
public void onChange(ConfigFileChangeEvent event) {
}
});
查询加密配置
需要更新 polaris-java 的版本至 v1.13.0 +
// 获取特定远程的配置文件
ConfigFile getConfigFile(String namespace, String fileGroup, String fileName);
// 获取特定远程的配置文件
ConfigFile getConfigFile(ConfigFileMetadata configFileMetadata);
调整 polaris.yml 配置文件
# 配置中心默认配置
config:
# 配置过滤器
configFilter:
enable: true
chain:
# 启用配置解密插件
- crypto
plugin:
crypto:
# 配置解密插件的算法插件类型
type: AES
监听配置分组下的已发布文件列表变化
需要更新 polaris-java 的版本至 v1.14.0 及以上版本, 获取到目标配置分组后, 调用配置分组的 addChangeListener 方法监听改配置分组下已发布配置文件列表的变化
ConfigFileGroup configFileGroup = configFileService.getConfigFileGroup(namespace, fileGroup);
if (configFileGroup != null) {
configFileGroup.addChangeListener(new ConfigFileGroupChangeListener() {
@Override
public void onChange(ConfigFileGroupChangedEvent event) {
Utils.print(event.toString());
}
});
}
ConfigFileGroupChangedEvent 结构体的具体信息
public class ConfigFileGroupChangedEvent {
// 配置分组自身元数据信息
private final ConfigFileGroupMetadata configFileGroupMetadata;
// 当前配置分组下的最新已发布的配置文件列表
private final List<ConfigFileMetadata> configFileMetadataList;
public ConfigFileGroupChangedEvent(ConfigFileGroupMetadata configFileGroupMetadata, List<ConfigFileMetadata> configFileMetadataList) {
this.configFileGroupMetadata = configFileGroupMetadata;
this.configFileMetadataList = configFileMetadataList;
}
public ConfigFileGroupMetadata getConfigFileGroupMetadata() {
return configFileGroupMetadata;
}
public List<ConfigFileMetadata> getConfigFileMetadataList() {
return configFileMetadataList;
}
@Override
public String toString() {
return "ConfigFileGroupChangedEvent{" +
"configFileGroupMetadata=" + configFileGroupMetadata +
", configFileMetadataList=" + configFileMetadataList +
'}';
}
}
配置文件修改操作
使用 ConfigFileServicePublishFactory 中的方法进行构造一个 ConfigFilePublishService SDK 实例
import com.tencent.polaris.configuration.factory.ConfigFileServicePublishFactory;
public static void main(String[] args) throws Exception {
ConfigFilePublishService configFilePublishService = ConfigFileServicePublishFactory.createConfigFilePublishService();
}
操作配置文件的方法
// 创建配置文件
void createConfigFile(String namespace, String fileGroup, String fileName, String content);
// 创建配置文件
void createConfigFile(ConfigFileMetadata configFileMetadata, String content);
// 修改配置文件
void updateConfigFile(String namespace, String fileGroup, String fileName, String content);
// 修改配置文件
void updateConfigFile(ConfigFileMetadata configFileMetadata, String content);
// 发布配置文件
void releaseConfigFile(String namespace, String fileGroup, String fileName);
// 发布配置文件
void releaseConfigFile(ConfigFileMetadata configFileMetadata);
相关示例工程代码
1.7 - 可观测性
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
通过配置文件 polaris.yml 开启监控上报
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
通过 prometheus pull 模式上报监控数据
global:
#描述: 监控及日志数据上报相关配置
statReporter:
#描述: 是否启用上报
enable: true
plugin:
prometheus:
type: pull
#描述: 设置 prometheus http-server 的监听端口
#类型:int
#默认值: 28080
#如果设置为负数,则不会开启默认的http-server,如果设置为0,则随机选择一个可用端口进行启动 http-server
port: 28080
#描述: 设置 prometheus http-server 的拉取path
#类型:string
#默认值: /metric
path: /metric
通过 pushgateway push 模式上报监控数据
global:
#描述: 监控及日志数据上报相关配置
statReporter:
#描述: 是否启用上报
enable: true
plugin:
prometheus:
type: push
#描述: 设置 pushgateway 的地址, 仅 type == push 时生效
#类型:string
address: 127.0.0.1:9091
#描述:设置metric数据推送到pushgateway的执行周期, 仅 type == push 时生效
#类型:string
#格式:^\d+(s|m|h)$
#范围:[1s:...]
#默认值:10s
pushInterval: 10s
通过代码开启监控上报
通过 prometheus pull 模式上报监控数据
ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory
.defaultConfig(ConfigProvider.DEFAULT_CONFIG);
configuration.getGlobal().getStatReporter().setEnable(true);
PrometheusHandlerConfig prometheusHandlerConfig = configuration.getGlobal().getStatReporter()
.getPluginConfig("prometheus", PrometheusHandlerConfig.class);
prometheusHandlerConfig.setPort(28080);
prometheusHandlerConfig.setPath("/metrics");
configuration.getGlobal().getStatReporter()
.setPluginConfig("prometheus", prometheusHandlerConfig);
通过 pushgateway push 模式上报监控数据
ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory
.defaultConfig(ConfigProvider.DEFAULT_CONFIG);
configuration.getGlobal().getStatReporter().setEnable(true);
PrometheusPushHandlerConfig prometheusHandlerConfig = configuration.getGlobal().getStatReporter()
.getPluginConfig("prometheus", PrometheusPushHandlerConfig.class);
prometheusHandlerConfig.setType("push");
prometheusHandlerConfig.setAddress("127.0.0.1:9091");
prometheusHandlerConfig.setPushInterval(30 * 1000L);
configuration.getGlobal().getStatReporter()
.setPluginConfig("prometheus", prometheusHandlerConfig);
SDK实例构建
当初始化好 polaris.yml 文件之后,你可以直接 import com.tencent.polaris.factory.api.DiscoveryAPIFactory, 使用 DiscoveryAPIFactory 中的方法进行构造一个 ConsumerAPI SDK 实例
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
public static void main(String[] args) throws Exception {
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPI();
}
服务调用结果
public enum RetStatus {
// 服务调用成功
RetSuccess,
// 服务调用失败
RetFail,
// 服务调用超时
RetTimeout,
}
ServiceCallResult result = new ServiceCallResult();
// 设置被调服务所在命名空间
result.setNamespace(String namespace);
// 设置被调服务的服务信息
result.setService(String service);
// 设置被调实例
result.setInstance(Instance instance);
// 设置本次请求的响应码
result.setRetCode(String code);
// 设置本次请求的耗时
result.setDelay(String delay);
// 设置本次请求的结果状态
result.setRetStatus(RetStatus status);
// 设置本次请求的请求标签,格式为 key=value;key=value;
result.setLabels(String labels);
// 设置本次请求调用的方法
result.setMethod(String method);
上报请求调用结果
你在根据请求调用情况对 ServiceCallResult 结构体完成初始化后,只需要调用 ConsumerAPI.updateServiceCallResult 方法即可完成请求调用结果上报。SDK 内部会根据上报的调用结果信息,将其转换为相应的流量调用指标数据,上报至 prometheus。
consumerAPI.updateServiceCallResult(ServiceCallResult)
1.8 - 二次寻址
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
初始化 polaris.yml
你需要在项目的 main/resources 下创建一个 polaris.yml 文件用于初始化 polaris-java SDK。polaris.yml 配置详细
修改 polaris.yml 开启二次寻址
global:
system:
discoverCluster:
namespace: Polaris # 设置服务注册发现集群服务所在的命名空间
service: polaris.discover # 设置服务注册发现集群服务的服务名称
sameAsBuiltin: false
healthCheckCluster:
namespace: Polaris # 设置健康检查集群服务所在的命名空间
service: polaris.healthcheck # 设置健康检查集群服务的服务名称
sameAsBuiltin: false
2 - 使用 Spring Cloud
3 - 使用 Spring Boot
3.1 - 概述
警告
该接入方式官方暂停维护,建议升级至 Spring Cloud Tencent 享受 Polaris 全部服务治理能力.
功能简介
Spring Boot是一个构建在Spring框架顶部的项目。它提供了一种简便,快捷的方式来设置,配置和运行基于Web的简单应用程序,为了方便 Spring Boot 用户快速接入北极星,我们通过以下几个示例帮助用户如何在 Spring Boot 中体验北极星的相关功能。
快速入门
前提条件
您需要先下载 Polaris Server,具体操作参见 Polaris 服务端安装
确定 Spring Boot 版本
确认自己项目的 Spring Boot 版本
➜ mvn dependency:tree | grep "org.springframework.boot:spring-boot-starter:jar"
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.6.9:compile
根据命令查询到的 spring boot 版本信息,我们在根据下面的版本列表对应关系选择合适的 Spring Boot 以及 Spring Boot Polaris 版本
版本列表
这里列出了不同 Spring Boot 版本相对应的 Spring Boot Polaris 版本。 您需要先查看您当前使用的 Spring Boot 版本,从而确定需要引入的 Spring Boot Polaris 版本。
| Spring Boot 兼容版本 | Spring Boot Polaris 版本 |
|---|---|
| 2.4.x | 1.1.0 |
接下来所有的示例我们将基于 Spring Boot 版本为 2.4.3、Spring Boot Polaris 版本为 1.1.0 开展。
3.2 - 服务注册
初始化项目
使用 jetbrain idea 等工具初始化一个 maven 项目
引入依赖
在上一步初始化好一个 maven 项目之后,我们在 pom.xml 中引入 Spring Boot Polaris 相关依赖。
- 引入 spring-boot-polaris-dependencies 进行管理 Spring Boot Polaris 相关组件的依赖版本。
- 引入 spring-boot-polaris-discovery-starter 实现 Spring Boot 服务注册到北极星中。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>spring-boot-polaris-dependencies</artifactId>
<version>1.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 Spring Boot Polaris Discovery 依赖用于实现服务注册 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>spring-boot-polaris-discovery-starter</artifactId>
</dependency>
</dependencies>
...
</project>
配置 application.properties
在 resources 目录下创建 application.properties 文件,并按照如下进行配置
.
├── java
│ └── com
│ └── example
│ └── springbootpolarisprovider
│ └── SpringbootProviderApplication.java
└── resources
└── application.properties
server.port=28888
spring.application.name=BootEchoServer
polaris.address=grpc://127.0.0.1:8091
polaris.discovery.register.enable=true
示例代码
```java
@SpringBootApplication
public class SpringbootProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootProviderApplication.class, args);
}
@RestController
static class EchoController {
private final PolarisDiscoveryProperties properties;
EchoController(PolarisDiscoveryProperties properties) {
this.properties = properties;
}
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello PolarisMesh " + string + ", I'm " + properties.getApplicationName();
}
}
}
验证
启动 Spring Boot 应用
在 Spring Boot 启动日志中,找到如下日志信息, 则表示 Spring Boot 应用已经成功注册到北极星中。
[Polaris] success to register instance 127.0.0.1:28888, service is BootEchoServer, namespace is default
[Polaris] success to schedule heartbeat instance 127.0.0.1:28888, service is BootEchoServer, namespace is default
可以通过 curl 命令查询服务端是否有该实例。
curl --location --request POST '127.0.0.1:8090/v1/Discover' \
--header 'Content-Type: application/json' \
--data-raw '{
"type": 1,
"service": {
"name": "BootEchoServer",
"namespace": "default"
}
}'
3.3 - 服务发现
引入 Spring Cloud Tencent
如果您当前的 Spring Boot 应用还未引入任何 Spring Cloud 依赖,可以将 Spring Boot 调整为 Spring Cloud 项目,使用 Spring Cloud Tencent 中的服务发现能力。
参考文档:Spring Cloud 应用接入
使用 Spring Boot Polaris Feign
初始化项目
使用 jetbrain idea 等工具初始化一个 maven 项目
引入依赖
在上一步初始化好一个 maven 项目之后,我们在 pom.xml 中引入 Spring Boot Polaris 相关依赖。
- 引入 spring-boot-polaris-dependencies 进行管理 Spring Boot Polaris 相关组件的依赖版本。
- 引入 spring-boot-polaris-discovery-starter 实现发现北极星中的服务并进行远程调用。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>spring-boot-polaris-dependencies</artifactId>
<version>1.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 Spring Boot Polaris Discovery 依赖用于实现服务注册 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>spring-boot-polaris-discovery-starter</artifactId>
</dependency>
</dependencies>
...
</project>
配置 application.properties
在 resources 目录下创建 application.properties 文件,并按照如下进行配置
.
├── java
│ └── com
│ └── example
│ └── springbootpolarisconsumer
│ └── SpringbootConsumerApplication.java
└── resources
└── application.properties
server.port=38888
spring.application.name=BootEchoConsumer
polaris.address=grpc://127.0.0.1:8091
polaris.discovery.register.enable=true
示例代码
@SpringBootApplication
public class SpringbootconsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootconsumerApplication.class, args);
}
@RestController
static class EchoController {
private final PolarisFeignBuilder targetBuilder;
EchoController(PolarisFeignBuilder targetBuilder) {
this.targetBuilder = targetBuilder;
}
@GetMapping(value = "/echo")
public String echo(@RequestParam(name = "value") String val) {
EchoServer echoServerBoot = Feign.builder().decoder(new StringDecoder())
.addCapability(targetBuilder.buildCircuitBreakCapability())
.target(targetBuilder.buildTarget(EchoServer.class,
PolarisFeignOptions.build().withService("BootEchoServer")));
return echoServerBoot.echo(val);
}
}
public interface EchoServer {
@RequestLine("GET /echo/{value}")
String echo(@Param("value") String value);
}
}
验证
通过 curl 命令对服务消费者发起调用。
curl --location --request GET '127.0.0.1:38888/echo?value=hello'
预期的结果如下
Hello PolarisMesh hello, I'm BootEchoServer
4 - 使用 Dubbo
4.1 - 服务注册
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 2.x 版本的接入,最新版本为
0.2.2 - dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
<p class="notice-title">
<span class="icon-notice baseline">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="300.5 134 300 300">
</span>提示</p><p>Dubbo 应用级注册发现 仅适用于北极星服务端版本 >= 1.18.0</p></div>
在 pom.xml 中引入以下依赖
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}</version>
</dependency>
<!-- 北极星元数据中心插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-metadatareport-polaris</artifactId>
<version>${revision}</version>
</dependency>
在 pom.xml 中引入以下依赖
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}</version>
</dependency>
参数配置
接下来,需要添加北极星registry的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
dubbo.registry.address=polaris://127.0.0.1:8091
dubbo.metadata-report.address=polaris://127.0.0.1:8091
dubbo.registry.address=polaris://127.0.0.1:8091
北极星地址的URL支持通过参数指定可选的配置,具体参数列表如下:
| 参数 | 类型 | 含义 |
|---|---|---|
| namespace | string | 指定服务的命名空间 |
| token | string | 指定用户token |
| persist_enable | bool | 设置是否开启客户端本地文件容灾缓存 |
| stat_type | string | 设置监控数据上报方式, pull 或者 push |
| stat_pull_port | int | stat_type == pull 时,设置 SDK 额外暴露的 metrics web 端口 |
| stat_push_addr | string | stat_type == push 时,设置 pushgateway 的 IP:PORT 地址 |
| stat_push_interval | int | stat_type == push 时,设置上报周期,单位为毫秒 |
| config_port | int | 设置北极星配置中心链接端口,默认为8093 |
| discover_port | int | 设置北极星注册中心链接端口,默认为8091 |
结果验证
服务注册样例可以参考:
4.2 - 元数据中心
提示
Dubbo 元数据中心仅适用于北极星服务端版本 >= 1.18.0
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
在 pom.xml 中引入以下依赖
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}</version>
</dependency>
<!-- 北极星元数据中心插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-metadatareport-polaris</artifactId>
<version>${revision}</version>
</dependency>
参数配置
接下来,需要添加北极星 metadata-report 的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
dubbo.metadata-report.address=polaris://127.0.0.1:8091
北极星地址的URL支持通过参数指定可选的配置,具体参数列表如下:
| 参数 | 类型 | 含义 | 支持版本 |
|---|---|---|---|
| namespace | string | 指定服务的命名空间 | 起始版本:0.1.0-3.2.7 |
| token | string | 指定用户token | 起始版本:0.1.0-3.2.7 |
| multi_address | string | 仅用于元数据中心多注册多发现, eg: nacos://127.0.0.1:8848?namespace=xxxxx&username=xxx | 起始版本:0.3.2-3.2.7 |
结果验证
服务接口定义
服务契约名称格式样例
"name": "dubbo::metadata::dubbo-provider::2e2e13eddf24272edcaa60c34afc5067",
"namespace": "dubbo",
"service": "dubbo-provider",
"protocol": "dubbo",
"version": "",
"revision": "2e2e13eddf24272edcaa60c34afc5067",
服务接口运维数据
服务契约名称格式样例
"name": "dubbo::metadata::1.0.0::provider::dubbo-provider",
"namespace": "dubbo",
"service": "dubbo-provider",
"protocol": "dubbo",
"version": "1.0.0",
"revision": "d297643d19dc4700a8c11d7fd57ef808",
接口-应用映射
服务契约名称格式样例
"name": "dubbo::mapping::com.tencent.polaris.dubbo.api.HelloService",
"namespace": "dubbo",
"service": "",
"protocol": "dubbo",
"version": "",
"revision": "f31bc6a132c84ce9afc39c1b98fdb6a7",
查询该接口下有多少应用提供了该接口
{
"@type": "type.googleapis.com/v1.ServiceContract",
"id": "535e686a7e8707b1d53e63f7578e80a2a94e4747",
"name": "dubbo::mapping::com.tencent.polaris.dubbo.api.HelloService",
"namespace": "dubbo",
"service": "",
"protocol": "dubbo",
"version": "",
"revision": "f31bc6a132c84ce9afc39c1b98fdb6a7",
"content": "",
"interfaces": [
{
"id": "6be61ef353a9e1918d5b84c100db0c8a5637f5a5",
"name": "dubbo-provider"
}
]
}
4.3 - 动态路由
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 2.x 版本的接入,最新版本为
0.2.2 - dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
首先,动态路由需要依赖以下2个插件,需要将2个插件引入POM中,插件版本建议使用最新版本。
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}<version>
</dependency>
<!-- 北极星动态路由插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-router-polaris</artifactId>
<version>${version}</version>
</dependency>
配置北极星注册中心地址
接下来,需要添加北极星 registry 的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
<dubbo:registry address="polaris://127.0.0.1:8091"/>
dubbo.registry.address=polaris://127.0.0.1:8091
启用北极星的路由插件
<dubbo:reference filter="polaris_router">
dubbo.consumer.filter=polaris_router
路由规则字段
动态路由可以实现基于dubbo的请求消息内容来对请求调度到不同的实例分组,比如将带了某些user标签的请求调度到灰度分组。
当前支持针对dubbo消息的以下内容进行路由调度:
应用级注册发现
| 消息类型 | dubbo消息内容 | 路由规则请求类型 |
|---|---|---|
| 消息头 | attachment | 请求头(HEADER) |
| RPC接口 | dubbo interface 全限定名 | 路径(PATH) |
| RPC方法 | dubbo interface 下的具体某个方法的名称 | 请求匹配规则-方法(METHOD) |
| 请求体参数 | dubbo 方法入参某个字段 | 请求匹配规则-请求参数(QUERY) |
接口级注册发现
| 消息类型 | dubbo消息内容 | 路由规则请求类型 | |
|---|---|---|---|
| 消息头 | attachment | 请求头(HEADER) | |
| RPC方法 | method | 方法(METHOD) | |
| 请求体参数 | dubbo 方法入参某个字段 | 请求匹配规则-请求参数(QUERY),字段格式 |
功能验证
动态路由样例包括3个工程,代表的是多个服务之间调用,调用链路为:front->middle->back。
配置自定义路由规则,指定带有附件 user 为 polaris 的请求,路由到 env 为 gray 的实例上。
执行服务调用,调用时,需要设置一下当前请求的attachement。
// 设置attachment,指定当前用户
public String doSayHello(String name) {
RpcContext.getClientAttachment().setAttachment("user", name);
return greetingService.sayHello(name);
}
代码中无需额外添加路由判断代码,插件会自动在被调端进行请求信息进行路由。
最终路由效果
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-normal] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-normal] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-normal] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-normal] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-normal] sayHello, 123%
➜ ~ curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=123
[FrontService] sayHi, 123 -> [MiddleService-gray] sayHello, 123 -> [BackendService-gray] sayHello, 123%
➜ .dubbo curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=polaris
[FrontService] sayHi, polaris -> [MiddleService-gray] sayHello, polaris -> [BackendService-gray] sayHello, polaris%
➜ .dubbo curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=polaris
[FrontService] sayHi, polaris -> [MiddleService-gray] sayHello, polaris -> [BackendService-gray] sayHello, polaris%
➜ .dubbo curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=polaris
[FrontService] sayHi, polaris -> [MiddleService-gray] sayHello, polaris -> [BackendService-gray] sayHello, polaris%
➜ .dubbo curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=polaris
[FrontService] sayHi, polaris -> [MiddleService-gray] sayHello, polaris -> [BackendService-gray] sayHello, polaris%
➜ .dubbo curl http://127.0.0.1:15700/echo\?method\=sayHi\&value\=polaris
[FrontService] sayHi, polaris -> [MiddleService-gray] sayHello, polaris -> [BackendService-gray] sayHello, polaris%
路由样例包括 3 个工程。
- front工程:dubbo-router-front
- middle工程:dubbo-router-middle
- back工程:dubbo-router-back
4.4 - 访问限流
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 2.x 版本的接入,最新版本为
0.2.2 - dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
首先,动态路由需要依赖以下2个插件,需要将2个插件引入POM中,插件版本建议使用最新版本。
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}<version>
</dependency>
<!-- 北极星限流功能插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-ratelimit-polaris</artifactId>
<version>${version}<version>
</dependency>
启用北极星访问限流插件
<dubbo:service filter="polaris_ratelimit">
dubbo.provider.filter=polaris_ratelimit
配置北极星注册中心地址
接下来,需要添加北极星 registry 的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
<dubbo:registry address="polaris://127.0.0.1:8091"/>
dubbo.registry.address=polaris://127.0.0.1:8091
限流规则字段
访问限流可以实现在被调端基于dubbo的请求消息内容来对请求进行流量限制,比如将带了某些user标签的请求限制速率为100/s。
当前支持针对dubbo消息的以下内容进行流量限制:
应用级注册发现
| 消息类型 | dubbo消息内容 | 路由规则请求类型 |
|---|---|---|
| 消息头 | attachment | 请求头(HEADER) |
| RPC接口 | dubbo interface 全限定名 | 接口名称 |
| RPC方法 | dubbo interface 下的具体某个方法的名称 | 请求匹配规则-方法(METHOD) |
| 请求体参数 | dubbo 方法入参某个字段 | 请求匹配规则-请求参数(QUERY) |
接口级注册发现
| 消息类型 | dubbo消息内容 | 路由规则请求类型 | |
|---|---|---|---|
| 消息头 | attachment | 请求头(HEADER) | |
| RPC方法 | method | 方法(METHOD) | |
| 请求体参数 | dubbo 方法入参某个字段 | 请求匹配规则-请求参数(QUERY),字段格式 |
- 请求匹配规则为 请求参数(QUERY)
- 请求匹配规则为 请求头(HEADER):
- 标签来源: RPC 调用的额外标签信息,即 Invoaction.Attachments()
- 根据 Dubbo 的 dubbo.application.register-mode 字段的值,决定限流规则的读取
- instance: 仅读取 dubbo 应用级的限流规则
- interface: 仅读取 dubbo 接口级的限流规则
- all: 同时读取 dubbo 应用级、接口级的限流规则,先匹配应用级下的限流规则,后匹配接口级限流规则,只要其中有一个触发限流,Filter 返回错误
功能验证
针对 Dubbo 接口级别的限流
针对 Dubbo 接口下某个方法的限流
代码中无需额外添加限流判断代码,插件会自动在被调端进行请求的限流计算和拦截。
最终限流效果
18:21:58.748 |-ERROR [DubboServerHandler-10.21.22.75:20880-thread-8] .apache.dubbo.rpc.filter.ExceptionFilter: -|
[DUBBO] Got unchecked and undeclared exception which called by 10.21.22.75. service: com.tencent.polaris.dubbo.example.
api.GreetingService, method: sayHi, exception: org.apache.dubbo.rpc.RpcException: Failed to invoke service com.tencent.
polaris.dubbo.example.api.GreetingService.sayHi because exceed max service tps., dubbo version: 3.2.6, current host:
192.168.255.10, error code: 5-36. This may be caused by , go to https://dubbo.apache.org/faq/5/36 to find instructions.
org.apache.dubbo.rpc.RpcException: Failed to invoke service com.tencent.polaris.dubbo.example.api.GreetingService.sayHi
because exceed max service tps.
访问限流样例包括2个工程,代表的是主调端和被调端,限流行为工作在被调端。
环境变量设置
export CONFIG_CENTER_ADDR=127.0.0.1:8093
export METADATA_REPORT_ADDR=127.0.0.1:8091
export POLARIS_DISCOVERY_ADDR=127.0.0.1:8091
export REGISTER_MODE=all
export POD_IP={IP}
- consumer工程:dubbo-governance-consumer
- provider工程:dubbo-governance-provider
代码中无需额外添加限流判断代码,插件会自动在被调端进行请求的限流计算和拦截。
最终限流效果
18:21:58.748 |-ERROR [DubboServerHandler-10.21.22.75:20880-thread-8] .apache.dubbo.rpc.filter.ExceptionFilter: -|
[DUBBO] Got unchecked and undeclared exception which called by 10.21.22.75. service: com.tencent.polaris.dubbo.example.
api.GreetingService, method: sayHi, exception: org.apache.dubbo.rpc.RpcException: Failed to invoke service com.tencent.
polaris.dubbo.example.api.GreetingService.sayHi because exceed max service tps., dubbo version: 3.2.6, current host:
192.168.255.10, error code: 5-36. This may be caused by , go to https://dubbo.apache.org/faq/5/36 to find instructions.
org.apache.dubbo.rpc.RpcException: Failed to invoke service com.tencent.polaris.dubbo.example.api.GreetingService.sayHi
because exceed max service tps.
代码中无需额外添加限流判断代码,插件会自动在被调端进行请求的限流计算和拦截,假如出现限流,则会返回PolarisBlockException异常给调用端。
访问限流样例包括2个工程,代表的是主调端和被调端,限流行为工作在被调端。
- consumer工程:dubbo-ratelimit-consumer
- provider工程:dubbo-ratelimit-provider
4.5 - 熔断降级
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 2.x 版本的接入,最新版本为
0.2.2 - dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
首先,熔断降级需要依赖以下2个插件,需要将2个插件引入POM中,插件版本建议使用最新版本。
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${revision}<version>
</dependency>
<!-- 北极星熔断功能插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-circuitbreaker-polaris</artifactId>
<version>${revision}</version>
</dependency>
启用北极星熔断降级插件
<dubbo:reference filter="polaris_circuitbreaker">
dubbo.consumer.filter=polaris_circuitbreaker
配置北极星注册中心地址
接下来,需要添加北极星registry的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
<dubbo:registry address="polaris://127.0.0.1:8091"/>
dubbo.registry.address=polaris://127.0.0.1:8091
使用服务熔断
结果验证
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
org.apache.dubbo.rpc.RpcException: Failed to invoke the method sayHi in the service com.tencent.polaris.dubbo.example.
api.GreetingService. Tried 3 times of the providers [192.168.31.119:20880] (1/1) from the registry 127.0.0.1:8091 on
the consumer 192.168.255.10 using the dubbo version 3.2.6. Last error is: com.tencent.polaris.circuitbreak.client.
exception.CallAbortedException: ERR-1020(CLIENT_CIRCUIT_BREAKING): rule application_rule, fallbackInfo null%
使用接口熔断
结果验证
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
org.apache.dubbo.rpc.RpcException: java.util.concurrent.ExecutionException: org.apache.dubbo.rpc.RpcException: I'm bad sayHi provider%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
org.apache.dubbo.rpc.RpcException: java.util.concurrent.ExecutionException: org.apache.dubbo.rpc.RpcException: I'm bad sayHi provider%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
circuitbreaker downgrade info%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
circuitbreaker downgrade info%
使用节点熔断
节点熔断可以根据RPC调用的连续错误数、失败率等统计指标,对异常节点进行剔除,保障请求只会路由到健康的节点上去。
当前支持针对RPC调用的服务名和接口进行设置熔断规则。
规则中,设置针对该服务下节点的调用,出现连续5次的失败, 则熔断该节点。
为了测试熔断效果,服务调用的时候,可以针对服务进行多次调用。
结果验证
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
org.apache.dubbo.rpc.RpcException: java.util.concurrent.ExecutionException: org.apache.dubbo.rpc.RpcException: I'm bad sayHi provider%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
[provider by polaris] hi, 123, source from 2.2.2.2%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
[provider by polaris] hi, 123, source from 2.2.2.2%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
[provider by polaris] hi, 123, source from 2.2.2.2%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
[provider by polaris] hi, 123, source from 2.2.2.2%
➜ ~ curl http://127.0.0.1:15800/echo\?method\=sayHi\&value\=123
样例
熔断样例包括2个工程,代表的是2个服务之间调用,调用链路为:consumer->provider(ok/nok)。
provider 通过环境变量来控制是否返回回包失败,启动的时候设置环境变量 EXCEPTION=true,则该provider进程固定会返回回包异常。
可以启动2个 provider 进程,一个进程启动的时候,不设置 EXCEPTION 变量,代表正常进程;另外一个进程设置 EXCEPTION 变量,代表不正常,用于测试熔断。
环境变量设置
export CONFIG_CENTER_ADDR=127.0.0.1:8093
export METADATA_REPORT_ADDR=127.0.0.1:8091
export POLARIS_DISCOVERY_ADDR=127.0.0.1:8091
export REGISTER_MODE=all
export POD_IP={IP}
- connsumer工程:dubbo-governance-consumer
- provider工程:dubbo-governance-provider
- connsumer工程:dubbo-circuitbreak-consumer
- provider工程:dubbo-circuitbreak-provider
4.6 - 配置中心
提示
Dubbo 动态配置中心仅适用于北极星服务端版本 >= 1.18.0
Dubbo 分类
Dubbo当前常用的有2个分支版本,一个是apache dubbo(GroupID是org.apache.dubbo), 一个是dubbox (GroupID是com.alibaba)。两个分支的dubbo,对应不同的接入插件,大家接入之前可以先通过GroupID判断下当前项目依赖的是哪个分支的dubbo。
Apache Dubbo 接入
支持版本
- dubbo 3.x 版本的接入,最新版本请参考: release
引入依赖
在 pom.xml 中引入以下依赖
<!-- 北极星注册发现插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-registry-polaris</artifactId>
<version>${version}</version>
</dependency>
<!-- 北极星元数据中心插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-metadatareport-polaris</artifactId>
<version>${revision}</version>
</dependency>
<!-- 北极星动态配置中心插件 -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>dubbo-configcenter-polaris</artifactId>
<version>${revision}</version>
</dependency>
参数配置
接下来,需要添加北极星 registry、config-center 的配置,指定北极星的地址及相关配置信息,可以通过配置文件及代码的方式进行指定:
配置文件方式添加:
dubbo.registry.address=polaris://127.0.0.1:8091
dubbo.metadata-report.address=polaris://127.0.0.1:8091
dubbo.config-center.address=polaris://127.0.0.1:8093
北极星地址的URL支持通过参数指定可选的配置,具体参数列表如下:
| 参数 | 类型 | 含义 |
|---|---|---|
| namespace | string | 指定服务的命名空间 |
| token | string | 指定用户token |
| persist_enable | bool | 设置是否开启客户端本地文件容灾缓存 |
| stat_type | string | 设置监控数据上报方式, pull 或者 push |
| stat_pull_port | int | stat_type == pull 时,设置 SDK 额外暴露的 metrics web 端口 |
| stat_push_addr | string | stat_type == push 时,设置 pushgateway 的 IP:PORT 地址 |
| stat_push_interval | int | stat_type == push 时,设置上报周期,单位为毫秒 |
| config_port | int | 设置北极星配置中心链接端口,默认为8093 |
| discover_port | int | 设置北极星注册中心链接端口,默认为8091 |
验证
服务注册样例可以参考:dubbo-discovery-provider
这里我们已 dubbo 本身的 QOS 能力开关做一个示范, 这里我们现在北极星创建一个控制 dubbo QOS 能力的配置
- 北极星配置分组名为 dubbo application name
- dubbo 默认会给配置中心的接入地址填充 namespace 信息为 dubbo
未在配置中心发布 Dubbo 配置
我们在启动 dubbo 应用之后,可以观察到 dubbo 开启了 qos-server
12:36:50.117 |-INFO [main] org.apache.dubbo.qos.server.Server:123 -| [DUBBO] qos-server bind localhost:22222, dubbo version: 3.2.6, current host: 10.21.22.75
在配置中心发布 Dubbo 配置
我们在启动 dubbo 应用之后,可以观察到 dubbo 在启动过程中, 从北极星配置中心读取到到了 dubbo.application.qos-enable=false 配置,因此不会启动 dubbo 内置的 qos-server
15:26:03.571 |-INFO [main] he.dubbo.qos.protocol.QosProtocolWrapper:109 -| [DUBBO] qos won't be started because it is disabled.
Please check dubbo.application.qos.enable is configured either in system property, dubbo.properties or XML/spring-boot configuration., dubbo version: 3.2.6, current host: 10.21.22.75
5 - 使用 gRPC-Java
5.1 - 服务注册
引入依赖
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>grpc-java-polaris</artifactId>
<version>${grpc-java-polaris.version}</version>
</dependency>
初始化 polaris.yaml
你需要在项目的根路径下创建一个 polaris.yaml 文件用于 grpc-java-polaris 初始化 polaris sdk。polaris.yaml配置详细
如何使用
将原本的 ServerBuilder 替换为 PolarisGrpcServerBuilder 即可实现将 gRPC-java 服务注册到北极星中
原本 gRPC-java 的创建方式
server = ServerBuilder.forPort(port).addService(new GreeterImpl()).build().start();
使用 gRPC-java-polaris 的创建方式
Server server = PolarisGrpcServerBuilder.forPort(port).addService(new GreeterImpl()).build().start();
注册信息控制
命名空间
默认情况下,gRPC-java 注册到北极星的 default 命名空间中,如果希望注册到别的命名空间,可通过设置namespace的方式
public class GrpcServerDemo {
public static void main(String[] args) {
Server server = PolarisGrpcServerBuilder
.forPort(0)
.namespace("grpc-java-demo")
.addService(new HelloProvider(metadata))
.addService(new HiProvider())
.build();
Server server = server.start();
JvmHookHelper.addShutdownHook(() -> {
server.shutdown();
});
}
}
注册粒度
默认情况下,gRPC-java的注册粒度是按照 ServerServiceDefinition 来进行注册的,如果希望将整个 gRPC-java 进程作为一个服务进行注册的话,可通过设置 applicationName 的方式
public class GrpcServerDemo {
public static void main(String[] args) {
Server server = PolarisGrpcServerBuilder
.forPort(0)
.applicationName("grpc-java-demo")
.addService(new HelloProvider(metadata))
.addService(new HiProvider())
.build();
Server server = server.start();
JvmHookHelper.addShutdownHook(() -> {
server.shutdown();
});
}
}
实例属性设置
public class GrpcServerDemo {
public static void main(String[] args) {
Server server = PolarisGrpcServerBuilder
.forPort(0)
// 设置实例的权重信息
.weight(int)
// 设置实例的元数据信息
.metadata(Map<String, String>)
// 设置实例的版本信息
.version(String)
.addService(new HelloProvider(metadata))
.addService(new HiProvider())
.build();
Server server = server.start();
JvmHookHelper.addShutdownHook(() -> {
server.shutdown();
});
}
}
如何基于 grpc-java-polaris 完成一个服务注册的程序
5.2 - 服务发现
引入依赖
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>grpc-java-polaris</artifactId>
<version>${grpc-java-polaris.version}</version>
</dependency>
初始化 polaris.yaml
你需要在项目的根路径下创建一个 polaris.yaml 文件用于 grpc-java-polaris 初始化 polaris sdk。polaris.yaml配置详细
如何使用
方式一
SDKContext context = SDKContext.initContext();
ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
.nameResolverFactory(new PolarisNameResolverProvider(context))
.usePlaintext()
.build();
方式二
ManagedChannel channel = PolarisManagedChannelBuilder.forTarget(target).usePlaintext().build();
额外参数设置
命名空间设置
默认情况下,gRPC-java只发现北极星default命名空间中的服务,如果希望发现别的命名空间下的服务,可通过设置url参数的方式
public class GrpcClientDemo {
public static void main(String[] args) {
ManagedChannel channel = PolarisManagedChannelBuilder.forTarget("polaris://grpc-java-demo?namespace=demo")
.usePlaintext()
.build();
}
}
如何基于 grpc-java-polaris 完成一个服务发现的程序
5.3 - 动态路由
当前支持针对 gRPC 消息的以下内容进行动态路由:
| 消息类型 | gRPC 消息内容 | 路由规则请求类型 |
|---|---|---|
| 消息头 | metadata | 请求头(HEADER) |
| gRPC方法 | method | 路径(PATH) |
引入依赖
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>grpc-java-polaris</artifactId>
<version>${grpc-java-polaris.version}</version>
</dependency>
初始化 polaris.yaml
你需要在项目的根路径下创建一个 polaris.yaml 文件用于 grpc-java-polaris 初始化 polaris sdk。polaris.yaml配置详细
gRPC Client 构建
// 使用 grpc-java-polaris 提供的 PolarisManagedChannelBuilder 即可
ManagedChannel channel = PolarisManagedChannelBuilder.forTarget(target).usePlaintext().build();
如何配置动态路由参数
gRPC-Java 中的 PolarisMesh Balancer 扩展点实现,能够根据用户配置的服务路由规则,自动的从当前 RPC 调用上下文以及请求信息中识别出需要参与服务路由的请求标签信息。
假定一个场景:
- 希望 uid 为 user-1 的请求,路由到 env 标签为 dev 的实例上
- 希望 uid 为 user-2 的请求,路由到 env 标签为 pre 的实例上
- 其他则路由到 env 标签为 prod 的实例上,那可以为 gRPC-Java 服务设置三条路由规则。
- 请求匹配规则为 请求头(HEADER):
- 标签来源: RPC 调用的额外标签信息,即 PickSubchannelArgs.getHeaders()
示例代码(gRPC-Java原生使用方式)
Metadata metadata = new Metadata();
headers.forEach((s, val) -> {
if (StringUtils.equals("uid", s.toLowerCase())) {
metadata.put(Key.of(s.toLowerCase(), Metadata.ASCII_STRING_MARSHALLER), val.get(0));
}
})
HelloGrpc.HelloBlockingStub helloBlockingStub = HelloGrpc.newBlockingStub(channel);
helloBlockingStub = helloBlockingStub.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));
HelloPolaris.request request = HelloPolaris.request.newBuilder().setMsg(value).build();
HelloPolaris.response response = helloBlockingStub.sayHello(request);
验证
可根据 grpc-java-polaris example 开展
5.4 - 访问限流
当前支持针对 gRPC 消息的以下内容进行访问限流:
| 消息类型 | gRPC 消息内容 | 路由规则请求类型 |
|---|---|---|
| 消息头 | metadata | 请求头(HEADER) |
| gRPC方法 | method | 路径(PATH) |
引入依赖
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>grpc-java-polaris</artifactId>
<version>${grpc-java-polaris.version}</version>
</dependency>
初始化 polaris.yaml
你需要在项目的根路径下创建一个 polaris.yaml 文件用于 grpc-java-polaris 初始化 polaris sdk。polaris.yaml配置详细
gRPC Server 构建
Server polarisGrpcServer = PolarisGrpcServerBuilder
.forPort(0)
.namespace("default")
.applicationName("RateLimitServerGRPCJava")
// 注入限流的 server 拦截器
.intercept(PolarisHelper.buildRateLimitInterceptor()
.build())
.heartbeatInterval(5)
.addService(new HelloProvider())
.addService(new HiProvider())
.build();
如何配置访问限流参数
gRPC-Java 中的 PolarisMesh RateLimiter 扩展点实现,能够根据用户配置的限流规则,自动的从当前 RPC 调用上下文以及请求信息中识别出需要参与限流的请求标签信息。
比如对 gRPC-Java 中的 sayHello 方法,对 Metadata 中 uid 为 user-1 的进行限流,速率为10/s。
- 请求匹配规则为 请求头(HEADER):
- 标签来源: RPC 调用的额外标签信息,即 interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next)
验证
可根据 grpc-java-polaris example 开展