Merge branch 'main' into main

pull/122/head
lepdou 3 years ago committed by GitHub
commit 954c5d2e6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,3 +3,6 @@
- [Bugfix: fix router bug and add router example](https://github.com/Tencent/spring-cloud-tencent/pull/89)
- [feat:add switch of polaris, discovery and register.](https://github.com/Tencent/spring-cloud-tencent/pull/122)
- [feat:add custom label resolver spi for rate limit](https://github.com/Tencent/spring-cloud-tencent/pull/105)
- [feat:fix discovery weight param not set to register request bug](https://github.com/Tencent/spring-cloud-tencent/pull/102)
- [Bugfix: fix causing cpu 100% when set ScheduledThreadPoolExecutor corePoolSize=0](https://github.com/Tencent/spring-cloud-tencent/pull/98)

@ -1,72 +1,81 @@
# Spring Cloud Tencent
[![Build Status](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml/badge.svg)](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml)
[![Maven Central](https://img.shields.io/maven-central/v/com.tencent.cloud/spring-cloud-tencent?label=Maven%20Central)](https://search.maven.org/search?q=g:com.tencent.cloud%20AND%20a:spring-cloud-tencent)
[English](./README.md) | 简体中文
---
## 介绍
Spring Cloud Tencent包含了分布式应用微服务开发过程中所需的组件,基于 Spring Cloud 框架的开发者可以使用这些组件快速进行分布式应用的开发
Spring Cloud Tencent 是腾讯开发和维护的一站式微服务解决方案
## 主要功能
Spring Cloud Tencent 实现了Spring Cloud 标准微服务 SPI开发者可以基于 Spring Cloud Tencent 快速开发 Spring Cloud 云原生分布式应用。
* **服务注册与发现**:基于 Spring Cloud Common的标准进行微服务的注册与发现。
* **服务路由与负载均衡**:基于 Ribbon 的接口标准,提供场景更丰富的动态路由以及负载均衡的能力。
* **故障节点熔断**:提供故障节点的熔断剔除以及主/被动探测恢复的能力,保证分布式服务的可靠性。
* **服务限流**:支持微服务被调接入层和网关主动调用的限流功能,保证后台微服务稳定性,可通过控制台动态配置规则,及查看流量监控数据。
* **元数据传递**: 支持网关及微服务应用之间的自定义元数据传递。
Spring Cloud Tencent 的核心依托腾讯开源的一站式服务发现与治理平台 [Polaris](https://github.com/polarismesh/polaris),实现各种分布式微服务场景。
## 如何构建
- [Polaris Github home page](https://github.com/polarismesh/polaris)
- [Polaris official website](https://polarismesh.cn/)
* [2020.0.x](https://github.com/Tencent/spring-cloud-tencent/tree/2020.0.x)分支对应的是 Spring Cloud 2020.0版本编译环境最低支持JDK 1.8。
* [main](https://github.com/Tencent/spring-cloud-tencent/tree/main) 分支对应的是 Spring Cloud Hoxton版本编译环境最低支持JDK 1.8。
* [greenwich](https://github.com/Tencent/spring-cloud-tencent/tree/greenwich) 分支对应的是 Spring Cloud Greenwich版本编译环境最低支持JDK 1.8。
Spring Cloud 腾讯提供的能力包括但不限于:
Spring Cloud Tencent 使用 Maven 来构建,最快的使用方式是将本项目 clone 到本地,然后执行以下命令:
```bash
./mvnw install
```
执行完毕后,项目将被安装到本地 Maven 仓库。
- 服务注册和发现
- 动态配置管理
- 服务治理
- 服务电流限制
- 服务断路器
- 服务路由
- ...
- 标签透传
## 如何使用
## 管控台
### 如何引入依赖
<img width="1792" alt="image" src="https://user-images.githubusercontent.com/4991116/163402268-48493802-4555-4b93-8e31-011410f2166b.png">
在 dependencyManagement 中添加如下配置,然后在 dependencies 中添加自己所需使用的依赖即可使用。
## 使用指南
````
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<version>1.1.4.Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
````
Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要引入依赖即可。
### 使用文档
- [Spring Cloud Tencent 版本管理](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86)
- [服务注册与发现](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3)
- [配置中心](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3)
- [服务限流](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3)
- [服务熔断](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3)
- [服务路由](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3)
- [元数据传递](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97)
例如:
## 版本号规范
```` xml
<!-- add spring-cloud-tencent bom -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<!--version number-->
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- add spring-cloud-starter-tencent-polaris-discovery dependency -->
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
</dependencies>
采取与Spring Cloud大版本号相关的版本策略。
项目的版本号格式为 ```大版本号.小版本号.补丁版本号-对应Spring Cloud的大版本号.对应Spring Cloud的小版本号-发布类型``` 的形式。
大版本号、小版本号、补丁版本号的类型为数字,从 0 开始取值。
对应Spring Cloud的大版本号为Spring Cloud提供的英文版本号例如Hoxton、Greenwich等。对应Spring Cloud的小版本号为Spring Cloud给出的小版本号例如 RS9 等。
发布类型目前包括正式发布和发布候选版RC。在实际的版本号中正式发布版不额外添加发布类型发布候选版将添加后缀并从 RC0 开始。
````
示例1.2.0-Hoxton.SR9-RC0
- ### 快速开始
- [Spring Cloud Tencent 版本管理](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Version-Management)
- [Spring Cloud Tencent 服务注册与发现](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-Usage-Documentation)
- [Spring Cloud Tencent 配置中心](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-Usage-Documentation)
- [Spring Cloud Tencent 限流](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-Usage-Document)
- [Spring Cloud Tencent 熔断](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-Usage-Document)
- [Spring Cloud Tencent 服务路由](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-Usage-Document)
- [Spring Cloud Tencent 标签传递](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-Usage-Document)
- ### 开发文档
- [项目概览](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88)
- [参与共建](https://github.com/Tencent/spring-cloud-tencent/wiki/Contributing)
## License
The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in the file [LICENSE](LICENSE)

@ -7,76 +7,73 @@ English | [简体中文](./README-zh.md)
## Introduction
Spring Cloud Tencent contains components distributed micro-service applications need during developing phase, developers that built their key architectures based on Spring Cloud can use these components
Based on Spring Cloud Tencent, you only need a small configuration to launch Spring Cloud and micro-service's joint solutions.
## Key Features
* **Service Registration and Discovery**: Based on Spring Cloud's discovery and registration standard.
* **Service Routing and LoadBalancer**: Based on ribbon's API port, provide dynamic routing and load balancing use cases.
* **CircuitBreaker Node**: Support circuitbreaker auto-reset ability, ensure the reliability of distributed server
* **Rate Limiter**: Support rate limit of microservice and gateway, ensure the stability of backend, one can configure policies and traffic data from the control panel
* **Metadata Delivery**: Support metadata delivery between gateways and microservices.
## Components
**[Polaris](https://github.com/PolarisMesh/polaris)**Polaris Spring Cloud operation centre, provide solutions to registration, dynamic routing, load balancing and circuitbreaker.
## How to build
* master's branch matches Spring Cloud Hoxton, support lowest at JDK 1.8.
Spring Cloud Tencent uses Maven to construct, the fastest way is to clone project to local files, then execute the following orders:
```bash
./mvnw install
```
When all the steps are finished, the project will be installed in local Maven repository.
## How to Use
### How to Introduce Dependency
Add the following configurations in dependencyManagement, then add the dependencies you need.
At the same time, you need to pay attention to the Spring Cloud version corresponding to Spring Cloud Tencent, and then the corresponding Spring Boot version.
For example, Spring Cloud Tencent's 1.0.1.Hoxton.SR9 corresponds to the Spring Cloud Hoxton version and requires Spring Boot 2.3.x.
Spring Cloud Tencent is a one-stop microservice solution developed and maintained by Tencent.
Spring Cloud Tencent implements the Spring Cloud standard microservice SPI, so developers can quickly develop Spring Cloud cloud-native distributed applications based on Spring Cloud Tencent.
The core of Spring Cloud Tencent relies on Tencent's open-source one-stop service discovery and governance platform [Polaris](https://github.com/polarismesh/polaris) to realize various distributed microservice scenarios.
- [Polaris Github home page](https://github.com/polarismesh/polaris)
- [Polaris official website](https://polarismesh.cn/)
The capabilities provided by Spring Cloud Tencent include but are not limited to:
- Service registration and discovery
- Dynamic configuration management
- Service Governance
- Service rate limit
- Service circuit breaker
- Service routing
- ...
- Label transparent transmission
## Screenshots
<img width="1792" alt="image" src="https://user-images.githubusercontent.com/4991116/163402268-48493802-4555-4b93-8e31-011410f2166b.png">
## Use Guide
All the components of Spring Cloud Tencent have been uploaded to the Maven central repository, just need to introduce dependencies.
For example:
```` xml
<!-- add spring-cloud-tencent bom -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<!--version number-->
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- add spring-cloud-starter-tencent-polaris-discovery dependency -->
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
</dependencies>
````
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<!--version number-->
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
````
### Starter Usage Doc
- [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Version-Management)
- [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-Usage-Documentation)
- [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-Usage-Documentation)
- [Spring Cloud Tencent Rate Limit](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-Usage-Document)
- [Spring Cloud Tencent CircuitBreaker](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-Usage-Document)
- [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-Usage-Document)
- [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-Usage-Document)
### Version Standard
We use a version policy related to Spring Cloud's major version number.
Project version includes ```${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}-${CORRESPONDING_MAJOR_VERSION_OF_SPRING_CLOUD}.${CORRESPONDING_MINOR_VERSION_OF_SPRING_CLOUD}-${RELEASE_TYPE}```.
```${MAJOR_VERSION}```, ```${MINOR_VERSION}```, ```${PATCH_VERSION}``` are in numbers starting from 0.
```${CORRESPONDING_MAJOR_VERSION_OF_SPRING_CLOUD}``` is the same as the major version number of Spring Cloud, like Hoxton, Greenwich. ```${CORRESPONDING_MINOR_VERSION_OF_SPRING_CLOUD}``` is the same as the major version number of Spring Cloud, like RS9.
```${RELEASE_TYPE}``` is like RELEASE or RC currently. Actually, the RELEASE version does not add a release type in the version, and the RS version will add a suffix and start from RC0.
For example: 1.2.0-Hoxton.SR9-RC0
- ### Quick Start
- [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Version-Management)
- [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-Usage-Documentation)
- [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-Usage-Documentation)
- [Spring Cloud Tencent Rate Limit](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-Usage-Document)
- [Spring Cloud Tencent CircuitBreaker](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-Usage-Document)
- [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-Usage-Document)
- [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-Usage-Document)
- ### Development Documentation
- [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88)
- [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/Contributing)
## License
The spring-cloud-tencent is licensed under the BSD 3-Clause License. Copyright and license information can be found in the file [LICENSE](LICENSE)

@ -63,7 +63,7 @@ public class PolarisDiscoveryProperties {
* Load balance weight.
*/
@Value("${spring.cloud.polaris.discovery.weight:#{100}}")
private float weight;
private int weight;
/**
* Version number.
@ -146,11 +146,11 @@ public class PolarisDiscoveryProperties {
this.namespace = namespace;
}
public float getWeight() {
public int getWeight() {
return weight;
}
public void setWeight(float weight) {
public void setWeight(int weight) {
this.weight = weight;
}

@ -18,8 +18,8 @@
package com.tencent.cloud.polaris.registry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
@ -71,13 +71,11 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
this.polarisDiscoveryHandler = polarisDiscoveryHandler;
this.metadataLocalProperties = metadataLocalProperties;
if (polarisDiscoveryProperties.isHeartbeatEnabled()) {
ScheduledThreadPoolExecutor heartbeatExecutor = new ScheduledThreadPoolExecutor(
0, new NamedThreadFactory("spring-cloud-heartbeat"));
heartbeatExecutor.setMaximumPoolSize(1);
this.heartbeatExecutor = heartbeatExecutor;
}
else {
this.heartbeatExecutor = Executors
.newSingleThreadScheduledExecutor(new NamedThreadFactory("spring-cloud-heartbeat"));
} else {
this.heartbeatExecutor = null;
}
}
@ -95,6 +93,7 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
instanceRegisterRequest.setService(registration.getServiceId());
instanceRegisterRequest.setHost(registration.getHost());
instanceRegisterRequest.setPort(registration.getPort());
instanceRegisterRequest.setWeight(polarisDiscoveryProperties.getWeight());
instanceRegisterRequest.setToken(polarisDiscoveryProperties.getToken());
if (null != heartbeatExecutor) {
instanceRegisterRequest.setTtl(ttl);

@ -56,7 +56,7 @@
},
{
"name": "spring.cloud.polaris.weight",
"type": "java.lang.String",
"type": "java.lang.Integer",
"defaultValue": 100,
"description": "the weight of polaris instance , use to load-balance."
}

@ -13,6 +13,7 @@
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.polaris.ratelimit.config;
@ -21,6 +22,8 @@ import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter;
import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
import com.tencent.polaris.client.api.SDKContext;
import com.tencent.polaris.ratelimit.api.core.LimitAPI;
import com.tencent.polaris.ratelimit.factory.LimitAPIFactory;
@ -31,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import static javax.servlet.DispatcherType.ASYNC;
import static javax.servlet.DispatcherType.ERROR;
@ -62,8 +66,9 @@ public class RateLimitConfiguration {
@Bean
@ConditionalOnMissingBean
public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI) {
return new QuotaCheckServletFilter(limitAPI);
public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI,
@Nullable PolarisRateLimiterLabelServletResolver labelResolver) {
return new QuotaCheckServletFilter(limitAPI, labelResolver);
}
@Bean
@ -87,8 +92,9 @@ public class RateLimitConfiguration {
static class MetadataReactiveFilterConfig {
@Bean
public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI) {
return new QuotaCheckReactiveFilter(limitAPI);
public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI,
@Nullable PolarisRateLimiterLabelReactiveResolver labelResolver) {
return new QuotaCheckReactiveFilter(limitAPI, labelResolver);
}
}

@ -37,6 +37,11 @@ public final class RateLimitConstant {
*/
public static String QUOTA_LIMITED_INFO = "The request is deny by rate limit because the throttling threshold is reached";
/**
* The build in label method.
*/
public static String LABEL_METHOD = "method";
private RateLimitConstant() {
}

@ -13,6 +13,7 @@
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.polaris.ratelimit.filter;
@ -23,6 +24,7 @@ import java.util.Map;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils;
import com.tencent.polaris.ratelimit.api.core.LimitAPI;
import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
@ -37,10 +39,13 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import static com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant.LABEL_METHOD;
/**
* Reactive filter to check quota.
*
@ -53,8 +58,12 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
private final LimitAPI limitAPI;
public QuotaCheckReactiveFilter(LimitAPI limitAPI) {
private final PolarisRateLimiterLabelReactiveResolver labelResolver;
public QuotaCheckReactiveFilter(LimitAPI limitAPI,
PolarisRateLimiterLabelReactiveResolver labelResolver) {
this.limitAPI = limitAPI;
this.labelResolver = labelResolver;
}
@Override
@ -66,23 +75,37 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String localNamespace = MetadataContext.LOCAL_NAMESPACE;
String localService = MetadataContext.LOCAL_SERVICE;
String method = exchange.getRequest().getURI().getPath();
Map<String, String> labels = null;
if (StringUtils.isNotBlank(method)) {
labels = new HashMap<>();
labels.put("method", method);
Map<String, String> labels = new HashMap<>();
// add build in labels
String path = exchange.getRequest().getURI().getPath();
if (StringUtils.isNotBlank(path)) {
labels.put(LABEL_METHOD, path);
}
// add custom labels
if (labelResolver != null) {
try {
Map<String, String> customLabels = labelResolver.resolve(exchange);
if (!CollectionUtils.isEmpty(customLabels)) {
labels.putAll(customLabels);
}
} catch (Throwable e) {
LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
}
}
try {
QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI,
localNamespace, localService, 1, labels, null);
if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
DataBuffer dataBuffer = response.bufferFactory().allocateBuffer().write(
(RateLimitConstant.QUOTA_LIMITED_INFO + quotaResponse.getInfo())
.getBytes(StandardCharsets.UTF_8));
RateLimitConstant.QUOTA_LIMITED_INFO.getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(dataBuffer));
}
}

@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils;
import com.tencent.polaris.ratelimit.api.core.LimitAPI;
import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
@ -38,8 +39,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import static com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant.LABEL_METHOD;
import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS;
/**
@ -54,9 +57,11 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
.getLogger(QuotaCheckServletFilter.class);
private final LimitAPI limitAPI;
private final PolarisRateLimiterLabelServletResolver labelResolver;
public QuotaCheckServletFilter(LimitAPI limitAPI) {
public QuotaCheckServletFilter(LimitAPI limitAPI, PolarisRateLimiterLabelServletResolver labelResolver) {
this.limitAPI = limitAPI;
this.labelResolver = labelResolver;
}
@Override
@ -65,11 +70,26 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
throws ServletException, IOException {
String localNamespace = MetadataContext.LOCAL_NAMESPACE;
String localService = MetadataContext.LOCAL_SERVICE;
String method = request.getRequestURI();
Map<String, String> labels = null;
if (StringUtils.isNotBlank(method)) {
labels = new HashMap<>();
labels.put("method", method);
Map<String, String> labels = new HashMap<>();
// add build in labels
String path = request.getRequestURI();
if (StringUtils.isNotBlank(path)) {
labels.put(LABEL_METHOD, path);
}
// add custom labels
if (labelResolver != null) {
try {
Map<String, String> customLabels = labelResolver.resolve(request);
if (!CollectionUtils.isEmpty(customLabels)) {
labels.putAll(customLabels);
}
} catch (Throwable e) {
LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
}
}
try {

@ -0,0 +1,40 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.polaris.ratelimit.spi;
import java.util.Map;
import org.springframework.web.server.ServerWebExchange;
/**
* Resolve custom label from request. The label used for rate limit params.
*
* @author lepdou 2022-03-31
*/
public interface PolarisRateLimiterLabelReactiveResolver {
/**
* Resolve custom label from request.
*
* @param exchange the http request
* @return resolved labels
*/
Map<String, String> resolve(ServerWebExchange exchange);
}

@ -0,0 +1,40 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.polaris.ratelimit.spi;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
* Resolve custom label from request. The label used for rate limit params.
*
* @author lepdou 2022-03-31
*/
public interface PolarisRateLimiterLabelServletResolver {
/**
* Resolve custom label from request.
*
* @param request the http request
* @return resolved labels
*/
Map<String, String> resolve(HttpServletRequest request);
}

@ -0,0 +1,47 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
*/
package com.tencent.cloud.ratelimit.example.service.callee;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
import org.springframework.stereotype.Component;
/**
* resolver custom label from request.
*
*@author lepdou 2022-03-31
*/
@Component
public class CustomLabelResolver implements PolarisRateLimiterLabelServletResolver {
@Override
public Map<String, String> resolve(HttpServletRequest request) {
//rate limit by some request params. such as query params, headers ..
Map<String, String> labels = new HashMap<>();
labels.put("user", "zhangsan");
return labels;
}
}

@ -7,8 +7,7 @@ spring:
tencent:
metadata:
content:
version: v2
xx: zz
label1: value2
polaris:
address: grpc://127.0.0.1:8091
namespace: default

Loading…
Cancel
Save