diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06c1f8175..85aeb11af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
 # Change Log
 ---
 
+- [feature:add PolarisRateLimiterLimitedFallback spi.](https://github.com/Tencent/spring-cloud-tencent/commit/52689515f5dd7f1ddf22dbe9b62fcd9d19fc8dbe)
+- [fix:fix the error capture of rate limit exception.](https://github.com/Tencent/spring-cloud-tencent/commit/edeeaded922ee3837eb5a58582a62f1f4c77608e)
+- [feat:enable stat reporting as default.](https://github.com/Tencent/spring-cloud-tencent/commit/f97a1b2450bfba047d22e96a85e2ab39e849f4a0)
+- [refactor:update to junit 5.](https://github.com/Tencent/spring-cloud-tencent/commit/21953e17b6549e0ce52fc4df0a94f96a10dbe0c5)
+- [docs:support auto snapshot release in GitHub Action.](https://github.com/Tencent/spring-cloud-tencent/commit/da2422ae71f83d229e8c322ce2ccd5850ffa8653)
+- [feature:add User-Agent:polaris for healthyCheck api.](https://github.com/Tencent/spring-cloud-tencent/commit/b2cecba273bfd0eaf5160791c1efe3acb01d0bfe)
+- [optimize ServiceRuleManager](https://github.com/Tencent/spring-cloud-tencent/commit/07f04174ca487cf1db1d9c19bbe44853e2bcf117)
+- [refactor:refactor stat module.](https://github.com/Tencent/spring-cloud-tencent/commit/9408bfbb948446738c050b3b18d8ed3124da36c1)
+- [fix:fix NPE.](https://github.com/Tencent/spring-cloud-tencent/commit/17a9a8d75aef6ed39a0a1c7aa4b7d547f5d3d40e)
+- [refactor:optimize sct-all.](https://github.com/Tencent/spring-cloud-tencent/commit/3859cd7eefcd93752d05113597656e584d97c38d)
+- [feature:add polaris circuit breaker support]()
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9ee70db2c..0117853f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,7 +89,7 @@
 
 	<properties>
 		<!-- Project revision -->
-		<revision>1.11.1-Hoxton.SR12-SNAPSHOT</revision>
+		<revision>1.11.2-Hoxton.SR12-SNAPSHOT</revision>
 
 		<!-- Spring Framework -->
 		<spring.framework.version>5.2.22.RELEASE</spring.framework.version>
diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java
index a8966025d..d3bfe31e4 100644
--- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java
@@ -29,6 +29,7 @@ import com.tencent.cloud.metadata.core.DecodeTransferMetadataServletFilter;
 import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor;
 import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor;
 import com.tencent.cloud.metadata.core.EncodeTransferMedataScgFilter;
+import com.tencent.cloud.metadata.core.EncodeTransferMedataWebClientFilter;
 import com.tencent.cloud.metadata.core.EncodeTransferMetadataZuulFilter;
 
 import org.springframework.beans.factory.SmartInitializingSingleton;
@@ -41,6 +42,7 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
 
 import static javax.servlet.DispatcherType.ASYNC;
 import static javax.servlet.DispatcherType.ERROR;
@@ -66,10 +68,12 @@ public class MetadataTransferAutoConfiguration {
 		@Bean
 		public FilterRegistrationBean<DecodeTransferMetadataServletFilter> metadataServletFilterRegistrationBean(
 				DecodeTransferMetadataServletFilter decodeTransferMetadataServletFilter) {
-			FilterRegistrationBean<DecodeTransferMetadataServletFilter> filterRegistrationBean =
-					new FilterRegistrationBean<>(decodeTransferMetadataServletFilter);
-			filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST);
-			filterRegistrationBean.setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER);
+			FilterRegistrationBean<DecodeTransferMetadataServletFilter> filterRegistrationBean = new FilterRegistrationBean<>(
+					decodeTransferMetadataServletFilter);
+			filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE,
+					REQUEST);
+			filterRegistrationBean
+					.setOrder(MetadataConstant.OrderConstant.WEB_FILTER_ORDER);
 			return filterRegistrationBean;
 		}
 
@@ -77,7 +81,6 @@ public class MetadataTransferAutoConfiguration {
 		public DecodeTransferMetadataServletFilter metadataServletFilter() {
 			return new DecodeTransferMetadataServletFilter();
 		}
-
 	}
 
 	/**
@@ -133,7 +136,6 @@ public class MetadataTransferAutoConfiguration {
 		public EncodeTransferMedataFeignInterceptor encodeTransferMedataFeignInterceptor() {
 			return new EncodeTransferMedataFeignInterceptor();
 		}
-
 	}
 
 	/**
@@ -160,4 +162,26 @@ public class MetadataTransferAutoConfiguration {
 			});
 		}
 	}
+
+	/**
+	 * Create when WebClient.Builder exists.
+	 */
+	@Configuration(proxyBeanMethods = false)
+	@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
+	protected static class MetadataTransferWebClientConfig {
+		@Autowired(required = false)
+		private List<WebClient.Builder> webClientBuilder = Collections.emptyList();
+
+		@Bean
+		public EncodeTransferMedataWebClientFilter encodeTransferMedataWebClientFilter() {
+			return new EncodeTransferMedataWebClientFilter();
+		}
+
+		@Bean
+		public SmartInitializingSingleton addEncodeTransferMetadataFilterForWebClient(EncodeTransferMedataWebClientFilter filter) {
+			return () -> webClientBuilder.forEach(webClient -> {
+				webClient.filter(filter);
+			});
+		}
+	}
 }
diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilter.java
new file mode 100644
index 000000000..3547add0e
--- /dev/null
+++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilter.java
@@ -0,0 +1,90 @@
+/*
+ * 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.metadata.core;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Map;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.common.util.JacksonUtils;
+import reactor.core.publisher.Mono;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.ExchangeFunction;
+
+import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
+import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA;
+import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA;
+
+/**
+ * web client filter used for writing metadata in HTTP request header.
+ *
+ * @author sean yu
+ */
+public class EncodeTransferMedataWebClientFilter implements ExchangeFilterFunction {
+
+	@Override
+	public Mono<ClientResponse> filter(ClientRequest clientRequest, ExchangeFunction next) {
+		MetadataContext metadataContext = MetadataContextHolder.get();
+		Map<String, String> customMetadata = metadataContext.getCustomMetadata();
+		Map<String, String> disposableMetadata = metadataContext.getDisposableMetadata();
+		Map<String, String> transHeaders = metadataContext.getTransHeadersKV();
+
+		ClientRequest.Builder requestBuilder = ClientRequest.from(clientRequest);
+
+		this.buildMetadataHeader(requestBuilder, customMetadata, CUSTOM_METADATA);
+		this.buildMetadataHeader(requestBuilder, disposableMetadata, CUSTOM_DISPOSABLE_METADATA);
+		this.buildTransmittedHeader(requestBuilder, transHeaders);
+
+		ClientRequest request = requestBuilder.build();
+
+		return next.exchange(request);
+	}
+
+	private void buildTransmittedHeader(ClientRequest.Builder requestBuilder, Map<String, String> transHeaders) {
+		if (!CollectionUtils.isEmpty(transHeaders)) {
+			transHeaders.forEach(requestBuilder::header);
+		}
+	}
+
+
+	/**
+	 * Set metadata into the request header for {@link ClientRequest} .
+	 * @param requestBuilder instance of {@link ClientRequest.Builder}
+	 * @param metadata metadata map .
+	 * @param headerName target metadata http header name .
+	 */
+	private void buildMetadataHeader(ClientRequest.Builder requestBuilder, Map<String, String> metadata, String headerName) {
+		if (!CollectionUtils.isEmpty(metadata)) {
+			String encodedMetadata = JacksonUtils.serialize2Json(metadata);
+			try {
+				requestBuilder.header(headerName, URLEncoder.encode(encodedMetadata, UTF_8));
+			}
+			catch (UnsupportedEncodingException e) {
+				requestBuilder.header(headerName, encodedMetadata);
+			}
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java
index 7f3164e3e..cd23e7615 100644
--- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java
+++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfigurationTest.java
@@ -26,10 +26,12 @@ import java.util.stream.Collectors;
 
 import com.tencent.cloud.metadata.core.EncodeTransferMedataFeignInterceptor;
 import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateInterceptor;
+import com.tencent.cloud.metadata.core.EncodeTransferMedataWebClientFilter;
 import org.junit.jupiter.api.Test;
 
 import org.springframework.boot.autoconfigure.AutoConfigurations;
 import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 import org.springframework.cloud.gateway.filter.GlobalFilter;
 import org.springframework.context.annotation.Bean;
@@ -47,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class MetadataTransferAutoConfigurationTest {
 
 	private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner();
+	private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner();
 
 	/**
 	 * No any web application.
@@ -88,6 +91,23 @@ public class MetadataTransferAutoConfigurationTest {
 				});
 	}
 
+	/**
+	 * Reactive web application.
+	 */
+	@Test
+	public void test3() {
+		this.reactiveWebApplicationContextRunner.withConfiguration(AutoConfigurations.of(MetadataTransferAutoConfiguration.class))
+				.run(context -> {
+					assertThat(context).hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferFeignInterceptorConfig.class);
+					assertThat(context).hasSingleBean(EncodeTransferMedataFeignInterceptor.class);
+					assertThat(context).hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferRestTemplateConfig.class);
+					assertThat(context).hasSingleBean(EncodeTransferMedataRestTemplateInterceptor.class);
+					assertThat(context).hasSingleBean(MetadataTransferAutoConfiguration.MetadataTransferScgFilterConfig.class);
+					assertThat(context).hasSingleBean(GlobalFilter.class);
+					assertThat(context).hasSingleBean(EncodeTransferMedataWebClientFilter.class);
+				});
+	}
+
 	@Configuration
 	static class RestTemplateConfiguration {
 
diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilterTest.java
new file mode 100644
index 000000000..85c8b2d35
--- /dev/null
+++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientFilterTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.metadata.core;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+/**
+ * Test for {@link EncodeTransferMedataWebClientFilter}.
+ *
+ * @author sean yu
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT,
+		classes = EncodeTransferMedataWebClientFilterTest.TestApplication.class,
+		properties = {"spring.config.location = classpath:application-test.yml",
+				"spring.main.web-application-type = reactive"})
+public class EncodeTransferMedataWebClientFilterTest {
+
+	@Autowired
+	private WebClient.Builder webClientBuilder;
+	@LocalServerPort
+	private int localServerPort;
+
+	@Test
+	public void testTransitiveMetadataFromApplicationConfig() {
+		MetadataContext metadataContext = MetadataContextHolder.get();
+		metadataContext.setTransHeadersKV("xxx", "xxx");
+		String metadata = webClientBuilder.baseUrl("http://localhost:" + localServerPort).build()
+				.get()
+				.uri("/test")
+				.retrieve()
+				.bodyToMono(String.class)
+				.block();
+		assertThat(metadata).isEqualTo("2");
+	}
+
+	@SpringBootApplication
+	@RestController
+	protected static class TestApplication {
+
+		@Bean
+		public WebClient.Builder webClientBuilder() {
+			return WebClient.builder();
+		}
+
+		@RequestMapping("/test")
+		public String test() {
+			return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b");
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
index 20bf4bdf2..5cc0cff59 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
@@ -15,8 +15,34 @@
 	<dependencies>
 		<!-- Spring Cloud Tencent dependencies start -->
 		<dependency>
-			<groupId>com.tencent.cloud</groupId>
-			<artifactId>spring-cloud-tencent-polaris-loadbalancer</artifactId>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-webflux</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-openfeign</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-gateway</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
+			<optional>true</optional>
 		</dependency>
 
 		<dependency>
@@ -60,6 +86,21 @@
 				</exclusion>
 			</exclusions>
 		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>healthchecker-http</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>healthchecker-udp</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>healthchecker-tcp</artifactId>
+		</dependency>
 		<!-- Polaris dependencies end -->
 
 		<dependency>
@@ -67,5 +108,35 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>polaris-test-common</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>polaris-test-mock-discovery</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-inline</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>io.projectreactor</groupId>
+			<artifactId>reactor-test</artifactId>
+			<scope>test</scope>
+		</dependency>
 	</dependencies>
 </project>
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreaker.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreaker.java
new file mode 100644
index 000000000..3f247093d
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreaker.java
@@ -0,0 +1,102 @@
+/*
+ * 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.circuitbreaker;
+
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisResultToErrorCode;
+import com.tencent.cloud.polaris.circuitbreaker.util.PolarisCircuitBreakerUtils;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.api.FunctionalDecorator;
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import com.tencent.polaris.circuitbreak.api.pojo.FunctionalDecoratorRequest;
+import com.tencent.polaris.circuitbreak.api.pojo.InvokeContext;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+
+/**
+ * PolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreaker implements CircuitBreaker, InvokeHandler {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCircuitBreaker.class);
+	private final PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf;
+	private final ConsumerAPI consumerAPI;
+	private final FunctionalDecorator decorator;
+	private final InvokeHandler invokeHandler;
+
+	public PolarisCircuitBreaker(PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf,
+			ConsumerAPI consumerAPI,
+			CircuitBreakAPI circuitBreakAPI) {
+		FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest(new ServiceKey(conf.getNamespace(), conf.getService()), conf.getMethod());
+		makeDecoratorRequest.setSourceService(new ServiceKey(conf.getSourceNamespace(), conf.getSourceService()));
+		makeDecoratorRequest.setResultToErrorCode(new PolarisResultToErrorCode());
+		this.consumerAPI = consumerAPI;
+		this.conf = conf;
+		this.decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
+		this.invokeHandler = circuitBreakAPI.makeInvokeHandler(makeDecoratorRequest);
+	}
+
+	@Override
+	public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
+		Supplier<T> toRunDecorator = decorator.decorateSupplier(toRun);
+		try {
+			return toRunDecorator.get();
+		}
+		catch (CallAbortedException e) {
+			LOGGER.debug("PolarisCircuitBreaker CallAbortedException: {}", e.getMessage());
+			PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, e);
+			return fallback.apply(e);
+		}
+		catch (Exception e) {
+			return fallback.apply(e);
+		}
+	}
+
+	@Override
+	public void acquirePermission() {
+		invokeHandler.acquirePermission();
+	}
+
+	@Override
+	public void onSuccess(InvokeContext.ResponseContext responseContext) {
+		invokeHandler.onSuccess(responseContext);
+	}
+
+	@Override
+	public void onError(InvokeContext.ResponseContext responseContext) {
+		invokeHandler.onError(responseContext);
+	}
+
+	public PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration getConf() {
+		return conf;
+	}
+
+	public ConsumerAPI getConsumerAPI() {
+		return consumerAPI;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFactory.java
new file mode 100644
index 000000000..1c789befe
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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.circuitbreaker;
+
+import java.util.function.Function;
+
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.util.PolarisCircuitBreakerUtils;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+
+/**
+ * PolarisCircuitBreakerFactory.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerFactory
+		extends CircuitBreakerFactory<PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration, PolarisCircuitBreakerConfigBuilder> {
+
+	private Function<String, PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration> defaultConfiguration =
+			id -> {
+				String[] metadata = PolarisCircuitBreakerUtils.resolveCircuitBreakerId(id);
+				return new PolarisCircuitBreakerConfigBuilder()
+						.namespace(metadata[0])
+						.service(metadata[1])
+						.method(metadata[2])
+						.build();
+			};
+
+
+	private final CircuitBreakAPI circuitBreakAPI;
+
+	private final ConsumerAPI consumerAPI;
+
+	public PolarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) {
+		this.circuitBreakAPI = circuitBreakAPI;
+		this.consumerAPI = consumerAPI;
+	}
+
+	@Override
+	public CircuitBreaker create(String id) {
+		PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf = getConfigurations()
+				.computeIfAbsent(id, defaultConfiguration);
+		return new PolarisCircuitBreaker(conf, consumerAPI, circuitBreakAPI);
+	}
+
+	@Override
+	protected PolarisCircuitBreakerConfigBuilder configBuilder(String id) {
+		String[] metadata = PolarisCircuitBreakerUtils.resolveCircuitBreakerId(id);
+		return new PolarisCircuitBreakerConfigBuilder(metadata[0], metadata[1], metadata[2]);
+	}
+
+	@Override
+	public void configureDefault(Function<String, PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration> defaultConfiguration) {
+		this.defaultConfiguration = defaultConfiguration;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreaker.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreaker.java
new file mode 100644
index 000000000..56b633ef4
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreaker.java
@@ -0,0 +1,91 @@
+/*
+ * 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.circuitbreaker;
+
+import java.util.function.Function;
+
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisResultToErrorCode;
+import com.tencent.cloud.polaris.circuitbreaker.reactor.PolarisCircuitBreakerReactorTransformer;
+import com.tencent.cloud.polaris.circuitbreaker.util.PolarisCircuitBreakerUtils;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import com.tencent.polaris.circuitbreak.api.pojo.FunctionalDecoratorRequest;
+import com.tencent.polaris.circuitbreak.api.pojo.InvokeContext;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
+
+/**
+ * ReactivePolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class ReactivePolarisCircuitBreaker implements ReactiveCircuitBreaker {
+
+	private final InvokeHandler invokeHandler;
+
+	private final ConsumerAPI consumerAPI;
+
+	private final PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf;
+
+	public ReactivePolarisCircuitBreaker(PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf,
+			ConsumerAPI consumerAPI,
+			CircuitBreakAPI circuitBreakAPI) {
+		InvokeContext.RequestContext requestContext = new FunctionalDecoratorRequest(new ServiceKey(conf.getNamespace(), conf.getService()), conf.getMethod());
+		requestContext.setSourceService(new ServiceKey(conf.getSourceNamespace(), conf.getSourceService()));
+		requestContext.setResultToErrorCode(new PolarisResultToErrorCode());
+		this.consumerAPI = consumerAPI;
+		this.conf = conf;
+		this.invokeHandler = circuitBreakAPI.makeInvokeHandler(requestContext);
+	}
+
+
+	@Override
+	public <T> Mono<T> run(Mono<T> toRun, Function<Throwable, Mono<T>> fallback) {
+		Mono<T> toReturn = toRun.transform(new PolarisCircuitBreakerReactorTransformer<>(invokeHandler));
+		if (fallback != null) {
+			toReturn = toReturn.onErrorResume(throwable -> {
+				if (throwable instanceof CallAbortedException) {
+					PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, (CallAbortedException) throwable);
+				}
+				return fallback.apply(throwable);
+			});
+		}
+		return toReturn;
+	}
+
+	@Override
+	public <T> Flux<T> run(Flux<T> toRun, Function<Throwable, Flux<T>> fallback) {
+		Flux<T> toReturn = toRun.transform(new PolarisCircuitBreakerReactorTransformer<>(invokeHandler));
+		if (fallback != null) {
+			toReturn = toReturn.onErrorResume(throwable -> {
+				if (throwable instanceof CallAbortedException) {
+					PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, (CallAbortedException) throwable);
+				}
+				return fallback.apply(throwable);
+			});
+		}
+		return toReturn;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerFactory.java
new file mode 100644
index 000000000..0a7bbb01f
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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.circuitbreaker;
+
+import java.util.function.Function;
+
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.util.PolarisCircuitBreakerUtils;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
+
+/**
+ * ReactivePolarisCircuitBreakerFactory.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class ReactivePolarisCircuitBreakerFactory extends
+		ReactiveCircuitBreakerFactory<PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration, PolarisCircuitBreakerConfigBuilder> {
+
+	private Function<String, PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration> defaultConfiguration =
+			id -> {
+				String[] metadata = PolarisCircuitBreakerUtils.resolveCircuitBreakerId(id);
+				return new PolarisCircuitBreakerConfigBuilder()
+						.namespace(metadata[0])
+						.service(metadata[1])
+						.method(metadata[2])
+						.build();
+			};
+
+	private final CircuitBreakAPI circuitBreakAPI;
+
+	private final ConsumerAPI consumerAPI;
+
+	public ReactivePolarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) {
+		this.circuitBreakAPI = circuitBreakAPI;
+		this.consumerAPI = consumerAPI;
+	}
+
+	@Override
+	public ReactiveCircuitBreaker create(String id) {
+		PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf = getConfigurations()
+				.computeIfAbsent(id, defaultConfiguration);
+		return new ReactivePolarisCircuitBreaker(conf, consumerAPI, circuitBreakAPI);
+	}
+
+	@Override
+	protected PolarisCircuitBreakerConfigBuilder configBuilder(String id) {
+		String[] metadata = PolarisCircuitBreakerUtils.resolveCircuitBreakerId(id);
+		return new PolarisCircuitBreakerConfigBuilder(metadata[0], metadata[1], metadata[2]);
+	}
+
+	@Override
+	public void configureDefault(
+			Function<String, PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration> defaultConfiguration) {
+		this.defaultConfiguration = defaultConfiguration;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/CircuitBreakerConfigModifier.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/CircuitBreakerConfigModifier.java
new file mode 100644
index 000000000..220d98490
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/CircuitBreakerConfigModifier.java
@@ -0,0 +1,62 @@
+/*
+ * 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.circuitbreaker.common;
+
+import com.tencent.cloud.common.constant.ContextConstant;
+import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
+
+/**
+ * CircuitBreakerConfigModifier.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class CircuitBreakerConfigModifier implements PolarisConfigModifier {
+
+	private final RpcEnhancementReporterProperties properties;
+
+	public CircuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) {
+		this.properties = properties;
+	}
+
+	@Override
+	public void modify(ConfigurationImpl configuration) {
+		properties.setEnabled(true);
+
+		// Turn on circuitbreaker configuration
+		configuration.getConsumer().getCircuitBreaker().setEnable(true);
+
+		// Set excludeCircuitBreakInstances to true
+		RecoverRouterConfig recoverRouterConfig = configuration.getConsumer().getServiceRouter()
+				.getPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, RecoverRouterConfig.class);
+
+		recoverRouterConfig.setExcludeCircuitBreakInstances(true);
+
+		// Update modified config to source properties
+		configuration.getConsumer().getServiceRouter()
+				.setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig);
+	}
+
+	@Override
+	public int getOrder() {
+		return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisCircuitBreakerConfigBuilder.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisCircuitBreakerConfigBuilder.java
new file mode 100644
index 000000000..733180491
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisCircuitBreakerConfigBuilder.java
@@ -0,0 +1,116 @@
+/*
+ * 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.circuitbreaker.common;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+
+import org.springframework.cloud.client.circuitbreaker.ConfigBuilder;
+
+/**
+ * PolarisCircuitBreakerConfigBuilder.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerConfigBuilder implements ConfigBuilder<PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration> {
+
+	private String namespace = MetadataContext.LOCAL_NAMESPACE;
+
+	private String service;
+
+	private String method;
+
+	public PolarisCircuitBreakerConfigBuilder() {
+
+	}
+
+	public PolarisCircuitBreakerConfigBuilder(String namespace, String service, String method) {
+		this.namespace = namespace;
+		this.service = service;
+		this.method = method;
+	}
+
+	public PolarisCircuitBreakerConfigBuilder namespace(String namespace) {
+		this.namespace = namespace;
+		return this;
+	}
+
+	public PolarisCircuitBreakerConfigBuilder service(String service) {
+		this.service = service;
+		return this;
+	}
+
+	public PolarisCircuitBreakerConfigBuilder method(String method) {
+		this.method = method;
+		return this;
+	}
+
+	@Override
+	public PolarisCircuitBreakerConfiguration build() {
+		PolarisCircuitBreakerConfiguration conf = new PolarisCircuitBreakerConfiguration();
+		conf.setNamespace(namespace);
+		conf.setService(service);
+		conf.setMethod(method);
+		return conf;
+	}
+
+	public static class PolarisCircuitBreakerConfiguration {
+
+		private final String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
+
+		private final String sourceService = MetadataContext.LOCAL_SERVICE;
+
+		private String namespace;
+
+		private String service;
+
+		private String method;
+
+		public String getNamespace() {
+			return namespace;
+		}
+
+		public void setNamespace(String namespace) {
+			this.namespace = namespace;
+		}
+
+		public String getService() {
+			return service;
+		}
+
+		public void setService(String service) {
+			this.service = service;
+		}
+
+		public String getMethod() {
+			return method;
+		}
+
+		public void setMethod(String method) {
+			this.method = method;
+		}
+
+		public String getSourceNamespace() {
+			return sourceNamespace;
+		}
+
+		public String getSourceService() {
+			return sourceService;
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisResultToErrorCode.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisResultToErrorCode.java
new file mode 100644
index 000000000..ec47e5f38
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/common/PolarisResultToErrorCode.java
@@ -0,0 +1,69 @@
+/*
+ * 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.circuitbreaker.common;
+
+import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisCircuitBreakerPostZuulFilter;
+import com.tencent.polaris.circuitbreak.api.pojo.ResultToErrorCode;
+import feign.FeignException;
+
+import org.springframework.web.client.RestClientResponseException;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
+
+/**
+ * PolarisResultToErrorCode.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisResultToErrorCode implements ResultToErrorCode {
+
+	@Override
+	public int onSuccess(Object value) {
+		return 200;
+	}
+
+	@Override
+	public int onError(Throwable e) {
+		if (checkClassExist("org.springframework.web.client.RestClientResponseException")
+				&& e instanceof RestClientResponseException) {
+			return ((RestClientResponseException) e).getRawStatusCode();
+		}
+		else if (checkClassExist("feign.FeignException")
+				&& e instanceof FeignException) {
+			return ((FeignException) e).status();
+		}
+		else if (checkClassExist("org.springframework.web.reactive.function.client.WebClientResponseException")
+				&& e instanceof WebClientResponseException) {
+			return ((WebClientResponseException) e).getRawStatusCode();
+		}
+		else if (e instanceof PolarisCircuitBreakerPostZuulFilter.CircuitBreakerStatusCodeException) {
+			return ((PolarisCircuitBreakerPostZuulFilter.CircuitBreakerStatusCodeException) e).getRawStatusCode();
+		}
+		return -1;
+	}
+
+	private boolean checkClassExist(String clazzName) {
+		try {
+			Class.forName(clazzName, false, getClass().getClassLoader());
+		}
+		catch (ClassNotFoundException e) {
+			return false;
+		}
+		return true;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/GatewayPolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/GatewayPolarisCircuitBreakerAutoConfiguration.java
new file mode 100644
index 000000000..e97358015
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/GatewayPolarisCircuitBreakerAutoConfiguration.java
@@ -0,0 +1,71 @@
+/*
+ * 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.circuitbreaker.config;
+
+import com.tencent.cloud.polaris.circuitbreaker.ReactivePolarisCircuitBreakerFactory;
+import com.tencent.cloud.polaris.circuitbreaker.gateway.PolarisCircuitBreakerFilterFactory;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
+import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
+import org.springframework.cloud.gateway.config.GatewayAutoConfiguration;
+import org.springframework.cloud.gateway.config.conditional.ConditionalOnEnabledFilter;
+import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
+import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.DispatcherHandler;
+
+/**
+ * GatewayPolarisCircuitBreakerAutoConfiguration.
+ *
+ * @author seanyu 2023-02-27
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
+@AutoConfigureAfter({ReactivePolarisCircuitBreakerAutoConfiguration.class })
+@ConditionalOnClass({ DispatcherHandler.class, ReactivePolarisCircuitBreakerAutoConfiguration.class,
+		ReactiveCircuitBreakerFactory.class, ReactivePolarisCircuitBreakerFactory.class, GatewayAutoConfiguration.class})
+public class GatewayPolarisCircuitBreakerAutoConfiguration {
+
+	@Bean
+	@ConditionalOnBean(ReactiveCircuitBreakerFactory.class)
+	@ConditionalOnEnabledFilter
+	public PolarisCircuitBreakerFilterFactory polarisCircuitBreakerFilterFactory(
+			ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory,
+			ObjectProvider<DispatcherHandler> dispatcherHandler,
+			@Autowired(required = false) ReactiveDiscoveryClient discoveryClient,
+			@Autowired(required = false) DiscoveryLocatorProperties properties
+	) {
+		return new PolarisCircuitBreakerFilterFactory(reactiveCircuitBreakerFactory, dispatcherHandler, discoveryClient, properties);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	@ConditionalOnEnabledFilter
+	public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() {
+		return new FallbackHeadersGatewayFilterFactory();
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
index a245d695a..7dd7bf0b0 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
@@ -17,62 +17,134 @@
 
 package com.tencent.cloud.polaris.circuitbreaker.config;
 
-import com.tencent.cloud.common.constant.ContextConstant;
-import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory;
+import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier;
+import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
+import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerRestTemplateBeanPostProcessor;
+import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisCircuitBreakerPostZuulFilter;
+import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisCircuitBreakerZuulFilter;
+import com.tencent.cloud.polaris.circuitbreaker.zuul.PolarisZuulFallbackFactory;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
-import com.tencent.polaris.factory.config.ConfigurationImpl;
-import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.api.SDKContext;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.client.circuitbreaker.Customizer;
+import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
+import org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeterAutoConfiguration;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.env.Environment;
+
 
 /**
- * Autoconfiguration at bootstrap phase.
+ * Autoconfiguration for PolarisCircuitBreaker.
  *
  * @author lepdou 2022-03-29
  */
 @Configuration(proxyBeanMethods = false)
 @ConditionalOnPolarisCircuitBreakerEnabled
 @AutoConfigureAfter(RpcEnhancementAutoConfiguration.class)
+@Import({
+		ReactivePolarisCircuitBreakerAutoConfiguration.class,
+		PolarisFeignCircuitBreakerTargeterAutoConfiguration.class,
+		PolarisCircuitBreakerFeignClientAutoConfiguration.class,
+		GatewayPolarisCircuitBreakerAutoConfiguration.class
+})
 public class PolarisCircuitBreakerAutoConfiguration {
 
+	@Autowired(required = false)
+	private List<Customizer<PolarisCircuitBreakerFactory>> customizers = new ArrayList<>();
+
+	{
+		// close zuul hystrix
+		System.setProperty("feign.hystrix.enabled", "false");
+		System.setProperty("hystrix.command.default.circuitBreaker.enabled", "false");
+	}
+
 	@Bean
-	public CircuitBreakerConfigModifier circuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) {
-		return new CircuitBreakerConfigModifier(properties);
+	@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
+	public static PolarisCircuitBreakerRestTemplateBeanPostProcessor polarisCircuitBreakerRestTemplateBeanPostProcessor(
+			ApplicationContext applicationContext) {
+		return new PolarisCircuitBreakerRestTemplateBeanPostProcessor(applicationContext);
 	}
 
-	public static class CircuitBreakerConfigModifier implements PolarisConfigModifier {
+	@Bean
+	@ConditionalOnMissingBean(CircuitBreakAPI.class)
+	public CircuitBreakAPI circuitBreakAPI(SDKContext polarisContext) {
+		return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class)
+	public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
+			SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) {
+		return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI);
+	}
 
-		private final RpcEnhancementReporterProperties properties;
+	@Bean
+	@ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class)
+	public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
+			SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) {
+		return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI);
+	}
 
-		public CircuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) {
-			this.properties = properties;
-		}
+	@Bean
+	@ConditionalOnMissingBean(CircuitBreakerFactory.class)
+	public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) {
+		PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI);
+		customizers.forEach(customizer -> customizer.customize(factory));
+		return factory;
+	}
 
-		@Override
-		public void modify(ConfigurationImpl configuration) {
-			properties.setEnabled(true);
+	@Bean
+	@ConditionalOnBean(RpcEnhancementReporterProperties.class)
+	@ConditionalOnMissingBean(CircuitBreakerConfigModifier.class)
+	public CircuitBreakerConfigModifier circuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) {
+		return new CircuitBreakerConfigModifier(properties);
+	}
 
-			// Turn on circuitbreaker configuration
-			configuration.getConsumer().getCircuitBreaker().setEnable(true);
+	@Configuration(proxyBeanMethods = false)
+	@ConditionalOnClass(name = "com.netflix.zuul.http.ZuulServlet")
+	protected static class PolarisCircuitBreakerZuulFilterConfig {
 
-			// Set excludeCircuitBreakInstances to true
-			RecoverRouterConfig recoverRouterConfig = configuration.getConsumer().getServiceRouter()
-					.getPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, RecoverRouterConfig.class);
+		@Autowired(required = false)
+		private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
 
-			recoverRouterConfig.setExcludeCircuitBreakInstances(true);
+		@Bean
+		public PolarisZuulFallbackFactory polarisZuulFallbackFactory() {
+			return new PolarisZuulFallbackFactory(zuulFallbackProviders);
+		}
 
-			// Update modified config to source properties
-			configuration.getConsumer().getServiceRouter()
-					.setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig);
+		@Bean
+		public PolarisCircuitBreakerZuulFilter polarisCircuitBreakerZuulFilter(
+				CircuitBreakerFactory circuitBreakerFactory,
+				PolarisZuulFallbackFactory polarisZuulFallbackFactory,
+				Environment environment) {
+			return new PolarisCircuitBreakerZuulFilter(circuitBreakerFactory, polarisZuulFallbackFactory, environment);
 		}
 
-		@Override
-		public int getOrder() {
-			return ContextConstant.ModifierOrder.CIRCUIT_BREAKER_ORDER;
+		@Bean
+		public PolarisCircuitBreakerPostZuulFilter polarisCircuitBreakerPostZuulFilter(
+				PolarisZuulFallbackFactory polarisZuulFallbackFactory,
+				Environment environment) {
+			return new PolarisCircuitBreakerPostZuulFilter(polarisZuulFallbackFactory, environment);
 		}
 	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java
index 9d21fbf0d..abf1e8e65 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfiguration.java
@@ -17,7 +17,10 @@
 
 package com.tencent.cloud.polaris.circuitbreaker.config;
 
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
+import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
@@ -27,8 +30,8 @@ import org.springframework.context.annotation.Import;
  * @author lepdou 2022-03-29
  */
 @Configuration(proxyBeanMethods = false)
-@ConditionalOnProperty("spring.cloud.polaris.enabled")
-@Import(PolarisCircuitBreakerAutoConfiguration.class)
+@ConditionalOnPolarisEnabled
+@Import({PolarisContextAutoConfiguration.class, RpcEnhancementAutoConfiguration.class, PolarisCircuitBreakerAutoConfiguration.class})
 public class PolarisCircuitBreakerBootstrapConfiguration {
 
 }
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerFeignClientAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerFeignClientAutoConfiguration.java
new file mode 100644
index 000000000..580ef128d
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerFeignClientAutoConfiguration.java
@@ -0,0 +1,56 @@
+/*
+ * 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.circuitbreaker.config;
+
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver;
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignCircuitBreaker;
+import feign.Feign;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.openfeign.FeignClientFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * PolarisCircuitBreakerFeignClientAutoConfiguration.
+ *
+ * @author seansyyu 2023-02-28
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnClass({Feign.class, FeignClientFactoryBean.class})
+@ConditionalOnPolarisCircuitBreakerEnabled
+public class PolarisCircuitBreakerFeignClientAutoConfiguration {
+
+	@Bean
+	@ConditionalOnMissingBean
+	public PolarisCircuitBreakerNameResolver polarisCircuitBreakerNameResolver() {
+		return new PolarisCircuitBreakerNameResolver();
+	}
+
+	@Bean
+	@Scope("prototype")
+	@ConditionalOnBean(CircuitBreakerFactory.class)
+	@ConditionalOnMissingBean(Feign.Builder.class)
+	public Feign.Builder circuitBreakerFeignBuilder() {
+		return PolarisFeignCircuitBreaker.builder();
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java
new file mode 100644
index 000000000..f2f509218
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java
@@ -0,0 +1,93 @@
+/*
+ * 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.circuitbreaker.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.tencent.cloud.polaris.circuitbreaker.ReactivePolarisCircuitBreakerFactory;
+import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier;
+import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
+import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.api.SDKContext;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.client.circuitbreaker.Customizer;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * AutoConfiguration for ReactivePolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnClass(name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux" })
+@ConditionalOnPolarisCircuitBreakerEnabled
+@AutoConfigureAfter(RpcEnhancementAutoConfiguration.class)
+public class ReactivePolarisCircuitBreakerAutoConfiguration {
+
+	@Autowired(required = false)
+	private List<Customizer<ReactivePolarisCircuitBreakerFactory>> customizers = new ArrayList<>();
+
+	@Bean
+	@ConditionalOnMissingBean(CircuitBreakAPI.class)
+	public CircuitBreakAPI circuitBreakAPI(SDKContext polarisContext) {
+		return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class)
+	public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
+			SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) {
+		return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class)
+	public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
+			SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) {
+		return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class)
+	public ReactiveCircuitBreakerFactory polarisReactiveCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) {
+		ReactivePolarisCircuitBreakerFactory factory = new ReactivePolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI);
+		customizers.forEach(customizer -> customizer.customize(factory));
+		return factory;
+	}
+
+	@Bean
+	@ConditionalOnBean(RpcEnhancementReporterProperties.class)
+	@ConditionalOnMissingBean(CircuitBreakerConfigModifier.class)
+	public CircuitBreakerConfigModifier reactiveCircuitBreakerConfigModifier(RpcEnhancementReporterProperties properties) {
+		return new CircuitBreakerConfigModifier(properties);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFallbackFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFallbackFactory.java
new file mode 100644
index 000000000..0bb6b9644
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFallbackFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.circuitbreaker.feign;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import feign.Request;
+import feign.RequestTemplate;
+import feign.Response;
+import feign.codec.Decoder;
+
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+/**
+ * PolarisCircuitBreakerFallbackFactory.
+ *
+ * @author sean yu
+ */
+public class PolarisCircuitBreakerFallbackFactory implements FallbackFactory {
+
+	private final Decoder decoder;
+
+	public PolarisCircuitBreakerFallbackFactory(Decoder decoder) {
+		this.decoder = decoder;
+	}
+
+	@Override
+	public Object create(Throwable t) {
+		return new DefaultFallback(t, decoder);
+	}
+
+	public class DefaultFallback {
+
+		private final Throwable t;
+
+		private final Decoder decoder;
+
+		public DefaultFallback(Throwable t, Decoder decoder) {
+			this.t = t;
+			this.decoder = decoder;
+		}
+
+		public Object fallback(Method method) {
+			if (t instanceof CallAbortedException) {
+				CircuitBreakerStatus.FallbackInfo fallbackInfo = ((CallAbortedException) t).getFallbackInfo();
+				if (fallbackInfo != null) {
+					Response.Builder responseBuilder = Response.builder()
+							.status(fallbackInfo.getCode());
+					if (fallbackInfo.getHeaders() != null) {
+						Map<String, Collection<String>> headers = new HashMap<>();
+						fallbackInfo.getHeaders().forEach((k, v) -> headers.put(k, Collections.singleton(v)));
+						responseBuilder.headers(headers);
+					}
+					if (fallbackInfo.getBody() != null) {
+						responseBuilder.body(fallbackInfo.getBody(), StandardCharsets.UTF_8);
+					}
+					// Feign Response need a nonnull Request,
+					// which is not important in fallback response (no real request),
+					// so we create a fake one
+					Request fakeRequest = Request.create(Request.HttpMethod.GET, "/", new HashMap<>(), Request.Body.empty(), new RequestTemplate());
+					responseBuilder.request(fakeRequest);
+
+					try (Response response = responseBuilder.build()) {
+						return decoder.decode(response, method.getGenericReturnType());
+					}
+					catch (IOException e) {
+						throw new IllegalStateException(e);
+					}
+				}
+			}
+			throw new IllegalStateException(t);
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java
new file mode 100644
index 000000000..e627ed09a
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java
@@ -0,0 +1,49 @@
+/*
+ * 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.circuitbreaker.feign;
+
+import java.lang.reflect.Method;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import feign.Target;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
+
+/**
+ * PolarisCircuitBreakerNameResolver.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerNameResolver {
+
+	public String resolveCircuitBreakerName(String feignClientName, Target<?> target, Method method) {
+		String serviceName = target.name();
+		RequestMapping requestMapping = findMergedAnnotation(method, RequestMapping.class);
+		String path = "";
+		if (requestMapping != null) {
+			path = requestMapping.path().length == 0 ?
+					requestMapping.value().length == 0 ? "" : requestMapping.value()[0] :
+					requestMapping.path()[0];
+		}
+		return "".equals(path) ?
+				MetadataContext.LOCAL_NAMESPACE + "#" + serviceName :
+				MetadataContext.LOCAL_NAMESPACE + "#" + serviceName + "#" + path;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreaker.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreaker.java
new file mode 100644
index 000000000..65b7086a6
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreaker.java
@@ -0,0 +1,99 @@
+/*
+ * 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.circuitbreaker.feign;
+
+import java.lang.reflect.Field;
+
+import feign.Feign;
+import feign.Target;
+import feign.codec.Decoder;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.cloud.openfeign.FeignCircuitBreaker;
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * PolarisFeignCircuitBreaker, mostly copy from {@link FeignCircuitBreaker}, but giving Polaris modification.
+ *
+ * @author sean yu
+ */
+public final class PolarisFeignCircuitBreaker {
+
+	private PolarisFeignCircuitBreaker() {
+		throw new IllegalStateException("Don't instantiate a utility class");
+	}
+
+	/**
+	 * @return builder for Feign CircuitBreaker integration
+	 */
+	public static Builder builder() {
+		return new Builder();
+	}
+
+	/**
+	 * Builder for Feign CircuitBreaker integration.
+	 */
+	public static final class Builder extends Feign.Builder {
+
+		private CircuitBreakerFactory circuitBreakerFactory;
+		private String feignClientName;
+		private PolarisCircuitBreakerNameResolver circuitBreakerNameResolver;
+
+		public Builder() {
+		}
+
+		public Builder circuitBreakerFactory(CircuitBreakerFactory circuitBreakerFactory) {
+			this.circuitBreakerFactory = circuitBreakerFactory;
+			return this;
+		}
+
+		public Builder feignClientName(String feignClientName) {
+			this.feignClientName = feignClientName;
+			return this;
+		}
+
+		public Builder circuitBreakerNameResolver(PolarisCircuitBreakerNameResolver circuitBreakerNameResolver) {
+			this.circuitBreakerNameResolver = circuitBreakerNameResolver;
+			return this;
+		}
+
+		public <T> T target(Target<T> target, T fallback) {
+			return build(fallback != null ? new FallbackFactory.Default<T>(fallback) : null).newInstance(target);
+		}
+
+		public <T> T target(Target<T> target, FallbackFactory<? extends T> fallbackFactory) {
+			return build(fallbackFactory).newInstance(target);
+		}
+
+		@Override
+		public <T> T target(Target<T> target) {
+			return build(null).newInstance(target);
+		}
+
+		public Feign build(final FallbackFactory<?> nullableFallbackFactory) {
+			Field field = ReflectionUtils.findField(Feign.Builder.class, "decoder");
+			field.setAccessible(true);
+			Decoder decoder = (Decoder) ReflectionUtils.getField(field, this);
+			this.invocationHandlerFactory((target, dispatch) -> new PolarisFeignCircuitBreakerInvocationHandler(
+					circuitBreakerFactory, feignClientName, target, dispatch, nullableFallbackFactory, circuitBreakerNameResolver, decoder));
+			return this.build();
+		}
+
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerInvocationHandler.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerInvocationHandler.java
new file mode 100644
index 000000000..18f7e8e61
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerInvocationHandler.java
@@ -0,0 +1,199 @@
+/*
+ * 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.circuitbreaker.feign;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import feign.InvocationHandlerFactory;
+import feign.Target;
+import feign.codec.Decoder;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import static feign.Util.checkNotNull;
+
+/**
+ * PolarisFeignCircuitBreakerInvocationHandler, mostly copy from {@link org.springframework.cloud.openfeign.FeignCircuitBreakerInvocationHandler}, but giving Polaris modification.
+ *
+ * @author sean yu
+ */
+public class PolarisFeignCircuitBreakerInvocationHandler implements InvocationHandler {
+
+	private final CircuitBreakerFactory factory;
+
+	private final String feignClientName;
+
+	private final Target<?> target;
+
+	private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;
+
+	private final FallbackFactory<?> nullableFallbackFactory;
+
+	private final Map<Method, Method> fallbackMethodMap;
+
+	private final PolarisCircuitBreakerNameResolver circuitBreakerNameResolver;
+
+	private final Decoder decoder;
+
+	public PolarisFeignCircuitBreakerInvocationHandler(CircuitBreakerFactory factory, String feignClientName, Target<?> target,
+			Map<Method, InvocationHandlerFactory.MethodHandler> dispatch, FallbackFactory<?> nullableFallbackFactory,
+			PolarisCircuitBreakerNameResolver circuitBreakerNameResolver, Decoder decoder) {
+		this.factory = factory;
+		this.feignClientName = feignClientName;
+		this.target = checkNotNull(target, "target");
+		this.dispatch = checkNotNull(dispatch, "dispatch");
+		this.fallbackMethodMap = toFallbackMethod(dispatch);
+		this.nullableFallbackFactory = nullableFallbackFactory;
+		this.circuitBreakerNameResolver = circuitBreakerNameResolver;
+		this.decoder = decoder;
+	}
+
+	/**
+	 * If the method param of {@link InvocationHandler#invoke(Object, Method, Object[])}
+	 * is not accessible, i.e in a package-private interface, the fallback call will cause
+	 * of access restrictions. But methods in dispatch are copied methods. So setting
+	 * access to dispatch method doesn't take effect to the method in
+	 * InvocationHandler.invoke. Use map to store a copy of method to invoke the fallback
+	 * to bypass this and reducing the count of reflection calls.
+	 * @return cached methods map for fallback invoking
+	 */
+	static Map<Method, Method> toFallbackMethod(Map<Method, InvocationHandlerFactory.MethodHandler> dispatch) {
+		Map<Method, Method> result = new LinkedHashMap<>();
+		for (Method method : dispatch.keySet()) {
+			method.setAccessible(true);
+			result.put(method, method);
+		}
+		return result;
+	}
+
+	@Override
+	public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+		// early exit if the invoked method is from java.lang.Object
+		// code is the same as ReflectiveFeign.FeignInvocationHandler
+		if ("equals".equals(method.getName())) {
+			try {
+				Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
+				return equals(otherHandler);
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+		}
+		else if ("hashCode".equals(method.getName())) {
+			return hashCode();
+		}
+		else if ("toString".equals(method.getName())) {
+			return toString();
+		}
+
+		String circuitName = circuitBreakerNameResolver.resolveCircuitBreakerName(feignClientName, target, method);
+		CircuitBreaker circuitBreaker = factory.create(circuitName);
+		Supplier<Object> supplier = asSupplier(method, args);
+		Function<Throwable, Object> fallbackFunction;
+		if (this.nullableFallbackFactory != null) {
+			fallbackFunction = throwable -> {
+				Object fallback = this.nullableFallbackFactory.create(throwable);
+				try {
+					return this.fallbackMethodMap.get(method).invoke(fallback, args);
+				}
+				catch (Exception exception) {
+					unwrapAndRethrow(exception);
+				}
+				return null;
+			};
+		}
+		else {
+			fallbackFunction = throwable -> {
+				PolarisCircuitBreakerFallbackFactory.DefaultFallback fallback =
+						(PolarisCircuitBreakerFallbackFactory.DefaultFallback) new PolarisCircuitBreakerFallbackFactory(this.decoder).create(throwable);
+				return fallback.fallback(method);
+			};
+		}
+		return circuitBreaker.run(supplier, fallbackFunction);
+	}
+
+	private void unwrapAndRethrow(Exception exception) {
+		if (exception instanceof InvocationTargetException || exception instanceof NoFallbackAvailableException) {
+			Throwable underlyingException = exception.getCause();
+			if (underlyingException instanceof RuntimeException) {
+				throw (RuntimeException) underlyingException;
+			}
+			if (underlyingException != null) {
+				throw new IllegalStateException(underlyingException);
+			}
+			throw new IllegalStateException(exception);
+		}
+	}
+
+	private Supplier<Object> asSupplier(final Method method, final Object[] args) {
+		final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+		final Thread caller = Thread.currentThread();
+		return () -> {
+			boolean isAsync = caller != Thread.currentThread();
+			try {
+				if (isAsync) {
+					RequestContextHolder.setRequestAttributes(requestAttributes);
+				}
+				return dispatch.get(method).invoke(args);
+			}
+			catch (RuntimeException throwable) {
+				throw throwable;
+			}
+			catch (Throwable throwable) {
+				throw new RuntimeException(throwable);
+			}
+			finally {
+				if (isAsync) {
+					RequestContextHolder.resetRequestAttributes();
+				}
+			}
+		};
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof PolarisFeignCircuitBreakerInvocationHandler) {
+			PolarisFeignCircuitBreakerInvocationHandler other = (PolarisFeignCircuitBreakerInvocationHandler) obj;
+			return this.target.equals(other.target);
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		return this.target.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return this.target.toString();
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java
new file mode 100644
index 000000000..0b474f8e5
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerFilterFactory.java
@@ -0,0 +1,278 @@
+/*
+ * 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.circuitbreaker.gateway;
+
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.beans.InvalidPropertyException;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
+import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
+import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
+import org.springframework.cloud.gateway.filter.GatewayFilter;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory;
+import org.springframework.cloud.gateway.route.Route;
+import org.springframework.cloud.gateway.support.HttpStatusHolder;
+import org.springframework.cloud.gateway.support.ServiceUnavailableException;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.reactive.DispatcherHandler;
+import org.springframework.web.server.ResponseStatusException;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import static java.util.Optional.ofNullable;
+import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.reset;
+
+/**
+ * PolarisCircuitBreakerFilterFactory.
+ * mostly copy from SpringCloudCircuitBreakerFilterFactory, but create ReactiveCircuitBreaker per request to build method level CircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerFilterFactory extends SpringCloudCircuitBreakerFilterFactory {
+
+	private final ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
+	private final ObjectProvider<DispatcherHandler> dispatcherHandlerProvider;
+	private String routeIdPrefix;
+	// do not use this dispatcherHandler directly, use getDispatcherHandler() instead.
+	private volatile DispatcherHandler dispatcherHandler;
+
+	public PolarisCircuitBreakerFilterFactory(
+			ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory,
+			ObjectProvider<DispatcherHandler> dispatcherHandlerProvider,
+			ReactiveDiscoveryClient discoveryClient,
+			DiscoveryLocatorProperties properties
+	) {
+		super(reactiveCircuitBreakerFactory, dispatcherHandlerProvider);
+		this.reactiveCircuitBreakerFactory = reactiveCircuitBreakerFactory;
+		this.dispatcherHandlerProvider = dispatcherHandlerProvider;
+		if (discoveryClient != null && properties != null) {
+			if (StringUtils.hasText(properties.getRouteIdPrefix())) {
+				routeIdPrefix = properties.getRouteIdPrefix();
+			}
+			else {
+				routeIdPrefix = discoveryClient.getClass().getSimpleName() + "_";
+			}
+		}
+	}
+
+	private void addExceptionDetails(Throwable t, ServerWebExchange exchange) {
+		ofNullable(t).ifPresent(
+				exception -> exchange.getAttributes().put(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR, exception));
+	}
+
+	private DispatcherHandler getDispatcherHandler() {
+		if (dispatcherHandler == null) {
+			dispatcherHandler = dispatcherHandlerProvider.getIfAvailable();
+		}
+		return dispatcherHandler;
+	}
+
+	private String getCircuitBreakerId(Config config) {
+		if (!StringUtils.hasText(config.getName()) && StringUtils.hasText(config.getRouteId())) {
+			if (routeIdPrefix != null && config.getRouteId().startsWith(routeIdPrefix)) {
+				return config.getRouteId().replace(routeIdPrefix, "");
+			}
+			return config.getRouteId();
+		}
+		return config.getName();
+	}
+
+	private boolean isNumeric(String statusString) {
+		try {
+			Integer.parseInt(statusString);
+			return true;
+		}
+		catch (NumberFormatException e) {
+			return false;
+		}
+	}
+
+	private List<HttpStatus> getSeriesStatus(String series) {
+		if (!Arrays.asList("1**", "2**", "3**", "4**", "5**").contains(series)) {
+			throw new InvalidPropertyException(Config.class, "statusCodes", "polaris circuit breaker status code can only be a numeric http status, or a http series pattern, e.g. [\"1**\",\"2**\",\"3**\",\"4**\",\"5**\"]");
+		}
+		HttpStatus[] allHttpStatus = HttpStatus.values();
+		if (series.startsWith("1")) {
+			return Arrays.stream(allHttpStatus).filter(HttpStatus::is1xxInformational).collect(Collectors.toList());
+		}
+		else if (series.startsWith("2")) {
+			return Arrays.stream(allHttpStatus).filter(HttpStatus::is2xxSuccessful).collect(Collectors.toList());
+		}
+		else if (series.startsWith("3")) {
+			return Arrays.stream(allHttpStatus).filter(HttpStatus::is3xxRedirection).collect(Collectors.toList());
+		}
+		else if (series.startsWith("4")) {
+			return Arrays.stream(allHttpStatus).filter(HttpStatus::is4xxClientError).collect(Collectors.toList());
+		}
+		else if (series.startsWith("5")) {
+			return Arrays.stream(allHttpStatus).filter(HttpStatus::is5xxServerError).collect(Collectors.toList());
+		}
+		return Arrays.asList(allHttpStatus);
+	}
+
+	private Set<HttpStatus> getDefaultStatus() {
+		return Arrays.stream(HttpStatus.values())
+				.filter(HttpStatus::is5xxServerError)
+				.collect(Collectors.toSet());
+	}
+
+	@Override
+	public GatewayFilter apply(Config config) {
+		Set<HttpStatus> statuses = config.getStatusCodes().stream()
+				.flatMap(statusCode -> {
+					List<HttpStatus> httpStatuses = new ArrayList<>();
+					if (isNumeric(statusCode)) {
+						httpStatuses.add(HttpStatusHolder.parse(statusCode).getHttpStatus());
+					}
+					else {
+						httpStatuses.addAll(getSeriesStatus(statusCode));
+					}
+					return httpStatuses.stream();
+				})
+				.filter(Objects::nonNull)
+				.collect(Collectors.toSet());
+		if (CollectionUtils.isEmpty(statuses)) {
+			statuses.addAll(getDefaultStatus());
+		}
+		String circuitBreakerId = getCircuitBreakerId(config);
+		return new GatewayFilter() {
+			@Override
+			public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+				Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
+				String serviceName = circuitBreakerId;
+				if (route != null) {
+					serviceName = route.getUri().getHost();
+				}
+				String path = exchange.getRequest().getPath().value();
+				ReactiveCircuitBreaker cb = reactiveCircuitBreakerFactory.create(serviceName + "#" + path);
+				return cb.run(
+								chain.filter(exchange)
+										.doOnSuccess(v -> {
+											// throw CircuitBreakerStatusCodeException by default for all need checking status
+											// so polaris can report right error status
+											Set<HttpStatus> statusNeedToCheck = new HashSet<>();
+											statusNeedToCheck.addAll(statuses);
+											statusNeedToCheck.addAll(getDefaultStatus());
+											HttpStatus status = exchange.getResponse().getStatusCode();
+											if (statusNeedToCheck.contains(status)) {
+												throw new CircuitBreakerStatusCodeException(status);
+											}
+										}),
+								t -> {
+									// pre-check CircuitBreakerStatusCodeException's status matches input status
+									if (t instanceof CircuitBreakerStatusCodeException) {
+										HttpStatus status = ((CircuitBreakerStatusCodeException) t).getStatusCode();
+										// no need to fallback
+										if (!statuses.contains(status)) {
+											return Mono.error(t);
+										}
+									}
+									// do fallback
+									if (config.getFallbackUri() == null) {
+										// polaris checking
+										if (t instanceof CallAbortedException) {
+											CircuitBreakerStatus.FallbackInfo fallbackInfo = ((CallAbortedException) t).getFallbackInfo();
+											if (fallbackInfo != null) {
+												ServerHttpResponse response = exchange.getResponse();
+												response.setRawStatusCode(fallbackInfo.getCode());
+												if (fallbackInfo.getHeaders() != null) {
+													fallbackInfo.getHeaders()
+															.forEach((k, v) -> response.getHeaders().add(k, v));
+												}
+												DataBuffer bodyBuffer = null;
+												if (fallbackInfo.getBody() != null) {
+													byte[] bytes = fallbackInfo.getBody().getBytes(StandardCharsets.UTF_8);
+													bodyBuffer = response.bufferFactory().wrap(bytes);
+												}
+												return bodyBuffer != null ? response.writeWith(Flux.just(bodyBuffer)) : response.setComplete();
+											}
+										}
+										return Mono.error(t);
+									}
+									exchange.getResponse().setStatusCode(null);
+									reset(exchange);
+
+									// TODO: copied from RouteToRequestUrlFilter
+									URI uri = exchange.getRequest().getURI();
+									// TODO: assume always?
+									boolean encoded = containsEncodedParts(uri);
+									URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null)
+											.uri(config.getFallbackUri()).scheme(null).build(encoded).toUri();
+									exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
+									addExceptionDetails(t, exchange);
+
+									// Reset the exchange
+									reset(exchange);
+
+									ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build();
+									return getDispatcherHandler().handle(exchange.mutate().request(request).build());
+								})
+						.onErrorResume(t -> handleErrorWithoutFallback(t));
+			}
+
+			@Override
+			public String toString() {
+				return filterToStringCreator(PolarisCircuitBreakerFilterFactory.this)
+						.append("name", config.getName()).append("fallback", config.getFallbackUri()).toString();
+			}
+		};
+
+	}
+
+	@Override
+	protected Mono<Void> handleErrorWithoutFallback(Throwable t) {
+		if (t instanceof java.util.concurrent.TimeoutException) {
+			return Mono.error(new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, t.getMessage(), t));
+		}
+		if (t instanceof CallAbortedException) {
+			return Mono.error(new ServiceUnavailableException());
+		}
+		if (t instanceof CircuitBreakerStatusCodeException) {
+			return Mono.empty();
+		}
+		return Mono.error(t);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerFluxOperator.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerFluxOperator.java
new file mode 100644
index 000000000..faad71135
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerFluxOperator.java
@@ -0,0 +1,57 @@
+/*
+ * 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.circuitbreaker.reactor;
+
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import reactor.core.CoreSubscriber;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.FluxOperator;
+import reactor.core.publisher.Operators;
+
+/**
+ * FluxOperator for PolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerFluxOperator<T> extends FluxOperator<T, T> {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCircuitBreakerFluxOperator.class);
+
+	private final InvokeHandler invokeHandler;
+
+	protected PolarisCircuitBreakerFluxOperator(Flux<? extends T> source, InvokeHandler invokeHandler) {
+		super(source);
+		this.invokeHandler = invokeHandler;
+	}
+
+	@Override
+	public void subscribe(CoreSubscriber<? super T> actual) {
+		try {
+			invokeHandler.acquirePermission();
+			source.subscribe(new PolarisCircuitBreakerReactorSubscriber<>(invokeHandler, actual, false));
+		}
+		catch (CallAbortedException e) {
+			LOGGER.debug("ReactivePolarisCircuitBreaker CallAbortedException: {}", e.getMessage());
+			Operators.error(actual, e);
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerMonoOperator.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerMonoOperator.java
new file mode 100644
index 000000000..6f0a44fef
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerMonoOperator.java
@@ -0,0 +1,57 @@
+/*
+ * 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.circuitbreaker.reactor;
+
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import reactor.core.CoreSubscriber;
+import reactor.core.publisher.Mono;
+import reactor.core.publisher.MonoOperator;
+import reactor.core.publisher.Operators;
+
+/**
+ * MonoOperator for PolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerMonoOperator<T> extends MonoOperator<T, T> {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCircuitBreakerMonoOperator.class);
+
+	private final InvokeHandler invokeHandler;
+
+	protected PolarisCircuitBreakerMonoOperator(Mono<? extends T> source, InvokeHandler invokeHandler) {
+		super(source);
+		this.invokeHandler = invokeHandler;
+	}
+
+	@Override
+	public void subscribe(CoreSubscriber<? super T> actual) {
+		try {
+			invokeHandler.acquirePermission();
+			source.subscribe(new PolarisCircuitBreakerReactorSubscriber<>(invokeHandler, actual, true));
+		}
+		catch (CallAbortedException e) {
+			LOGGER.debug("ReactivePolarisCircuitBreaker CallAbortedException: {}", e.getMessage());
+			Operators.error(actual, e);
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorSubscriber.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorSubscriber.java
new file mode 100644
index 000000000..202f63369
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorSubscriber.java
@@ -0,0 +1,119 @@
+/*
+ * 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.circuitbreaker.reactor;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import com.tencent.polaris.circuitbreak.api.pojo.InvokeContext;
+import org.reactivestreams.Subscription;
+import reactor.core.CoreSubscriber;
+import reactor.core.publisher.BaseSubscriber;
+import reactor.util.context.Context;
+
+/**
+ * Reactor Subscriber for PolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerReactorSubscriber<T> extends BaseSubscriber<T> {
+
+	private final InvokeHandler invokeHandler;
+
+
+	private final CoreSubscriber<? super T> downstreamSubscriber;
+
+	private final long startTimeMilli;
+	private final boolean singleProducer;
+
+	private final AtomicBoolean successSignaled = new AtomicBoolean(false);
+	private final AtomicBoolean eventWasEmitted = new AtomicBoolean(false);
+
+	public PolarisCircuitBreakerReactorSubscriber(InvokeHandler invokeHandler, CoreSubscriber<? super T> downstreamSubscriber, boolean singleProducer) {
+		this.invokeHandler = invokeHandler;
+		this.downstreamSubscriber = downstreamSubscriber;
+		this.singleProducer = singleProducer;
+		this.startTimeMilli = System.currentTimeMillis();
+	}
+
+	@Override
+	public Context currentContext() {
+		return downstreamSubscriber.currentContext();
+	}
+
+	@Override
+	protected void hookOnSubscribe(Subscription subscription) {
+		downstreamSubscriber.onSubscribe(this);
+	}
+
+	@Override
+	protected void hookOnNext(T value) {
+		if (!isDisposed()) {
+			if (singleProducer && successSignaled.compareAndSet(false, true)) {
+				long delay = System.currentTimeMillis() - startTimeMilli;
+				InvokeContext.ResponseContext responseContext = new InvokeContext.ResponseContext();
+				responseContext.setDuration(delay);
+				responseContext.setDurationUnit(TimeUnit.MILLISECONDS);
+				responseContext.setResult(value);
+				invokeHandler.onSuccess(responseContext);
+			}
+			eventWasEmitted.set(true);
+
+			downstreamSubscriber.onNext(value);
+		}
+	}
+
+	@Override
+	protected void hookOnComplete() {
+		if (successSignaled.compareAndSet(false, true)) {
+			long delay = System.currentTimeMillis() - startTimeMilli;
+			InvokeContext.ResponseContext responseContext = new InvokeContext.ResponseContext();
+			responseContext.setDuration(delay);
+			responseContext.setDurationUnit(TimeUnit.MILLISECONDS);
+			invokeHandler.onSuccess(responseContext);
+		}
+
+		downstreamSubscriber.onComplete();
+	}
+
+	@Override
+	public void hookOnCancel() {
+		if (!successSignaled.get()) {
+			if (eventWasEmitted.get()) {
+				long delay = System.currentTimeMillis() - startTimeMilli;
+				InvokeContext.ResponseContext responseContext = new InvokeContext.ResponseContext();
+				responseContext.setDuration(delay);
+				responseContext.setDurationUnit(TimeUnit.MILLISECONDS);
+				invokeHandler.onSuccess(responseContext);
+			}
+		}
+	}
+
+	@Override
+	protected void hookOnError(Throwable e) {
+		long delay = System.currentTimeMillis() - startTimeMilli;
+		InvokeContext.ResponseContext responseContext = new InvokeContext.ResponseContext();
+		responseContext.setDuration(delay);
+		responseContext.setDurationUnit(TimeUnit.MILLISECONDS);
+		responseContext.setError(e);
+		invokeHandler.onError(responseContext);
+		downstreamSubscriber.onError(e);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorTransformer.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorTransformer.java
new file mode 100644
index 000000000..b7fa450e1
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorTransformer.java
@@ -0,0 +1,53 @@
+/*
+ * 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.circuitbreaker.reactor;
+
+import java.util.function.Function;
+
+import com.tencent.polaris.circuitbreak.api.InvokeHandler;
+import org.reactivestreams.Publisher;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * Reactor Transformer for PolarisCircuitBreaker.
+ *
+ * @author seanyu 2023-02-27
+ */
+public class PolarisCircuitBreakerReactorTransformer<T> implements Function<Publisher<T>, Publisher<T>> {
+
+	private final InvokeHandler invokeHandler;
+
+	public PolarisCircuitBreakerReactorTransformer(InvokeHandler invokeHandler) {
+		this.invokeHandler = invokeHandler;
+	}
+
+	@Override
+	public Publisher<T> apply(Publisher<T> publisher) {
+		if (publisher instanceof Mono) {
+			return new PolarisCircuitBreakerMonoOperator<>((Mono<? extends T>) publisher, invokeHandler);
+		}
+		else if (publisher instanceof Flux) {
+			return new PolarisCircuitBreakerFluxOperator<>((Flux<? extends T>) publisher, invokeHandler);
+		}
+		else {
+			throw new IllegalStateException("Publisher type is not supported: " + publisher.getClass().getCanonicalName());
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java
new file mode 100644
index 000000000..b47c1a4a2
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java
@@ -0,0 +1,97 @@
+/*
+ * 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.circuitbreaker.reporter;
+
+import java.util.Optional;
+
+import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.core.Ordered;
+
+public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ExceptionCircuitBreakerReporter.class);
+
+	private final CircuitBreakAPI circuitBreakAPI;
+
+	public ExceptionCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties,
+			SDKContext context,
+			CircuitBreakAPI circuitBreakAPI) {
+		super(reportProperties, context);
+		this.circuitBreakAPI = circuitBreakAPI;
+	}
+
+	@Override
+	public String getName() {
+		return ExceptionCircuitBreakerReporter.class.getName();
+	}
+
+	@Override
+	public EnhancedPluginType getType() {
+		return EnhancedPluginType.EXCEPTION;
+	}
+
+	@Override
+	public void run(EnhancedPluginContext context) throws Throwable {
+		if (!super.reportProperties.isEnabled()) {
+			return;
+		}
+
+		EnhancedRequestContext request = context.getRequest();
+		ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance());
+
+		ResourceStat resourceStat = createInstanceResourceStat(
+				serviceInstance.getServiceId(),
+				serviceInstance.getHost(),
+				serviceInstance.getPort(),
+				request.getUrl(),
+				null,
+				context.getDelay(),
+				context.getThrowable()
+		);
+
+		LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
+				resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay());
+
+		circuitBreakAPI.report(resourceStat);
+
+	}
+
+	@Override
+	public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
+		LOG.error("ExceptionCircuitBreakerReporter runs failed. context=[{}].",
+				context, throwable);
+	}
+
+	@Override
+	public int getOrder() {
+		return Ordered.HIGHEST_PRECEDENCE + 2;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java
new file mode 100644
index 000000000..ce5fe2a81
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java
@@ -0,0 +1,99 @@
+/*
+ * 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.circuitbreaker.reporter;
+
+import java.util.Optional;
+
+import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
+import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.core.Ordered;
+
+
+public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin {
+
+	private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class);
+
+	private final CircuitBreakAPI circuitBreakAPI;
+
+	public SuccessCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties,
+			SDKContext context,
+			CircuitBreakAPI circuitBreakAPI) {
+		super(reportProperties, context);
+		this.circuitBreakAPI = circuitBreakAPI;
+	}
+
+	@Override
+	public String getName() {
+		return SuccessCircuitBreakerReporter.class.getName();
+	}
+
+	@Override
+	public EnhancedPluginType getType() {
+		return EnhancedPluginType.POST;
+	}
+
+	@Override
+	public void run(EnhancedPluginContext context) throws Throwable {
+		if (!super.reportProperties.isEnabled()) {
+			return;
+		}
+		EnhancedRequestContext request = context.getRequest();
+		EnhancedResponseContext response = context.getResponse();
+		ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance());
+
+		ResourceStat resourceStat = createInstanceResourceStat(
+				serviceInstance.getServiceId(),
+				serviceInstance.getHost(),
+				serviceInstance.getPort(),
+				request.getUrl(),
+				response.getHttpStatus(),
+				context.getDelay(),
+				null
+		);
+
+		LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
+				resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay());
+
+		circuitBreakAPI.report(resourceStat);
+	}
+
+	@Override
+	public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
+		LOG.error("SuccessCircuitBreakerReporter runs failed. context=[{}].",
+				context, throwable);
+	}
+
+	@Override
+	public int getOrder() {
+		return Ordered.HIGHEST_PRECEDENCE + 2;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java
new file mode 100644
index 000000000..d3a8af492
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java
@@ -0,0 +1,54 @@
+/*
+ * 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.circuitbreaker.resttemplate;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * PolarisCircuitBreaker annotation.
+ * if coded fallback or fallbackClass provided, RestTemplate will always return fallback when any exception occurs,
+ * if none coded fallback or fallbackClass provided, RestTemplate will return fallback response from Polaris server when fallback occurs.
+ * fallback and fallbackClass cannot provide at same time.
+ *
+ * @author sean yu
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface PolarisCircuitBreaker {
+
+	/**
+	 * a fallback string, will return a response { status: 200, body: fallback string} when any exception occurs.
+	 *
+	 * @return fallback string
+	 */
+	String fallback() default "";
+
+	/**
+	 * a fallback Class, will return a PolarisCircuitBreakerHttpResponse when any exception occurs.
+	 * fallback Class must be a spring bean.
+	 *
+	 * @return PolarisCircuitBreakerFallback
+	 */
+	Class<? extends PolarisCircuitBreakerFallback> fallbackClass() default PolarisCircuitBreakerFallback.class;
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerFallback.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerFallback.java
new file mode 100644
index 000000000..9c59795c9
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerFallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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.circuitbreaker.resttemplate;
+
+/**
+ * PolarisCircuitBreakerFallback.
+ *
+ * @author sean yu
+ */
+public interface PolarisCircuitBreakerFallback {
+
+	PolarisCircuitBreakerHttpResponse fallback();
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerHttpResponse.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerHttpResponse.java
new file mode 100644
index 000000000..0aeade4d5
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerHttpResponse.java
@@ -0,0 +1,102 @@
+/*
+ * 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.circuitbreaker.resttemplate;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.AbstractClientHttpResponse;
+
+/**
+ * PolarisCircuitBreakerHttpResponse.
+ *
+ * @author sean yu
+ */
+public class PolarisCircuitBreakerHttpResponse extends AbstractClientHttpResponse {
+
+	private final CircuitBreakerStatus.FallbackInfo fallbackInfo;
+
+	private final HttpHeaders headers = new HttpHeaders();
+
+	private InputStream body;
+
+	public PolarisCircuitBreakerHttpResponse(int code) {
+		this(new CircuitBreakerStatus.FallbackInfo(code, null, null));
+	}
+
+	public PolarisCircuitBreakerHttpResponse(int code, String body) {
+		this(new CircuitBreakerStatus.FallbackInfo(code, null, body));
+	}
+
+	public PolarisCircuitBreakerHttpResponse(int code, Map<String, String> headers, String body) {
+		this(new CircuitBreakerStatus.FallbackInfo(code, headers, body));
+	}
+
+	public PolarisCircuitBreakerHttpResponse(CircuitBreakerStatus.FallbackInfo fallbackInfo) {
+		this.fallbackInfo = fallbackInfo;
+		if (fallbackInfo.getHeaders() != null) {
+			fallbackInfo.getHeaders().forEach(headers::add);
+		}
+		if (fallbackInfo.getBody() != null) {
+			body = new ByteArrayInputStream(fallbackInfo.getBody().getBytes());
+		}
+	}
+
+	@Override
+	public final int getRawStatusCode() {
+		return fallbackInfo.getCode();
+	}
+
+	@Override
+	public final String getStatusText() {
+		HttpStatus status = HttpStatus.resolve(getRawStatusCode());
+		return (status != null ? status.getReasonPhrase() : "");
+	}
+
+	@Override
+	public final void close() {
+		if (this.body != null) {
+			try {
+				this.body.close();
+			}
+			catch (IOException e) {
+				// Ignore exception on close...
+			}
+		}
+	}
+
+	@Override
+	public final InputStream getBody() {
+		return this.body;
+	}
+
+	@Override
+	public final HttpHeaders getHeaders() {
+		return this.headers;
+	}
+
+	public CircuitBreakerStatus.FallbackInfo getFallbackInfo() {
+		return this.fallbackInfo;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java
new file mode 100644
index 000000000..775a6cfa6
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateBeanPostProcessor.java
@@ -0,0 +1,125 @@
+/*
+ * 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.circuitbreaker.resttemplate;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.type.MethodMetadata;
+import org.springframework.core.type.StandardMethodMetadata;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * PolarisCircuitBreakerRestTemplateBeanPostProcessor.
+ *
+ * @author sean yu
+ */
+public class PolarisCircuitBreakerRestTemplateBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
+
+	private final ApplicationContext applicationContext;
+
+	public PolarisCircuitBreakerRestTemplateBeanPostProcessor(ApplicationContext applicationContext) {
+		this.applicationContext = applicationContext;
+	}
+
+	private final ConcurrentHashMap<String, PolarisCircuitBreaker> cache = new ConcurrentHashMap<>();
+
+	private void checkPolarisCircuitBreakerRestTemplate(PolarisCircuitBreaker polarisCircuitBreaker) {
+		if (
+				StringUtils.hasText(polarisCircuitBreaker.fallback()) &&
+						!PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreaker.fallbackClass().toGenericString())
+		) {
+			throw new IllegalArgumentException("PolarisCircuitBreaker's fallback and fallbackClass could not set at sametime !");
+		}
+	}
+
+	@Override
+	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
+		if (checkAnnotated(beanDefinition, beanType, beanName)) {
+			PolarisCircuitBreaker polarisCircuitBreaker;
+			if (beanDefinition.getSource() instanceof StandardMethodMetadata) {
+				polarisCircuitBreaker = ((StandardMethodMetadata) beanDefinition.getSource()).getIntrospectedMethod()
+						.getAnnotation(PolarisCircuitBreaker.class);
+			}
+			else {
+				polarisCircuitBreaker = beanDefinition.getResolvedFactoryMethod()
+						.getAnnotation(PolarisCircuitBreaker.class);
+			}
+			checkPolarisCircuitBreakerRestTemplate(polarisCircuitBreaker);
+			cache.put(beanName, polarisCircuitBreaker);
+		}
+	}
+
+	@Override
+	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+		if (cache.containsKey(beanName)) {
+			// add interceptor for each RestTemplate with @PolarisCircuitBreaker annotation
+			StringBuilder interceptorBeanNamePrefix = new StringBuilder();
+			PolarisCircuitBreaker polarisCircuitBreaker = cache.get(beanName);
+			interceptorBeanNamePrefix
+					.append(StringUtils.uncapitalize(
+							PolarisCircuitBreaker.class.getSimpleName()))
+					.append("_")
+					.append(polarisCircuitBreaker.fallback())
+					.append("_")
+					.append(polarisCircuitBreaker.fallbackClass().getSimpleName());
+			RestTemplate restTemplate = (RestTemplate) bean;
+			String interceptorBeanName = interceptorBeanNamePrefix + "@" + bean;
+			CircuitBreakerFactory circuitBreakerFactory = this.applicationContext.getBean(CircuitBreakerFactory.class);
+			registerBean(interceptorBeanName, polarisCircuitBreaker, applicationContext, circuitBreakerFactory, restTemplate);
+			PolarisCircuitBreakerRestTemplateInterceptor polarisCircuitBreakerRestTemplateInterceptor = applicationContext
+					.getBean(interceptorBeanName, PolarisCircuitBreakerRestTemplateInterceptor.class);
+			restTemplate.getInterceptors().add(0, polarisCircuitBreakerRestTemplateInterceptor);
+		}
+		return bean;
+	}
+
+	private boolean checkAnnotated(RootBeanDefinition beanDefinition,
+			Class<?> beanType, String beanName) {
+		return beanName != null && beanType == RestTemplate.class
+				&& beanDefinition.getSource() instanceof MethodMetadata
+				&& ((MethodMetadata) beanDefinition.getSource())
+				.isAnnotated(PolarisCircuitBreaker.class.getName());
+	}
+
+	private void registerBean(String interceptorBeanName, PolarisCircuitBreaker polarisCircuitBreaker,
+			ApplicationContext applicationContext, CircuitBreakerFactory circuitBreakerFactory, RestTemplate restTemplate) {
+		// register PolarisCircuitBreakerRestTemplateInterceptor bean
+		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
+				.getAutowireCapableBeanFactory();
+		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
+				.genericBeanDefinition(PolarisCircuitBreakerRestTemplateInterceptor.class);
+		beanDefinitionBuilder.addConstructorArgValue(polarisCircuitBreaker);
+		beanDefinitionBuilder.addConstructorArgValue(applicationContext);
+		beanDefinitionBuilder.addConstructorArgValue(circuitBreakerFactory);
+		beanDefinitionBuilder.addConstructorArgValue(restTemplate);
+		BeanDefinition interceptorBeanDefinition = beanDefinitionBuilder
+				.getRawBeanDefinition();
+		beanFactory.registerBeanDefinition(interceptorBeanName,
+				interceptorBeanDefinition);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java
new file mode 100644
index 000000000..49afb2210
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateInterceptor.java
@@ -0,0 +1,101 @@
+/*
+ * 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.circuitbreaker.resttemplate;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * PolarisCircuitBreakerRestTemplateInterceptor.
+ *
+ * @author sean yu
+ */
+public class PolarisCircuitBreakerRestTemplateInterceptor implements ClientHttpRequestInterceptor {
+
+	private final PolarisCircuitBreaker polarisCircuitBreaker;
+
+	private final ApplicationContext applicationContext;
+
+	private final CircuitBreakerFactory circuitBreakerFactory;
+
+	private final RestTemplate restTemplate;
+
+	public PolarisCircuitBreakerRestTemplateInterceptor(
+			PolarisCircuitBreaker polarisCircuitBreaker,
+			ApplicationContext applicationContext,
+			CircuitBreakerFactory circuitBreakerFactory,
+			RestTemplate restTemplate
+	) {
+		this.polarisCircuitBreaker = polarisCircuitBreaker;
+		this.applicationContext = applicationContext;
+		this.circuitBreakerFactory = circuitBreakerFactory;
+		this.restTemplate =  restTemplate;
+	}
+
+	@Override
+	public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
+		return circuitBreakerFactory.create(request.getURI().getHost() + "#" + request.getURI().getPath()).run(
+				() -> {
+					try {
+						ClientHttpResponse response = execution.execute(request, body);
+						ResponseErrorHandler errorHandler = restTemplate.getErrorHandler();
+						if (errorHandler.hasError(response)) {
+							errorHandler.handleError(request.getURI(), request.getMethod(), response);
+						}
+						return response;
+					}
+					catch (IOException e) {
+						throw new IllegalStateException(e);
+					}
+				},
+				t -> {
+					if (StringUtils.hasText(polarisCircuitBreaker.fallback())) {
+						CircuitBreakerStatus.FallbackInfo fallbackInfo = new CircuitBreakerStatus.FallbackInfo(200, null, polarisCircuitBreaker.fallback());
+						return new PolarisCircuitBreakerHttpResponse(fallbackInfo);
+					}
+					if (!PolarisCircuitBreakerFallback.class.toGenericString().equals(polarisCircuitBreaker.fallbackClass().toGenericString())) {
+						Method method = ReflectionUtils.findMethod(PolarisCircuitBreakerFallback.class, "fallback");
+						PolarisCircuitBreakerFallback polarisCircuitBreakerFallback = applicationContext.getBean(polarisCircuitBreaker.fallbackClass());
+						return (PolarisCircuitBreakerHttpResponse) ReflectionUtils.invokeMethod(method, polarisCircuitBreakerFallback);
+					}
+					if (t instanceof CallAbortedException) {
+						CircuitBreakerStatus.FallbackInfo fallbackInfo = ((CallAbortedException) t).getFallbackInfo();
+						if (fallbackInfo != null) {
+							return new PolarisCircuitBreakerHttpResponse(fallbackInfo);
+						}
+					}
+					throw new IllegalStateException(t);
+				}
+		);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtils.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtils.java
new file mode 100644
index 000000000..961c30802
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtils.java
@@ -0,0 +1,87 @@
+/*
+ * 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.circuitbreaker.util;
+
+import java.util.Objects;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.pojo.RetStatus;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.util.Assert;
+
+/**
+ * PolarisCircuitBreakerUtils.
+ *
+ * @author seanyu 2023-02-27
+ */
+public final class PolarisCircuitBreakerUtils {
+
+	private static final Logger LOG = LoggerFactory.getLogger(PolarisCircuitBreakerUtils.class);
+
+	private PolarisCircuitBreakerUtils() {
+
+	}
+
+	/**
+	 *
+	 * @param id CircuitBreakerId
+	 *              Format: namespace#service#method or service#method or service ,
+	 *              namespace set as default spring.cloud.polaris.namespace if absent
+	 * @return String[]{namespace, service, method}
+	 */
+	public static String[] resolveCircuitBreakerId(String id) {
+		Assert.hasText(id, "A CircuitBreaker must have an id. Id could be : namespace#service#method or service#method or service");
+		String[] polarisCircuitBreakerMetaData = id.split("#");
+		if (polarisCircuitBreakerMetaData.length == 2) {
+			return new String[]{MetadataContext.LOCAL_NAMESPACE, polarisCircuitBreakerMetaData[0], polarisCircuitBreakerMetaData[1]};
+		}
+		if (polarisCircuitBreakerMetaData.length == 3) {
+			return new String[]{polarisCircuitBreakerMetaData[0], polarisCircuitBreakerMetaData[1], polarisCircuitBreakerMetaData[2]};
+		}
+		return new String[]{MetadataContext.LOCAL_NAMESPACE, id, ""};
+	}
+
+	public static void reportStatus(ConsumerAPI consumerAPI,
+			PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf, CallAbortedException e) {
+		try {
+			ServiceCallResult result = new ServiceCallResult();
+			result.setMethod(conf.getMethod());
+			result.setNamespace(conf.getNamespace());
+			result.setService(conf.getService());
+			result.setRuleName(e.getRuleName());
+			result.setRetStatus(RetStatus.RetReject);
+			result.setCallerService(new ServiceKey(conf.getSourceNamespace(), conf.getSourceService()));
+
+			if (Objects.nonNull(e.getFallbackInfo())) {
+				result.setRetCode(e.getFallbackInfo().getCode());
+			}
+			consumerAPI.updateServiceCallResult(result);
+		}
+		catch (Throwable ex) {
+			LOG.error("[CircuitBreaker] report circuitbreaker call result fail ", ex);
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerPostZuulFilter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerPostZuulFilter.java
new file mode 100644
index 000000000..ac6db8536
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerPostZuulFilter.java
@@ -0,0 +1,152 @@
+/*
+ * 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.circuitbreaker.zuul;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletResponse;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+import com.tencent.cloud.common.util.ZuulFilterUtils;
+import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreaker;
+import com.tencent.polaris.circuitbreak.api.pojo.InvokeContext;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.HttpStatusCodeException;
+
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_CIRCUIT_BREAKER;
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;
+
+/**
+ * Polaris circuit breaker post-processing. Including reporting.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisCircuitBreakerPostZuulFilter extends ZuulFilter {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCircuitBreakerPostZuulFilter.class);
+
+	private final PolarisZuulFallbackFactory polarisZuulFallbackFactory;
+
+	private final Environment environment;
+
+	public PolarisCircuitBreakerPostZuulFilter(PolarisZuulFallbackFactory polarisZuulFallbackFactory,
+			Environment environment) {
+		this.polarisZuulFallbackFactory = polarisZuulFallbackFactory;
+		this.environment = environment;
+	}
+
+	@Override
+	public String filterType() {
+		return POST_TYPE;
+	}
+
+	@Override
+	public int filterOrder() {
+		return SEND_RESPONSE_FILTER_ORDER - 1;
+	}
+
+	@Override
+	public boolean shouldFilter() {
+		String enabled = environment.getProperty("spring.cloud.polaris.circuitbreaker.enabled");
+		return StringUtils.isEmpty(enabled) || enabled.equals("true");
+	}
+
+	@Override
+	public Object run() throws ZuulException {
+		RequestContext context = RequestContext.getCurrentContext();
+
+		HttpServletResponse response = context.getResponse();
+		HttpStatus status = HttpStatus.resolve(response.getStatus());
+
+		Object polarisCircuitBreakerObject = context.get(POLARIS_CIRCUIT_BREAKER);
+		Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME);
+		if (polarisCircuitBreakerObject != null && polarisCircuitBreakerObject instanceof PolarisCircuitBreaker
+				&& startTimeMilliObject != null && startTimeMilliObject instanceof Long) {
+			PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) polarisCircuitBreakerObject;
+			Long startTimeMilli = (Long) startTimeMilliObject;
+			long delay = System.currentTimeMillis() - startTimeMilli;
+			InvokeContext.ResponseContext responseContext = new InvokeContext.ResponseContext();
+			responseContext.setDuration(delay);
+			responseContext.setDurationUnit(TimeUnit.MILLISECONDS);
+
+			if (status != null && status.is5xxServerError()) {
+				Throwable throwable = new CircuitBreakerStatusCodeException(status);
+				responseContext.setError(throwable);
+
+				// fallback if FallbackProvider is implemented.
+				String serviceId = ZuulFilterUtils.getServiceId(context);
+				FallbackProvider fallbackProvider = polarisZuulFallbackFactory.getFallbackProvider(serviceId);
+				if (fallbackProvider != null) {
+					ClientHttpResponse clientHttpResponse = fallbackProvider.fallbackResponse(serviceId, throwable);
+					try {
+						// set status code
+						context.setResponseStatusCode(clientHttpResponse.getRawStatusCode());
+						// set headers
+						HttpHeaders headers = clientHttpResponse.getHeaders();
+						for (String key : headers.keySet()) {
+							List<String> values = headers.get(key);
+							if (!CollectionUtils.isEmpty(values)) {
+								for (String value : values) {
+									context.addZuulResponseHeader(key, value);
+								}
+							}
+						}
+						// set body
+						context.getResponse().setCharacterEncoding("UTF-8");
+						context.setResponseBody(IOUtils.toString(clientHttpResponse.getBody(), StandardCharsets.UTF_8));
+					}
+					catch (Exception e) {
+						LOGGER.error("error filter exception", e);
+					}
+				}
+			}
+
+			if (responseContext.getError() == null) {
+				polarisCircuitBreaker.onSuccess(responseContext);
+			}
+			else {
+				polarisCircuitBreaker.onError(responseContext);
+			}
+		}
+		return null;
+	}
+
+	public class CircuitBreakerStatusCodeException extends HttpStatusCodeException {
+
+		public CircuitBreakerStatusCodeException(HttpStatus statusCode) {
+			super(statusCode);
+		}
+
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerZuulFilter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerZuulFilter.java
new file mode 100644
index 000000000..ce09b2db5
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisCircuitBreakerZuulFilter.java
@@ -0,0 +1,154 @@
+/*
+ * 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.circuitbreaker.zuul;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ZuulFilterUtils;
+import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreaker;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse;
+import com.tencent.cloud.polaris.circuitbreaker.util.PolarisCircuitBreakerUtils;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_CIRCUIT_BREAKER;
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_IS_IN_ROUTING_STATE;
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
+
+/**
+ * Polaris circuit breaker implement in Zuul.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisCircuitBreakerZuulFilter extends ZuulFilter {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCircuitBreakerZuulFilter.class);
+
+	private final CircuitBreakerFactory circuitBreakerFactory;
+
+	private final PolarisZuulFallbackFactory polarisZuulFallbackFactory;
+
+	private final Environment environment;
+
+	public PolarisCircuitBreakerZuulFilter(
+			CircuitBreakerFactory circuitBreakerFactory,
+			PolarisZuulFallbackFactory polarisZuulFallbackFactory,
+			Environment environment) {
+		this.circuitBreakerFactory = circuitBreakerFactory;
+		this.polarisZuulFallbackFactory = polarisZuulFallbackFactory;
+		this.environment = environment;
+	}
+
+	@Override
+	public String filterType() {
+		return PRE_TYPE;
+	}
+
+	/**
+	 * ServiceId is set after PreDecorationFilter.
+	 *
+	 * @return filter order
+	 */
+	@Override
+	public int filterOrder() {
+		return PRE_DECORATION_FILTER_ORDER + 2;
+	}
+
+	@Override
+	public boolean shouldFilter() {
+		String enabled = environment.getProperty("spring.cloud.polaris.circuitbreaker.enabled");
+		return StringUtils.isEmpty(enabled) || enabled.equals("true");
+	}
+
+	@Override
+	public Object run() throws ZuulException {
+		RequestContext context = RequestContext.getCurrentContext();
+		String serviceId = ZuulFilterUtils.getServiceId(context);
+		String path = ZuulFilterUtils.getPath(context);
+		String circuitName = "".equals(path) ?
+				MetadataContext.LOCAL_NAMESPACE + "#" + serviceId :
+				MetadataContext.LOCAL_NAMESPACE + "#" + serviceId + "#" + path;
+		CircuitBreaker circuitBreaker = circuitBreakerFactory.create(circuitName);
+		if (circuitBreaker instanceof PolarisCircuitBreaker) {
+			PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) circuitBreaker;
+			context.set(POLARIS_CIRCUIT_BREAKER, circuitBreaker);
+			try {
+				polarisCircuitBreaker.acquirePermission();
+			}
+			catch (CallAbortedException exception) {
+				FallbackProvider fallbackProvider = polarisZuulFallbackFactory.getFallbackProvider(serviceId);
+				ClientHttpResponse clientHttpResponse;
+				if (fallbackProvider != null) {
+					clientHttpResponse = fallbackProvider.fallbackResponse(serviceId, exception);
+				}
+				else if (exception.getFallbackInfo() != null) {
+					clientHttpResponse = new PolarisCircuitBreakerHttpResponse(exception.getFallbackInfo());
+				}
+				else {
+					throw new IllegalStateException(exception);
+				}
+				try {
+					context.setSendZuulResponse(false);
+					// set status code
+					context.setResponseStatusCode(clientHttpResponse.getRawStatusCode());
+					// set headers
+					HttpHeaders headers = clientHttpResponse.getHeaders();
+					for (String key : headers.keySet()) {
+						List<String> values = headers.get(key);
+						if (!CollectionUtils.isEmpty(values)) {
+							for (String value : values) {
+								context.addZuulResponseHeader(key, value);
+							}
+						}
+					}
+					// set body
+					context.getResponse().setCharacterEncoding("UTF-8");
+					context.setResponseBody(IOUtils.toString(clientHttpResponse.getBody(), StandardCharsets.UTF_8));
+					LOGGER.debug("PolarisCircuitBreaker CallAbortedException: {}", exception.getMessage());
+					PolarisCircuitBreakerUtils.reportStatus(polarisCircuitBreaker.getConsumerAPI(), polarisCircuitBreaker.getConf(), exception);
+				}
+				catch (IOException e) {
+					LOGGER.error("Return circuit breaker fallback info failed: {}", e.getMessage());
+					throw new IllegalStateException(e);
+				}
+			}
+			context.set(POLARIS_PRE_ROUTE_TIME, Long.valueOf(System.currentTimeMillis()));
+			context.set(POLARIS_IS_IN_ROUTING_STATE, true);
+		}
+		return null;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisZuulFallbackFactory.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisZuulFallbackFactory.java
new file mode 100644
index 000000000..cdf1d3c4b
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/PolarisZuulFallbackFactory.java
@@ -0,0 +1,57 @@
+/*
+ * 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.circuitbreaker.zuul;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
+
+/**
+ * Zuul fallback factory.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisZuulFallbackFactory {
+	private final Map<String, FallbackProvider> fallbackProviderCache;
+
+	private FallbackProvider defaultFallbackProvider = null;
+
+	public PolarisZuulFallbackFactory(Set<FallbackProvider> fallbackProviders) {
+		this.fallbackProviderCache = new HashMap<>();
+		for (FallbackProvider provider : fallbackProviders) {
+			String route = provider.getRoute();
+			if ("*".equals(route) || route == null) {
+				defaultFallbackProvider = provider;
+			}
+			else {
+				fallbackProviderCache.put(route, provider);
+			}
+		}
+	}
+
+	public FallbackProvider getFallbackProvider(String route) {
+		FallbackProvider provider = fallbackProviderCache.get(route);
+		if (provider == null) {
+			provider = defaultFallbackProvider;
+		}
+		return provider;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeter.java
new file mode 100644
index 000000000..9ac2ad59b
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeter.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.springframework.cloud.openfeign;
+
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver;
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignCircuitBreaker;
+import feign.Feign;
+import feign.Target;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.util.StringUtils;
+
+/**
+ * PolarisFeignCircuitBreakerTargeter, mostly copy from {@link org.springframework.cloud.openfeign.FeignCircuitBreakerTargeter}, but giving Polaris modification.
+ *
+ * @author sean yu
+ */
+public class PolarisFeignCircuitBreakerTargeter implements Targeter {
+
+	private final CircuitBreakerFactory circuitBreakerFactory;
+
+	private final PolarisCircuitBreakerNameResolver circuitBreakerNameResolver;
+
+	public PolarisFeignCircuitBreakerTargeter(CircuitBreakerFactory circuitBreakerFactory, PolarisCircuitBreakerNameResolver circuitBreakerNameResolver) {
+		this.circuitBreakerFactory = circuitBreakerFactory;
+		this.circuitBreakerNameResolver = circuitBreakerNameResolver;
+	}
+
+	@Override
+	public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
+			Target.HardCodedTarget<T> target) {
+		if (!(feign instanceof PolarisFeignCircuitBreaker.Builder)) {
+			return feign.target(target);
+		}
+		PolarisFeignCircuitBreaker.Builder builder = (PolarisFeignCircuitBreaker.Builder) feign;
+		String name = !StringUtils.hasText(factory.getContextId()) ? factory.getName() : factory.getContextId();
+		Class<?> fallback = factory.getFallback();
+		if (fallback != void.class) {
+			return targetWithFallback(name, context, target, builder, fallback);
+		}
+		Class<?> fallbackFactory = factory.getFallbackFactory();
+		if (fallbackFactory != void.class) {
+			return targetWithFallbackFactory(name, context, target, builder, fallbackFactory);
+		}
+		return builder(name, builder).target(target);
+	}
+
+	private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context,
+			Target.HardCodedTarget<T> target, PolarisFeignCircuitBreaker.Builder builder, Class<?> fallbackFactoryClass) {
+		FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>) getFromContext("fallbackFactory",
+				feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
+		return builder(feignClientName, builder).target(target, fallbackFactory);
+	}
+
+	private <T> T targetWithFallback(String feignClientName, FeignContext context, Target.HardCodedTarget<T> target,
+			PolarisFeignCircuitBreaker.Builder builder, Class<?> fallback) {
+		T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type());
+		return builder(feignClientName, builder).target(target, fallbackInstance);
+	}
+
+	private <T> T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context,
+			Class<?> beanType, Class<T> targetType) {
+		Object fallbackInstance = context.getInstance(feignClientName, beanType);
+		if (fallbackInstance == null) {
+			throw new IllegalStateException(
+					String.format("No " + fallbackMechanism + " instance of type %s found for feign client %s",
+							beanType, feignClientName));
+		}
+
+		if (!targetType.isAssignableFrom(beanType)) {
+			throw new IllegalStateException(String.format("Incompatible " + fallbackMechanism
+							+ " instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s",
+					beanType, targetType, feignClientName));
+		}
+		return (T) fallbackInstance;
+	}
+
+	private PolarisFeignCircuitBreaker.Builder builder(String feignClientName, PolarisFeignCircuitBreaker.Builder builder) {
+		return builder
+				.circuitBreakerFactory(circuitBreakerFactory)
+				.feignClientName(feignClientName)
+				.circuitBreakerNameResolver(circuitBreakerNameResolver);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java
new file mode 100644
index 000000000..63b25fe2c
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/org/springframework/cloud/openfeign/PolarisFeignCircuitBreakerTargeterAutoConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.springframework.cloud.openfeign;
+
+import com.tencent.cloud.polaris.circuitbreaker.config.ConditionalOnPolarisCircuitBreakerEnabled;
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver;
+
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+/**
+ * Auto configuration for PolarisFeignCircuitBreakerTargeter.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnClass({Targeter.class})
+@ConditionalOnProperty(value = "feign.circuitbreaker.enabled", havingValue = "true")
+@AutoConfigureBefore(FeignAutoConfiguration.class)
+@ConditionalOnPolarisCircuitBreakerEnabled
+public class PolarisFeignCircuitBreakerTargeterAutoConfiguration {
+
+	@Bean
+	@Primary
+	@ConditionalOnBean(CircuitBreakerFactory.class)
+	public Targeter polarisFeignCircuitBreakerTargeter(CircuitBreakerFactory circuitBreakerFactory, PolarisCircuitBreakerNameResolver circuitBreakerNameResolver) {
+		return new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories
index 418da24ab..41da60a9e 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,8 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration
+  com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration,\
+  com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration,\
+  com.tencent.cloud.polaris.circuitbreaker.config.GatewayPolarisCircuitBreakerAutoConfiguration,\
+  com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration,\
+  org.springframework.cloud.openfeign.PolarisFeignCircuitBreakerTargeterAutoConfiguration
 org.springframework.cloud.bootstrap.BootstrapConfiguration=\
   com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java
similarity index 50%
rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java
rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java
index f1dcf17a7..5b05ab5ad 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/CircuitBreakerPolarisAutoConfigurationTest.java
@@ -15,14 +15,21 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.config;
+package com.tencent.cloud.polaris.circuitbreaker;
 
+import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisCircuitBreakerNameResolver;
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
 import org.junit.jupiter.api.Test;
 
 import org.springframework.boot.autoconfigure.AutoConfigurations;
 import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
 import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -32,21 +39,42 @@ import static org.assertj.core.api.Assertions.assertThat;
  *
  * @author Haotian Zhang
  */
-public class PolarisCircuitBreakerAutoConfigurationTest {
+public class CircuitBreakerPolarisAutoConfigurationTest {
 	private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
 			.withConfiguration(AutoConfigurations.of(
 					PolarisContextAutoConfiguration.class,
 					RpcEnhancementAutoConfiguration.class,
 					LoadBalancerAutoConfiguration.class,
-					RpcEnhancementAutoConfiguration.class,
 					PolarisCircuitBreakerAutoConfiguration.class))
 			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
 
+	private final ApplicationContextRunner reactiveContextRunner = new ApplicationContextRunner()
+			.withConfiguration(AutoConfigurations.of(
+					PolarisContextAutoConfiguration.class,
+					RpcEnhancementAutoConfiguration.class,
+					LoadBalancerAutoConfiguration.class,
+					ReactivePolarisCircuitBreakerAutoConfiguration.class))
+			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+
 	@Test
 	public void testDefaultInitialization() {
 		this.contextRunner.run(context -> {
-			assertThat(context).hasSingleBean(
-					PolarisCircuitBreakerAutoConfiguration.CircuitBreakerConfigModifier.class);
+			assertThat(context).hasSingleBean(PolarisCircuitBreakerAutoConfiguration.class);
+			assertThat(context).hasSingleBean(CircuitBreakerFactory.class);
+			assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class);
+			assertThat(context).hasSingleBean(CircuitBreakAPI.class);
+			assertThat(context).hasSingleBean(PolarisCircuitBreakerNameResolver.class);
+		});
+	}
+
+	@Test
+	public void testReactiveInitialization() {
+		this.reactiveContextRunner.run(context -> {
+			assertThat(context).hasSingleBean(ReactivePolarisCircuitBreakerAutoConfiguration.class);
+			assertThat(context).hasSingleBean(ReactiveCircuitBreakerFactory.class);
+			assertThat(context).hasSingleBean(CircuitBreakerConfigModifier.class);
+			assertThat(context).hasSingleBean(CircuitBreakAPI.class);
 		});
 	}
+
 }
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java
similarity index 69%
rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java
rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java
index 9213272cd..c78784308 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java
@@ -15,8 +15,12 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.config;
+package com.tencent.cloud.polaris.circuitbreaker;
 
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration;
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
 import org.junit.jupiter.api.Test;
@@ -34,10 +38,10 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 public class PolarisCircuitBreakerBootstrapConfigurationTest {
 	private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
-			.withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class,
+			.withConfiguration(AutoConfigurations.of(
+					PolarisContextAutoConfiguration.class,
 					RpcEnhancementAutoConfiguration.class,
 					LoadBalancerAutoConfiguration.class,
-					RpcEnhancementAutoConfiguration.class,
 					PolarisCircuitBreakerBootstrapConfiguration.class))
 			.withPropertyValues("spring.cloud.polaris.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
@@ -45,8 +49,9 @@ public class PolarisCircuitBreakerBootstrapConfigurationTest {
 	@Test
 	public void testDefaultInitialization() {
 		this.contextRunner.run(context -> {
-			assertThat(context).hasSingleBean(
-					PolarisCircuitBreakerAutoConfiguration.CircuitBreakerConfigModifier.class);
+			assertThat(context).hasSingleBean(PolarisCircuitBreakerAutoConfiguration.class);
+			assertThat(context).hasSingleBean(PolarisCircuitBreakerFeignClientAutoConfiguration.class);
+			assertThat(context).hasSingleBean(ReactivePolarisCircuitBreakerAutoConfiguration.class);
 		});
 	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java
new file mode 100644
index 000000000..f3518f872
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.circuitbreaker;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.util.Utils;
+import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
+import com.tencent.polaris.test.common.TestUtils;
+import com.tencent.polaris.test.mock.discovery.NamingServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+/**
+ * @author sean yu
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT,
+		classes = PolarisCircuitBreakerFeignIntegrationTest.TestConfig.class,
+		properties = {
+				"spring.cloud.gateway.enabled=false",
+				"feign.circuitbreaker.enabled=true",
+				"spring.cloud.polaris.namespace=default",
+				"spring.cloud.polaris.service=Test",
+				"spring.cloud.polaris.address=grpc://127.0.0.1:10081"
+		})
+@DirtiesContext
+public class PolarisCircuitBreakerFeignIntegrationTest {
+
+	private static final String TEST_SERVICE_NAME = "test-service-callee";
+	private static NamingServer namingServer;
+	@Autowired
+	private EchoService echoService;
+	@Autowired
+	private FooService fooService;
+	@Autowired
+	private BarService barService;
+	@Autowired
+	private BazService bazService;
+
+	@AfterAll
+	public static void afterAll() {
+		if (null != namingServer) {
+			namingServer.terminate();
+		}
+	}
+
+	@Test
+	public void contextLoads() throws Exception {
+		assertThat(echoService).isNotNull();
+		assertThat(fooService).isNotNull();
+	}
+
+	@Test
+	public void testFeignClient() throws InvocationTargetException {
+		assertThat(echoService.echo("test")).isEqualTo("echo fallback");
+		Utils.sleepUninterrupted(2000);
+		assertThatThrownBy(() -> {
+			echoService.echo(null);
+		}).isInstanceOf(Exception.class);
+		assertThatThrownBy(() -> {
+			fooService.echo("test");
+		}).isInstanceOf(NoFallbackAvailableException.class);
+		Utils.sleepUninterrupted(2000);
+		assertThat(barService.bar()).isEqualTo("\"fallback from polaris server\"");
+		Utils.sleepUninterrupted(2000);
+		assertThat(bazService.baz()).isEqualTo("\"fallback from polaris server\"");
+		assertThat(fooService.toString()).isNotEqualTo(echoService.toString());
+		assertThat(fooService.hashCode()).isNotEqualTo(echoService.hashCode());
+		assertThat(echoService.equals(fooService)).isEqualTo(Boolean.FALSE);
+	}
+
+	@FeignClient(value = TEST_SERVICE_NAME, contextId = "1", fallback = EchoServiceFallback.class)
+	public interface EchoService {
+
+		@RequestMapping(path = "echo/{str}")
+		String echo(@RequestParam("str") String param) throws InvocationTargetException;
+
+	}
+
+	@FeignClient(value = TEST_SERVICE_NAME, contextId = "2", fallbackFactory = CustomFallbackFactory.class)
+	public interface FooService {
+
+		@RequestMapping("echo/{str}")
+		String echo(@RequestParam("str") String param);
+
+	}
+
+	@FeignClient(value = TEST_SERVICE_NAME, contextId = "3")
+	public interface BarService {
+
+		@RequestMapping(path = "bar")
+		String bar();
+
+	}
+
+	public interface BazService {
+
+		@RequestMapping(path = "baz")
+		String baz();
+
+	}
+
+	@FeignClient(value = TEST_SERVICE_NAME, contextId = "4")
+	public interface BazClient extends BazService {
+
+	}
+
+	@Configuration
+	@EnableAutoConfiguration
+	@ImportAutoConfiguration({PolarisCircuitBreakerFeignClientAutoConfiguration.class})
+	@EnableFeignClients
+	public static class TestConfig {
+
+		@Bean
+		public EchoServiceFallback echoServiceFallback() {
+			return new EchoServiceFallback();
+		}
+
+		@Bean
+		public CustomFallbackFactory customFallbackFactory() {
+			return new CustomFallbackFactory();
+		}
+
+		@Bean
+		public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException {
+			try {
+				namingServer = NamingServer.startNamingServer(10081);
+				System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
+			}
+			catch (IOException e) {
+
+			}
+			ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME);
+
+			CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
+			InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader()
+					.getResourceAsStream("circuitBreakerRule.json");
+			String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
+					.collect(Collectors.joining(""));
+			JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
+			CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
+			CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
+					.addRules(circuitBreakerRule).build();
+			namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
+			com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
+			return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
+		}
+
+	}
+
+	public static class EchoServiceFallback implements EchoService {
+
+		@Override
+		public String echo(@RequestParam("str") String param) throws InvocationTargetException {
+			if (param == null) {
+				throw new InvocationTargetException(new Exception());
+			}
+			return "echo fallback";
+		}
+
+	}
+
+	public static class FooServiceFallback implements FooService {
+
+		@Override
+		public String echo(@RequestParam("str") String param) {
+			throw new NoFallbackAvailableException("fallback", new RuntimeException());
+		}
+
+	}
+
+	public static class CustomFallbackFactory
+			implements FallbackFactory<FooService> {
+
+		private final FooService fooService = new FooServiceFallback();
+
+		@Override
+		public FooService create(Throwable throwable) {
+			return fooService;
+		}
+
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java
new file mode 100644
index 000000000..af254508f
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java
@@ -0,0 +1,231 @@
+/*
+ * 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.circuitbreaker;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.polaris.circuitbreaker.gateway.PolarisCircuitBreakerFilterFactory;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.util.Utils;
+import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
+import com.tencent.polaris.test.common.TestUtils;
+import com.tencent.polaris.test.mock.discovery.NamingServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import reactor.core.publisher.Mono;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
+import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.reactive.server.WebTestClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+/**
+ * @author sean yu
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(
+		webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+		properties = {
+				"spring.cloud.gateway.enabled=true",
+				"spring.cloud.polaris.namespace=default",
+				"spring.cloud.polaris.service=Test",
+				"spring.main.web-application-type=reactive",
+				"httpbin=http://localhost:${wiremock.server.port}",
+				"spring.cloud.polaris.address=grpc://127.0.0.1:10081"
+		},
+		classes = PolarisCircuitBreakerGatewayIntegrationTest.TestApplication.class
+)
+@AutoConfigureWireMock(port = 0)
+@ActiveProfiles("test-gateway")
+@AutoConfigureWebTestClient(timeout = "1000000")
+public class PolarisCircuitBreakerGatewayIntegrationTest {
+
+	private static final String TEST_SERVICE_NAME = "test-service-callee";
+	private static NamingServer namingServer;
+	@Autowired
+	private WebTestClient webClient;
+	@Autowired
+	private ApplicationContext applicationContext;
+
+	@AfterAll
+	public static void afterAll() {
+		if (null != namingServer) {
+			namingServer.terminate();
+		}
+	}
+
+	@Test
+	public void fallback() throws Exception {
+		SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config();
+		applicationContext.getBean(PolarisCircuitBreakerFilterFactory.class).apply(config).toString();
+
+		webClient
+				.get().uri("/err")
+				.header("Host", "www.circuitbreaker.com")
+				.exchange()
+				.expectStatus().isOk()
+				.expectBody()
+				.consumeWith(
+						response -> assertThat(response.getResponseBody()).isEqualTo("fallback".getBytes()));
+
+		Utils.sleepUninterrupted(2000);
+
+		webClient
+				.get().uri("/err-skip-fallback")
+				.header("Host", "www.circuitbreaker-skip-fallback.com")
+				.exchange()
+				.expectStatus();
+
+		Utils.sleepUninterrupted(2000);
+
+		// this should be 200, but for some unknown reason, GitHub action run failed in windows, so we skip this check
+		webClient
+				.get().uri("/err-skip-fallback")
+				.header("Host", "www.circuitbreaker-skip-fallback.com")
+				.exchange()
+				.expectStatus();
+
+		Utils.sleepUninterrupted(2000);
+
+		webClient
+				.get().uri("/err-no-fallback")
+				.header("Host", "www.circuitbreaker-no-fallback.com")
+				.exchange()
+				.expectStatus();
+
+		Utils.sleepUninterrupted(2000);
+
+		webClient
+				.get().uri("/err-no-fallback")
+				.header("Host", "www.circuitbreaker-no-fallback.com")
+				.exchange()
+				.expectStatus();
+
+		Utils.sleepUninterrupted(2000);
+
+		webClient
+				.get().uri("/err-no-fallback")
+				.header("Host", "www.circuitbreaker-no-fallback.com")
+				.exchange()
+				.expectStatus();
+	}
+
+
+	@Configuration
+	@EnableAutoConfiguration
+	public static class TestApplication {
+
+		@Bean
+		public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException {
+			try {
+				namingServer = NamingServer.startNamingServer(10081);
+				System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
+			}
+			catch (IOException e) {
+
+			}
+			ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME);
+
+			CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
+			InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader()
+					.getResourceAsStream("circuitBreakerRule.json");
+			String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
+					.collect(Collectors.joining(""));
+			JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
+			CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
+			CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
+					.addRules(circuitBreakerRule).build();
+			namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
+			com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
+			return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
+		}
+
+		@Bean
+		public RouteLocator myRoutes(RouteLocatorBuilder builder) {
+			Set<String> codeSets = new HashSet<>();
+			codeSets.add("4**");
+			codeSets.add("5**");
+			return builder.routes()
+					.route(p -> p
+							.host("*.circuitbreaker.com")
+							.filters(f -> f
+									.circuitBreaker(config -> config
+											.setStatusCodes(codeSets)
+											.setFallbackUri("forward:/fallback")
+											.setName(TEST_SERVICE_NAME)
+									))
+							.uri("http://httpbin.org:80"))
+					.route(p -> p
+							.host("*.circuitbreaker-skip-fallback.com")
+							.filters(f -> f
+									.circuitBreaker(config -> config
+											.setStatusCodes(Collections.singleton("5**"))
+											.setName(TEST_SERVICE_NAME)
+									))
+							.uri("http://httpbin.org:80"))
+					.route(p -> p
+							.host("*.circuitbreaker-no-fallback.com")
+							.filters(f -> f
+									.circuitBreaker(config -> config
+											.setName(TEST_SERVICE_NAME)
+									))
+							.uri("lb://" + TEST_SERVICE_NAME))
+					.build();
+		}
+
+		@RestController
+		static class Controller {
+			@RequestMapping("/fallback")
+			public Mono<String> fallback() {
+				return Mono.just("fallback");
+			}
+		}
+
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java
new file mode 100644
index 000000000..abe66d7f7
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java
@@ -0,0 +1,309 @@
+/*
+ * 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.circuitbreaker;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerFallback;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.util.Utils;
+import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
+import com.tencent.polaris.test.common.TestUtils;
+import com.tencent.polaris.test.mock.discovery.NamingServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.client.ExpectedCount;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+
+import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+
+/**
+ * @author sean yu
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT,
+		classes = PolarisCircuitBreakerIntegrationTest.TestConfig.class,
+		properties = {
+				"spring.cloud.gateway.enabled=false",
+				"feign.circuitbreaker.enabled=true",
+				"spring.cloud.polaris.namespace=default",
+				"spring.cloud.polaris.service=test",
+				"spring.cloud.polaris.address=grpc://127.0.0.1:10081"
+		})
+@DirtiesContext
+public class PolarisCircuitBreakerIntegrationTest {
+
+	private static final String TEST_SERVICE_NAME = "test-service-callee";
+
+	private static NamingServer namingServer;
+	@Autowired
+	@Qualifier("defaultRestTemplate")
+	private RestTemplate defaultRestTemplate;
+	@Autowired
+	@Qualifier("restTemplateFallbackFromPolaris")
+	private RestTemplate restTemplateFallbackFromPolaris;
+	@Autowired
+	@Qualifier("restTemplateFallbackFromCode")
+	private RestTemplate restTemplateFallbackFromCode;
+	@Autowired
+	@Qualifier("restTemplateFallbackFromCode2")
+	private RestTemplate restTemplateFallbackFromCode2;
+	@Autowired
+	@Qualifier("restTemplateFallbackFromCode3")
+	private RestTemplate restTemplateFallbackFromCode3;
+	@Autowired
+	@Qualifier("restTemplateFallbackFromCode4")
+	private RestTemplate restTemplateFallbackFromCode4;
+	@Autowired
+	private ApplicationContext applicationContext;
+
+	@AfterAll
+	public static void afterAll() {
+		if (null != namingServer) {
+			namingServer.terminate();
+		}
+	}
+
+	@Test
+	public void testRestTemplate() throws URISyntaxException {
+		MockRestServiceServer mockServer = MockRestServiceServer.createServer(defaultRestTemplate);
+		mockServer
+				.expect(ExpectedCount.once(), requestTo(new URI("http://localhost:18001/example/service/b/info")))
+				.andExpect(method(HttpMethod.GET))
+				.andRespond(withStatus(HttpStatus.OK).body("OK"));
+		assertThat(defaultRestTemplate.getForObject("http://localhost:18001/example/service/b/info", String.class)).isEqualTo("OK");
+		mockServer.verify();
+		mockServer.reset();
+		HttpHeaders headers = new HttpHeaders();
+		mockServer
+				.expect(ExpectedCount.once(), requestTo(new URI("http://localhost:18001/example/service/b/info")))
+				.andExpect(method(HttpMethod.GET))
+				.andRespond(withStatus(HttpStatus.BAD_GATEWAY).headers(headers).body("BAD_GATEWAY"));
+		assertThat(defaultRestTemplate.getForObject("http://localhost:18001/example/service/b/info", String.class)).isEqualTo("fallback");
+		mockServer.verify();
+		mockServer.reset();
+		assertThat(restTemplateFallbackFromCode.getForObject("/example/service/b/info", String.class)).isEqualTo("\"this is a fallback class\"");
+		Utils.sleepUninterrupted(2000);
+		assertThat(restTemplateFallbackFromCode2.getForObject("/example/service/b/info", String.class)).isEqualTo("\"this is a fallback class\"");
+		Utils.sleepUninterrupted(2000);
+		assertThat(restTemplateFallbackFromCode3.getForEntity("/example/service/b/info", String.class)
+				.getStatusCode()).isEqualTo(HttpStatus.OK);
+		Utils.sleepUninterrupted(2000);
+		assertThat(restTemplateFallbackFromCode4.getForObject("/example/service/b/info", String.class)).isEqualTo("fallback");
+		Utils.sleepUninterrupted(2000);
+		assertThat(restTemplateFallbackFromPolaris.getForObject("/example/service/b/info", String.class)).isEqualTo("\"fallback from polaris server\"");
+		// just for code coverage
+		PolarisCircuitBreakerHttpResponse response = ((CustomPolarisCircuitBreakerFallback) applicationContext.getBean("customPolarisCircuitBreakerFallback")).fallback();
+		assertThat(response.getStatusText()).isEqualTo("OK");
+		assertThat(response.getFallbackInfo().getCode()).isEqualTo(200);
+	}
+
+	@Configuration
+	@EnableAutoConfiguration
+	@ImportAutoConfiguration({PolarisCircuitBreakerFeignClientAutoConfiguration.class})
+	@EnableFeignClients
+	public static class TestConfig {
+
+		@Bean
+		@PolarisCircuitBreaker(fallback = "fallback")
+		public RestTemplate defaultRestTemplate() {
+			return new RestTemplate();
+		}
+
+		@Bean
+		@LoadBalanced
+		@PolarisCircuitBreaker
+		public RestTemplate restTemplateFallbackFromPolaris() {
+			DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME);
+			RestTemplate restTemplate = new RestTemplate();
+			restTemplate.setUriTemplateHandler(uriBuilderFactory);
+			return restTemplate;
+		}
+
+		@Bean
+		@LoadBalanced
+		@PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class)
+		public RestTemplate restTemplateFallbackFromCode() {
+			DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME);
+			RestTemplate restTemplate = new RestTemplate();
+			restTemplate.setUriTemplateHandler(uriBuilderFactory);
+			return restTemplate;
+		}
+
+		@Bean
+		@LoadBalanced
+		@PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class)
+		public RestTemplate restTemplateFallbackFromCode2() {
+			DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME);
+			RestTemplate restTemplate = new RestTemplate();
+			restTemplate.setUriTemplateHandler(uriBuilderFactory);
+			return restTemplate;
+		}
+
+		@Bean
+		@LoadBalanced
+		@PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class)
+		public RestTemplate restTemplateFallbackFromCode3() {
+			DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME);
+			RestTemplate restTemplate = new RestTemplate();
+			restTemplate.setUriTemplateHandler(uriBuilderFactory);
+			return restTemplate;
+		}
+
+		@Bean
+		@LoadBalanced
+		@PolarisCircuitBreaker(fallback = "fallback")
+		public RestTemplate restTemplateFallbackFromCode4() {
+			DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME);
+			RestTemplate restTemplate = new RestTemplate();
+			restTemplate.setUriTemplateHandler(uriBuilderFactory);
+			return restTemplate;
+		}
+
+		@Bean
+		public CustomPolarisCircuitBreakerFallback customPolarisCircuitBreakerFallback() {
+			return new CustomPolarisCircuitBreakerFallback();
+		}
+
+		@Bean
+		public CustomPolarisCircuitBreakerFallback2 customPolarisCircuitBreakerFallback2() {
+			return new CustomPolarisCircuitBreakerFallback2();
+		}
+
+		@Bean
+		public CustomPolarisCircuitBreakerFallback3 customPolarisCircuitBreakerFallback3() {
+			return new CustomPolarisCircuitBreakerFallback3();
+		}
+
+		@Bean
+		public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException {
+			try {
+				namingServer = NamingServer.startNamingServer(10081);
+				System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
+			}
+			catch (IOException e) {
+
+			}
+			ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME);
+
+			CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
+			InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader()
+					.getResourceAsStream("circuitBreakerRule.json");
+			String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
+					.collect(Collectors.joining(""));
+			JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
+			CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
+			CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
+					.addRules(circuitBreakerRule).build();
+			namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
+			com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
+			return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
+		}
+
+		@RestController
+		@RequestMapping("/example/service/b")
+		public class ServiceBController {
+
+			/**
+			 * Get service information.
+			 *
+			 * @return service information
+			 */
+			@GetMapping("/info")
+			public String info() {
+				return "hello world ! I'm a service B1";
+			}
+
+		}
+
+	}
+
+	public static class CustomPolarisCircuitBreakerFallback implements PolarisCircuitBreakerFallback {
+		@Override
+		public PolarisCircuitBreakerHttpResponse fallback() {
+			return new PolarisCircuitBreakerHttpResponse(
+					200,
+					new HashMap<String, String>() {{
+						put("xxx", "xxx");
+					}},
+					"\"this is a fallback class\"");
+		}
+	}
+
+	public static class CustomPolarisCircuitBreakerFallback2 implements PolarisCircuitBreakerFallback {
+		@Override
+		public PolarisCircuitBreakerHttpResponse fallback() {
+			return new PolarisCircuitBreakerHttpResponse(
+					200,
+					"\"this is a fallback class\""
+			);
+		}
+	}
+
+	public static class CustomPolarisCircuitBreakerFallback3 implements PolarisCircuitBreakerFallback {
+		@Override
+		public PolarisCircuitBreakerHttpResponse fallback() {
+			return new PolarisCircuitBreakerHttpResponse(
+					200
+			);
+		}
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java
new file mode 100644
index 000000000..5058a8a22
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.circuitbreaker;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
+import com.tencent.polaris.client.util.Utils;
+import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
+import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
+import com.tencent.polaris.test.common.TestUtils;
+import com.tencent.polaris.test.mock.discovery.NamingServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER;
+import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link PolarisCircuitBreaker} and {@link ReactivePolarisCircuitBreaker} using real mock server.
+ *
+ * @author sean yu
+ */
+@ExtendWith(MockitoExtension.class)
+public class PolarisCircuitBreakerMockServerTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	private static NamingServer namingServer;
+
+	@BeforeAll
+	public static void beforeAll() throws IOException {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.namespace"))
+				.thenReturn(NAMESPACE_TEST);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service"))
+				.thenReturn(SERVICE_CIRCUIT_BREAKER);
+
+		try {
+			namingServer = NamingServer.startNamingServer(-1);
+			System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
+		}
+		catch (IOException e) {
+
+		}
+		ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER);
+
+		CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder =  CircuitBreakerProto.CircuitBreakerRule.newBuilder();
+		InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json");
+		String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining(""));
+		JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
+		CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
+		CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build();
+		namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
+	}
+
+	@AfterAll
+	public static void afterAll() {
+		if (null != namingServer) {
+			namingServer.terminate();
+		}
+	}
+
+	@Test
+	public void testCircuitBreaker() {
+		Configuration configuration = TestUtils.configWithEnvAddress();
+		CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
+
+		ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPIByConfig(configuration);
+		PolarisCircuitBreakerFactory polarisCircuitBreakerFactory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI);
+		CircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER);
+
+		// trigger fallback for 5 times
+		List<String> resList = new ArrayList<>();
+		for (int i = 0; i < 5; i++) {
+			int finalI = i;
+			String res = cb.run(() -> {
+				if (finalI % 2 == 1) {
+					throw new IllegalArgumentException("invoke failed");
+				}
+				else {
+					return "invoke success";
+				}
+			}, t -> "fallback");
+			resList.add(res);
+			Utils.sleepUninterrupted(2000);
+		}
+		assertThat(resList).isEqualTo(Arrays.asList("invoke success", "fallback", "fallback", "fallback", "fallback"));
+
+		// always fallback
+		ReactivePolarisCircuitBreakerFactory reactivePolarisCircuitBreakerFactory = new ReactivePolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI);
+		ReactiveCircuitBreaker rcb = reactivePolarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER);
+
+		assertThat(Mono.just("foobar").transform(it -> rcb.run(it, t -> Mono.just("fallback")))
+				.block()).isEqualTo("fallback");
+
+		assertThat(Mono.error(new RuntimeException("boom")).transform(it -> rcb.run(it, t -> Mono.just("fallback")))
+				.block()).isEqualTo("fallback");
+
+		assertThat(Flux.just("foobar", "hello world").transform(it -> rcb.run(it, t -> Flux.just("fallback", "fallback")))
+				.collectList().block())
+				.isEqualTo(Arrays.asList("fallback", "fallback"));
+
+		assertThat(Flux.error(new RuntimeException("boom")).transform(it -> rcb.run(it, t -> Flux.just("fallback")))
+				.collectList().block())
+				.isEqualTo(Collections.singletonList("fallback"));
+
+
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java
new file mode 100644
index 000000000..494ae7798
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.circuitbreaker;
+
+
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration;
+import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
+import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link PolarisCircuitBreaker}.
+ *
+ * @author sean yu
+ */
+@ExtendWith(MockitoExtension.class)
+public class PolarisCircuitBreakerTest {
+
+	private static final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+			.withConfiguration(AutoConfigurations.of(
+					PolarisContextAutoConfiguration.class,
+					RpcEnhancementAutoConfiguration.class,
+					LoadBalancerAutoConfiguration.class,
+					PolarisCircuitBreakerFeignClientAutoConfiguration.class,
+					PolarisCircuitBreakerAutoConfiguration.class))
+			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+
+	@BeforeAll
+	public static void beforeClass() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.namespace"))
+				.thenReturn(NAMESPACE_TEST);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service"))
+				.thenReturn(SERVICE_CIRCUIT_BREAKER);
+	}
+
+	@AfterAll
+	public static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@Test
+	public void run() {
+		contextRunner.run(context -> {
+
+			PolarisCircuitBreakerFactory polarisCircuitBreakerFactory = context.getBean(PolarisCircuitBreakerFactory.class);
+			CircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER);
+
+			PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration configuration =
+					polarisCircuitBreakerFactory.configBuilder(SERVICE_CIRCUIT_BREAKER).build();
+
+			polarisCircuitBreakerFactory.configureDefault(id -> configuration);
+
+			assertThat(cb.run(() -> "foobar")).isEqualTo("foobar");
+
+			assertThat((String) cb.run(() -> {
+				throw new RuntimeException("boom");
+			}, t -> "fallback")).isEqualTo("fallback");
+
+		});
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerTest.java
new file mode 100644
index 000000000..f06502c87
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/ReactivePolarisCircuitBreakerTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.circuitbreaker;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration;
+import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link ReactivePolarisCircuitBreaker}.
+ *
+ * @author sean yu
+ */
+@ExtendWith(MockitoExtension.class)
+public class ReactivePolarisCircuitBreakerTest {
+
+	private final ApplicationContextRunner reactiveContextRunner = new ApplicationContextRunner()
+			.withConfiguration(AutoConfigurations.of(
+					PolarisContextAutoConfiguration.class,
+					RpcEnhancementAutoConfiguration.class,
+					LoadBalancerAutoConfiguration.class,
+					ReactivePolarisCircuitBreakerAutoConfiguration.class))
+			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+
+	@BeforeAll
+	public static void beforeClass() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.namespace"))
+				.thenReturn(NAMESPACE_TEST);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service"))
+				.thenReturn(SERVICE_CIRCUIT_BREAKER);
+	}
+
+	@AfterAll
+	public static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@Test
+	public void run() {
+		this.reactiveContextRunner.run(context -> {
+			ReactivePolarisCircuitBreakerFactory polarisCircuitBreakerFactory = context.getBean(ReactivePolarisCircuitBreakerFactory.class);
+			ReactiveCircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER);
+
+			PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration configuration =
+					polarisCircuitBreakerFactory.configBuilder(SERVICE_CIRCUIT_BREAKER).build();
+
+			polarisCircuitBreakerFactory.configureDefault(id -> configuration);
+
+			assertThat(Mono.just("foobar").transform(cb::run).block()).isEqualTo("foobar");
+
+			assertThat(Mono.error(new RuntimeException("boom")).transform(it -> cb.run(it, t -> Mono.just("fallback")))
+					.block()).isEqualTo("fallback");
+
+			assertThat(Flux.just("foobar", "hello world").transform(cb::run).collectList().block())
+					.isEqualTo(Arrays.asList("foobar", "hello world"));
+
+			assertThat(Flux.error(new RuntimeException("boom")).transform(it -> cb.run(it, t -> Flux.just("fallback")))
+					.collectList().block()).isEqualTo(Collections.singletonList("fallback"));
+		});
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java
new file mode 100644
index 000000000..53e38c9d2
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.circuitbreaker.reporter;
+
+import java.net.URI;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * ExceptionCircuitBreakerReporterTest.
+ *
+ * @author sean yu
+ */
+@ExtendWith(MockitoExtension.class)
+public class ExceptionCircuitBreakerReporterTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+	@InjectMocks
+	private ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter;
+	@Mock
+	private CircuitBreakAPI circuitBreakAPI;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testGetName() {
+		assertThat(exceptionCircuitBreakerReporter.getName()).isEqualTo(ExceptionCircuitBreakerReporter.class.getName());
+	}
+
+	@Test
+	public void testType() {
+		assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION);
+	}
+
+	@Test
+	public void testRun() throws Throwable {
+		EnhancedPluginContext context = mock(EnhancedPluginContext.class);
+		// test not report
+		exceptionCircuitBreakerReporter.run(context);
+		verify(context, times(0)).getRequest();
+
+		doReturn(true).when(reporterProperties).isEnabled();
+
+		EnhancedPluginContext pluginContext = new EnhancedPluginContext();
+		EnhancedRequestContext request = EnhancedRequestContext.builder()
+				.httpMethod(HttpMethod.GET)
+				.url(URI.create("http://0.0.0.0/"))
+				.httpHeaders(new HttpHeaders())
+				.build();
+		EnhancedResponseContext response = EnhancedResponseContext.builder()
+				.httpStatus(200)
+				.build();
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		serviceInstance.setServiceId(SERVICE_PROVIDER);
+
+		pluginContext.setRequest(request);
+		pluginContext.setResponse(response);
+		pluginContext.setServiceInstance(serviceInstance);
+		pluginContext.setThrowable(new RuntimeException());
+
+		exceptionCircuitBreakerReporter.run(pluginContext);
+		exceptionCircuitBreakerReporter.getOrder();
+		exceptionCircuitBreakerReporter.getName();
+		exceptionCircuitBreakerReporter.getType();
+	}
+
+	@Test
+	public void testHandlerThrowable() {
+		// mock request
+		EnhancedRequestContext request = mock(EnhancedRequestContext.class);
+		// mock response
+		EnhancedResponseContext response = mock(EnhancedResponseContext.class);
+
+		EnhancedPluginContext context = new EnhancedPluginContext();
+		context.setRequest(request);
+		context.setResponse(response);
+		exceptionCircuitBreakerReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java
new file mode 100644
index 000000000..4dcd3d19e
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.circuitbreaker.reporter;
+
+import java.net.URI;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * SuccessCircuitBreakerReporterTest.
+ *
+ * @author sean yu
+ */
+@ExtendWith(MockitoExtension.class)
+public class SuccessCircuitBreakerReporterTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private SDKContext sdkContext;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@InjectMocks
+	private SuccessCircuitBreakerReporter successCircuitBreakerReporter;
+	@Mock
+	private CircuitBreakAPI circuitBreakAPI;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testGetName() {
+		assertThat(successCircuitBreakerReporter.getName()).isEqualTo(SuccessCircuitBreakerReporter.class.getName());
+	}
+
+	@Test
+	public void testType() {
+		assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.POST);
+	}
+
+	@Test
+	public void testRun() throws Throwable {
+
+		EnhancedPluginContext context = mock(EnhancedPluginContext.class);
+		// test not report
+		successCircuitBreakerReporter.run(context);
+		verify(context, times(0)).getRequest();
+
+		doReturn(true).when(reporterProperties).isEnabled();
+
+		EnhancedPluginContext pluginContext = new EnhancedPluginContext();
+		EnhancedRequestContext request = EnhancedRequestContext.builder()
+				.httpMethod(HttpMethod.GET)
+				.url(URI.create("http://0.0.0.0/"))
+				.build();
+		EnhancedResponseContext response = EnhancedResponseContext.builder()
+				.httpStatus(200)
+				.build();
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		serviceInstance.setServiceId(SERVICE_PROVIDER);
+
+		pluginContext.setRequest(request);
+		pluginContext.setResponse(response);
+		pluginContext.setServiceInstance(serviceInstance);
+
+		successCircuitBreakerReporter.run(pluginContext);
+		successCircuitBreakerReporter.getOrder();
+		successCircuitBreakerReporter.getName();
+		successCircuitBreakerReporter.getType();
+	}
+
+	@Test
+	public void testHandlerThrowable() {
+		// mock request
+		EnhancedRequestContext request = mock(EnhancedRequestContext.class);
+		// mock response
+		EnhancedResponseContext response = mock(EnhancedResponseContext.class);
+
+		EnhancedPluginContext context = new EnhancedPluginContext();
+		context.setRequest(request);
+		context.setResponse(response);
+		successCircuitBreakerReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java
new file mode 100644
index 000000000..e6213dbab
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java
@@ -0,0 +1,71 @@
+/*
+ * 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.circuitbreaker.util;
+
+import java.util.HashMap;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.polaris.circuitbreaker.common.PolarisCircuitBreakerConfigBuilder;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.mockito.ArgumentMatchers.anyString;
+
+public class PolarisCircuitBreakerUtilsTests {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testReportStatus() {
+		ConsumerAPI consumerAPI = Mockito.mock(ConsumerAPI.class);
+		Mockito.doNothing().when(consumerAPI).updateServiceCallResult(new ServiceCallResult());
+		PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration conf = new PolarisCircuitBreakerConfigBuilder.PolarisCircuitBreakerConfiguration();
+		PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, new CallAbortedException("mock", new CircuitBreakerStatus.FallbackInfo(0, new HashMap<>(), "")));
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml
new file mode 100644
index 000000000..6094b46e5
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/application-test-gateway.yml
@@ -0,0 +1,36 @@
+spring:
+  application:
+    name: GatewayScgService
+  cloud:
+    tencent:
+      plugin:
+        scg:
+          staining:
+            enabled: true
+            rule-staining:
+              enabled: true
+        router:
+          feature-env:
+            enabled: true
+    polaris:
+      address: grpc://127.0.0.1:8091
+      namespace: default
+      enabled: true
+    gateway:
+      routes:
+        - id: cb-test
+          uri: http://localhost:${server.port}/hello/1
+          predicates:
+            - Path=/cb-test/**
+          filters:
+            - name: CircuitBreaker
+              args:
+                statusCodes: 5**,4**,3**,2**,1**,500,400
+                fallbackUri: forward:/polaris-fallback
+logging:
+  level:
+    root: info
+    com.tencent.polaris.discovery.client.flow.RegisterFlow: off
+    com.tencent.polaris.plugins.registry.memory.CacheObject: off
+    com.tencent.cloud.polaris.circuitbreaker: debug
+
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule-method.json b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule-method.json
new file mode 100644
index 000000000..749e43479
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule-method.json
@@ -0,0 +1,59 @@
+{
+  "@type": "type.googleapis.com/v1.CircuitBreakerRule",
+  "id": "5f1601f01823474d9be39c0bbb26ab87",
+  "name": "test",
+  "namespace": "TestCircuitBreakerRule",
+  "enable": true,
+  "revision": "10b120c08706429f8fdc3fb44a53224b",
+  "ctime": "1754-08-31 06:49:24",
+  "mtime": "2023-02-21 17:35:31",
+  "etime": "",
+  "description": "",
+  "level": "METHOD",
+  "ruleMatcher": {
+    "source": {
+      "service": "*",
+      "namespace": "*"
+    },
+    "destination": {
+      "service": "*",
+      "namespace": "*",
+      "method": {"type": "REGEX", "value": "*"}
+    }
+  },
+  "errorConditions": [
+    {
+      "inputType": "RET_CODE",
+      "condition": {
+        "type": "NOT_EQUALS",
+        "value": "200",
+        "valueType": "TEXT"
+      }
+    }
+  ],
+  "triggerCondition": [
+    {
+      "triggerType": "CONSECUTIVE_ERROR",
+      "errorCount": 1,
+      "errorPercent": 1,
+      "interval": 5,
+      "minimumRequest": 5
+    }
+  ],
+  "maxEjectionPercent": 0,
+  "recoverCondition": {
+    "sleepWindow": 60,
+    "consecutiveSuccess": 3
+  },
+  "faultDetectConfig": {
+    "enable": true
+  },
+  "fallbackConfig": {
+    "enable": true,
+    "response": {
+      "code": 200,
+      "headers": [{"key": "xxx", "value": "xxx"}],
+      "body": "\"fallback from polaris server\""
+    }
+  }
+}
\ No newline at end of file
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule.json b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule.json
new file mode 100644
index 000000000..7adef7fba
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/resources/circuitBreakerRule.json
@@ -0,0 +1,59 @@
+{
+  "@type": "type.googleapis.com/v1.CircuitBreakerRule",
+  "id": "5f1601f01823474d9be39c0bbb26ab87",
+  "name": "test",
+  "namespace": "TestCircuitBreakerRule",
+  "enable": true,
+  "revision": "10b120c08706429f8fdc3fb44a53224b",
+  "ctime": "1754-08-31 06:49:24",
+  "mtime": "2023-02-21 17:35:31",
+  "etime": "",
+  "description": "",
+  "level": "SERVICE",
+  "ruleMatcher": {
+    "source": {
+      "service": "*",
+      "namespace": "*"
+    },
+    "destination": {
+      "service": "*",
+      "namespace": "*",
+      "method": null
+    }
+  },
+  "errorConditions": [
+    {
+      "inputType": "RET_CODE",
+      "condition": {
+        "type": "NOT_EQUALS",
+        "value": "200",
+        "valueType": "TEXT"
+      }
+    }
+  ],
+  "triggerCondition": [
+    {
+      "triggerType": "CONSECUTIVE_ERROR",
+      "errorCount": 1,
+      "errorPercent": 1,
+      "interval": 5,
+      "minimumRequest": 5
+    }
+  ],
+  "maxEjectionPercent": 0,
+  "recoverCondition": {
+    "sleepWindow": 60,
+    "consecutiveSuccess": 3
+  },
+  "faultDetectConfig": {
+    "enable": true
+  },
+  "fallbackConfig": {
+    "enable": true,
+    "response": {
+      "code": 200,
+      "headers": [{"key": "xxx", "value": "xxx"}],
+      "body": "\"fallback from polaris server\""
+    }
+  }
+}
\ No newline at end of file
diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml
index c16e5ffcb..7b881c93e 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml
@@ -32,6 +32,18 @@
 			<scope>test</scope>
 		</dependency>
 
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>connector-consul</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>connector-nacos</artifactId>
+			<scope>test</scope>
+		</dependency>
+
 		<dependency>
 			<groupId>com.tencent.polaris</groupId>
 			<artifactId>polaris-test-mock-discovery</artifactId>
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java
index 70a4f703f..e9bed3e61 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/consul/ConsulConfigModifier.java
@@ -31,6 +31,8 @@ import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl;
 import com.tencent.polaris.factory.config.provider.RegisterConfigImpl;
 import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
 import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.springframework.util.CollectionUtils;
 
@@ -38,6 +40,9 @@ import org.springframework.util.CollectionUtils;
  * @author lingxiao.wlx
  */
 public class ConsulConfigModifier implements PolarisConfigModifier {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigModifier.class);
+
 	private static final String ID = "consul";
 
 	private final ConsulContextProperties consulContextProperties;
@@ -49,6 +54,23 @@ public class ConsulConfigModifier implements PolarisConfigModifier {
 	@Override
 	public void modify(ConfigurationImpl configuration) {
 		if (consulContextProperties != null && consulContextProperties.isEnabled()) {
+			// Check if Consul client Available
+			boolean consulAvailable = false;
+			try {
+				consulAvailable = null != Class.forName("com.ecwid.consul.v1.ConsulClient");
+			}
+			catch (Throwable ignored) {
+
+			}
+			if (!consulAvailable) {
+				LOGGER.error("Please import \"connector-consul\" dependency when enabling consul service registration and discovery.\n"
+						+ "Add dependency configuration below to pom.xml:\n"
+						+ "<dependency>\n"
+						+ "\t<groupId>com.tencent.polaris</groupId>\n"
+						+ "\t<artifactId>connector-consul</artifactId>\n"
+						+ "</dependency>");
+				throw new RuntimeException("Dependency \"connector-consul\" not found.");
+			}
 			if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) {
 				configuration.getGlobal().setServerConnectors(new ArrayList<>());
 			}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java
index ca80e5038..4f6838177 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java
@@ -30,6 +30,8 @@ import com.tencent.polaris.factory.config.consumer.DiscoveryConfigImpl;
 import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl;
 import com.tencent.polaris.factory.config.provider.RegisterConfigImpl;
 import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.springframework.util.CollectionUtils;
 
@@ -40,7 +42,6 @@ import org.springframework.util.CollectionUtils;
  */
 public class NacosConfigModifier implements PolarisConfigModifier {
 
-	private static final String ID = "nacos";
 	/**
 	 * nacos username.
 	 */
@@ -53,7 +54,8 @@ public class NacosConfigModifier implements PolarisConfigModifier {
 	 * nacos contextPath.
 	 */
 	public static final String CONTEXT_PATH = "contextPath";
-
+	private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfigModifier.class);
+	private static final String ID = "nacos";
 	private final NacosContextProperties nacosContextProperties;
 
 	public NacosConfigModifier(NacosContextProperties nacosContextProperties) {
@@ -65,6 +67,23 @@ public class NacosConfigModifier implements PolarisConfigModifier {
 		if (Objects.isNull(nacosContextProperties) || !nacosContextProperties.isEnabled()) {
 			return;
 		}
+		// Check if Nacos Available
+		boolean nacosAvailable = false;
+		try {
+			nacosAvailable = null != Class.forName("com.alibaba.nacos.api.naming.NamingService");
+		}
+		catch (Throwable ignored) {
+
+		}
+		if (!nacosAvailable) {
+			LOGGER.error("Please import \"connector-nacos\" dependency when enabling nacos service registration and discovery.\n"
+					+ "Add dependency configuration below to pom.xml:\n"
+					+ "<dependency>\n"
+					+ "\t<groupId>com.tencent.polaris</groupId>\n"
+					+ "\t<artifactId>connector-nacos</artifactId>\n"
+					+ "</dependency>");
+			throw new RuntimeException("Dependency \"connector-nacos\" not found.");
+		}
 		if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) {
 			configuration.getGlobal().setServerConnectors(new ArrayList<>());
 		}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
index 269c6931b..e320ed531 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
@@ -41,6 +41,7 @@ import com.tencent.polaris.api.rpc.InstanceRegisterRequest;
 import com.tencent.polaris.api.rpc.InstanceRegisterResponse;
 import com.tencent.polaris.api.rpc.InstancesResponse;
 import com.tencent.polaris.client.util.NamedThreadFactory;
+import com.tencent.polaris.factory.config.provider.ServiceConfigImpl;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -144,6 +145,11 @@ public class PolarisServiceRegistry implements ServiceRegistry<PolarisRegistrati
 					LOGGER.warn("Stat server started error, ", e);
 				}
 			}
+
+			ServiceConfigImpl serviceConfig = (ServiceConfigImpl) polarisDiscoveryHandler.getSdkContext().getConfig()
+					.getProvider().getService();
+			serviceConfig.setNamespace(polarisDiscoveryProperties.getNamespace());
+			serviceConfig.setName(serviceId);
 		}
 		catch (Exception e) {
 			LOGGER.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e);
@@ -197,7 +203,7 @@ public class PolarisServiceRegistry implements ServiceRegistry<PolarisRegistrati
 		String serviceName = registration.getServiceId();
 		InstancesResponse instancesResponse = polarisDiscoveryHandler.getInstances(serviceName);
 		Instance[] instances = instancesResponse.getInstances();
-		if (null == instances || instances.length == 0) {
+		if (null == instances) {
 			return null;
 		}
 		for (Instance instance : instances) {
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java
index 42448d2b7..715ab2f39 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/ribbon/PolarisRibbonServerListConfigurationTest.java
@@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.test.context.runner.ApplicationContextRunner;
 import org.springframework.context.annotation.Bean;
 
+import static com.tencent.polaris.test.common.Consts.PORT;
 import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -44,6 +45,9 @@ public class PolarisRibbonServerListConfigurationTest {
 		this.applicationContextRunner
 				.withConfiguration(AutoConfigurations.of(
 						TestApplication.class, PolarisRibbonServerListConfiguration.class))
+				.withPropertyValues("spring.application.name=" + SERVICE_PROVIDER)
+				.withPropertyValues("server.port=" + PORT)
+				.withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081")
 				.run(context -> {
 					assertThat(context).hasSingleBean(PolarisRibbonServerListConfiguration.class);
 					assertThat(context).hasSingleBean(ServerList.class);
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java
index 7590b8b1e..b718e88e9 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java
@@ -37,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
  * @author Haotian Zhang
  */
 @ExtendWith(SpringExtension.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = OkHttpUtilTest.TestApplication.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = OkHttpUtilTest.TestApplication.class, properties = {"spring.application.name=test", "spring.cloud.polaris.discovery.register=false"})
 public class OkHttpUtilTest {
 
 	@LocalServerPort
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml
index a7ee8e340..0b08cd790 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/pom.xml
@@ -15,10 +15,10 @@
 
 	<dependencies>
 		<!-- Spring Cloud Tencent dependencies start -->
-        <dependency>
-            <groupId>com.tencent.cloud</groupId>
-            <artifactId>spring-cloud-tencent-polaris-context</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
+		</dependency>
 		<!-- Spring Cloud Tencent dependencies end -->
 
 		<!-- Polaris dependencies start -->
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java
index c0d3de241..f51b6f0b8 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/RateLimitRuleLabelResolver.java
@@ -34,8 +34,9 @@ import org.springframework.util.CollectionUtils;
 /**
  * resolve labels from rate limit rule.
  *
- * @author lepdou 2022-05-13
+ *@author lepdou 2022-05-13
  */
+@Deprecated
 public class RateLimitRuleLabelResolver {
 
 	private final ServiceRuleManager serviceRuleManager;
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java
index b8b79b7a9..1a20a298f 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfiguration.java
@@ -20,10 +20,10 @@ package com.tencent.cloud.polaris.ratelimit.config;
 
 import com.tencent.cloud.polaris.context.ServiceRuleManager;
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
-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.resolver.RateLimitRuleArgumentReactiveResolver;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
@@ -31,6 +31,7 @@ import com.tencent.polaris.client.api.SDKContext;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
 import com.tencent.polaris.ratelimit.factory.LimitAPIFactory;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
@@ -39,6 +40,7 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.lang.Nullable;
 
+import static com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant.FILTER_ORDER;
 import static com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter.QUOTA_FILTER_BEAN_NAME;
 import static javax.servlet.DispatcherType.ASYNC;
 import static javax.servlet.DispatcherType.ERROR;
@@ -62,11 +64,6 @@ public class PolarisRateLimitAutoConfiguration {
 		return LimitAPIFactory.createLimitAPIByContext(polarisContext);
 	}
 
-	@Bean
-	public RateLimitRuleLabelResolver rateLimitRuleLabelService(ServiceRuleManager serviceRuleManager) {
-		return new RateLimitRuleLabelResolver(serviceRuleManager);
-	}
-
 	/**
 	 * Create when web application type is SERVLET.
 	 */
@@ -74,15 +71,19 @@ public class PolarisRateLimitAutoConfiguration {
 	@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
 	protected static class QuotaCheckFilterConfig {
 
+		@Bean
+		public RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver(ServiceRuleManager serviceRuleManager,
+				@Autowired(required = false) PolarisRateLimiterLabelServletResolver labelResolver) {
+			return new RateLimitRuleArgumentServletResolver(serviceRuleManager, labelResolver);
+		}
+
 		@Bean
 		@ConditionalOnMissingBean
 		public QuotaCheckServletFilter quotaCheckFilter(LimitAPI limitAPI,
-				@Nullable PolarisRateLimiterLabelServletResolver labelResolver,
 				PolarisRateLimitProperties polarisRateLimitProperties,
-				RateLimitRuleLabelResolver rateLimitRuleLabelResolver,
-				@Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
-			return new QuotaCheckServletFilter(limitAPI, labelResolver,
-					polarisRateLimitProperties, rateLimitRuleLabelResolver, polarisRateLimiterLimitedFallback);
+				RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver,
+				@Autowired(required = false) PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
+			return new QuotaCheckServletFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback);
 		}
 
 		@Bean
@@ -92,9 +93,10 @@ public class PolarisRateLimitAutoConfiguration {
 					quotaCheckServletFilter);
 			registrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST);
 			registrationBean.setName(QUOTA_FILTER_BEAN_NAME);
-			registrationBean.setOrder(RateLimitConstant.FILTER_ORDER);
+			registrationBean.setOrder(FILTER_ORDER);
 			return registrationBean;
 		}
+
 	}
 
 	/**
@@ -104,14 +106,18 @@ public class PolarisRateLimitAutoConfiguration {
 	@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
 	protected static class MetadataReactiveFilterConfig {
 
+		@Bean
+		public RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentResolver(ServiceRuleManager serviceRuleManager,
+				@Autowired(required = false) PolarisRateLimiterLabelReactiveResolver labelResolver) {
+			return new RateLimitRuleArgumentReactiveResolver(serviceRuleManager, labelResolver);
+		}
+
 		@Bean
 		public QuotaCheckReactiveFilter quotaCheckReactiveFilter(LimitAPI limitAPI,
-				@Nullable PolarisRateLimiterLabelReactiveResolver labelResolver,
 				PolarisRateLimitProperties polarisRateLimitProperties,
-				RateLimitRuleLabelResolver rateLimitRuleLabelResolver,
+				RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentResolver,
 				@Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
-			return new QuotaCheckReactiveFilter(limitAPI, labelResolver,
-					polarisRateLimitProperties, rateLimitRuleLabelResolver, polarisRateLimiterLimitedFallback);
+			return new QuotaCheckReactiveFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentResolver, polarisRateLimiterLimitedFallback);
 		}
 	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java
index 776e776a5..b3129eed0 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilter.java
@@ -20,27 +20,22 @@ package com.tencent.cloud.polaris.ratelimit.filter;
 
 import java.nio.charset.StandardCharsets;
 import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
 import javax.annotation.PostConstruct;
 
-import com.google.common.collect.Maps;
 import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
 import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
 import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
-import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentReactiveResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
 import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils;
 import com.tencent.cloud.polaris.ratelimit.utils.RateLimitUtils;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResultCode;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import reactor.core.publisher.Mono;
@@ -54,8 +49,6 @@ 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.
  *
@@ -67,11 +60,9 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
 
 	private final LimitAPI limitAPI;
 
-	private final PolarisRateLimiterLabelReactiveResolver labelResolver;
-
 	private final PolarisRateLimitProperties polarisRateLimitProperties;
 
-	private final RateLimitRuleLabelResolver rateLimitRuleLabelResolver;
+	private final RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentResolver;
 
 	private final PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback;
 
@@ -79,14 +70,12 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
 	private String rejectTips;
 
 	public QuotaCheckReactiveFilter(LimitAPI limitAPI,
-									PolarisRateLimiterLabelReactiveResolver labelResolver,
-									PolarisRateLimitProperties polarisRateLimitProperties,
-									RateLimitRuleLabelResolver rateLimitRuleLabelResolver,
-									@Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
+			PolarisRateLimitProperties polarisRateLimitProperties,
+			RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentResolver,
+			@Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
 		this.limitAPI = limitAPI;
-		this.labelResolver = labelResolver;
 		this.polarisRateLimitProperties = polarisRateLimitProperties;
-		this.rateLimitRuleLabelResolver = rateLimitRuleLabelResolver;
+		this.rateLimitRuleArgumentResolver = rateLimitRuleArgumentResolver;
 		this.polarisRateLimiterLimitedFallback = polarisRateLimiterLimitedFallback;
 	}
 
@@ -105,12 +94,12 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
 		String localNamespace = MetadataContext.LOCAL_NAMESPACE;
 		String localService = MetadataContext.LOCAL_SERVICE;
 
-		Map<String, String> labels = getRequestLabels(exchange, localNamespace, localService);
+		Set<Argument> arguments = rateLimitRuleArgumentResolver.getArguments(exchange, localNamespace, localService);
 		long waitMs = -1;
 		try {
 			String path = exchange.getRequest().getURI().getPath();
-			QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI,
-					localNamespace, localService, 1, labels, path);
+			QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(
+					limitAPI, localNamespace, localService, 1, arguments, path);
 
 			if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) {
 				ServerHttpResponse response = exchange.getResponse();
@@ -119,7 +108,8 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
 					response.setRawStatusCode(polarisRateLimiterLimitedFallback.rejectHttpCode());
 					response.getHeaders().setContentType(polarisRateLimiterLimitedFallback.mediaType());
 					dataBuffer = response.bufferFactory().allocateBuffer()
-							.write(polarisRateLimiterLimitedFallback.rejectTips().getBytes(polarisRateLimiterLimitedFallback.charset()));
+							.write(polarisRateLimiterLimitedFallback.rejectTips()
+									.getBytes(polarisRateLimiterLimitedFallback.charset()));
 				}
 				else {
 					response.setRawStatusCode(polarisRateLimitProperties.getRejectHttpCode());
@@ -149,40 +139,4 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
 		}
 	}
 
-	private Map<String, String> getRequestLabels(ServerWebExchange exchange, String localNamespace, String localService) {
-		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 rule expression labels
-		Map<String, String> expressionLabels = getRuleExpressionLabels(exchange, localNamespace, localService);
-		labels.putAll(expressionLabels);
-
-		// add custom labels
-		Map<String, String> customResolvedLabels = getCustomResolvedLabels(exchange);
-		labels.putAll(customResolvedLabels);
-
-		return labels;
-	}
-
-	private Map<String, String> getCustomResolvedLabels(ServerWebExchange exchange) {
-		if (labelResolver != null) {
-			try {
-				return labelResolver.resolve(exchange);
-			}
-			catch (Throwable e) {
-				LOGGER.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
-			}
-		}
-		return Maps.newHashMap();
-	}
-
-	private Map<String, String> getRuleExpressionLabels(ServerWebExchange exchange, String namespace, String service) {
-		Set<String> expressionLabels = rateLimitRuleLabelResolver.getExpressionLabelKeys(namespace, service);
-		return SpringWebExpressionLabelUtils.resolve(exchange, expressionLabels);
-	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java
index 434046434..a054d5be3 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilter.java
@@ -19,9 +19,6 @@
 package com.tencent.cloud.polaris.ratelimit.filter;
 
 import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -31,19 +28,19 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.tencent.cloud.common.constant.HeaderConstant;
 import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.util.expresstion.ServletExpressionLabelUtils;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
 import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
 import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
-import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
 import com.tencent.cloud.polaris.ratelimit.utils.QuotaCheckUtils;
 import com.tencent.cloud.polaris.ratelimit.utils.RateLimitUtils;
+import com.tencent.polaris.api.pojo.RetStatus;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResultCode;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,8 +50,6 @@ import org.springframework.lang.NonNull;
 import org.springframework.lang.Nullable;
 import org.springframework.web.filter.OncePerRequestFilter;
 
-import static com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant.LABEL_METHOD;
-
 /**
  * Servlet filter to check quota.
  *
@@ -70,25 +65,21 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
 	private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckServletFilter.class);
 	private final LimitAPI limitAPI;
 
-	private final PolarisRateLimiterLabelServletResolver labelResolver;
-
 	private final PolarisRateLimitProperties polarisRateLimitProperties;
 
-	private final RateLimitRuleLabelResolver rateLimitRuleLabelResolver;
+	private final RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver;
 
 	private final PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback;
 
 	private String rejectTips;
 
 	public QuotaCheckServletFilter(LimitAPI limitAPI,
-			PolarisRateLimiterLabelServletResolver labelResolver,
 			PolarisRateLimitProperties polarisRateLimitProperties,
-			RateLimitRuleLabelResolver rateLimitRuleLabelResolver,
+			RateLimitRuleArgumentServletResolver rateLimitRuleArgumentResolver,
 			@Nullable PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback) {
 		this.limitAPI = limitAPI;
-		this.labelResolver = labelResolver;
 		this.polarisRateLimitProperties = polarisRateLimitProperties;
-		this.rateLimitRuleLabelResolver = rateLimitRuleLabelResolver;
+		this.rateLimitRuleArgumentResolver = rateLimitRuleArgumentResolver;
 		this.polarisRateLimiterLimitedFallback = polarisRateLimiterLimitedFallback;
 	}
 
@@ -104,11 +95,11 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
 		String localNamespace = MetadataContext.LOCAL_NAMESPACE;
 		String localService = MetadataContext.LOCAL_SERVICE;
 
-		Map<String, String> labels = getRequestLabels(request, localNamespace, localService);
+		Set<Argument> arguments = rateLimitRuleArgumentResolver.getArguments(request, localNamespace, localService);
 
 		try {
 			QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI,
-					localNamespace, localService, 1, labels, request.getRequestURI());
+					localNamespace, localService, 1, arguments, request.getRequestURI());
 
 			if (quotaResponse.getCode() == QuotaResultCode.QuotaResultLimited) {
 				if (!Objects.isNull(polarisRateLimiterLimitedFallback)) {
@@ -122,6 +113,11 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
 					response.setContentType("text/html;charset=UTF-8");
 					response.getWriter().write(rejectTips);
 				}
+				response.addHeader(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
+				if (Objects.nonNull(quotaResponse.getActiveRule())) {
+					response.addHeader(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, quotaResponse.getActiveRule().getName()
+							.getValue());
+				}
 				return;
 			}
 			// Unirate
@@ -140,40 +136,4 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
 		filterChain.doFilter(request, response);
 	}
 
-	private Map<String, String> getRequestLabels(HttpServletRequest request, String localNamespace, String localService) {
-		Map<String, String> labels = new HashMap<>();
-
-		// add build in labels
-		String path = request.getRequestURI();
-		if (StringUtils.isNotBlank(path)) {
-			labels.put(LABEL_METHOD, path);
-		}
-
-		// add rule expression labels
-		Map<String, String> expressionLabels = getRuleExpressionLabels(request, localNamespace, localService);
-		labels.putAll(expressionLabels);
-
-		// add custom resolved labels
-		Map<String, String> customLabels = getCustomResolvedLabels(request);
-		labels.putAll(customLabels);
-
-		return labels;
-	}
-
-	private Map<String, String> getCustomResolvedLabels(HttpServletRequest request) {
-		if (labelResolver != null) {
-			try {
-				return labelResolver.resolve(request);
-			}
-			catch (Throwable e) {
-				LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
-			}
-		}
-		return Collections.emptyMap();
-	}
-
-	private Map<String, String> getRuleExpressionLabels(HttpServletRequest request, String namespace, String service) {
-		Set<String> expressionLabels = rateLimitRuleLabelResolver.getExpressionLabelKeys(namespace, service);
-		return ServletExpressionLabelUtils.resolve(request, expressionLabels);
-	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolver.java
new file mode 100644
index 000000000..13c57d817
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolver.java
@@ -0,0 +1,128 @@
+/*
+ * 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.resolver;
+
+import java.net.InetSocketAddress;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
+import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.server.ServerWebExchange;
+
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+
+/**
+ * resolve arguments from rate limit rule for Reactive.
+ *
+ * @author seansyyu 2023-03-09
+ */
+public class RateLimitRuleArgumentReactiveResolver {
+
+	private static final Logger LOG = LoggerFactory.getLogger(RateLimitRuleArgumentReactiveResolver.class);
+
+	private final ServiceRuleManager serviceRuleManager;
+
+	private final PolarisRateLimiterLabelReactiveResolver labelResolver;
+
+	public RateLimitRuleArgumentReactiveResolver(ServiceRuleManager serviceRuleManager, PolarisRateLimiterLabelReactiveResolver labelResolver) {
+		this.serviceRuleManager = serviceRuleManager;
+		this.labelResolver = labelResolver;
+	}
+
+	public Set<Argument> getArguments(ServerWebExchange request, String namespace, String service) {
+		RateLimitProto.RateLimit rateLimitRule = serviceRuleManager.getServiceRateLimitRule(namespace, service);
+		if (rateLimitRule == null) {
+			return Collections.emptySet();
+		}
+		List<RateLimitProto.Rule> rules = rateLimitRule.getRulesList();
+		if (CollectionUtils.isEmpty(rules)) {
+			return Collections.emptySet();
+		}
+		return rules.stream()
+				.flatMap(rule -> rule.getArgumentsList().stream())
+				.map(matchArgument -> {
+					String matchKey = matchArgument.getKey();
+					Argument argument = null;
+					switch (matchArgument.getType()) {
+					case CUSTOM:
+						argument = StringUtils.isBlank(matchKey) ? null :
+								Argument.buildCustom(matchKey, Optional.ofNullable(getCustomResolvedLabels(request).get(matchKey))
+										.orElse(StringUtils.EMPTY));
+						break;
+					case METHOD:
+						argument = Argument.buildMethod(request.getRequest().getMethodValue());
+						break;
+					case HEADER:
+						argument = StringUtils.isBlank(matchKey) ? null :
+								Argument.buildHeader(matchKey, Optional.ofNullable(request.getRequest().getHeaders()
+										.getFirst(matchKey)).orElse(StringUtils.EMPTY));
+						break;
+					case QUERY:
+						argument = StringUtils.isBlank(matchKey) ? null :
+								Argument.buildQuery(matchKey, Optional.ofNullable(request.getRequest().getQueryParams()
+										.getFirst(matchKey)).orElse(StringUtils.EMPTY));
+						break;
+					case CALLER_SERVICE:
+						String sourceServiceNamespace = MetadataContextHolder.getDisposableMetadata(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, true)
+								.orElse(StringUtils.EMPTY);
+						String sourceServiceName = MetadataContextHolder.getDisposableMetadata(DEFAULT_METADATA_SOURCE_SERVICE_NAME, true)
+								.orElse(StringUtils.EMPTY);
+						if (!StringUtils.isEmpty(sourceServiceNamespace) && !StringUtils.isEmpty(sourceServiceName)) {
+							argument = Argument.buildCallerService(sourceServiceNamespace, sourceServiceName);
+						}
+						break;
+					case CALLER_IP:
+						InetSocketAddress remoteAddress = request.getRequest().getRemoteAddress();
+						argument = Argument.buildCallerIP(remoteAddress != null ? remoteAddress.getAddress()
+								.getHostAddress() : StringUtils.EMPTY);
+						break;
+					default:
+						break;
+					}
+					return argument;
+				}).filter(Objects::nonNull).collect(Collectors.toSet());
+	}
+
+	private Map<String, String> getCustomResolvedLabels(ServerWebExchange request) {
+		if (labelResolver != null) {
+			try {
+				return labelResolver.resolve(request);
+			}
+			catch (Throwable e) {
+				LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
+			}
+		}
+		return Collections.emptyMap();
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolver.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolver.java
new file mode 100644
index 000000000..e384d0333
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolver.java
@@ -0,0 +1,123 @@
+/*
+ * 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.resolver;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
+import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter;
+import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.util.CollectionUtils;
+
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+
+/**
+ * resolve arguments from rate limit rule for Servlet.
+ *
+ * @author seansyyu 2023-03-09
+ */
+public class RateLimitRuleArgumentServletResolver {
+
+	private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckServletFilter.class);
+
+	private final ServiceRuleManager serviceRuleManager;
+
+	private final PolarisRateLimiterLabelServletResolver labelResolver;
+
+	public RateLimitRuleArgumentServletResolver(ServiceRuleManager serviceRuleManager, PolarisRateLimiterLabelServletResolver labelResolver) {
+		this.serviceRuleManager = serviceRuleManager;
+		this.labelResolver = labelResolver;
+	}
+
+	public Set<Argument> getArguments(HttpServletRequest request, String namespace, String service) {
+		RateLimitProto.RateLimit rateLimitRule = serviceRuleManager.getServiceRateLimitRule(namespace, service);
+		if (rateLimitRule == null) {
+			return Collections.emptySet();
+		}
+		List<RateLimitProto.Rule> rules = rateLimitRule.getRulesList();
+		if (CollectionUtils.isEmpty(rules)) {
+			return Collections.emptySet();
+		}
+		return rules.stream()
+				.flatMap(rule -> rule.getArgumentsList().stream())
+				.map(matchArgument -> {
+					String matchKey = matchArgument.getKey();
+					Argument argument = null;
+					switch (matchArgument.getType()) {
+						case CUSTOM:
+							argument = StringUtils.isBlank(matchKey) ? null :
+									Argument.buildCustom(matchKey, Optional.ofNullable(getCustomResolvedLabels(request).get(matchKey)).orElse(StringUtils.EMPTY));
+							break;
+						case METHOD:
+							argument = Argument.buildMethod(request.getMethod());
+							break;
+						case HEADER:
+							argument = StringUtils.isBlank(matchKey) ? null :
+									Argument.buildHeader(matchKey, Optional.ofNullable(request.getHeader(matchKey)).orElse(StringUtils.EMPTY));
+							break;
+						case QUERY:
+							argument = StringUtils.isBlank(matchKey) ? null :
+									Argument.buildQuery(matchKey, Optional.ofNullable(request.getParameter(matchKey)).orElse(StringUtils.EMPTY));
+							break;
+						case CALLER_SERVICE:
+							String sourceServiceNamespace = MetadataContextHolder.getDisposableMetadata(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, true).orElse(StringUtils.EMPTY);
+							String sourceServiceName = MetadataContextHolder.getDisposableMetadata(DEFAULT_METADATA_SOURCE_SERVICE_NAME, true).orElse(StringUtils.EMPTY);
+							if (!StringUtils.isEmpty(sourceServiceNamespace) && !StringUtils.isEmpty(sourceServiceName)) {
+								argument = Argument.buildCallerService(sourceServiceNamespace, sourceServiceName);
+							}
+							break;
+						case CALLER_IP:
+							argument = Argument.buildCallerIP(Optional.ofNullable(request.getRemoteAddr()).orElse(StringUtils.EMPTY));
+							break;
+						default:
+							break;
+					}
+					return argument;
+				}).filter(Objects::nonNull).collect(Collectors.toSet());
+	}
+
+	private Map<String, String> getCustomResolvedLabels(HttpServletRequest request) {
+		if (labelResolver != null) {
+			try {
+				return labelResolver.resolve(request);
+			}
+			catch (Throwable e) {
+				LOG.error("resolve custom label failed. resolver = {}", labelResolver.getClass().getName(), e);
+			}
+		}
+		return Collections.emptyMap();
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java
index d7e4aaae6..3adcee5e4 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtils.java
@@ -18,9 +18,11 @@
 package com.tencent.cloud.polaris.ratelimit.utils;
 
 import java.util.Map;
+import java.util.Set;
 
 import com.tencent.polaris.api.plugin.ratelimiter.QuotaResult;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaRequest;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
 import org.slf4j.Logger;
@@ -38,8 +40,9 @@ public final class QuotaCheckUtils {
 	private QuotaCheckUtils() {
 	}
 
-	public static QuotaResponse getQuota(LimitAPI limitAPI, String namespace,
-			String service, int count, Map<String, String> labels, String method) {
+	@Deprecated
+	public static QuotaResponse getQuota(LimitAPI limitAPI, String namespace, String service, int count,
+			Map<String, String> labels, String method) {
 		// build quota request
 		QuotaRequest quotaRequest = new QuotaRequest();
 		quotaRequest.setNamespace(namespace);
@@ -52,10 +55,27 @@ public final class QuotaCheckUtils {
 			return limitAPI.getQuota(quotaRequest);
 		}
 		catch (Throwable throwable) {
-			LOG.error("fail to invoke getQuota of LimitAPI with QuotaRequest[{}].",
-					quotaRequest, throwable);
-			return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0,
-					"get quota failed"));
+			LOG.error("fail to invoke getQuota of LimitAPI with QuotaRequest[{}].", quotaRequest, throwable);
+			return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, "get quota failed"));
+		}
+	}
+
+	public static QuotaResponse getQuota(LimitAPI limitAPI, String namespace, String service, int count,
+			Set<Argument> arguments, String method) {
+		// build quota request
+		QuotaRequest quotaRequest = new QuotaRequest();
+		quotaRequest.setNamespace(namespace);
+		quotaRequest.setService(service);
+		quotaRequest.setCount(count);
+		quotaRequest.setArguments(arguments);
+		quotaRequest.setMethod(method);
+
+		try {
+			return limitAPI.getQuota(quotaRequest);
+		}
+		catch (Throwable throwable) {
+			LOG.error("fail to invoke getQuota of LimitAPI with QuotaRequest[{}].", quotaRequest, throwable);
+			return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, "get quota failed"));
 		}
 	}
 }
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java
index 54fafa35c..c21a71f3e 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitAutoConfigurationTest.java
@@ -18,9 +18,10 @@
 package com.tencent.cloud.polaris.ratelimit.config;
 
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
 import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckReactiveFilter;
 import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentReactiveResolver;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
 import org.junit.jupiter.api.Test;
 
@@ -43,7 +44,8 @@ public class PolarisRateLimitAutoConfigurationTest {
 
 	private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner();
 
-	private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner();
+	private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner =
+			new ReactiveWebApplicationContextRunner();
 
 	@Test
 	public void testNoWebApplication() {
@@ -54,12 +56,12 @@ public class PolarisRateLimitAutoConfigurationTest {
 						PolarisRateLimitAutoConfiguration.class))
 				.run(context -> {
 					assertThat(context).hasSingleBean(LimitAPI.class);
-					assertThat(context).hasSingleBean(RateLimitRuleLabelResolver.class);
+					assertThat(context).doesNotHaveBean(RateLimitRuleArgumentServletResolver.class);
+					assertThat(context).doesNotHaveBean(RateLimitRuleArgumentReactiveResolver.class);
 					assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class);
 					assertThat(context).doesNotHaveBean(QuotaCheckServletFilter.class);
 					assertThat(context).doesNotHaveBean(FilterRegistrationBean.class);
-					assertThat(context).doesNotHaveBean(
-							PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
+					assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
 					assertThat(context).doesNotHaveBean(QuotaCheckReactiveFilter.class);
 				});
 	}
@@ -67,37 +69,35 @@ public class PolarisRateLimitAutoConfigurationTest {
 	@Test
 	public void testServletWebApplication() {
 		this.webApplicationContextRunner
-				.withConfiguration(AutoConfigurations.of(
-						PolarisContextAutoConfiguration.class,
+				.withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class,
 						PolarisRateLimitProperties.class,
 						PolarisRateLimitAutoConfiguration.class))
 				.run(context -> {
 					assertThat(context).hasSingleBean(LimitAPI.class);
-					assertThat(context).hasSingleBean(RateLimitRuleLabelResolver.class);
+					assertThat(context).hasSingleBean(RateLimitRuleArgumentServletResolver.class);
 					assertThat(context).hasSingleBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class);
 					assertThat(context).hasSingleBean(QuotaCheckServletFilter.class);
 					assertThat(context).hasSingleBean(FilterRegistrationBean.class);
-					assertThat(context).doesNotHaveBean(
-							PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
+					assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
 					assertThat(context).doesNotHaveBean(QuotaCheckReactiveFilter.class);
+					assertThat(context).doesNotHaveBean(RateLimitRuleArgumentReactiveResolver.class);
 				});
 	}
 
 	@Test
 	public void testReactiveWebApplication() {
 		this.reactiveWebApplicationContextRunner
-				.withConfiguration(AutoConfigurations.of(
-						PolarisContextAutoConfiguration.class,
+				.withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class,
 						PolarisRateLimitProperties.class,
 						PolarisRateLimitAutoConfiguration.class))
 				.run(context -> {
 					assertThat(context).hasSingleBean(LimitAPI.class);
-					assertThat(context).hasSingleBean(RateLimitRuleLabelResolver.class);
+					assertThat(context).doesNotHaveBean(RateLimitRuleArgumentServletResolver.class);
+					assertThat(context).hasSingleBean(RateLimitRuleArgumentReactiveResolver.class);
 					assertThat(context).doesNotHaveBean(PolarisRateLimitAutoConfiguration.QuotaCheckFilterConfig.class);
 					assertThat(context).doesNotHaveBean(QuotaCheckServletFilter.class);
 					assertThat(context).doesNotHaveBean(FilterRegistrationBean.class);
-					assertThat(context).hasSingleBean(
-							PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
+					assertThat(context).hasSingleBean(PolarisRateLimitAutoConfiguration.MetadataReactiveFilterConfig.class);
 					assertThat(context).hasSingleBean(QuotaCheckReactiveFilter.class);
 				});
 	}
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesTest.java
index e36b9d530..3b27fe84a 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesTest.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/config/PolarisRateLimitPropertiesTest.java
@@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat;
  * @author Haotian Zhang
  */
 @ExtendWith(SpringExtension.class)
-@SpringBootTest(classes = PolarisRateLimitPropertiesTest.TestApplication.class)
+@SpringBootTest(classes = PolarisRateLimitPropertiesTest.TestApplication.class, properties = "spring.application.name=test")
 @ActiveProfiles("test")
 public class PolarisRateLimitPropertiesTest {
 
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java
index 3d3c3c62e..95e2a0103 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckReactiveFilterTest.java
@@ -17,32 +17,32 @@
 
 package com.tencent.cloud.polaris.ratelimit.filter;
 
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
 import java.util.Collections;
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
 
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
 import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
-import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
 import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
 import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentReactiveResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
 import com.tencent.polaris.api.plugin.ratelimiter.QuotaResult;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaRequest;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.mockito.junit.jupiter.MockitoSettings;
 import org.mockito.quality.Strictness;
@@ -60,10 +60,8 @@ import org.springframework.web.server.WebFilterChain;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anySet;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
 
 /**
@@ -76,36 +74,15 @@ import static org.mockito.Mockito.when;
 @SpringBootTest(classes = QuotaCheckReactiveFilterTest.TestApplication.class,
 		properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"})
 public class QuotaCheckReactiveFilterTest {
-
-	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
-	private static MockedStatic<SpringWebExpressionLabelUtils> expressionLabelUtilsMockedStatic;
 	private final PolarisRateLimiterLabelReactiveResolver labelResolver =
-			exchange -> Collections.singletonMap("ReactiveResolver", "ReactiveResolver");
+			exchange -> Collections.singletonMap("xxx", "xxx");
 	private QuotaCheckReactiveFilter quotaCheckReactiveFilter;
 	private QuotaCheckReactiveFilter quotaCheckWithRateLimiterLimitedFallbackReactiveFilter;
 	private PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback;
 
-	@BeforeAll
-	static void beforeAll() {
-		expressionLabelUtilsMockedStatic = mockStatic(SpringWebExpressionLabelUtils.class);
-		when(SpringWebExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet()))
-				.thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver"));
-
-		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
-		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
-				.thenReturn("unit-test");
-	}
-
-	@AfterAll
-	static void afterAll() {
-		mockedApplicationContextAwareUtils.close();
-		expressionLabelUtilsMockedStatic.close();
-	}
-
 	@BeforeEach
-	void setUp() {
+	void setUp() throws InvalidProtocolBufferException {
 		MetadataContext.LOCAL_NAMESPACE = "TEST";
-		polarisRateLimiterLimitedFallback = new JsonPolarisRateLimiterLimitedFallback();
 
 		LimitAPI limitAPI = mock(LimitAPI.class);
 		when(limitAPI.getQuota(any(QuotaRequest.class))).thenAnswer(invocationOnMock -> {
@@ -117,10 +94,12 @@ public class QuotaCheckReactiveFilterTest {
 				return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 1000, "QuotaResultOk"));
 			}
 			else if (serviceName.equals("TestApp3")) {
-				return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultLimited, 0, "QuotaResultLimited"));
+				QuotaResponse response = new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultLimited, 0, "QuotaResultLimited"));
+				response.setActiveRule(RateLimitProto.Rule.newBuilder().build());
+				return response;
 			}
 			else {
-				return new QuotaResponse(new QuotaResult(null, 0, null));
+				return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 0, null));
 			}
 		});
 
@@ -128,14 +107,26 @@ public class QuotaCheckReactiveFilterTest {
 		polarisRateLimitProperties.setRejectRequestTips("RejectRequestTips提示消息");
 		polarisRateLimitProperties.setRejectHttpCode(419);
 
-		RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class);
-		when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString()))
-				.thenReturn(Collections.emptySet());
-
-		this.quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(
-				limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver, null);
-		this.quotaCheckWithRateLimiterLimitedFallbackReactiveFilter = new QuotaCheckReactiveFilter(
-				limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver, polarisRateLimiterLimitedFallback);
+		PolarisRateLimitProperties polarisRateLimitWithHtmlRejectTipsProperties = new PolarisRateLimitProperties();
+		polarisRateLimitWithHtmlRejectTipsProperties.setRejectRequestTips("<h1>RejectRequestTips提示消息</h1>");
+		polarisRateLimitWithHtmlRejectTipsProperties.setRejectHttpCode(419);
+
+		ServiceRuleManager serviceRuleManager = mock(ServiceRuleManager.class);
+
+		RateLimitProto.Rule.Builder ratelimitRuleBuilder = RateLimitProto.Rule.newBuilder();
+		InputStream inputStream = QuotaCheckServletFilterTest.class.getClassLoader()
+				.getResourceAsStream("ratelimit.json");
+		String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
+				.collect(Collectors.joining(""));
+		JsonFormat.parser().ignoringUnknownFields().merge(json, ratelimitRuleBuilder);
+		RateLimitProto.Rule rateLimitRule = ratelimitRuleBuilder.build();
+		RateLimitProto.RateLimit rateLimit = RateLimitProto.RateLimit.newBuilder().addRules(rateLimitRule).build();
+		when(serviceRuleManager.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit);
+
+		RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentReactiveResolver = new RateLimitRuleArgumentReactiveResolver(serviceRuleManager, labelResolver);
+		this.quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentReactiveResolver, null);
+		this.polarisRateLimiterLimitedFallback = new JsonPolarisRateLimiterLimitedFallback();
+		this.quotaCheckWithRateLimiterLimitedFallbackReactiveFilter = new QuotaCheckReactiveFilter(limitAPI, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleArgumentReactiveResolver, polarisRateLimiterLimitedFallback);
 	}
 
 	@Test
@@ -156,42 +147,6 @@ public class QuotaCheckReactiveFilterTest {
 		}
 	}
 
-	@Test
-	public void testGetRuleExpressionLabels() {
-		try {
-			Method getCustomResolvedLabels =
-					QuotaCheckReactiveFilter.class.getDeclaredMethod("getCustomResolvedLabels", ServerWebExchange.class);
-			getCustomResolvedLabels.setAccessible(true);
-
-			// Mock request
-			MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost:8080/test").build();
-			ServerWebExchange exchange = MockServerWebExchange.from(request);
-
-			// labelResolver != null
-			Map<String, String> result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckReactiveFilter, exchange);
-			assertThat(result.size()).isEqualTo(1);
-			assertThat(result.get("ReactiveResolver")).isEqualTo("ReactiveResolver");
-
-			// throw exception
-			PolarisRateLimiterLabelReactiveResolver exceptionLabelResolver = exchange1 -> {
-				throw new RuntimeException("Mock exception.");
-			};
-			quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(null, exceptionLabelResolver, null, null, null);
-			result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckReactiveFilter, exchange);
-			assertThat(result.size()).isEqualTo(0);
-
-			// labelResolver == null
-			quotaCheckReactiveFilter = new QuotaCheckReactiveFilter(null, null, null, null, null);
-			result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckReactiveFilter, exchange);
-			assertThat(result.size()).isEqualTo(0);
-
-			getCustomResolvedLabels.setAccessible(false);
-		}
-		catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-			fail("Exception encountered.", e);
-		}
-	}
-
 	@Test
 	public void testFilter() {
 		// Create mock WebFilterChain
@@ -199,19 +154,20 @@ public class QuotaCheckReactiveFilterTest {
 
 		// Mock request
 		MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost:8080/test").build();
-		ServerWebExchange exchange = MockServerWebExchange.from(request);
 
 		quotaCheckReactiveFilter.init();
 
 		// Pass
 		MetadataContext.LOCAL_SERVICE = "TestApp1";
-		quotaCheckReactiveFilter.filter(exchange, webFilterChain);
+		ServerWebExchange testApp1Exchange = MockServerWebExchange.from(request);
+		quotaCheckReactiveFilter.filter(testApp1Exchange, webFilterChain);
 
 		// Unirate waiting 1000ms
 		MetadataContext.LOCAL_SERVICE = "TestApp2";
+		ServerWebExchange testApp2Exchange = MockServerWebExchange.from(request);
 		long startTimestamp = System.currentTimeMillis();
 		CountDownLatch countDownLatch = new CountDownLatch(1);
-		quotaCheckReactiveFilter.filter(exchange, webFilterChain).subscribe(e -> {
+		quotaCheckReactiveFilter.filter(testApp2Exchange, webFilterChain).subscribe(e -> {
 		}, t -> {
 		}, countDownLatch::countDown);
 		try {
@@ -224,14 +180,16 @@ public class QuotaCheckReactiveFilterTest {
 
 		// Rate limited
 		MetadataContext.LOCAL_SERVICE = "TestApp3";
-		quotaCheckReactiveFilter.filter(exchange, webFilterChain);
-		ServerHttpResponse response = exchange.getResponse();
+		ServerWebExchange testApp3Exchange = MockServerWebExchange.from(request);
+		quotaCheckReactiveFilter.filter(testApp3Exchange, webFilterChain);
+		ServerHttpResponse response = testApp3Exchange.getResponse();
 		assertThat(response.getRawStatusCode()).isEqualTo(419);
 		assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE);
 
 		// Exception
 		MetadataContext.LOCAL_SERVICE = "TestApp4";
-		quotaCheckReactiveFilter.filter(exchange, webFilterChain);
+		ServerWebExchange testApp4Exchange = MockServerWebExchange.from(request);
+		quotaCheckReactiveFilter.filter(testApp4Exchange, webFilterChain);
 	}
 
 	@Test
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java
index 81f3cd2cb..1b747699e 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/filter/QuotaCheckServletFilterTest.java
@@ -17,53 +17,47 @@
 
 package com.tencent.cloud.polaris.ratelimit.filter;
 
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
 import java.util.Collections;
-import java.util.Map;
+import java.util.stream.Collectors;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
 
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
 import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
-import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
-import com.tencent.cloud.polaris.ratelimit.RateLimitRuleLabelResolver;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
 import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
+import com.tencent.cloud.polaris.ratelimit.resolver.RateLimitRuleArgumentServletResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
 import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
 import com.tencent.polaris.api.plugin.ratelimiter.QuotaResult;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaRequest;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaResponse;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.junit.jupiter.MockitoSettings;
-import org.mockito.quality.Strictness;
 
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.http.MediaType;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.web.server.ServerWebExchange;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anySet;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
 
 /**
@@ -71,41 +65,23 @@ import static org.mockito.Mockito.when;
  *
  * @author Haotian Zhang, cheese8
  */
-@ExtendWith(MockitoExtension.class)
-@MockitoSettings(strictness = Strictness.LENIENT)
-@SpringBootTest(classes = QuotaCheckServletFilterTest.TestApplication.class, properties = {
-		"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"
-})
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+		classes = QuotaCheckServletFilterTest.TestApplication.class,
+		properties = {
+				"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"
+		})
 public class QuotaCheckServletFilterTest {
 
-	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
-	private static MockedStatic<SpringWebExpressionLabelUtils> expressionLabelUtilsMockedStatic;
-	private PolarisRateLimiterLabelServletResolver labelResolver =
-			exchange -> Collections.singletonMap("ServletResolver", "ServletResolver");
+	private final PolarisRateLimiterLabelServletResolver labelResolver =
+			exchange -> Collections.singletonMap("xxx", "xxx");
 	private QuotaCheckServletFilter quotaCheckServletFilter;
 	private QuotaCheckServletFilter quotaCheckWithHtmlRejectTipsServletFilter;
 	private QuotaCheckServletFilter quotaCheckWithRateLimiterLimitedFallbackFilter;
 	private PolarisRateLimiterLimitedFallback polarisRateLimiterLimitedFallback;
 
-	@BeforeAll
-	static void beforeAll() {
-		expressionLabelUtilsMockedStatic = mockStatic(SpringWebExpressionLabelUtils.class);
-		when(SpringWebExpressionLabelUtils.resolve(any(ServerWebExchange.class), anySet()))
-				.thenReturn(Collections.singletonMap("RuleLabelResolver", "RuleLabelResolver"));
-
-		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
-		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
-				.thenReturn("unit-test");
-	}
-
-	@AfterAll
-	static void afterAll() {
-		mockedApplicationContextAwareUtils.close();
-		expressionLabelUtilsMockedStatic.close();
-	}
-
 	@BeforeEach
-	void setUp() {
+	void setUp() throws InvalidProtocolBufferException {
 		MetadataContext.LOCAL_NAMESPACE = "TEST";
 
 		LimitAPI limitAPI = mock(LimitAPI.class);
@@ -118,7 +94,9 @@ public class QuotaCheckServletFilterTest {
 				return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultOk, 1000, "QuotaResultOk"));
 			}
 			else if (serviceName.equals("TestApp3")) {
-				return new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultLimited, 0, "QuotaResultLimited"));
+				QuotaResponse response = new QuotaResponse(new QuotaResult(QuotaResult.Code.QuotaResultLimited, 0, "QuotaResultLimited"));
+				response.setActiveRule(RateLimitProto.Rule.newBuilder().build());
+				return response;
 			}
 			else {
 				return new QuotaResponse(new QuotaResult(null, 0, null));
@@ -133,15 +111,23 @@ public class QuotaCheckServletFilterTest {
 		polarisRateLimitWithHtmlRejectTipsProperties.setRejectRequestTips("<h1>RejectRequestTips提示消息</h1>");
 		polarisRateLimitWithHtmlRejectTipsProperties.setRejectHttpCode(419);
 
-		RateLimitRuleLabelResolver rateLimitRuleLabelResolver = mock(RateLimitRuleLabelResolver.class);
-		when(rateLimitRuleLabelResolver.getExpressionLabelKeys(anyString(), anyString())).thenReturn(Collections.emptySet());
-
-		this.quotaCheckServletFilter = new QuotaCheckServletFilter(limitAPI, labelResolver, polarisRateLimitProperties, rateLimitRuleLabelResolver, null);
-		this.quotaCheckWithHtmlRejectTipsServletFilter = new QuotaCheckServletFilter(
-				limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver, null);
-		polarisRateLimiterLimitedFallback = new JsonPolarisRateLimiterLimitedFallback();
-		this.quotaCheckWithRateLimiterLimitedFallbackFilter = new QuotaCheckServletFilter(
-				limitAPI, labelResolver, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleLabelResolver, polarisRateLimiterLimitedFallback);
+		ServiceRuleManager serviceRuleManager = mock(ServiceRuleManager.class);
+
+		RateLimitProto.Rule.Builder ratelimitRuleBuilder = RateLimitProto.Rule.newBuilder();
+		InputStream inputStream = QuotaCheckServletFilterTest.class.getClassLoader()
+				.getResourceAsStream("ratelimit.json");
+		String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
+				.collect(Collectors.joining(""));
+		JsonFormat.parser().ignoringUnknownFields().merge(json, ratelimitRuleBuilder);
+		RateLimitProto.Rule rateLimitRule = ratelimitRuleBuilder.build();
+		RateLimitProto.RateLimit rateLimit = RateLimitProto.RateLimit.newBuilder().addRules(rateLimitRule).build();
+		when(serviceRuleManager.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit);
+
+		RateLimitRuleArgumentServletResolver rateLimitRuleArgumentServletResolver = new RateLimitRuleArgumentServletResolver(serviceRuleManager, labelResolver);
+		this.quotaCheckServletFilter = new QuotaCheckServletFilter(limitAPI, polarisRateLimitProperties, rateLimitRuleArgumentServletResolver, null);
+		this.quotaCheckWithHtmlRejectTipsServletFilter = new QuotaCheckServletFilter(limitAPI, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleArgumentServletResolver, null);
+		this.polarisRateLimiterLimitedFallback = new JsonPolarisRateLimiterLimitedFallback();
+		this.quotaCheckWithRateLimiterLimitedFallbackFilter = new QuotaCheckServletFilter(limitAPI, polarisRateLimitWithHtmlRejectTipsProperties, rateLimitRuleArgumentServletResolver, polarisRateLimiterLimitedFallback);
 	}
 
 	@Test
@@ -167,40 +153,6 @@ public class QuotaCheckServletFilterTest {
 		quotaCheckWithRateLimiterLimitedFallbackFilter.init();
 	}
 
-	@Test
-	public void testGetRuleExpressionLabels() {
-		try {
-			Method getCustomResolvedLabels = QuotaCheckServletFilter.class.getDeclaredMethod("getCustomResolvedLabels", HttpServletRequest.class);
-			getCustomResolvedLabels.setAccessible(true);
-
-			// Mock request
-			MockHttpServletRequest request = new MockHttpServletRequest();
-
-			// labelResolver != null
-			Map<String, String> result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckServletFilter, request);
-			assertThat(result.size()).isEqualTo(1);
-			assertThat(result.get("ServletResolver")).isEqualTo("ServletResolver");
-
-			// throw exception
-			PolarisRateLimiterLabelServletResolver exceptionLabelResolver = request1 -> {
-				throw new RuntimeException("Mock exception.");
-			};
-			quotaCheckServletFilter = new QuotaCheckServletFilter(null, exceptionLabelResolver, null, null, null);
-			result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckServletFilter, request);
-			assertThat(result.size()).isEqualTo(0);
-
-			// labelResolver == null
-			quotaCheckServletFilter = new QuotaCheckServletFilter(null, null, null, null, null);
-			result = (Map<String, String>) getCustomResolvedLabels.invoke(quotaCheckServletFilter, request);
-			assertThat(result.size()).isEqualTo(0);
-
-			getCustomResolvedLabels.setAccessible(false);
-		}
-		catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-			fail("Exception encountered.", e);
-		}
-	}
-
 	@Test
 	public void testDoFilterInternal() {
 		// Create mock FilterChain
@@ -210,34 +162,39 @@ public class QuotaCheckServletFilterTest {
 
 		// Mock request
 		MockHttpServletRequest request = new MockHttpServletRequest();
-		MockHttpServletResponse response = new MockHttpServletResponse();
 
 		quotaCheckServletFilter.init();
+		quotaCheckWithHtmlRejectTipsServletFilter.init();
 		try {
 			// Pass
 			MetadataContext.LOCAL_SERVICE = "TestApp1";
-			quotaCheckServletFilter.doFilterInternal(request, response, filterChain);
+			MockHttpServletResponse testApp1Response = new MockHttpServletResponse();
+			quotaCheckServletFilter.doFilterInternal(request, testApp1Response, filterChain);
 
 			// Unirate waiting 1000ms
 			MetadataContext.LOCAL_SERVICE = "TestApp2";
+			MockHttpServletResponse testApp2Response = new MockHttpServletResponse();
 			long startTimestamp = System.currentTimeMillis();
-			quotaCheckServletFilter.doFilterInternal(request, response, filterChain);
+			quotaCheckServletFilter.doFilterInternal(request, testApp2Response, filterChain);
 			assertThat(System.currentTimeMillis() - startTimestamp).isGreaterThanOrEqualTo(1000L);
 
 			// Rate limited
 			MetadataContext.LOCAL_SERVICE = "TestApp3";
-			quotaCheckServletFilter.doFilterInternal(request, response, filterChain);
-			assertThat(response.getStatus()).isEqualTo(419);
-			assertThat(response.getContentAsString()).isEqualTo("RejectRequestTips提示消息");
+			MockHttpServletResponse testApp3Response = new MockHttpServletResponse();
+			quotaCheckServletFilter.doFilterInternal(request, testApp3Response, filterChain);
+			assertThat(testApp3Response.getStatus()).isEqualTo(419);
+			assertThat(testApp3Response.getContentAsString()).isEqualTo("RejectRequestTips提示消息");
 
-			quotaCheckWithHtmlRejectTipsServletFilter.doFilterInternal(request, response, filterChain);
-			assertThat(response.getStatus()).isEqualTo(419);
-			assertThat(response.getContentAsString()).isEqualTo("RejectRequestTips提示消息");
+			MockHttpServletResponse testApp3Response2 = new MockHttpServletResponse();
+			quotaCheckWithHtmlRejectTipsServletFilter.doFilterInternal(request, testApp3Response2, filterChain);
+			assertThat(testApp3Response2.getStatus()).isEqualTo(419);
+			assertThat(testApp3Response2.getContentAsString()).isEqualTo("<h1>RejectRequestTips提示消息</h1>");
 
 
 			// Exception
+			MockHttpServletResponse testApp4Response = new MockHttpServletResponse();
 			MetadataContext.LOCAL_SERVICE = "TestApp4";
-			quotaCheckServletFilter.doFilterInternal(request, response, filterChain);
+			quotaCheckServletFilter.doFilterInternal(request, testApp4Response, filterChain);
 		}
 		catch (ServletException | IOException e) {
 			fail("Exception encountered.", e);
@@ -252,31 +209,34 @@ public class QuotaCheckServletFilterTest {
 
 		// Mock request
 		MockHttpServletRequest request = new MockHttpServletRequest();
-		MockHttpServletResponse response = new MockHttpServletResponse();
 
 		quotaCheckWithRateLimiterLimitedFallbackFilter.init();
 		try {
 			// Pass
 			MetadataContext.LOCAL_SERVICE = "TestApp1";
-			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, response, filterChain);
+			MockHttpServletResponse testApp1response = new MockHttpServletResponse();
+			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, testApp1response, filterChain);
 
 			// Unirate waiting 1000ms
 			MetadataContext.LOCAL_SERVICE = "TestApp2";
+			MockHttpServletResponse testApp2response = new MockHttpServletResponse();
 			long startTimestamp = System.currentTimeMillis();
-			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, response, filterChain);
+			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, testApp2response, filterChain);
 			assertThat(System.currentTimeMillis() - startTimestamp).isGreaterThanOrEqualTo(1000L);
 
 			// Rate limited
 			MetadataContext.LOCAL_SERVICE = "TestApp3";
+			MockHttpServletResponse testApp3response = new MockHttpServletResponse();
 			String contentType = new MediaType(polarisRateLimiterLimitedFallback.mediaType(), polarisRateLimiterLimitedFallback.charset()).toString();
-			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, response, filterChain);
-			assertThat(response.getStatus()).isEqualTo(polarisRateLimiterLimitedFallback.rejectHttpCode());
-			assertThat(response.getContentAsString()).isEqualTo(polarisRateLimiterLimitedFallback.rejectTips());
-			assertThat(response.getContentType()).isEqualTo(contentType);
+			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, testApp3response, filterChain);
+			assertThat(testApp3response.getStatus()).isEqualTo(polarisRateLimiterLimitedFallback.rejectHttpCode());
+			assertThat(testApp3response.getContentAsString()).isEqualTo(polarisRateLimiterLimitedFallback.rejectTips());
+			assertThat(testApp3response.getContentType()).isEqualTo(contentType);
 
 			// Exception
 			MetadataContext.LOCAL_SERVICE = "TestApp4";
-			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, response, filterChain);
+			MockHttpServletResponse testApp4response = new MockHttpServletResponse();
+			quotaCheckWithRateLimiterLimitedFallbackFilter.doFilterInternal(request, testApp4response, filterChain);
 		}
 		catch (ServletException | IOException e) {
 			fail("Exception encountered.", e);
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolverTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolverTest.java
new file mode 100644
index 000000000..1648a9618
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentReactiveResolverTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.resolver;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
+import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilterTest;
+import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.web.server.ServerWebExchange;
+
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+		classes = RateLimitRuleArgumentReactiveResolverTest.TestApplication.class,
+		properties = {
+				"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"
+		})
+public class RateLimitRuleArgumentReactiveResolverTest {
+
+	private final PolarisRateLimiterLabelReactiveResolver labelResolver =
+			exchange -> Collections.singletonMap("xxx", "xxx");
+
+	private final PolarisRateLimiterLabelReactiveResolver labelResolverEx =
+			exchange -> {
+				throw new RuntimeException();
+			};
+
+	private RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentReactiveResolver1;
+	private RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentReactiveResolver2;
+	private RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentReactiveResolver3;
+	private RateLimitRuleArgumentReactiveResolver rateLimitRuleArgumentReactiveResolver4;
+
+	@BeforeEach
+	void setUp() throws InvalidProtocolBufferException {
+		MetadataContext.LOCAL_NAMESPACE = "TEST";
+
+		ServiceRuleManager serviceRuleManager = mock(ServiceRuleManager.class);
+
+		RateLimitProto.Rule.Builder ratelimitRuleBuilder =  RateLimitProto.Rule.newBuilder();
+		InputStream inputStream = QuotaCheckServletFilterTest.class.getClassLoader().getResourceAsStream("ratelimit.json");
+		String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining(""));
+		JsonFormat.parser().ignoringUnknownFields().merge(json, ratelimitRuleBuilder);
+		RateLimitProto.Rule rateLimitRule = ratelimitRuleBuilder.build();
+		RateLimitProto.RateLimit rateLimit = RateLimitProto.RateLimit.newBuilder().addRules(rateLimitRule).build();
+		when(serviceRuleManager.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit);
+
+		// normal
+		this.rateLimitRuleArgumentReactiveResolver1 = new RateLimitRuleArgumentReactiveResolver(serviceRuleManager, labelResolver);
+		// ex
+		this.rateLimitRuleArgumentReactiveResolver2 = new RateLimitRuleArgumentReactiveResolver(serviceRuleManager, labelResolverEx);
+		// null
+		ServiceRuleManager serviceRuleManager1 = mock(ServiceRuleManager.class);
+		when(serviceRuleManager1.getServiceRateLimitRule(anyString(), anyString())).thenReturn(null);
+		this.rateLimitRuleArgumentReactiveResolver3 = new RateLimitRuleArgumentReactiveResolver(serviceRuleManager1, labelResolver);
+		// null 2
+		ServiceRuleManager serviceRuleManager2 = mock(ServiceRuleManager.class);
+		RateLimitProto.RateLimit rateLimit2 = RateLimitProto.RateLimit.newBuilder().build();
+		when(serviceRuleManager2.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit2);
+		this.rateLimitRuleArgumentReactiveResolver4 = new RateLimitRuleArgumentReactiveResolver(serviceRuleManager2, labelResolver);
+	}
+
+	@Test
+	public void testGetRuleArguments() {
+		// Mock request
+		MetadataContext.LOCAL_SERVICE = "Test";
+		// Mock request
+		MockServerHttpRequest request = MockServerHttpRequest.get("http://127.0.0.1:8080/test")
+				.remoteAddress(new InetSocketAddress("127.0.0.1", 8080))
+				.header("xxx", "xxx")
+				.queryParam("yyy", "yyy")
+				.build();
+		ServerWebExchange exchange = MockServerWebExchange.from(request);
+		MetadataContext metadataContext = new MetadataContext();
+		metadataContext.setUpstreamDisposableMetadata(new HashMap<String, String>() {{
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, MetadataContext.LOCAL_NAMESPACE);
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAME, MetadataContext.LOCAL_SERVICE);
+		}});
+		MetadataContextHolder.set(metadataContext);
+		Set<Argument> arguments = rateLimitRuleArgumentReactiveResolver1.getArguments(exchange, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		Set<Argument> exceptRes = new HashSet<>();
+		exceptRes.add(Argument.buildMethod("GET"));
+		exceptRes.add(Argument.buildHeader("xxx", "xxx"));
+		exceptRes.add(Argument.buildQuery("yyy", "yyy"));
+		exceptRes.add(Argument.buildCallerIP("127.0.0.1"));
+		exceptRes.add(Argument.buildCustom("xxx", "xxx"));
+		exceptRes.add(Argument.buildCallerService(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE));
+		assertThat(arguments).isEqualTo(exceptRes);
+
+		rateLimitRuleArgumentReactiveResolver2.getArguments(exchange, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		rateLimitRuleArgumentReactiveResolver3.getArguments(exchange, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		rateLimitRuleArgumentReactiveResolver4.getArguments(exchange, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+	}
+
+	@SpringBootApplication
+	protected static class TestApplication {
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolverTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolverTest.java
new file mode 100644
index 000000000..1a8b49ed7
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/resolver/RateLimitRuleArgumentServletResolverTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.resolver;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.polaris.context.ServiceRuleManager;
+import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilterTest;
+import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelServletResolver;
+import com.tencent.polaris.ratelimit.api.rpc.Argument;
+import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+		classes = RateLimitRuleArgumentServletResolverTest.TestApplication.class,
+		properties = {
+				"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"
+		})
+public class RateLimitRuleArgumentServletResolverTest {
+
+	private final PolarisRateLimiterLabelServletResolver labelResolver =
+			exchange -> Collections.singletonMap("xxx", "xxx");
+	private final PolarisRateLimiterLabelServletResolver labelResolverEx =
+			exchange -> {
+				throw new RuntimeException();
+			};
+
+	private RateLimitRuleArgumentServletResolver rateLimitRuleArgumentServletResolver1;
+	private RateLimitRuleArgumentServletResolver rateLimitRuleArgumentServletResolver2;
+	private RateLimitRuleArgumentServletResolver rateLimitRuleArgumentServletResolver3;
+	private RateLimitRuleArgumentServletResolver rateLimitRuleArgumentServletResolver4;
+
+	@BeforeEach
+	void setUp() throws InvalidProtocolBufferException {
+		MetadataContext.LOCAL_NAMESPACE = "TEST";
+
+		ServiceRuleManager serviceRuleManager = mock(ServiceRuleManager.class);
+
+		RateLimitProto.Rule.Builder ratelimitRuleBuilder =  RateLimitProto.Rule.newBuilder();
+		InputStream inputStream = QuotaCheckServletFilterTest.class.getClassLoader().getResourceAsStream("ratelimit.json");
+		String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining(""));
+		JsonFormat.parser().ignoringUnknownFields().merge(json, ratelimitRuleBuilder);
+		RateLimitProto.Rule rateLimitRule = ratelimitRuleBuilder.build();
+		RateLimitProto.RateLimit rateLimit = RateLimitProto.RateLimit.newBuilder().addRules(rateLimitRule).build();
+		when(serviceRuleManager.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit);
+
+		// normal
+		this.rateLimitRuleArgumentServletResolver1 = new RateLimitRuleArgumentServletResolver(serviceRuleManager, labelResolver);
+		// ex
+		this.rateLimitRuleArgumentServletResolver2 = new RateLimitRuleArgumentServletResolver(serviceRuleManager, labelResolverEx);
+		// null
+		ServiceRuleManager serviceRuleManager1 = mock(ServiceRuleManager.class);
+		when(serviceRuleManager1.getServiceRateLimitRule(anyString(), anyString())).thenReturn(null);
+		this.rateLimitRuleArgumentServletResolver3 = new RateLimitRuleArgumentServletResolver(serviceRuleManager1, labelResolver);
+		// null 2
+		ServiceRuleManager serviceRuleManager2 = mock(ServiceRuleManager.class);
+		RateLimitProto.RateLimit rateLimit2 = RateLimitProto.RateLimit.newBuilder().build();
+		when(serviceRuleManager2.getServiceRateLimitRule(anyString(), anyString())).thenReturn(rateLimit2);
+		this.rateLimitRuleArgumentServletResolver4 = new RateLimitRuleArgumentServletResolver(serviceRuleManager2, labelResolver);
+	}
+
+	@Test
+	public void testGetRuleArguments() {
+		// Mock request
+		MetadataContext.LOCAL_SERVICE = "Test";
+		MockHttpServletRequest request = new MockHttpServletRequest(null, "GET", "/xxx");
+		request.setParameter("yyy", "yyy");
+		request.addHeader("xxx", "xxx");
+		MetadataContext metadataContext = new MetadataContext();
+		metadataContext.setUpstreamDisposableMetadata(new HashMap<String, String>() {{
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, MetadataContext.LOCAL_NAMESPACE);
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAME, MetadataContext.LOCAL_SERVICE);
+		}});
+		MetadataContextHolder.set(metadataContext);
+		Set<Argument> arguments = rateLimitRuleArgumentServletResolver1.getArguments(request, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		Set<Argument> exceptRes = new HashSet<>();
+		exceptRes.add(Argument.buildMethod("GET"));
+		exceptRes.add(Argument.buildHeader("xxx", "xxx"));
+		exceptRes.add(Argument.buildQuery("yyy", "yyy"));
+		exceptRes.add(Argument.buildCallerIP("127.0.0.1"));
+		exceptRes.add(Argument.buildCustom("xxx", "xxx"));
+		exceptRes.add(Argument.buildCallerService(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE));
+		assertThat(arguments).isEqualTo(exceptRes);
+
+		rateLimitRuleArgumentServletResolver2.getArguments(request, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		rateLimitRuleArgumentServletResolver3.getArguments(request, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		rateLimitRuleArgumentServletResolver4.getArguments(request, MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+	}
+
+	@SpringBootApplication
+	protected static class TestApplication {
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtilsTest.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtilsTest.java
index 91e361a8f..ad2691f4d 100644
--- a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtilsTest.java
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/java/com/tencent/cloud/polaris/ratelimit/utils/QuotaCheckUtilsTest.java
@@ -17,6 +17,9 @@
 
 package com.tencent.cloud.polaris.ratelimit.utils;
 
+import java.util.HashMap;
+import java.util.HashSet;
+
 import com.tencent.polaris.api.plugin.ratelimiter.QuotaResult;
 import com.tencent.polaris.ratelimit.api.core.LimitAPI;
 import com.tencent.polaris.ratelimit.api.rpc.QuotaRequest;
@@ -66,28 +69,59 @@ public class QuotaCheckUtilsTest {
 	public void testGetQuota() {
 		// Pass
 		String serviceName = "TestApp1";
-		QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, null, null);
+		QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashMap<>(), null);
+		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
+		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
+		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultOk");
+
+		// Unirate waiting 1000ms
+		serviceName = "TestApp2";
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashMap<>(), null);
+		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
+		assertThat(quotaResponse.getWaitMs()).isEqualTo(1000);
+		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultOk");
+
+		// Rate limited
+		serviceName = "TestApp3";
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashMap<>(), null);
+		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultLimited);
+		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
+		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultLimited");
+
+		// Exception
+		serviceName = "TestApp4";
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashMap<>(), null);
+		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
+		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
+		assertThat(quotaResponse.getInfo()).isEqualTo("get quota failed");
+	}
+
+	@Test
+	public void testGetQuota2() {
+		// Pass
+		String serviceName = "TestApp1";
+		QuotaResponse quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashSet<>(), null);
 		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
 		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
 		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultOk");
 
 		// Unirate waiting 1000ms
 		serviceName = "TestApp2";
-		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, null, null);
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashSet<>(), null);
 		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
 		assertThat(quotaResponse.getWaitMs()).isEqualTo(1000);
 		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultOk");
 
 		// Rate limited
 		serviceName = "TestApp3";
-		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, null, null);
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashSet<>(), null);
 		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultLimited);
 		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
 		assertThat(quotaResponse.getInfo()).isEqualTo("QuotaResultLimited");
 
 		// Exception
 		serviceName = "TestApp4";
-		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, null, null);
+		quotaResponse = QuotaCheckUtils.getQuota(limitAPI, null, serviceName, 1, new HashSet<>(), null);
 		assertThat(quotaResponse.getCode()).isEqualTo(QuotaResultCode.QuotaResultOk);
 		assertThat(quotaResponse.getWaitMs()).isEqualTo(0);
 		assertThat(quotaResponse.getInfo()).isEqualTo("get quota failed");
diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/test/resources/ratelimit.json b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/resources/ratelimit.json
new file mode 100644
index 000000000..92908114d
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/test/resources/ratelimit.json
@@ -0,0 +1,95 @@
+{
+  "id": "f7560cce829e4d4c8556a6be63539af5",
+  "service": "xxx",
+  "namespace": "default",
+  "subset": {},
+  "priority": 0,
+  "resource": "QPS",
+  "type": "GLOBAL",
+  "labels": {},
+  "amounts": [
+    {
+      "maxAmount": 1,
+      "validDuration": "1s",
+      "precision": null,
+      "startAmount": null,
+      "minAmount": null
+    }
+  ],
+  "action": "REJECT",
+  "disable": false,
+  "report": null,
+  "ctime": "2022-12-11 21:56:59",
+  "mtime": "2023-03-10 15:40:33",
+  "revision": "6eec6f416bee40ecbf664c93add61358",
+  "service_token": null,
+  "adjuster": null,
+  "regex_combine": true,
+  "amountMode": "GLOBAL_TOTAL",
+  "failover": "FAILOVER_LOCAL",
+  "cluster": null,
+  "method": {
+    "type": "EXACT",
+    "value": "/xxx",
+    "value_type": "TEXT"
+  },
+  "arguments": [
+    {
+      "type": "CALLER_SERVICE",
+      "key": "default",
+      "value": {
+        "type": "EXACT",
+        "value": "xxx",
+        "value_type": "TEXT"
+      }
+    },
+    {
+      "type": "HEADER",
+      "key": "xxx",
+      "value": {
+        "type": "EXACT",
+        "value": "xxx",
+        "value_type": "TEXT"
+      }
+    },
+    {
+      "type": "QUERY",
+      "key": "yyy",
+      "value": {
+        "type": "EXACT",
+        "value": "yyy",
+        "value_type": "TEXT"
+      }
+    },
+    {
+      "type": "METHOD",
+      "key": "$method",
+      "value": {
+        "type": "EXACT",
+        "value": "GET",
+        "value_type": "TEXT"
+      }
+    },
+    {
+      "type": "CALLER_IP",
+      "key": "$caller_ip",
+      "value": {
+        "type": "EXACT",
+        "value": "127.0.0.1",
+        "value_type": "TEXT"
+      }
+    },
+    {
+      "type": "CUSTOM",
+      "key": "xxx",
+      "value": {
+        "type": "EXACT",
+        "value": "xxx",
+        "value_type": "TEXT"
+      }
+    }
+  ],
+  "name": "xxx",
+  "etime": "2023-03-10 15:40:33",
+  "max_queue_delay": 30
+}
\ No newline at end of file
diff --git a/spring-cloud-starter-tencent-polaris-router/pom.xml b/spring-cloud-starter-tencent-polaris-router/pom.xml
index 180edcc95..56ac0fe50 100644
--- a/spring-cloud-starter-tencent-polaris-router/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-router/pom.xml
@@ -73,10 +73,10 @@
 			<artifactId>spring-retry</artifactId>
 			<optional>true</optional>
 		</dependency>
-		
+
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-netflix-zuul</artifactId>
+			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
 			<optional>true</optional>
 		</dependency>
 
diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRule.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRule.java
index f06a8f323..26d5fbb88 100644
--- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRule.java
+++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisLoadBalancerCompositeRule.java
@@ -136,24 +136,29 @@ public class PolarisLoadBalancerCompositeRule extends AbstractLoadBalancerRule {
 
 		// 2. filter by router
 		List<Server> serversAfterRouter;
-		if (key instanceof PolarisRouterContext) {
-			// router implement for Feign and scg
-			PolarisRouterContext routerContext = (PolarisRouterContext) key;
-			serversAfterRouter = doRouter(allServers, routerContext);
-		}
-		else if (key instanceof HttpRequest) {
-			// router implement for rest template
-			HttpRequest request = (HttpRequest) key;
-
-			String routerContextStr = request.getHeaders().getFirst(RouterConstant.HEADER_ROUTER_CONTEXT);
-
-			if (StringUtils.isEmpty(routerContextStr)) {
-				serversAfterRouter = allServers;
+		if (key != null) {
+			if (key instanceof PolarisRouterContext) {
+				// router implement for Feign and scg
+				PolarisRouterContext routerContext = (PolarisRouterContext) key;
+				serversAfterRouter = doRouter(allServers, routerContext);
+			}
+			else if (key instanceof HttpRequest) {
+				// router implement for rest template
+				HttpRequest request = (HttpRequest) key;
+
+				String routerContextStr = request.getHeaders().getFirst(RouterConstant.HEADER_ROUTER_CONTEXT);
+
+				if (StringUtils.isEmpty(routerContextStr)) {
+					serversAfterRouter = allServers;
+				}
+				else {
+					PolarisRouterContext routerContext = JacksonUtils.deserialize(UriEncoder.decode(routerContextStr),
+							PolarisRouterContext.class);
+					serversAfterRouter = doRouter(allServers, routerContext);
+				}
 			}
 			else {
-				PolarisRouterContext routerContext = JacksonUtils.deserialize(UriEncoder.decode(routerContextStr),
-						PolarisRouterContext.class);
-				serversAfterRouter = doRouter(allServers, routerContext);
+				serversAfterRouter = allServers;
 			}
 		}
 		else {
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java
index 66a8f08b5..4c3307a63 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java
@@ -79,4 +79,29 @@ public final class ContextConstant {
 		 */
 		public static Integer STAT_REPORTER_ORDER = 1;
 	}
+
+	public static final class Zuul {
+
+		/**
+		 * polaris circuit breaker.
+		 */
+		public static final String POLARIS_CIRCUIT_BREAKER = "PolarisCircuitBreaker";
+
+		/**
+		 * timestamp before route.
+		 */
+		public static final String POLARIS_PRE_ROUTE_TIME = "PolarisPreRouteTime";
+		/**
+		 * is in routing state.
+		 */
+		public static final String POLARIS_IS_IN_ROUTING_STATE = "PolarisIsInRoutingState";
+
+		/**
+		 * polaris circuit breaker.
+		 */
+		public static final String ENHANCED_PLUGIN_CONTEXT = "EnhancedPluginContext";
+
+		private Zuul() {
+		}
+	}
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/HeaderConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/HeaderConstant.java
new file mode 100644
index 000000000..feffd0f49
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/HeaderConstant.java
@@ -0,0 +1,52 @@
+/*
+ * 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.common.constant;
+
+/**
+ * Built-in system http header fields.
+ */
+public final class HeaderConstant {
+
+	/**
+	 * The called service returns the real call result of its own processing request.
+	 */
+	public static final String INTERNAL_CALLEE_RET_STATUS = "internal-callee-retstatus";
+
+	/**
+	 * The name of the rule that the current limit/circiutbreaker rule takes effect.
+	 */
+	public static final String INTERNAL_ACTIVE_RULE_NAME = "internal-callee-activerule";
+
+	/**
+	 * The name information of the called service.
+	 */
+	public static final String INTERNAL_CALLEE_SERVICE_ID = "internal-callee-serviceid";
+
+	/**
+	 * The name information of the called instance host.
+	 */
+	public static final String INTERNAL_CALLEE_INSTANCE_HOST = "internal-callee-instance-host";
+
+	/**
+	 * The name information of the called instance port.
+	 */
+	public static final String INTERNAL_CALLEE_INSTANCE_PORT = "internal-callee-instance-port";
+
+	private HeaderConstant() {
+	}
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java
index e51d7042a..d007a8921 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java
@@ -26,17 +26,10 @@ import org.springframework.core.Ordered;
  */
 public final class MetadataConstant {
 
-	/**
-	 * Default Private Constructor.
-	 */
-	private MetadataConstant() {
-	}
-
 	/**
 	 * sct transitive header prefix.
 	 */
 	public static final String SCT_TRANSITIVE_HEADER_PREFIX = "X-SCT-Metadata-Transitive-";
-
 	/**
 	 * sct transitive header prefix length.
 	 */
@@ -46,12 +39,15 @@ public final class MetadataConstant {
 	 * polaris transitive header prefix.
 	 */
 	public static final String POLARIS_TRANSITIVE_HEADER_PREFIX = "X-Polaris-Metadata-Transitive-";
-
 	/**
 	 * polaris transitive header prefix length.
 	 */
 	public static final int POLARIS_TRANSITIVE_HEADER_PREFIX_LENGTH = POLARIS_TRANSITIVE_HEADER_PREFIX.length();
 
+	private MetadataConstant() {
+
+	}
+
 	/**
 	 * Order of filter, interceptor, ...
 	 */
@@ -60,7 +56,7 @@ public final class MetadataConstant {
 		/**
 		 * Order of filter.
 		 */
-		public static final int WEB_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 13;
+		public static final int WEB_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 9;
 
 		/**
 		 * Order of MetadataFirstFeignInterceptor.
@@ -98,4 +94,19 @@ public final class MetadataConstant {
 		 */
 		public static final String METADATA_CONTEXT = "SCT-METADATA-CONTEXT";
 	}
+
+	public static class DefaultMetadata {
+
+		/**
+		 * Default Metadata Source Service Namespace Key.
+		 */
+		public static final String DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE = "source_service_namespace";
+
+		/**
+		 * Default Metadata Source Service Name Key.
+		 */
+		public static final String DEFAULT_METADATA_SOURCE_SERVICE_NAME = "source_service_name";
+
+	}
+
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java
index 60983ef69..90a949d2e 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java
@@ -29,8 +29,6 @@ import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
 import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_DISPOSABLE;
-import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_RAW_TRANSHEADERS;
-import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_TRANSITIVE;
 import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_UPSTREAM_DISPOSABLE;
 
 /**
@@ -67,11 +65,11 @@ public final class MetadataContextHolder {
 
 		// init static transitive metadata
 		MetadataContext metadataContext = new MetadataContext();
-		metadataContext.putFragmentContext(FRAGMENT_TRANSITIVE, staticMetadataManager.getMergedStaticTransitiveMetadata());
-		metadataContext.putFragmentContext(FRAGMENT_DISPOSABLE, staticMetadataManager.getMergedStaticDisposableMetadata());
+		metadataContext.setTransitiveMetadata(staticMetadataManager.getMergedStaticTransitiveMetadata());
+		metadataContext.setDisposableMetadata(staticMetadataManager.getMergedStaticDisposableMetadata());
 
 		if (StringUtils.hasText(staticMetadataManager.getTransHeaderFromEnv())) {
-			metadataContext.putContext(FRAGMENT_RAW_TRANSHEADERS, staticMetadataManager.getTransHeaderFromEnv(), "");
+			metadataContext.setTransHeaders(staticMetadataManager.getTransHeaderFromEnv(), "");
 		}
 
 		METADATA_CONTEXT.set(metadataContext);
@@ -132,18 +130,19 @@ public final class MetadataContextHolder {
 
 		// Save transitive metadata to ThreadLocal.
 		if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) {
-			Map<String, String> staticTransitiveMetadata = metadataContext.getFragmentContext(FRAGMENT_TRANSITIVE);
+			Map<String, String> staticTransitiveMetadata = metadataContext.getTransitiveMetadata();
 			Map<String, String> mergedTransitiveMetadata = new HashMap<>();
 			mergedTransitiveMetadata.putAll(staticTransitiveMetadata);
 			mergedTransitiveMetadata.putAll(dynamicTransitiveMetadata);
-			metadataContext.putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(mergedTransitiveMetadata));
-
-			Map<String, String> mergedDisposableMetadata = new HashMap<>(dynamicDisposableMetadata);
-			metadataContext.putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(mergedDisposableMetadata));
-
-			Map<String, String> staticDisposableMetadata = metadataContext.getFragmentContext(FRAGMENT_DISPOSABLE);
-			metadataContext.putFragmentContext(FRAGMENT_DISPOSABLE, Collections.unmodifiableMap(staticDisposableMetadata));
+			metadataContext.setTransitiveMetadata(Collections.unmodifiableMap(mergedTransitiveMetadata));
 		}
+		if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) {
+			Map<String, String> mergedUpstreamDisposableMetadata = new HashMap<>(dynamicDisposableMetadata);
+			metadataContext.setUpstreamDisposableMetadata(Collections.unmodifiableMap(mergedUpstreamDisposableMetadata));
+		}
+
+		Map<String, String> staticDisposableMetadata = metadataContext.getFragmentContext(FRAGMENT_DISPOSABLE);
+		metadataContext.setDisposableMetadata(Collections.unmodifiableMap(staticDisposableMetadata));
 		MetadataContextHolder.set(metadataContext);
 	}
 
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
index 2cf156713..d37deb006 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
 import com.tencent.cloud.common.spi.InstanceMetadataProvider;
@@ -34,7 +35,7 @@ import org.springframework.util.CollectionUtils;
 /**
  * manage metadata from env/config file/custom spi.
  *
- * @author lepdou 2022-05-20
+ * @author lepdou, Haotian Zhang
  */
 public class StaticMetadataManager {
 	/**
@@ -53,7 +54,6 @@ public class StaticMetadataManager {
 	private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_";
 	private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length();
 	private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE";
-
 	private static final String ENV_METADATA_CONTENT_DISPOSABLE = "SCT_METADATA_CONTENT_DISPOSABLE";
 	/**
 	 * This is the key of the header's key list needed to be transmitted. The list is a string split with ,.
@@ -82,14 +82,14 @@ public class StaticMetadataManager {
 	private String campus;
 
 	public StaticMetadataManager(MetadataLocalProperties metadataLocalProperties,
-			InstanceMetadataProvider instanceMetadataProvider) {
+			List<InstanceMetadataProvider> instanceMetadataProviders) {
 		parseConfigMetadata(metadataLocalProperties);
 
 		parseEnvMetadata();
 
-		parseCustomMetadata(instanceMetadataProvider);
+		parseCustomMetadata(instanceMetadataProviders);
 
-		parseLocationMetadata(metadataLocalProperties, instanceMetadataProvider);
+		parseLocationMetadata(metadataLocalProperties, instanceMetadataProviders);
 
 		merge();
 
@@ -183,21 +183,25 @@ public class StaticMetadataManager {
 	}
 
 	@SuppressWarnings("DuplicatedCode")
-	private void parseCustomMetadata(InstanceMetadataProvider instanceMetadataProvider) {
-		if (instanceMetadataProvider == null) {
-			customSPIMetadata = Collections.emptyMap();
-			customSPITransitiveMetadata = Collections.emptyMap();
-			customSPIDisposableMetadata = Collections.emptyMap();
-			return;
+	private void parseCustomMetadata(List<InstanceMetadataProvider> instanceMetadataProviders) {
+		// init customSPIMetadata
+		customSPIMetadata = new HashMap<>();
+		customSPITransitiveMetadata = new HashMap<>();
+		customSPIDisposableMetadata = new HashMap<>();
+		if (!CollectionUtils.isEmpty(instanceMetadataProviders)) {
+			instanceMetadataProviders.forEach(this::parseCustomMetadata);
 		}
+		customSPIMetadata = Collections.unmodifiableMap(customSPIMetadata);
+		customSPITransitiveMetadata = Collections.unmodifiableMap(customSPITransitiveMetadata);
+		customSPIDisposableMetadata = Collections.unmodifiableMap(customSPIDisposableMetadata);
+	}
 
+	@SuppressWarnings("DuplicatedCode")
+	private void parseCustomMetadata(InstanceMetadataProvider instanceMetadataProvider) {
 		// resolve all metadata
 		Map<String, String> allMetadata = instanceMetadataProvider.getMetadata();
-		if (allMetadata == null) {
-			customSPIMetadata = Collections.emptyMap();
-		}
-		else {
-			customSPIMetadata = Collections.unmodifiableMap(allMetadata);
+		if (!CollectionUtils.isEmpty(allMetadata)) {
+			customSPIMetadata.putAll(allMetadata);
 		}
 
 		// resolve transitive metadata
@@ -210,7 +214,7 @@ public class StaticMetadataManager {
 				}
 			}
 		}
-		customSPITransitiveMetadata = Collections.unmodifiableMap(transitiveMetadata);
+		customSPITransitiveMetadata.putAll(transitiveMetadata);
 
 		Set<String> disposableKeys = instanceMetadataProvider.getDisposableMetadataKeys();
 		Map<String, String> disposableMetadata = new HashMap<>();
@@ -221,7 +225,7 @@ public class StaticMetadataManager {
 				}
 			}
 		}
-		customSPIDisposableMetadata = Collections.unmodifiableMap(disposableMetadata);
+		customSPIDisposableMetadata.putAll(disposableMetadata);
 	}
 
 	private void merge() {
@@ -231,6 +235,7 @@ public class StaticMetadataManager {
 		mergedMetadataResult.putAll(configMetadata);
 		mergedMetadataResult.putAll(envMetadata);
 		mergedMetadataResult.putAll(customSPIMetadata);
+
 		this.mergedStaticMetadata = Collections.unmodifiableMap(mergedMetadataResult);
 
 		Map<String, String> mergedTransitiveMetadataResult = new HashMap<>();
@@ -247,10 +252,16 @@ public class StaticMetadataManager {
 	}
 
 	private void parseLocationMetadata(MetadataLocalProperties metadataLocalProperties,
-			InstanceMetadataProvider instanceMetadataProvider) {
+			List<InstanceMetadataProvider> instanceMetadataProviders) {
 		// resolve region info
-		if (instanceMetadataProvider != null) {
-			region = instanceMetadataProvider.getRegion();
+		if (!CollectionUtils.isEmpty(instanceMetadataProviders)) {
+			Set<String> providerRegions = instanceMetadataProviders.stream().map(InstanceMetadataProvider::getRegion).filter(region -> !StringUtils.isBlank(region)).collect(Collectors.toSet());
+			if (!CollectionUtils.isEmpty(providerRegions)) {
+				if (providerRegions.size() > 1) {
+					throw new IllegalArgumentException("Multiple Regions Provided in InstanceMetadataProviders");
+				}
+				region = providerRegions.iterator().next();
+			}
 		}
 		if (StringUtils.isBlank(region)) {
 			region = System.getenv(ENV_METADATA_REGION);
@@ -260,8 +271,14 @@ public class StaticMetadataManager {
 		}
 
 		// resolve zone info
-		if (instanceMetadataProvider != null) {
-			zone = instanceMetadataProvider.getZone();
+		if (!CollectionUtils.isEmpty(instanceMetadataProviders)) {
+			Set<String> providerZones = instanceMetadataProviders.stream().map(InstanceMetadataProvider::getZone).filter(zone -> !StringUtils.isBlank(zone)).collect(Collectors.toSet());
+			if (!CollectionUtils.isEmpty(providerZones)) {
+				if (providerZones.size() > 1) {
+					throw new IllegalArgumentException("Multiple Zones Provided in InstanceMetadataProviders");
+				}
+				zone = providerZones.iterator().next();
+			}
 		}
 		if (StringUtils.isBlank(zone)) {
 			zone = System.getenv(ENV_METADATA_ZONE);
@@ -271,8 +288,14 @@ public class StaticMetadataManager {
 		}
 
 		// resolve campus info
-		if (instanceMetadataProvider != null) {
-			campus = instanceMetadataProvider.getCampus();
+		if (!CollectionUtils.isEmpty(instanceMetadataProviders)) {
+			Set<String> providerCampus = instanceMetadataProviders.stream().map(InstanceMetadataProvider::getCampus).filter(campus -> !StringUtils.isBlank(campus)).collect(Collectors.toSet());
+			if (!CollectionUtils.isEmpty(providerCampus)) {
+				if (providerCampus.size() > 1) {
+					throw new IllegalArgumentException("Multiple Campus Provided in InstanceMetadataProviders");
+				}
+				campus = providerCampus.iterator().next();
+			}
 		}
 		if (StringUtils.isBlank(campus)) {
 			campus = System.getenv(ENV_METADATA_CAMPUS);
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java
index 060bed30d..a5a02b67b 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfiguration.java
@@ -18,8 +18,12 @@
 
 package com.tencent.cloud.common.metadata.config;
 
+import java.util.List;
+
 import com.tencent.cloud.common.metadata.StaticMetadataManager;
 import com.tencent.cloud.common.spi.InstanceMetadataProvider;
+import com.tencent.cloud.common.spi.impl.DefaultInstanceMetadataProvider;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -42,10 +46,15 @@ public class MetadataAutoConfiguration {
 		return new MetadataLocalProperties();
 	}
 
+	@Bean
+	public InstanceMetadataProvider defaultInstanceMetadataProvider(ApplicationContextAwareUtils applicationContextAwareUtils) {
+		return new DefaultInstanceMetadataProvider(applicationContextAwareUtils);
+	}
+
 	@Bean
 	public StaticMetadataManager metadataManager(MetadataLocalProperties metadataLocalProperties,
-			@Nullable InstanceMetadataProvider instanceMetadataProvider) {
-		return new StaticMetadataManager(metadataLocalProperties, instanceMetadataProvider);
+			@Nullable List<InstanceMetadataProvider> instanceMetadataProviders) {
+		return new StaticMetadataManager(metadataLocalProperties, instanceMetadataProviders);
 	}
 
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/impl/DefaultInstanceMetadataProvider.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/impl/DefaultInstanceMetadataProvider.java
new file mode 100644
index 000000000..e4a99636c
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/impl/DefaultInstanceMetadataProvider.java
@@ -0,0 +1,63 @@
+/*
+ * 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.common.spi.impl;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.tencent.cloud.common.spi.InstanceMetadataProvider;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+import static com.tencent.cloud.common.metadata.MetadataContext.LOCAL_NAMESPACE;
+import static com.tencent.cloud.common.metadata.MetadataContext.LOCAL_SERVICE;
+
+/**
+ * DefaultInstanceMetadataProvider.
+ * provide DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, DEFAULT_METADATA_SOURCE_SERVICE_NAME
+ *
+ * @author sean yu
+ */
+public class DefaultInstanceMetadataProvider implements InstanceMetadataProvider {
+
+	private final ApplicationContextAwareUtils applicationContextAwareUtils;
+
+	// ensure ApplicationContextAwareUtils init before
+	public DefaultInstanceMetadataProvider(ApplicationContextAwareUtils applicationContextAwareUtils) {
+		this.applicationContextAwareUtils = applicationContextAwareUtils;
+	}
+
+	@Override
+	public Map<String, String> getMetadata() {
+		return new HashMap<String, String>() {{
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, LOCAL_NAMESPACE);
+			put(DEFAULT_METADATA_SOURCE_SERVICE_NAME, LOCAL_SERVICE);
+		}};
+	}
+
+	@Override
+	public Set<String> getDisposableMetadataKeys() {
+		return new HashSet<>(Arrays.asList(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE, DEFAULT_METADATA_SOURCE_SERVICE_NAME));
+	}
+
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java
index 2951d7848..a6c14a0d6 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java
@@ -111,14 +111,4 @@ public final class JacksonUtils {
 			throw new RuntimeException("Json to map failed.", e);
 		}
 	}
-
-	public static <T> T json2JavaBean(String content, Class<T> valueType) {
-		try {
-			return OM.readValue(content, valueType);
-		}
-		catch (Exception e) {
-			LOG.error("json {} to class {} failed. ", content, valueType, e);
-			throw new RuntimeException("json to class failed.", e);
-		}
-	}
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/RequestLabelUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/RequestLabelUtils.java
new file mode 100644
index 000000000..d76e5bf4d
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/RequestLabelUtils.java
@@ -0,0 +1,34 @@
+/*
+ * 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.common.util;
+
+/**
+ * Request Label Utils.
+ */
+public final class RequestLabelUtils {
+
+	private RequestLabelUtils() {
+	}
+
+	public static String convertLabel(String label) {
+		label = label.replaceAll("\"|\\{|\\}", "")
+				.replaceAll(",", "|");
+		return label;
+	}
+
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ZuulFilterUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ZuulFilterUtils.java
new file mode 100644
index 000000000..a0bae9e3f
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ZuulFilterUtils.java
@@ -0,0 +1,80 @@
+/*
+ * 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.common.util;
+
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.netflix.zuul.context.RequestContext;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.web.util.UriUtils;
+import org.springframework.web.util.WebUtils;
+
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
+
+/**
+ * Utils for Zuul filter.
+ *
+ * @author Haotian Zhang
+ */
+public final class ZuulFilterUtils {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(ZuulFilterUtils.class);
+
+	private ZuulFilterUtils() {
+	}
+
+	public static String getServiceId(RequestContext context) {
+		String serviceId = (String) context.get(SERVICE_ID_KEY);
+		if (StringUtils.isBlank(serviceId)) {
+			URL url = context.getRouteHost();
+			if (url != null) {
+				serviceId = url.getAuthority();
+				context.set(SERVICE_ID_KEY, serviceId);
+			}
+		}
+		return serviceId;
+	}
+
+	public static String getPath(RequestContext context) {
+		HttpServletRequest request = context.getRequest();
+		String uri = request.getRequestURI();
+		String contextURI = (String) context.get(REQUEST_URI_KEY);
+		if (contextURI != null) {
+			try {
+				uri = UriUtils.encodePath(contextURI, characterEncoding(request));
+			}
+			catch (Exception e) {
+				LOGGER.debug("unable to encode uri path from context, falling back to uri from request", e);
+			}
+		}
+		// remove double slashes
+		uri = uri.replace("//", "/");
+		return uri;
+	}
+
+	private static String characterEncoding(HttpServletRequest request) {
+		return request.getCharacterEncoding() != null ? request.getCharacterEncoding()
+				: WebUtils.DEFAULT_CHARACTER_ENCODING;
+	}
+}
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
index 2283e4bbe..784213c57 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
@@ -18,6 +18,7 @@
 
 package com.tencent.cloud.common.metadata;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -26,20 +27,33 @@ import java.util.Set;
 
 import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
 import com.tencent.cloud.common.spi.InstanceMetadataProvider;
+import com.tencent.cloud.common.spi.impl.DefaultInstanceMetadataProvider;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
 import uk.org.webcompere.systemstubs.jupiter.SystemStub;
 import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
 
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAME;
+import static com.tencent.cloud.common.constant.MetadataConstant.DefaultMetadata.DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE;
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
 /**
  * test for {@link StaticMetadataManager}.
- *@author lepdou 2022-06-27
+ *
+ * @author lepdou 2022-06-27
  */
 @ExtendWith({MockitoExtension.class, SystemStubsExtension.class})
 public class StaticMetadataManagerTest {
@@ -52,6 +66,26 @@ public class StaticMetadataManagerTest {
 	@Mock
 	private MetadataLocalProperties metadataLocalProperties;
 
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
 	@Test
 	public void testParseConfigMetadata() {
 		Map<String, String> content = new HashMap<>();
@@ -62,6 +96,7 @@ public class StaticMetadataManagerTest {
 
 		when(metadataLocalProperties.getContent()).thenReturn(content);
 		when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1"));
+		when(metadataLocalProperties.getDisposable()).thenReturn(Collections.singletonList("k1"));
 
 		StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, null);
 
@@ -74,6 +109,10 @@ public class StaticMetadataManagerTest {
 		assertThat(transitiveMetadata.size()).isEqualTo(1);
 		assertThat(transitiveMetadata.get("k1")).isEqualTo("v1");
 
+		Map<String, String> disposableMetadata = metadataManager.getConfigDisposableMetadata();
+		assertThat(disposableMetadata.size()).isEqualTo(1);
+		assertThat(disposableMetadata.get("k1")).isEqualTo("v1");
+
 		assertThat(metadataManager.getZone()).isEqualTo("zone1");
 		assertThat(metadataManager.getRegion()).isEqualTo("region1");
 
@@ -92,17 +131,25 @@ public class StaticMetadataManagerTest {
 		when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1"));
 
 		StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties,
-				new MockedMetadataProvider());
+				Arrays.asList(new MockedMetadataProvider(), new DefaultInstanceMetadataProvider(null)));
 
 		Map<String, String> metadata = metadataManager.getAllCustomMetadata();
-		assertThat(metadata.size()).isEqualTo(3);
+		assertThat(metadata.size()).isEqualTo(5);
 		assertThat(metadata.get("k1")).isEqualTo("v1");
 		assertThat(metadata.get("k2")).isEqualTo("v22");
 		assertThat(metadata.get("k3")).isEqualTo("v33");
+		assertThat(metadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE)).isEqualTo(NAMESPACE_TEST);
+		assertThat(metadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAME)).isEqualTo(SERVICE_PROVIDER);
 
 		Map<String, String> transitiveMetadata = metadataManager.getCustomSPITransitiveMetadata();
 		assertThat(transitiveMetadata.size()).isEqualTo(1);
-		assertThat(metadata.get("k2")).isEqualTo("v22");
+		assertThat(transitiveMetadata.get("k2")).isEqualTo("v22");
+
+		Map<String, String> disposableMetadata = metadataManager.getCustomSPIDisposableMetadata();
+		assertThat(disposableMetadata.size()).isEqualTo(3);
+		assertThat(disposableMetadata.get("k3")).isEqualTo("v33");
+		assertThat(disposableMetadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE)).isEqualTo(NAMESPACE_TEST);
+		assertThat(disposableMetadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAME)).isEqualTo(SERVICE_PROVIDER);
 
 		assertThat(metadataManager.getZone()).isEqualTo("zone2");
 		assertThat(metadataManager.getRegion()).isEqualTo("region1");
@@ -125,29 +172,38 @@ public class StaticMetadataManagerTest {
 		when(metadataLocalProperties.getTransitive()).thenReturn(Collections.singletonList("k1"));
 
 		StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties,
-				new MockedMetadataProvider());
+				Arrays.asList(new MockedMetadataProvider(), new DefaultInstanceMetadataProvider(null)));
 
 		Map<String, String> metadata = metadataManager.getMergedStaticMetadata();
-		assertThat(metadata.size()).isEqualTo(6);
+		assertThat(metadata.size()).isEqualTo(8);
 		assertThat(metadata.get("k1")).isEqualTo("v1");
 		assertThat(metadata.get("k2")).isEqualTo("v22");
 		assertThat(metadata.get("k3")).isEqualTo("v33");
+		assertThat(metadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE)).isEqualTo(NAMESPACE_TEST);
+		assertThat(metadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAME)).isEqualTo(SERVICE_PROVIDER);
 
 		Map<String, String> transitiveMetadata = metadataManager.getMergedStaticTransitiveMetadata();
 		assertThat(transitiveMetadata.size()).isEqualTo(2);
-		assertThat(metadata.get("k1")).isEqualTo("v1");
-		assertThat(metadata.get("k2")).isEqualTo("v22");
+		assertThat(transitiveMetadata.get("k1")).isEqualTo("v1");
+		assertThat(transitiveMetadata.get("k2")).isEqualTo("v22");
+
+		Map<String, String> disposableMetadata = metadataManager.getMergedStaticDisposableMetadata();
+		assertThat(disposableMetadata.size()).isEqualTo(3);
+		assertThat(disposableMetadata.get("k3")).isEqualTo("v33");
+		assertThat(disposableMetadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAMESPACE)).isEqualTo(NAMESPACE_TEST);
+		assertThat(disposableMetadata.get(DEFAULT_METADATA_SOURCE_SERVICE_NAME)).isEqualTo(SERVICE_PROVIDER);
 
 		assertThat(metadataManager.getAllEnvMetadata()).isEmpty();
 		assertThat(metadataManager.getEnvTransitiveMetadata()).isEmpty();
 
 		assertThat(metadataManager.getZone()).isEqualTo("zone2");
 		assertThat(metadataManager.getRegion()).isEqualTo("region1");
+		assertThat(metadataManager.getCampus()).isEqualTo("campus2");
 
 		Map<String, String> locationInfo = metadataManager.getLocationMetadata();
 		assertThat(locationInfo.get("zone")).isEqualTo("zone2");
 		assertThat(locationInfo.get("region")).isEqualTo("region1");
-		assertThat(locationInfo.get("campus")).isEqualTo("campus1");
+		assertThat(locationInfo.get("campus")).isEqualTo("campus2");
 	}
 
 	@Test
@@ -194,6 +250,13 @@ public class StaticMetadataManagerTest {
 			return transitiveKeys;
 		}
 
+		@Override
+		public Set<String> getDisposableMetadataKeys() {
+			Set<String> transitiveKeys = new HashSet<>();
+			transitiveKeys.add("k3");
+			return transitiveKeys;
+		}
+
 		@Override
 		public String getRegion() {
 			return "region1";
@@ -206,7 +269,7 @@ public class StaticMetadataManagerTest {
 
 		@Override
 		public String getCampus() {
-			return null;
+			return "campus2";
 		}
 	}
 }
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java
index 1987843e5..c5cda081c 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/config/MetadataAutoConfigurationTest.java
@@ -18,6 +18,8 @@
 
 package com.tencent.cloud.common.metadata.config;
 
+
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
 import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -33,12 +35,17 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
  */
 public class MetadataAutoConfigurationTest {
 
-	private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner();
+	private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withPropertyValues(
+			"spring.application.name=test"
+	);
 
-	private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner();
+	private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner().withPropertyValues(
+			"spring.application.name=test"
+	);
 
-	private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner =
-			new ReactiveWebApplicationContextRunner();
+	private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner().withPropertyValues(
+			"spring.application.name=test"
+	);
 
 	/**
 	 * No any web application.
@@ -46,7 +53,7 @@ public class MetadataAutoConfigurationTest {
 	@Test
 	public void test1() {
 		this.applicationContextRunner
-				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class))
+				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class, ApplicationContextAwareUtils.class))
 				.run(context -> {
 					Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class);
 				});
@@ -58,7 +65,7 @@ public class MetadataAutoConfigurationTest {
 	@Test
 	public void test2() {
 		this.webApplicationContextRunner
-				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class))
+				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class, ApplicationContextAwareUtils.class))
 				.run(context -> {
 					Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class);
 				});
@@ -70,7 +77,7 @@ public class MetadataAutoConfigurationTest {
 	@Test
 	public void test3() {
 		this.reactiveWebApplicationContextRunner
-				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class))
+				.withConfiguration(AutoConfigurations.of(MetadataAutoConfiguration.class, ApplicationContextAwareUtils.class))
 				.run(context -> {
 					Assertions.assertThat(context).hasSingleBean(MetadataLocalProperties.class);
 				});
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java
index afa2eec25..107310331 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/pojo/PolarisServiceInstanceTest.java
@@ -17,6 +17,7 @@
 
 package com.tencent.cloud.common.pojo;
 
+import com.tencent.polaris.api.pojo.DefaultInstance;
 import com.tencent.polaris.api.pojo.Instance;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
@@ -38,7 +39,7 @@ public class PolarisServiceInstanceTest {
 
 	@Test
 	@DisplayName("test getters and setters.")
-	void test() {
+	public void test1() {
 		Instance secureInstance = mock(Instance.class);
 		doReturn("test-ID").when(secureInstance).getId();
 		doReturn(SERVICE_PROVIDER).when(secureInstance).getService();
@@ -53,6 +54,7 @@ public class PolarisServiceInstanceTest {
 		assertThat(securePolarisServiceInstance.getPort()).isEqualTo(8080);
 		assertThat(securePolarisServiceInstance.isSecure()).isTrue();
 		assertThat(securePolarisServiceInstance.getScheme()).isEqualTo("https");
+		assertThat(securePolarisServiceInstance.getUri().toString()).isEqualTo("https://1.1.1.1:8080");
 
 		Instance insecureInstance = mock(Instance.class);
 		doReturn("http").when(insecureInstance).getProtocol();
@@ -60,4 +62,37 @@ public class PolarisServiceInstanceTest {
 		assertThat(insecurePolarisServiceInstance.isSecure()).isFalse();
 		assertThat(insecurePolarisServiceInstance.getScheme()).isEqualTo("http");
 	}
+
+
+	@Test
+	@DisplayName("test equals().")
+	public void test2() {
+		DefaultInstance instance1 = new DefaultInstance();
+		instance1.setId("test-1");
+		instance1.setProtocol("http");
+		PolarisServiceInstance polarisServiceInstance1 = new PolarisServiceInstance(instance1);
+
+		DefaultInstance instance2 = new DefaultInstance();
+		instance2.setId("test-1");
+		instance2.setProtocol("http");
+		PolarisServiceInstance polarisServiceInstance2 = new PolarisServiceInstance(instance2);
+
+		assertThat(polarisServiceInstance1.equals(polarisServiceInstance2)).isTrue();
+	}
+
+	@Test
+	@DisplayName("test hashCode().")
+	public void test3() {
+		DefaultInstance instance1 = new DefaultInstance();
+		instance1.setId("test-1");
+		instance1.setProtocol("http");
+		PolarisServiceInstance polarisServiceInstance1 = new PolarisServiceInstance(instance1);
+
+		DefaultInstance instance2 = new DefaultInstance();
+		instance2.setId("test-1");
+		instance2.setProtocol("http");
+		PolarisServiceInstance polarisServiceInstance2 = new PolarisServiceInstance(instance2);
+
+		assertThat(polarisServiceInstance1.hashCode()).isEqualTo(polarisServiceInstance2.hashCode());
+	}
 }
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java
index 9a94a32e4..e4e6001f9 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/BeanFactoryUtilsTest.java
@@ -19,10 +19,16 @@ package com.tencent.cloud.common.util;
 
 import org.junit.jupiter.api.Test;
 
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.ResolvableType;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 /**
  * Test for {@link BeanFactoryUtils}.
@@ -41,6 +47,11 @@ public class BeanFactoryUtilsTest {
 		assertThat(childBeanFactory.getBeansOfType(Foo.class)).isEmpty();
 		assertThat(BeanFactoryUtils.getBeans(childBeanFactory, Foo.class).size()).isEqualTo(1);
 		assertThat(BeanFactoryUtils.getBeans(childBeanFactory, Bar.class)).isEmpty();
+
+		MockBeanFactory mockBeanFactory = new MockBeanFactory();
+		assertThatThrownBy(() -> BeanFactoryUtils.getBeans(mockBeanFactory, Bar.class))
+				.isExactlyInstanceOf(RuntimeException.class)
+				.hasMessageContaining("bean factory not support get list bean.");
 	}
 
 	static class Foo {
@@ -50,4 +61,82 @@ public class BeanFactoryUtilsTest {
 	static class Bar {
 
 	}
+
+	static class MockBeanFactory implements BeanFactory {
+
+		@Override
+		public Object getBean(String s) throws BeansException {
+			return null;
+		}
+
+		@Override
+		public <T> T getBean(String s, Class<T> aClass) throws BeansException {
+			return null;
+		}
+
+		@Override
+		public Object getBean(String s, Object... objects) throws BeansException {
+			return null;
+		}
+
+		@Override
+		public <T> T getBean(Class<T> aClass) throws BeansException {
+			return null;
+		}
+
+		@Override
+		public <T> T getBean(Class<T> aClass, Object... objects) throws BeansException {
+			return null;
+		}
+
+		@Override
+		public <T> ObjectProvider<T> getBeanProvider(Class<T> aClass) {
+			return null;
+		}
+
+		@Override
+		public <T> ObjectProvider<T> getBeanProvider(ResolvableType resolvableType) {
+			return null;
+		}
+
+		@Override
+		public boolean containsBean(String s) {
+			return false;
+		}
+
+		@Override
+		public boolean isSingleton(String s) throws NoSuchBeanDefinitionException {
+			return false;
+		}
+
+		@Override
+		public boolean isPrototype(String s) throws NoSuchBeanDefinitionException {
+			return false;
+		}
+
+		@Override
+		public boolean isTypeMatch(String s, ResolvableType resolvableType) throws NoSuchBeanDefinitionException {
+			return false;
+		}
+
+		@Override
+		public boolean isTypeMatch(String s, Class<?> aClass) throws NoSuchBeanDefinitionException {
+			return false;
+		}
+
+		@Override
+		public Class<?> getType(String s) throws NoSuchBeanDefinitionException {
+			return null;
+		}
+
+		@Override
+		public Class<?> getType(String s, boolean b) throws NoSuchBeanDefinitionException {
+			return null;
+		}
+
+		@Override
+		public String[] getAliases(String s) {
+			return new String[0];
+		}
+	}
 }
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java
index 962f014a3..df2b3aa7b 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/JacksonUtilsTest.java
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+import org.springframework.util.StringUtils;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -43,6 +45,7 @@ public class JacksonUtilsTest {
 		sourceMap.put("k2", "v2");
 		sourceMap.put("k3", "v3");
 		assertThat(JacksonUtils.serialize2Json(sourceMap)).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}");
+		assertThat(StringUtils.trimAllWhitespace(JacksonUtils.serialize2Json(sourceMap, true))).isEqualTo("{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\"}");
 	}
 
 	@Test
diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml
index 15fe089d4..09f414a21 100644
--- a/spring-cloud-tencent-dependencies/pom.xml
+++ b/spring-cloud-tencent-dependencies/pom.xml
@@ -70,10 +70,10 @@
 	</developers>
 
 	<properties>
-		<revision>1.11.1-Hoxton.SR12-SNAPSHOT</revision>
+		<revision>1.11.2-Hoxton.SR12-SNAPSHOT</revision>
 
 		<!-- Dependencies -->
-		<polaris.version>1.12.0</polaris.version>
+		<polaris.version>1.12.2</polaris.version>
 		<guava.version>31.0.1-jre</guava.version>
 		<logback.version>1.2.11</logback.version>
 		<mocktio.version>4.5.1</mocktio.version>
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README-zh.md b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README-zh.md
index 23fe50ad6..30679375a 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README-zh.md
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README-zh.md
@@ -1,27 +1,24 @@
-# Spring Cloud Polaris CircuitBreaker Example
+# Spring Cloud Polaris Circuitbreaker example
 
 ## 样例简介
 
 本样例将介绍如何在Spring Cloud项目中使用```spring-cloud-starter-tencent-polaris-circuitbreaker```以使用其各项功能。
 
-该样例分为两个微服务,即 
-
-1. ```polaris-circuitbreaker-example-a``` 
-2. ```polaris-circuitbreaker-example-b``` 有两个实例 B(默认正常服务)和 B2(模拟异常服务)
-
-``` polaris-circuitbreaker-example-a``` 对 ```polaris-circuitbreaker-example-b```发生调用。
+本样例包括被调方```polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-callee-service2```和主调方```polaris-circuitbreaker-feign-example```、```polaris-circuitbreaker-gateway-example```、```polaris-circuitbreaker-webclient-example```。
 
 ## 使用说明
 
 ### 修改配置
 
-修改 resource/bootstrap.yml 中北极星的服务端地址
+配置如下所示。其中,${ip}和${port}为Polaris后端服务的IP地址与端口号。
 
 ```yaml
 spring:
+  application:
+    name: ${application.name}
   cloud:
     polaris:
-       address: grpc://${ip}:8091
+      address: ${ip}:${port}
 ```
 
 ### 启动样例
@@ -30,43 +27,40 @@ spring:
 
 参考[Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)。
 
-### 启动应用
+#### 启动被调应用
 
-- IDEA启动
+分别启动```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2```
 
-分别启动
 
-1. ```spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a```下的```ServiceA```
-2. ```spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b```下的```ServiceB```
-3. ```spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2```下的```ServiceB2```
+#### 启动主调应用
 
+##### 启动Feign并验证
 
-## 验证
+启动```polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example```。
 
-### Feign调用
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, 验证熔断和Polaris-server远程拉取降级。
 
-执行以下命令发起Feign调用,其逻辑为```ServiceB```抛出一个异常
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, 验证熔断和代码降级。
 
-```shell
-curl -L -X GET 'localhost:48080/example/service/a/getBServiceInfo'
-```
+##### 启动RestTemplate并验证
 
-预期返回情况:
+启动```polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example```。
 
-在出现
-```
-hello world ! I'm a service B1
-```            
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, 验证熔断和Polaris-server远程拉取降级。
+
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, 验证熔断和代码降级。
+
+##### 启动WebClient并验证
+
+启动```polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example```。
+
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo'`, 验证熔断和代码降级。
 
-时,表示 B2 已经被熔断了,请求只会打到 B1。
+##### 启动SCG并验证
 
-### 验证更多场景
+启动```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example```。
 
-您也可以调整 ```example-b``` 和 ```example-b2``` 中 ```resource/bootstrap.yml``` is-throw-runtime-exception
-参数调整服务是否抛出异常。
+发送请求`curl --location --request GET 'http://127.0.0.1:48080/polaris-circuitbreaker-callee-service/example/service/b/info'`, 验证熔断和代码降级。
 
-例如测试以下场景:
-1. 两个实例都是正常的,这时候预期是 B1 和 B2 都能正常被调用到
-2. 一个实例正常一个实例不正常,这时候预期是不正常实例被熔断,请求只会打到正常的实例
-3. 两个实例都不正常,这时候 Feign 会自动 Fallback 到 ProviderBFallback.java 的实现类
+修改```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/resources/bootstrap.yml```。删除本地fallback方法并重启,验证熔断和Polaris-server远程拉取降级。
 
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README.md b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README.md
index d298346d1..0c297ef02 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README.md
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/README.md
@@ -1,10 +1,10 @@
-# Spring Cloud Polaris CircuitBreaker Example
+# Spring Cloud Polaris Circuitbreaker example
 
 ## Example Introduction
 
-This example shows how to use```spring-cloud-starter-tencent-polaris-circuitbreaker``` in Spring Cloud project and other features
+This example shows how to use```spring-cloud-starter-tencent-polaris-circuitbreaker```in Spring Cloud project for its features.
 
-This example is divided to two microservice, ```polaris-circuitbreaker-example-a``` and ```polaris-circuitbreaker-example-b```. In these two microservices, ```polaris-circuitbreaker-example-a``` invokes ```polaris-circuitbreaker-example-b```.
+This example contains callee-service```polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-callee-service2```and caller-service```polaris-circuitbreaker-feign-example```、```polaris-circuitbreaker-gateway-example```、```polaris-circuitbreaker-webclient-example```.
 
 ## Instruction
 
@@ -21,58 +21,46 @@ spring:
       address: ${ip}:${port}
 ```
 
-###Launching Example
+### Launching Example
 
-###Launching Polaris Backend Service
+#### Launching Polaris Backend Service
 
 Reference to [Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)
 
-####Launching Application
+#### Launching callee service
 
-Note, because verification is needed for circuit-break feature, therefore, one needs to deploy more than two invoked services (two deployment in this example)
+Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2```
 
-Launching```spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a```'s ServiceA and ```spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b```'s ServiceB
 
-note, Service B needs to launch two. One can adjust the port on the same machine.
+#### Launching caller service
 
-Two Services B's ```com.tencent.cloud.polaris.circuitbreaker.example.ServiceBController.info``` logics are different. One returns normally, one is abnormal.
+##### Launching Feign and Verify
 
-- Maven Package Launching
+Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example```.
 
-Execute under ```spring-cloud-tencent-examples/polaris-discovery-example```
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, Verify circuit breaker and fallback from Polaris-server.
 
-note, Service B needs to launch two. One can adjust the port on the same machine.
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, Verify circuit breaker and fallback from code.
 
-Two Services B's com.tencent.cloud.polaris.circuitbreaker.example.ServiceBController.info logics are different. One returns normally, one is abnormal.
+##### Launching RestTemplate and Verify
 
-```sh
-mvn clean package
-```
+Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example```.
 
-Then under ``polaris-circuitbreaker-example-a``` and ``polaris-circuitbreaker-example-b``` find the package that generated jar, and run it
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, Verify circuit breaker and fallback from Polaris-server.
 
-```
-java -jar ${app.jar}
-```
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, Verify circuit breaker and fallback from code.
 
-Launch application, change ${app.jar} to jar's package name
+##### Launching WebClient and Verify
 
-##Verify
+Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example```。
 
-####Feign Invoke
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo'`, Verify circuit breaker and fallback from code.
 
-Execute the following orders to invoke Feign, the logic is ```ServiceB``` has an abnormal signal
+##### Launching SCG and Verify
 
-```shell
-curl -L -X GET 'localhost:48080/example/service/a/getBServiceInfo'
-```
+Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example```。
 
-Expected return condition:
+Sending request`curl --location --request GET 'http://127.0.0.1:48080/polaris-circuitbreaker-callee-service/example/service/b/info'`, Verify circuit breaker and fallback from code.
 
-when appear
-
-```
-trigger the refuse for service b
-```
+Changing```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/resources/bootstrap.yml```, delete local fallback and restart, Verify circuit breaker and fallback from Polaris-server.
 
-it means the request signals abnormal ServiceB, and will ciruitbreak this instance, the later requests will return normally. 
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/pom.xml
similarity index 91%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/pom.xml
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/pom.xml
index 01dd7904a..e1ee856b3 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/pom.xml
@@ -10,8 +10,8 @@
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 
-	<artifactId>polaris-circuitbreaker-example-b</artifactId>
-	<name>Polaris Circuit Breaker Example B</name>
+	<artifactId>polaris-circuitbreaker-callee-service</artifactId>
+	<name>Polaris Circuit Breaker Callee Example</name>
 
 	<dependencies>
 		<dependency>
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java
similarity index 100%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceB.java
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java
similarity index 80%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java
index 128ea5e4d..8628db06a 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceBController.java
@@ -40,4 +40,16 @@ public class ServiceBController {
 	public String info() {
 		return "hello world ! I'm a service B1";
 	}
+
+	@GetMapping("/health")
+	public String health() {
+		System.out.println("health check: 200 instance");
+		return "hello world ! I'm a service B1";
+	}
+
+	@GetMapping("/health-svc")
+	public String healthsvc() {
+		System.out.println("health-svc check: 200 instance");
+		return "hello world ! I'm a service B1";
+	}
 }
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml
similarity index 81%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml
index d6945b5b4..5fa99c252 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service/src/main/resources/bootstrap.yml
@@ -2,7 +2,7 @@ server:
   port: 48081
 spring:
   application:
-    name: polaris-circuitbreaker-example-b
+    name: polaris-circuitbreaker-callee-service
   cloud:
     polaris:
       address: grpc://183.47.111.80:8091
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/pom.xml
similarity index 92%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/pom.xml
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/pom.xml
index 340de2286..152aeef96 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/pom.xml
@@ -10,7 +10,8 @@
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 
-	<artifactId>polaris-circuitbreaker-example-b2</artifactId>
+	<artifactId>polaris-circuitbreaker-callee-service2</artifactId>
+	<name>Polaris Circuit Breaker Callee Example 2</name>
 
 	<dependencies>
 		<dependency>
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java
similarity index 100%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceB2.java
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java
new file mode 100644
index 000000000..2d5287c3a
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java
@@ -0,0 +1,98 @@
+/*
+ * 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.ciruitbreaker.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Service B Controller.
+ *
+ * @author Haotian Zhang
+ */
+@RestController
+@RequestMapping("/example/service/b")
+public class ServiceBController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ServiceBController.class);
+
+	private boolean ifBadGateway = true;
+
+	private boolean ifDelay = true;
+
+	@GetMapping("/setBadGateway")
+	public void setBadGateway(@RequestParam boolean param) {
+		if (param) {
+			LOG.info("info is set to return HttpStatus.BAD_GATEWAY.");
+		}
+		else {
+			LOG.info("info is set to return HttpStatus.OK.");
+		}
+		this.ifBadGateway = param;
+	}
+
+	@GetMapping("/setDelay")
+	public void setDelay(@RequestParam boolean param) {
+		if (param) {
+			LOG.info("info is set to delay 100ms.");
+		}
+		else {
+			LOG.info("info is set to no delay.");
+		}
+		this.ifDelay = param;
+	}
+
+	/**
+	 * Get service information.
+	 *
+	 * @return service information
+	 */
+	@GetMapping("/info")
+	public ResponseEntity<String> info() throws InterruptedException {
+		if (ifBadGateway) {
+			return new ResponseEntity<>("failed for call my service", HttpStatus.BAD_GATEWAY);
+		}
+		if (ifDelay) {
+			Thread.sleep(100);
+		}
+		return new ResponseEntity<>("hello world ! I'm a service B2", HttpStatus.OK);
+	}
+
+	@GetMapping("/health")
+	@ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service")
+	public String health() {
+		System.out.println("health check: 502 instance");
+		return "hello world ! I'm a service B1";
+	}
+
+	@GetMapping("/health-svc")
+	@ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service")
+	public String healthsvc() {
+		System.out.println("health-svc check: 502 instance");
+		return "hello world ! I'm a service B1";
+	}
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml
similarity index 81%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml
index 5ef89145c..54cb21355 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/resources/bootstrap.yml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2/src/main/resources/bootstrap.yml
@@ -2,7 +2,7 @@ server:
   port: 48082
 spring:
   application:
-    name: polaris-circuitbreaker-example-b
+    name: polaris-circuitbreaker-callee-service
   cloud:
     polaris:
       address: grpc://183.47.111.80:8091
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/ESAPI.properties b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/ESAPI.properties
deleted file mode 100644
index 32df629d9..000000000
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/ESAPI.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-ESAPI.printProperties=true
-ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder
-ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
-
-Encoder.AllowMultipleEncoding=false
-Encoder.AllowMixedEncoding=false
-Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec
-
-Logger.LogEncodingRequired=false
-Logger.UserInfo=false
-Logger.ClientInfo=false
-Logger.ApplicationName=ExampleApplication
-Logger.LogApplicationName=false
-Logger.LogServerIP=false
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml
deleted file mode 100644
index ad35a87da..000000000
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-server:
-  port: 48080
-spring:
-  application:
-    name: polaris-circuitbreaker-example-a
-  cloud:
-    polaris:
-      address: grpc://183.47.111.80:8091
-      namespace: default
-      enabled: true
-      circuitbreaker:
-        enabled: true
-      stat:
-        enabled: true
-        port: 28081
-    tencent:
-      rpc-enhancement:
-        enabled: true
-        reporter:
-          ignore-internal-server-error: true
-          series: server_error
-          statuses: gateway_timeout, bad_gateway, service_unavailable
-
-feign:
-  hystrix:
-    enabled: true
-  compression:
-    request:
-      enabled: false
-      mime-types: text/xml,application/xml,application/json
-      min-request-size: 2048
-    response:
-      enabled: false
-ribbon:
-  polaris:
-    enabled: true
-  MaxAutoRetries: 1
-  MaxAutoRetriesNextServer: 2
-  OkToRetryOnAllOperations: false
-  ConnectionTimeout: 1000
-  ReadTimeout: 1000
-  eager-load:
-    enabled: on
-
-serivceB:
-  url: http://localhost:48081
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/pom.xml
similarity index 86%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/pom.xml
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/pom.xml
index 70351a785..9093881bb 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/pom.xml
@@ -10,8 +10,8 @@
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 
-	<artifactId>polaris-circuitbreaker-example-a</artifactId>
-	<name>Polaris Circuit Breaker Example A</name>
+	<artifactId>polaris-circuitbreaker-feign-example</artifactId>
+	<name>Polaris Circuit Breaker Feign Example</name>
 
 	<dependencies>
 		<dependency>
@@ -24,11 +24,6 @@
 			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
 		</dependency>
 
-		<dependency>
-			<groupId>com.tencent.cloud</groupId>
-			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
-		</dependency>
-
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-starter-openfeign</artifactId>
@@ -36,12 +31,12 @@
 
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
+			<artifactId>spring-cloud-starter-loadbalancer</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>org.owasp.esapi</groupId>
-			<artifactId>esapi</artifactId>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
 		</dependency>
 	</dependencies>
 
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderB.java
similarity index 85%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderB.java
index f0c05217a..63dbbdb17 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderB.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderB.java
@@ -15,7 +15,7 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.example;
+package com.tencent.cloud.polaris.circuitbreaker.feign.example;
 
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -23,9 +23,9 @@ import org.springframework.web.bind.annotation.GetMapping;
 /**
  * Circuit breaker example callee provider.
  *
- * @author Haotian Zhang
+ * @author sean yu
  */
-@FeignClient(name = "polaris-circuitbreaker-example-b", fallback = ProviderBFallback.class)
+@FeignClient(name = "polaris-circuitbreaker-callee-service", contextId = "fallback-from-polaris")
 public interface ProviderB {
 
 	/**
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBFallback.java
similarity index 81%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBFallback.java
index bf47d49dd..419b18cfc 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ProviderBFallback.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBFallback.java
@@ -15,20 +15,20 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.example;
+package com.tencent.cloud.polaris.circuitbreaker.feign.example;
 
 import org.springframework.stereotype.Component;
 
 /**
  * Circuit breaker example callee fallback.
  *
- * @author Haotian Zhang
+ * @author sean yu
  */
 @Component
-public class ProviderBFallback implements ProviderB {
+public class ProviderBFallback implements ProviderBWithFallback {
 
 	@Override
 	public String info() {
-		return "trigger the refuse for service b";
+		return "fallback: trigger the refuse for service b";
 	}
 }
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBWithFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBWithFallback.java
new file mode 100644
index 000000000..194ac1305
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ProviderBWithFallback.java
@@ -0,0 +1,39 @@
+/*
+ * 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.circuitbreaker.feign.example;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * ProviderBWithFallback.
+ *
+ * @author sean yu
+ */
+@FeignClient(name = "polaris-circuitbreaker-callee-service", contextId = "fallback-from-code", fallback = ProviderBFallback.class)
+public interface ProviderBWithFallback {
+
+	/**
+	 * Get info of service B.
+	 *
+	 * @return info of service B
+	 */
+	@GetMapping("/example/service/b/info")
+	String info();
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAController.java
similarity index 58%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAController.java
index 04570498c..30aa94c49 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceAController.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAController.java
@@ -15,21 +15,18 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.example;
+package com.tencent.cloud.polaris.circuitbreaker.feign.example;
 
-import org.owasp.esapi.ESAPI;
 
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.RestTemplate;
 
 /**
  * Circuit breaker example caller controller.
  *
- * @author Haotian Zhang
+ * @author sean yu
  */
 @RestController
 @RequestMapping("/example/service/a")
@@ -39,37 +36,24 @@ public class ServiceAController {
 	private ProviderB polarisServiceB;
 
 	@Autowired
-	private RestTemplate restTemplate;
+	private ProviderBWithFallback providerBWithFallback;
 
 	/**
 	 * Get info of Service B by Feign.
 	 * @return info of Service B
 	 */
-	@GetMapping("/getBServiceInfo")
-	public String getBServiceInfo() {
-		return polarisServiceB.info();
-	}
-
-	@GetMapping("/getBServiceInfoByRestTemplate")
-	public String getBServiceInfoByRestTemplate() {
-		return restTemplate.getForObject("http://polaris-circuitbreaker-example-b/example/service/b/info", String.class);
+	@GetMapping("/getBServiceInfo/fallbackFromCode")
+	public String getBServiceInfoFallbackFromCode() {
+		return providerBWithFallback.info();
 	}
 
 	/**
-	 * Get info of Service B by RestTemplate.
+	 * Get info of Service B by Feign.
 	 * @return info of Service B
 	 */
-	@GetMapping("/testRest")
-	public String testRest() {
-		ResponseEntity<String> entity = restTemplate.getForEntity(
-				"http://polaris-circuitbreaker-example-b/example/service/b/info",
-				String.class);
-		String response = entity.getBody();
-		return cleanXSS(response);
+	@GetMapping("/getBServiceInfo/fallbackFromPolaris")
+	public String getBServiceInfoFallbackFromPolaris() {
+		return polarisServiceB.info();
 	}
 
-	private String cleanXSS(String str) {
-		str = ESAPI.encoder().encodeForHTML(str);
-		return str;
-	}
 }
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAFeign.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAFeign.java
new file mode 100644
index 000000000..f6a012bb0
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/example/ServiceAFeign.java
@@ -0,0 +1,38 @@
+/*
+ * 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.circuitbreaker.feign.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+/**
+ * Circuit breaker example caller application.
+ *
+ * @author sean yu
+ */
+@SpringBootApplication
+@EnableFeignClients
+public class ServiceAFeign {
+
+	public static void main(String[] args) {
+		SpringApplication.run(ServiceAFeign.class, args);
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml
new file mode 100644
index 000000000..bf20a3b2b
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example/src/main/resources/application.yml
@@ -0,0 +1,22 @@
+server:
+  port: 48080
+spring:
+  application:
+    name: polaris-circuitbreaker-feign-example
+  cloud:
+    polaris:
+      address: grpc://183.47.111.80:8091
+      namespace: default
+      enabled: true
+      loadbalancer:
+        enabled: true
+
+feign:
+  circuitbreaker:
+    enabled: true
+
+logging:
+  level:
+    root: info
+    com.tencent.cloud: debug
+
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/pom.xml
new file mode 100644
index 000000000..342df6ae1
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>polaris-circuitbreaker-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>polaris-circuitbreaker-gateway-example</artifactId>
+	<name>Polaris Circuit Breaker Gateway Example</name>
+
+	<dependencies>
+		<dependency>
+			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
+			<groupId>com.tencent.cloud</groupId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-tencent-gateway-plugin</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-tencent-featureenv-plugin</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-gateway</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/FallbackController.java
similarity index 59%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/FallbackController.java
index 384167816..c0d964b56 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b2/src/main/java/com/tencent/cloud/polaris/ciruitbreaker/example/ServiceBController.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/FallbackController.java
@@ -13,34 +13,25 @@
  * 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.ciruitbreaker.example;
+package com.tencent.cloud.polaris.circuitbreaker.gateway.example;
+
+import reactor.core.publisher.Mono;
 
-import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestController;
 
 /**
- * Service B Controller.
+ * FallbackController.
  *
- * @author Haotian Zhang
+ * sean yu
  */
 @RestController
-@RequestMapping("/example/service/b")
-public class ServiceBController {
+public class FallbackController {
 
-	/**
-	 * Get service information.
-	 *
-	 * @return service information
-	 */
-	@GetMapping("/info")
-	@ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service")
-	public String info() {
-		return "failed for call service B2";
+	@GetMapping("/polaris-fallback")
+	Mono<String> getFallback() {
+		return Mono.just("fallback: trigger the refuse for service b");
 	}
 }
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/GatewayScgApplication.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/GatewayScgApplication.java
new file mode 100644
index 000000000..ea042b2f9
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/gateway/example/GatewayScgApplication.java
@@ -0,0 +1,35 @@
+/*
+ * 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.circuitbreaker.gateway.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * SCG application.
+ *
+ * @author sean yu
+ */
+@SpringBootApplication
+public class GatewayScgApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(GatewayScgApplication.class, args);
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..a7bdb3f4b
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/src/main/resources/bootstrap.yml
@@ -0,0 +1,59 @@
+server:
+  session-timeout: 1800
+  port: 48080
+spring:
+  application:
+    name: GatewayScgService
+  cloud:
+    tencent:
+      plugin:
+        scg:
+          staining:
+            enabled: true
+            rule-staining:
+              enabled: true
+        router:
+          feature-env:
+            enabled: true
+    polaris:
+      address: grpc://183.47.111.80:8091
+      namespace: default
+      enabled: true
+    gateway:
+      discovery:
+        locator:
+          enabled: true
+          'predicates[0]':
+            name: Path
+            args:
+              patterns: '''/'' + serviceId + ''/**'''
+          'filters[0]':
+            name: RewritePath
+            args:
+              regexp: '''/'' + serviceId + ''/(?<remaining>.*)'''
+              replacement: '''/$\{remaining}'''
+          'filters[1]':
+            name: CircuitBreaker
+            args:
+              # statusCodes 缺省时会自动识别 "5**" 为错误
+#              statusCodes: '''404,5**'''
+              # fallbackUri 缺省时会在熔断触发后拉取 plaris server 配置的降级作为 response
+              fallbackUri: '''forward:/polaris-fallback'''
+#      routes:
+#        - id: polaris-circuitbreaker-callee-service
+#          uri: lb://polaris-circuitbreaker-callee-service
+#          predicates:
+#            - Path=/polaris-circuitbreaker-callee-service/**
+#          filters:
+#            - StripPrefix=1
+#            - name: CircuitBreaker
+#              args:
+#                statusCodes: 502
+#                fallbackUri: forward:/polaris-fallback
+logging:
+  level:
+    root: info
+    com.tencent.polaris.discovery.client.flow.RegisterFlow: off
+    com.tencent.polaris.plugins.registry: off
+    com.tencent.cloud: debug
+
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/pom.xml
new file mode 100644
index 000000000..dc59e6607
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>polaris-circuitbreaker-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>polaris-circuitbreaker-resttemplate-example</artifactId>
+	<name>Polaris Circuit Breaker RestTemplate Example</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-loadbalancer</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/CustomFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/CustomFallback.java
new file mode 100644
index 000000000..a7f5f1a65
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/CustomFallback.java
@@ -0,0 +1,43 @@
+/*
+ * 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.circuitbreaker.resttemplate.example;
+
+import java.util.HashMap;
+
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerFallback;
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * CustomFallback.
+ *
+ * @author sean yu
+ */
+@Component
+public class CustomFallback implements PolarisCircuitBreakerFallback {
+	@Override
+	public PolarisCircuitBreakerHttpResponse fallback() {
+		return new PolarisCircuitBreakerHttpResponse(
+				200,
+				new HashMap<String, String>() {{
+					put("Content-Type", "application/json");
+				}},
+				"{\"msg\": \"this is a fallback class\"}");
+	}
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAController.java
new file mode 100644
index 000000000..d17744ce3
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAController.java
@@ -0,0 +1,74 @@
+/*
+ * 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.circuitbreaker.resttemplate.example;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Circuit breaker example caller controller.
+ *
+ * @author sean yu
+ */
+@RestController
+@RequestMapping("/example/service/a")
+public class ServiceAController {
+
+	@Autowired
+	@Qualifier("defaultRestTemplate")
+	private RestTemplate defaultRestTemplate;
+
+	@Autowired
+	@Qualifier("restTemplateFallbackFromPolaris")
+	private RestTemplate restTemplateFallbackFromPolaris;
+
+	@Autowired
+	@Qualifier("restTemplateFallbackFromCode")
+	private RestTemplate restTemplateFallbackFromCode;
+
+	@Autowired
+	private CircuitBreakerFactory circuitBreakerFactory;
+
+	@GetMapping("/getBServiceInfo")
+	public String getBServiceInfo() {
+		return circuitBreakerFactory
+				.create("polaris-circuitbreaker-callee-service#/example/service/b/info")
+				.run(() ->
+						defaultRestTemplate.getForObject("/example/service/b/info", String.class),
+						throwable -> "trigger the refuse for service b"
+				);
+	}
+
+	@GetMapping("/getBServiceInfo/fallbackFromPolaris")
+	public ResponseEntity<String> getBServiceInfoFallback() {
+		return restTemplateFallbackFromPolaris.getForEntity("/example/service/b/info", String.class);
+	}
+
+	@GetMapping("/getBServiceInfo/fallbackFromCode")
+	public ResponseEntity<String> getBServiceInfoFallbackClass() {
+		return restTemplateFallbackFromCode.getForEntity("/example/service/b/info", String.class);
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java
new file mode 100644
index 000000000..fb6495912
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/example/ServiceAResTemplate.java
@@ -0,0 +1,71 @@
+/*
+ * 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.circuitbreaker.resttemplate.example;
+
+import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.DefaultUriBuilderFactory;
+
+/**
+ * Circuit breaker example caller application.
+ *
+ * @author sean yu
+ */
+@SpringBootApplication
+public class ServiceAResTemplate {
+
+	public static void main(String[] args) {
+		SpringApplication.run(ServiceAResTemplate.class, args);
+	}
+
+	@Bean
+	@LoadBalanced
+	public RestTemplate defaultRestTemplate() {
+		DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
+		RestTemplate restTemplate = new RestTemplate();
+		restTemplate.setUriTemplateHandler(uriBuilderFactory);
+		return restTemplate;
+	}
+
+	@Bean
+	@LoadBalanced
+	@PolarisCircuitBreaker
+	public RestTemplate restTemplateFallbackFromPolaris() {
+		DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
+		RestTemplate restTemplate = new RestTemplate();
+		restTemplate.setUriTemplateHandler(uriBuilderFactory);
+		return restTemplate;
+	}
+
+	@Bean
+	@LoadBalanced
+	@PolarisCircuitBreaker(fallbackClass = CustomFallback.class)
+	public RestTemplate restTemplateFallbackFromCode() {
+		DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
+		RestTemplate restTemplate = new RestTemplate();
+		restTemplate.setUriTemplateHandler(uriBuilderFactory);
+		return restTemplate;
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..720c3df80
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example/src/main/resources/bootstrap.yml
@@ -0,0 +1,20 @@
+server:
+  port: 48080
+spring:
+  application:
+    name: polaris-circuitbreaker-resttemplate-example
+  cloud:
+    polaris:
+      address: grpc://183.47.111.80:8091
+      namespace: default
+      enabled: true
+      loadbalancer:
+        enabled: true
+      circuitbreaker:
+        enabled: true
+
+logging:
+  level:
+    root: info
+    com.tencent.cloud: debug
+
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/pom.xml
new file mode 100644
index 000000000..efb1089ae
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>polaris-circuitbreaker-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>polaris-circuitbreaker-webclient-example</artifactId>
+	<name>Polaris Circuit Breaker WebClient Example</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-webflux</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-loadbalancer</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAController.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAController.java
new file mode 100644
index 000000000..72f3c80d5
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.circuitbreaker.webclient.example;
+
+import reactor.core.publisher.Mono;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Circuit breaker example caller controller.
+ *
+ * @author sean yu
+ */
+@RestController
+@RequestMapping("/example/service/a")
+public class ServiceAController {
+
+	@Autowired
+	private ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
+
+	@Autowired
+	private WebClient.Builder webClientBuilder;
+
+	@GetMapping("/getBServiceInfo")
+	public Mono<String> getBServiceInfo() {
+		return webClientBuilder
+				.build()
+				.get()
+				.uri("/example/service/b/info")
+				.retrieve()
+				.bodyToMono(String.class)
+				.transform(it ->
+						reactiveCircuitBreakerFactory
+								.create("polaris-circuitbreaker-callee-service#/example/service/b/info")
+								.run(it, throwable -> Mono.just("fallback: trigger the refuse for service b"))
+				);
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAWebClient.java
similarity index 75%
rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java
rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAWebClient.java
index 3db7df8f3..8104ae873 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/java/com/tencent/cloud/polaris/circuitbreaker/example/ServiceA.java
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/webclient/example/ServiceAWebClient.java
@@ -16,31 +16,30 @@
  *
  */
 
-package com.tencent.cloud.polaris.circuitbreaker.example;
+package com.tencent.cloud.polaris.circuitbreaker.webclient.example;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
-import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.annotation.Bean;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
 
 /**
  * Circuit breaker example caller application.
  *
- * @author Haotian Zhang
+ * @author sean yu
  */
 @SpringBootApplication
-@EnableFeignClients
-public class ServiceA {
+public class ServiceAWebClient {
 
 	public static void main(String[] args) {
-		SpringApplication.run(ServiceA.class, args);
+		SpringApplication.run(ServiceAWebClient.class, args);
 	}
 
-	@Bean
 	@LoadBalanced
-	public RestTemplate restTemplate() {
-		return new RestTemplate();
+	@Bean
+	WebClient.Builder webClientBuilder() {
+		return WebClient.builder()
+				.baseUrl("http://polaris-circuitbreaker-callee-service");
 	}
 }
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..7e75556f3
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example/src/main/resources/bootstrap.yml
@@ -0,0 +1,20 @@
+server:
+  port: 48080
+spring:
+  application:
+    name: polaris-circuitbreaker-webclient-example
+  cloud:
+    polaris:
+      address: grpc://183.47.111.80:8091
+      namespace: default
+      enabled: true
+      loadbalancer:
+        enabled: true
+      circuitbreaker:
+        enabled: true
+
+logging:
+  level:
+    root: info
+    com.tencent.cloud: debug
+
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/pom.xml
new file mode 100644
index 000000000..670565bc8
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>polaris-circuitbreaker-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>polaris-circuitbreaker-zuul-example</artifactId>
+	<name>Polaris Circuit Breaker Zuul Example</name>
+
+	<dependencies>
+		<dependency>
+			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
+			<groupId>com.tencent.cloud</groupId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ConsumerFallback.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ConsumerFallback.java
new file mode 100644
index 000000000..dd8147311
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ConsumerFallback.java
@@ -0,0 +1,89 @@
+/*
+ * 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.circuitbreaker.zuul.example;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.stereotype.Component;
+
+/**
+ * Custom fallback.
+ *
+ * @author Haotian Zhang
+ */
+@Component
+public class ConsumerFallback implements FallbackProvider {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ConsumerFallback.class);
+
+	@Override
+	public String getRoute() {
+		return "polaris-circuitbreaker-callee-service";
+	}
+
+	@Override
+	public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
+		if (cause != null && cause.getCause() != null) {
+			LOG.error("Fallback is called.", cause);
+		}
+
+		return new ClientHttpResponse() {
+			@Override
+			public HttpStatus getStatusCode() {
+				return HttpStatus.OK;
+			}
+
+			@Override
+			public int getRawStatusCode() {
+				return 200;
+			}
+
+			@Override
+			public String getStatusText() {
+				return "OK";
+			}
+
+			@Override
+			public void close() {
+
+			}
+
+			@Override
+			public InputStream getBody() {
+				return new ByteArrayInputStream("zuul custom fallback".getBytes());
+			}
+
+			@Override
+			public HttpHeaders getHeaders() {
+				HttpHeaders httpHeaders = new HttpHeaders();
+				httpHeaders.setContentType(MediaType.TEXT_PLAIN);
+				return httpHeaders;
+			}
+		};
+	}
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ServiceAZuul.java b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ServiceAZuul.java
new file mode 100644
index 000000000..ba96e7bb8
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/java/com/tencent/cloud/polaris/circuitbreaker/zuul/example/ServiceAZuul.java
@@ -0,0 +1,37 @@
+/*
+ * 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.circuitbreaker.zuul.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+
+/**
+ * Zuul application.
+ *
+ * @author Haotian Zhang
+ */
+@SpringBootApplication
+@EnableZuulProxy
+public class ServiceAZuul {
+
+	public static void main(String[] args) {
+		SpringApplication.run(ServiceAZuul.class, args);
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..8b871b721
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-zuul-example/src/main/resources/bootstrap.yml
@@ -0,0 +1,23 @@
+server:
+  session-timeout: 1800
+  port: 48080
+spring:
+  application:
+    name: polaris-circuitbreaker-zuul-example
+  cloud:
+    polaris:
+      address: grpc://183.47.111.80:8091
+      namespace: default
+      circuitbreaker:
+        enabled: true
+zuul:
+  routes:
+    GatewayCalleeService:
+      serviceId: polaris-circuitbreaker-callee-service
+      path: /polaris-circuitbreaker-callee-service/**
+logging:
+  level:
+    root: info
+    com.tencent.polaris.discovery.client.flow.RegisterFlow: off
+    com.tencent.polaris.plugins.registry: off
+    com.tencent.cloud: debug
diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/pom.xml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/pom.xml
index 6b5daa263..032c6e28f 100644
--- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/pom.xml
@@ -15,8 +15,12 @@
 	<packaging>pom</packaging>
 
 	<modules>
-		<module>polaris-circuitbreaker-example-a</module>
-		<module>polaris-circuitbreaker-example-b</module>
-		<module>polaris-circuitbreaker-example-b2</module>
+		<module>polaris-circuitbreaker-feign-example</module>
+		<module>polaris-circuitbreaker-gateway-example</module>
+		<module>polaris-circuitbreaker-zuul-example</module>
+		<module>polaris-circuitbreaker-resttemplate-example</module>
+		<module>polaris-circuitbreaker-webclient-example</module>
+		<module>polaris-circuitbreaker-callee-service</module>
+		<module>polaris-circuitbreaker-callee-service2</module>
 	</modules>
 </project>
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
index 19179dac1..873b5c81e 100644
--- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service/pom.xml
@@ -30,14 +30,14 @@
 		</dependency>
 
 		<!--		<dependency>-->
-		<!--			<groupId>org.springframework.cloud</groupId>-->
-		<!--			<artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
+		<!--			<groupId>com.tencent.polaris</groupId>-->
+		<!--			<artifactId>connector-consul</artifactId>-->
 		<!--		</dependency>-->
 
-		<!--        <dependency>-->
-		<!--            <groupId>org.springframework.cloud</groupId>-->
-		<!--            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
-		<!--        </dependency>-->
+		<!--		<dependency>-->
+		<!--			<groupId>com.tencent.polaris</groupId>-->
+		<!--			<artifactId>connector-nacos</artifactId>-->
+		<!--		</dependency>-->
 	</dependencies>
 
 	<build>
diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml
index 1d370e7f5..aadcea9ee 100644
--- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/pom.xml
@@ -28,15 +28,15 @@
 			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
 		</dependency>
 
-		<!--        <dependency>-->
-		<!--            <groupId>org.springframework.cloud</groupId>-->
-		<!--            <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
-		<!--        </dependency>-->
+		<!--		<dependency>-->
+		<!--			<groupId>com.tencent.polaris</groupId>-->
+		<!--			<artifactId>connector-consul</artifactId>-->
+		<!--		</dependency>-->
 
-		<!--        <dependency>-->
-		<!--            <groupId>org.springframework.cloud</groupId>-->
-		<!--            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
-		<!--        </dependency>-->
+		<!--		<dependency>-->
+		<!--			<groupId>com.tencent.polaris</groupId>-->
+		<!--			<artifactId>connector-nacos</artifactId>-->
+		<!--		</dependency>-->
 	</dependencies>
 
 	<build>
diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml
index f7cbb1e6f..7788c0a2d 100644
--- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml
+++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/pom.xml
@@ -18,6 +18,11 @@
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
 
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-webflux</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>com.tencent.cloud</groupId>
 			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java
index e33c6f708..902d6681f 100644
--- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java
+++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/BusinessController.java
@@ -17,15 +17,22 @@
 
 package com.tencent.cloud.ratelimit.example.service.callee;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Mono;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -33,6 +40,8 @@ import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.HttpClientErrorException.TooManyRequests;
 import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 
 /**
  * Rate limit controller.
@@ -49,6 +58,8 @@ public class BusinessController {
 	private final AtomicLong lastTimestamp = new AtomicLong(0);
 	@Autowired
 	private RestTemplate restTemplate;
+	@Autowired
+	private WebClient.Builder webClientBuilder;
 	@Value("${spring.application.name}")
 	private String appName;
 
@@ -62,6 +73,44 @@ public class BusinessController {
 		return "hello world for ratelimit service " + index.incrementAndGet();
 	}
 
+	@GetMapping("/info/webclient")
+	public Mono<String> infoWebClient() {
+		return Mono.just("hello world for ratelimit service " + index.incrementAndGet());
+	}
+
+	@GetMapping("/invoke/webclient")
+	public String invokeInfoWebClient() throws InterruptedException, ExecutionException {
+		StringBuffer builder = new StringBuffer();
+		WebClient webClient = webClientBuilder.baseUrl("http://" + appName).build();
+		List<Mono<String>> monoList = new ArrayList<>();
+		for (int i = 0; i < 30; i++) {
+			Mono<String> response = webClient.get()
+					.uri(uriBuilder -> uriBuilder
+							.path("/business/info/webclient")
+							.queryParam("yyy", "yyy")
+							.build()
+					)
+					.header("xxx", "xxx")
+					.retrieve()
+					.bodyToMono(String.class)
+					.doOnSuccess(s -> builder.append(s + "\n"))
+					.doOnError(e -> {
+						if (e instanceof WebClientResponseException) {
+							if (((WebClientResponseException) e).getRawStatusCode() == 429) {
+								builder.append("TooManyRequests ").append(index.incrementAndGet() + "\n");
+							}
+						}
+					})
+					.onErrorReturn("");
+			monoList.add(response);
+		}
+		for (Mono<String> mono : monoList) {
+			mono.toFuture().get();
+		}
+		index.set(0);
+		return builder.toString();
+	}
+
 	/**
 	 * Get information 30 times per 1 second.
 	 *
@@ -75,19 +124,31 @@ public class BusinessController {
 		for (int i = 0; i < 30; i++) {
 			new Thread(() -> {
 				try {
-					ResponseEntity<String> entity = restTemplate.getForEntity("http://" + appName + "/business/info",
-							String.class);
+					HttpHeaders httpHeaders = new HttpHeaders();
+					httpHeaders.add("xxx", "xxx");
+					ResponseEntity<String> entity = restTemplate.exchange(
+							"http://" + appName + "/business/info?yyy={yyy}",
+							HttpMethod.GET,
+							new HttpEntity<>(httpHeaders),
+							String.class,
+							"yyy"
+					);
 					builder.append(entity.getBody() + "\n");
 				}
 				catch (RestClientException e) {
 					if (e instanceof TooManyRequests) {
-						builder.append("TooManyRequests " + index.incrementAndGet() + "\n");
+						builder.append("TooManyRequests ").append(index.incrementAndGet() + "\n");
 					}
 					else {
 						throw e;
 					}
 				}
-				count.countDown();
+				catch (Exception e) {
+					e.printStackTrace();
+				}
+				finally {
+					count.countDown();
+				}
 			}).start();
 		}
 		count.await();
diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/CustomLabelResolverReactive.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/CustomLabelResolverReactive.java
new file mode 100644
index 000000000..eb6e01b03
--- /dev/null
+++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/CustomLabelResolverReactive.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLabelReactiveResolver;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+
+/**
+ * resolver custom label from request.
+ *
+ * @author sean yu
+ */
+@Component
+public class CustomLabelResolverReactive implements PolarisRateLimiterLabelReactiveResolver {
+	@Override
+	public Map<String, String> resolve(ServerWebExchange exchange) {
+		// rate limit by some request params. such as query params, headers ..
+
+		Map<String, String> labels = new HashMap<>();
+		labels.put("user", "zhangsan");
+
+		return labels;
+	}
+}
diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java
index 12a9270cc..c8a49d2a7 100644
--- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java
+++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/java/com/tencent/cloud/ratelimit/example/service/callee/RateLimitCalleeService.java
@@ -22,6 +22,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 import org.springframework.context.annotation.Bean;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
 
 /**
  * Rate limit application.
@@ -40,4 +41,11 @@ public class RateLimitCalleeService {
 	public RestTemplate restTemplate() {
 		return new RestTemplate();
 	}
+
+
+	@LoadBalanced
+	@Bean
+	WebClient.Builder webClientBuilder() {
+		return WebClient.builder();
+	}
 }
diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java
index 15d56b312..774a3c6f0 100644
--- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java
+++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java
@@ -24,6 +24,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.test.context.runner.ApplicationContextRunner;
 
+import static com.tencent.polaris.test.common.Consts.PORT;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
 import static org.assertj.core.api.Assertions.assertThat;
 
 /**
@@ -41,6 +43,9 @@ public class PolarisRibbonClientConfigurationTest {
 				.withConfiguration(AutoConfigurations.of(
 						TestApplication.class,
 						PolarisRibbonClientConfiguration.class))
+				.withPropertyValues("spring.application.name=" + SERVICE_PROVIDER)
+				.withPropertyValues("server.port=" + PORT)
+				.withPropertyValues("spring.cloud.polaris.address=grpc://127.0.0.1:10081")
 				.run(context -> {
 					assertThat(context).hasSingleBean(PolarisRibbonClientConfiguration.class);
 					assertThat(context).hasSingleBean(PolarisLoadBalancer.class);
diff --git a/spring-cloud-tencent-rpc-enhancement/pom.xml b/spring-cloud-tencent-rpc-enhancement/pom.xml
index 65f9c45ff..f9fb98732 100644
--- a/spring-cloud-tencent-rpc-enhancement/pom.xml
+++ b/spring-cloud-tencent-rpc-enhancement/pom.xml
@@ -42,7 +42,6 @@
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-loadbalancer</artifactId>
-			<optional>true</optional>
 		</dependency>
 
 		<dependency>
@@ -52,20 +51,32 @@
 		</dependency>
 
 		<dependency>
-			<groupId>com.tencent.polaris</groupId>
-			<artifactId>polaris-test-common</artifactId>
-			<scope>test</scope>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-gateway-server</artifactId>
+			<optional>true</optional>
 		</dependency>
 
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
-			<scope>test</scope>
+			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-webflux</artifactId>
+			<optional>true</optional>
 		</dependency>
 
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-web</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>polaris-test-common</artifactId>
 			<scope>test</scope>
 		</dependency>
 
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java
index 599b2cc76..d177aad8b 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java
@@ -17,18 +17,38 @@
 
 package com.tencent.cloud.rpc.enhancement;
 
+import java.io.UnsupportedEncodingException;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.constant.RouterConstant;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.RequestLabelUtils;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
+import com.tencent.polaris.api.plugin.circuitbreaker.entity.InstanceResource;
+import com.tencent.polaris.api.plugin.circuitbreaker.entity.Resource;
+import com.tencent.polaris.api.pojo.RetStatus;
+import com.tencent.polaris.api.pojo.ServiceKey;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.api.utils.CollectionUtils;
+import com.tencent.polaris.client.api.SDKContext;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.lang.Nullable;
 
+import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
 import static org.springframework.http.HttpStatus.BAD_GATEWAY;
 import static org.springframework.http.HttpStatus.BANDWIDTH_LIMIT_EXCEEDED;
 import static org.springframework.http.HttpStatus.GATEWAY_TIMEOUT;
@@ -48,22 +68,85 @@ import static org.springframework.http.HttpStatus.VARIANT_ALSO_NEGOTIATES;
  * @author <a href="mailto:iskp.me@gmail.com">Elve.Xu</a> 2022-07-11
  */
 public abstract class AbstractPolarisReporterAdapter {
-
 	private static final Logger LOG = LoggerFactory.getLogger(AbstractPolarisReporterAdapter.class);
 	private static final List<HttpStatus> HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY,
 			SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES,
 			INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED);
+
 	protected final RpcEnhancementReporterProperties reportProperties;
 
+	protected final SDKContext context;
+
 	/**
 	 * Constructor With {@link RpcEnhancementReporterProperties} .
 	 *
 	 * @param reportProperties instance of {@link RpcEnhancementReporterProperties}.
 	 */
-	protected AbstractPolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties) {
+	protected AbstractPolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) {
 		this.reportProperties = reportProperties;
+		this.context = context;
+	}
+
+	/**
+	 * createServiceCallResult.
+	 * @param calleeServiceName will pick up url host when null
+	 * @param calleeHost will pick up url host when null
+	 * @param calleePort will pick up url port when null
+	 * @param uri request url
+	 * @param requestHeaders request header
+	 * @param responseHeaders response header
+	 * @param statusCode response status
+	 * @param delay delay
+	 * @param exception exception
+	 * @return ServiceCallResult
+	 */
+	public ServiceCallResult createServiceCallResult(
+			@Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort,
+			URI uri, HttpHeaders requestHeaders, @Nullable HttpHeaders responseHeaders,
+			@Nullable Integer statusCode, long delay, @Nullable Throwable exception) {
+
+		ServiceCallResult resultRequest = new ServiceCallResult();
+		resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
+		resultRequest.setService(StringUtils.isBlank(calleeServiceName) ? uri.getHost() : calleeServiceName);
+		resultRequest.setMethod(uri.getPath());
+		resultRequest.setRetCode(statusCode == null ? -1 : statusCode);
+		resultRequest.setDelay(delay);
+		resultRequest.setCallerService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE));
+		resultRequest.setCallerIp(this.context.getConfig().getGlobal().getAPI().getBindIP());
+		resultRequest.setHost(StringUtils.isBlank(calleeHost) ? uri.getHost() : calleeHost);
+		resultRequest.setPort(calleePort == null ? getPort(uri) : calleePort);
+		resultRequest.setLabels(getLabels(requestHeaders));
+		resultRequest.setRetStatus(getRetStatusFromRequest(responseHeaders, getDefaultRetStatus(statusCode, exception)));
+		resultRequest.setRuleName(getActiveRuleNameFromRequest(responseHeaders));
+		return resultRequest;
 	}
 
+	/**
+	 * createInstanceResourceStat.
+	 * @param calleeServiceName will pick up url host when null
+	 * @param calleeHost will pick up url host when null
+	 * @param calleePort will pick up url port when null
+	 * @param uri request url
+	 * @param statusCode response status
+	 * @param delay delay
+	 * @param exception exception
+	 * @return ResourceStat
+	 */
+	public ResourceStat createInstanceResourceStat(
+			@Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort,
+			URI uri, @Nullable Integer statusCode, long delay, @Nullable Throwable exception) {
+		ServiceKey calleeServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, StringUtils.isBlank(calleeServiceName) ? uri.getHost() : calleeServiceName);
+		ServiceKey callerServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE);
+		Resource resource = new InstanceResource(
+				calleeServiceKey,
+				StringUtils.isBlank(calleeHost) ? uri.getHost() : calleeHost,
+				calleePort == null ? getPort(uri) : calleePort,
+				callerServiceKey
+		);
+		return new ResourceStat(resource, statusCode == null ? -1 : statusCode, delay, getDefaultRetStatus(statusCode, exception));
+	}
+
+
 	/**
 	 * Convert items to List.
 	 *
@@ -116,4 +199,68 @@ public abstract class AbstractPolarisReporterAdapter {
 		// DEFAULT RETURN FALSE.
 		return false;
 	}
+
+	protected RetStatus getRetStatusFromRequest(HttpHeaders headers, RetStatus defaultVal) {
+		if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_CALLEE_RET_STATUS)) {
+			List<String> values = headers.get(HeaderConstant.INTERNAL_CALLEE_RET_STATUS);
+			if (CollectionUtils.isNotEmpty(values)) {
+				String retStatusVal = com.tencent.polaris.api.utils.StringUtils.defaultString(values.get(0));
+				if (Objects.equals(retStatusVal, RetStatus.RetFlowControl.getDesc())) {
+					return RetStatus.RetFlowControl;
+				}
+				if (Objects.equals(retStatusVal, RetStatus.RetReject.getDesc())) {
+					return RetStatus.RetReject;
+				}
+			}
+		}
+		return defaultVal;
+	}
+
+	protected String getActiveRuleNameFromRequest(HttpHeaders headers) {
+		if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME)) {
+			Collection<String> values = headers.get(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME);
+			if (CollectionUtils.isNotEmpty(values)) {
+				return com.tencent.polaris.api.utils.StringUtils.defaultString(new ArrayList<>(values).get(0));
+			}
+		}
+		return "";
+	}
+
+	private RetStatus getDefaultRetStatus(Integer statusCode, Throwable exception) {
+		RetStatus retStatus = RetStatus.RetSuccess;
+		if (exception != null) {
+			retStatus = RetStatus.RetFail;
+			if (exception instanceof SocketTimeoutException) {
+				retStatus = RetStatus.RetTimeout;
+			}
+		}
+		else if (statusCode == null || apply(HttpStatus.resolve(statusCode))) {
+			retStatus = RetStatus.RetFail;
+		}
+		return retStatus;
+	}
+
+	private int getPort(URI uri) {
+		// -1 means access directly by url, and use http default port number 80
+		return uri.getPort() == -1 ? 80 : uri.getPort();
+	}
+
+	private String getLabels(HttpHeaders headers) {
+		if (headers != null) {
+			Collection<String> labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER);
+			if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) {
+				String label = labels.iterator().next();
+				try {
+					label = URLDecoder.decode(label, UTF_8);
+				}
+				catch (UnsupportedEncodingException e) {
+					LOG.error("unsupported charset exception " + UTF_8, e);
+				}
+				return RequestLabelUtils.convertLabel(label);
+			}
+		}
+		return null;
+	}
+
+
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
index 53bd5f414..582292807 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
@@ -20,17 +20,26 @@ package com.tencent.cloud.rpc.enhancement.config;
 import java.util.Collections;
 import java.util.List;
 
+import com.netflix.zuul.ZuulFilter;
 import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
-import com.tencent.cloud.rpc.enhancement.feign.DefaultEnhancedFeignPluginRunner;
 import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor;
-import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignPluginRunner;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter;
+import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
 import com.tencent.cloud.rpc.enhancement.resttemplate.BlockingLoadBalancerClientAspect;
-import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateReporter;
+import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor;
+import com.tencent.cloud.rpc.enhancement.resttemplate.RibbonLoadBalancerClientAspect;
+import com.tencent.cloud.rpc.enhancement.scg.EnhancedGatewayGlobalFilter;
+import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientReporter;
+import com.tencent.cloud.rpc.enhancement.webclient.PolarisLoadBalancerClientRequestTransformer;
+import com.tencent.cloud.rpc.enhancement.zuul.EnhancedErrorZuulFilter;
+import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPostZuulFilter;
+import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPreZuulFilter;
 import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.client.api.SDKContext;
 
 import org.springframework.beans.factory.SmartInitializingSingleton;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,7 +55,9 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.context.annotation.Role;
+import org.springframework.core.env.Environment;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
 
 /**
  * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call
@@ -61,6 +72,26 @@ import org.springframework.web.client.RestTemplate;
 @AutoConfigureAfter(PolarisContextAutoConfiguration.class)
 public class RpcEnhancementAutoConfiguration {
 
+	@Bean
+	public EnhancedPluginRunner enhancedFeignPluginRunner(
+			@Autowired(required = false) List<EnhancedPlugin> enhancedPlugins) {
+		return new DefaultEnhancedPluginRunner(enhancedPlugins);
+	}
+
+	@Bean
+	public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties,
+			SDKContext context,
+			ConsumerAPI consumerAPI) {
+		return new SuccessPolarisReporter(properties, context, consumerAPI);
+	}
+
+	@Bean
+	public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties,
+			SDKContext context,
+			ConsumerAPI consumerAPI) {
+		return new ExceptionPolarisReporter(properties, context, consumerAPI);
+	}
+
 	/**
 	 * Configuration for Polaris {@link feign.Feign} which can automatically bring in the call
 	 * results for reporting.
@@ -74,31 +105,10 @@ public class RpcEnhancementAutoConfiguration {
 	protected static class PolarisFeignClientAutoConfiguration {
 
 		@Bean
-		public EnhancedFeignPluginRunner enhancedFeignPluginRunner(
-				@Autowired(required = false) List<EnhancedFeignPlugin> enhancedFeignPlugins) {
-			return new DefaultEnhancedFeignPluginRunner(enhancedFeignPlugins);
-		}
-
-		@Bean
-		public EnhancedFeignBeanPostProcessor polarisFeignBeanPostProcessor(@Lazy EnhancedFeignPluginRunner pluginRunner) {
+		public EnhancedFeignBeanPostProcessor polarisFeignBeanPostProcessor(@Lazy EnhancedPluginRunner pluginRunner) {
 			return new EnhancedFeignBeanPostProcessor(pluginRunner);
 		}
 
-		@Configuration
-		static class PolarisReporterConfig {
-
-			@Bean
-			public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties,
-																@Autowired(required = false) ConsumerAPI consumerAPI) {
-				return new SuccessPolarisReporter(properties, consumerAPI);
-			}
-
-			@Bean
-			public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties,
-																	@Autowired(required = false) ConsumerAPI consumerAPI) {
-				return new ExceptionPolarisReporter(properties, consumerAPI);
-			}
-		}
 	}
 
 	/**
@@ -116,16 +126,15 @@ public class RpcEnhancementAutoConfiguration {
 		private List<RestTemplate> restTemplates = Collections.emptyList();
 
 		@Bean
-		public EnhancedRestTemplateReporter enhancedRestTemplateReporter(
-				RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI) {
-			return new EnhancedRestTemplateReporter(properties, consumerAPI);
+		public EnhancedRestTemplateInterceptor enhancedPolarisRestTemplateReporter(@Lazy EnhancedPluginRunner pluginRunner) {
+			return new EnhancedRestTemplateInterceptor(pluginRunner);
 		}
 
 		@Bean
-		public SmartInitializingSingleton setErrorHandlerForRestTemplate(EnhancedRestTemplateReporter reporter) {
+		public SmartInitializingSingleton setPolarisReporterForRestTemplate(EnhancedRestTemplateInterceptor reporter) {
 			return () -> {
 				for (RestTemplate restTemplate : restTemplates) {
-					restTemplate.setErrorHandler(reporter);
+					restTemplate.getInterceptors().add(reporter);
 				}
 			};
 		}
@@ -136,5 +145,84 @@ public class RpcEnhancementAutoConfiguration {
 		public BlockingLoadBalancerClientAspect blockingLoadBalancerClientAspect() {
 			return new BlockingLoadBalancerClientAspect();
 		}
+
+		@Bean
+		@ConditionalOnMissingBean
+		@ConditionalOnClass(name = {"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"})
+		public RibbonLoadBalancerClientAspect ribbonLoadBalancerClientAspect() {
+			return new RibbonLoadBalancerClientAspect();
+		}
+	}
+
+	/**
+	 * Configuration for Polaris {@link org.springframework.web.reactive.function.client.WebClient} which can automatically bring in the call
+	 * results for reporting.
+	 */
+	@Configuration(proxyBeanMethods = false)
+	@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
+	protected static class PolarisWebClientAutoConfiguration {
+
+		@Autowired(required = false)
+		private List<WebClient.Builder> webClientBuilder = Collections.emptyList();
+
+		@Bean
+		public EnhancedWebClientReporter exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) {
+			return new EnhancedWebClientReporter(pluginRunner);
+		}
+
+		@Bean
+		public SmartInitializingSingleton addEnhancedWebClientReporterForWebClient(EnhancedWebClientReporter reporter) {
+			return () -> webClientBuilder.forEach(webClient -> {
+				webClient.filter(reporter);
+			});
+		}
+
+		@Bean
+		@ConditionalOnMissingBean
+		@ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer")
+		public PolarisLoadBalancerClientRequestTransformer polarisLoadBalancerClientRequestTransformer() {
+			return new PolarisLoadBalancerClientRequestTransformer();
+		}
+
+	}
+
+	/**
+	 * Configuration for Polaris {@link org.springframework.web.reactive.function.client.WebClient} which can automatically bring in the call
+	 * results for reporting.
+	 */
+	@Configuration(proxyBeanMethods = false)
+	@ConditionalOnClass(name = "org.springframework.cloud.gateway.config.GatewayAutoConfiguration")
+	@Role(RootBeanDefinition.ROLE_INFRASTRUCTURE)
+	protected static class PolarisGatewayAutoConfiguration {
+
+		@Bean
+		@ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.GlobalFilter")
+		public EnhancedGatewayGlobalFilter enhancedPolarisGatewayReporter(@Lazy EnhancedPluginRunner pluginRunner) {
+			return new EnhancedGatewayGlobalFilter(pluginRunner);
+		}
+
+	}
+
+	/**
+	 * Configuration for Polaris {@link ZuulFilter} which can automatically bring in the call
+	 * results for reporting.
+	 */
+	@Configuration(proxyBeanMethods = false)
+	@ConditionalOnClass(name = "com.netflix.zuul.http.ZuulServlet")
+	protected static class PolarisCircuitBreakerZuulFilterConfig {
+		@Bean
+		public EnhancedPreZuulFilter enhancedZuulPreFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) {
+			return new EnhancedPreZuulFilter(pluginRunner, environment);
+		}
+
+		@Bean
+		public EnhancedPostZuulFilter enhancedZuulPostFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) {
+			return new EnhancedPostZuulFilter(pluginRunner, environment);
+		}
+
+		@Bean
+		public EnhancedErrorZuulFilter enhancedErrorZuulFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) {
+			return new EnhancedErrorZuulFilter(pluginRunner, environment);
+		}
 	}
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java
index fc51b31c6..8bfaf9b9e 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java
@@ -35,7 +35,7 @@ public class RpcEnhancementReporterProperties {
 	/**
 	 * Whether report call result to polaris.
 	 */
-	private boolean enabled;
+	private boolean enabled = true;
 
 	/**
 	 * Specify the Http status code(s) that needs to be reported as FAILED.
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java
index b415172ad..3e0fedd0f 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java
@@ -17,6 +17,7 @@
 
 package com.tencent.cloud.rpc.enhancement.feign;
 
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
 import feign.Client;
 
 import org.springframework.beans.BeansException;
@@ -26,6 +27,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
 import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
 import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
+import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient;
 import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
 import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
 import org.springframework.lang.NonNull;
@@ -37,11 +39,11 @@ import org.springframework.lang.NonNull;
  */
 public class EnhancedFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
 
-	private EnhancedFeignPluginRunner pluginRunner;
+	private final EnhancedPluginRunner pluginRunner;
 
 	private BeanFactory factory;
 
-	public EnhancedFeignBeanPostProcessor(EnhancedFeignPluginRunner pluginRunner) {
+	public EnhancedFeignBeanPostProcessor(EnhancedPluginRunner pluginRunner) {
 		this.pluginRunner = pluginRunner;
 	}
 
@@ -59,11 +61,19 @@ public class EnhancedFeignBeanPostProcessor implements BeanPostProcessor, BeanFa
 						factory(),
 						clientFactory());
 			}
-			if (bean instanceof FeignBlockingLoadBalancerClient) {
-				FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean;
-				return new EnhancedFeignBlockingLoadBalancerClient(
-						createPolarisFeignClient(client.getDelegate()),
-						factory.getBean(BlockingLoadBalancerClient.class));
+			if (bean instanceof RetryableFeignBlockingLoadBalancerClient
+					|| bean instanceof FeignBlockingLoadBalancerClient) {
+				Client delegate;
+				if (bean instanceof RetryableFeignBlockingLoadBalancerClient) {
+					delegate = ((RetryableFeignBlockingLoadBalancerClient) bean).getDelegate();
+				}
+				else {
+					delegate = ((FeignBlockingLoadBalancerClient) bean).getDelegate();
+				}
+				if (delegate != null) {
+					return new EnhancedFeignBlockingLoadBalancerClient(createPolarisFeignClient(delegate),
+							factory.getBean(BlockingLoadBalancerClient.class));
+				}
 			}
 			return createPolarisFeignClient((Client) bean);
 		}
@@ -81,7 +91,7 @@ public class EnhancedFeignBeanPostProcessor implements BeanPostProcessor, BeanFa
 	}
 
 	@Override
-	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+	public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
 		this.factory = beanFactory;
 	}
 
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java
index 4bdf14eff..e191edfde 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java
@@ -18,17 +18,26 @@
 package com.tencent.cloud.rpc.enhancement.feign;
 
 import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
 
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
 import feign.Client;
 import feign.Request;
 import feign.Request.Options;
 import feign.Response;
 
-import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.EXCEPTION;
-import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.FINALLY;
-import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.POST;
-import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.PRE;
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE;
 import static feign.Util.checkNotNull;
 
 /**
@@ -40,38 +49,64 @@ public class EnhancedFeignClient implements Client {
 
 	private final Client delegate;
 
-	private EnhancedFeignPluginRunner pluginRunner;
+	private final EnhancedPluginRunner pluginRunner;
 
-	public EnhancedFeignClient(Client target, EnhancedFeignPluginRunner pluginRunner) {
+	public EnhancedFeignClient(Client target, EnhancedPluginRunner pluginRunner) {
 		this.delegate = checkNotNull(target, "target");
 		this.pluginRunner = pluginRunner;
 	}
 
 	@Override
 	public Response execute(Request request, Options options) throws IOException {
-		EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext();
-		enhancedFeignContext.setRequest(request);
-		enhancedFeignContext.setOptions(options);
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+
+		HttpHeaders requestHeaders = new HttpHeaders();
+		request.headers().forEach((s, strings) -> requestHeaders.addAll(s, new ArrayList<>(strings)));
+		URI url = URI.create(request.url());
+
+		EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
+				.httpHeaders(requestHeaders)
+				.httpMethod(HttpMethod.resolve(request.httpMethod().name()))
+				.url(url)
+				.build();
+		enhancedPluginContext.setRequest(enhancedRequestContext);
 
-		// Run pre enhanced feign plugins.
-		pluginRunner.run(PRE, enhancedFeignContext);
+		// Run pre enhanced plugins.
+		pluginRunner.run(PRE, enhancedPluginContext);
+		long startMillis = System.currentTimeMillis();
 		try {
 			Response response = delegate.execute(request, options);
-			enhancedFeignContext.setResponse(response);
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis);
+
+			HttpHeaders responseHeaders = new HttpHeaders();
+			response.headers().forEach((s, strings) -> responseHeaders.addAll(s, new ArrayList<>(strings)));
+
+			EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+					.httpStatus(response.status())
+					.httpHeaders(responseHeaders)
+					.build();
+			enhancedPluginContext.setResponse(enhancedResponseContext);
+
+			DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+			serviceInstance.setServiceId(request.requestTemplate().feignTarget().name());
+			serviceInstance.setHost(url.getHost());
+			serviceInstance.setPort(url.getPort());
+			enhancedPluginContext.setServiceInstance(serviceInstance);
 
-			// Run post enhanced feign plugins.
-			pluginRunner.run(POST, enhancedFeignContext);
+			// Run post enhanced plugins.
+			pluginRunner.run(POST, enhancedPluginContext);
 			return response;
 		}
 		catch (IOException origin) {
-			enhancedFeignContext.setException(origin);
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis);
+			enhancedPluginContext.setThrowable(origin);
 			// Run exception enhanced feign plugins.
-			pluginRunner.run(EXCEPTION, enhancedFeignContext);
+			pluginRunner.run(EXCEPTION, enhancedPluginContext);
 			throw origin;
 		}
 		finally {
-			// Run finally enhanced feign plugins.
-			pluginRunner.run(FINALLY, enhancedFeignContext);
+			// Run finally enhanced plugins.
+			pluginRunner.run(FINALLY, enhancedPluginContext);
 		}
 	}
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java
deleted file mode 100644
index e6f3be612..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin;
-
-import feign.Request;
-import feign.Response;
-
-/**
- * Context used by EnhancedFeignPlugin.
- *
- * @author Haotian Zhang
- */
-public class EnhancedFeignContext {
-
-	private Request request;
-
-	private Request.Options options;
-
-	private Response response;
-
-	private Exception exception;
-
-	public Request getRequest() {
-		return request;
-	}
-
-	public void setRequest(Request request) {
-		this.request = request;
-	}
-
-	public Request.Options getOptions() {
-		return options;
-	}
-
-	public void setOptions(Request.Options options) {
-		this.options = options;
-	}
-
-	public Response getResponse() {
-		return response;
-	}
-
-	public void setResponse(Response response) {
-		this.response = response;
-	}
-
-	public Exception getException() {
-		return exception;
-	}
-
-	public void setException(Exception exception) {
-		this.exception = exception;
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java
deleted file mode 100644
index 0e1b2c87a..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin.reporter;
-
-import java.net.SocketTimeoutException;
-
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import feign.Request;
-import feign.Response;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.core.Ordered;
-
-/**
- * Polaris reporter when feign call fails.
- *
- * @author Haotian Zhang
- */
-public class ExceptionPolarisReporter implements EnhancedFeignPlugin {
-
-	private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class);
-	private final RpcEnhancementReporterProperties reporterProperties;
-
-	private final ConsumerAPI consumerAPI;
-
-	public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties,
-									ConsumerAPI consumerAPI) {
-		this.reporterProperties = reporterProperties;
-		this.consumerAPI = consumerAPI;
-	}
-
-	@Override
-	public String getName() {
-		return ExceptionPolarisReporter.class.getName();
-	}
-
-	@Override
-	public EnhancedFeignPluginType getType() {
-		return EnhancedFeignPluginType.EXCEPTION;
-	}
-
-	@Override
-	public void run(EnhancedFeignContext context) {
-		if (!reporterProperties.isEnabled()) {
-			return;
-		}
-
-		if (consumerAPI != null) {
-			Request request = context.getRequest();
-			Response response = context.getResponse();
-			Exception exception = context.getException();
-			RetStatus retStatus = RetStatus.RetFail;
-			if (exception instanceof SocketTimeoutException) {
-				retStatus = RetStatus.RetTimeout;
-			}
-			LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", retStatus.name(), request, response);
-			ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus);
-			consumerAPI.updateServiceCallResult(resultRequest);
-			// update result without method for service circuit break.
-			resultRequest.setMethod("");
-			consumerAPI.updateServiceCallResult(resultRequest);
-		}
-	}
-
-	@Override
-	public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
-		Request request = context.getRequest();
-		Response response = context.getResponse();
-		LOG.error("ExceptionPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable);
-	}
-
-	@Override
-	public int getOrder() {
-		return Ordered.HIGHEST_PRECEDENCE + 1;
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java
deleted file mode 100644
index b1d15f532..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtils.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin.reporter;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.util.Collection;
-
-import com.tencent.cloud.common.constant.RouterConstant;
-import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.pojo.ServiceKey;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import com.tencent.polaris.api.utils.CollectionUtils;
-import feign.Request;
-import feign.RequestTemplate;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
-
-/**
- * Util for polaris reporter.
- *
- * @author Haotian Zhang
- */
-public final class ReporterUtils {
-
-	private static final Logger LOGGER = LoggerFactory.getLogger(ReporterUtils.class);
-
-	private ReporterUtils() {
-	}
-
-	public static ServiceCallResult createServiceCallResult(final Request request, RetStatus retStatus) {
-		ServiceCallResult resultRequest = new ServiceCallResult();
-
-		resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
-		RequestTemplate requestTemplate = request.requestTemplate();
-		String serviceName = requestTemplate.feignTarget().name();
-		Collection<String> labels = requestTemplate.headers().get(RouterConstant.ROUTER_LABEL_HEADER);
-		if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) {
-			String label = labels.iterator().next();
-			try {
-				label = URLDecoder.decode(label, UTF_8);
-			}
-			catch (UnsupportedEncodingException e) {
-				LOGGER.error("unsupported charset exception " + UTF_8, e);
-			}
-			resultRequest.setLabels(convertLabel(label));
-		}
-		resultRequest.setService(serviceName);
-		URI uri = URI.create(request.url());
-		resultRequest.setMethod(uri.getPath());
-		resultRequest.setRetStatus(retStatus);
-		String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
-		String sourceService = MetadataContext.LOCAL_SERVICE;
-		if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
-			resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
-		}
-		resultRequest.setHost(uri.getHost());
-		// -1 means access directly by url, and use http default port number 80
-		resultRequest.setPort(uri.getPort() == -1 ? 80 : uri.getPort());
-		return resultRequest;
-	}
-
-	private static String convertLabel(String label) {
-		label = label.replaceAll("\"|\\{|\\}", "")
-				.replaceAll(",", "|");
-		return label;
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java
deleted file mode 100644
index 2fefd6dcf..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin.reporter;
-
-import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import feign.Request;
-import feign.Response;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.core.Ordered;
-import org.springframework.http.HttpStatus;
-
-/**
- * Polaris reporter when feign call is successful.
- *
- * @author Haotian Zhang
- */
-public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedFeignPlugin {
-
-	private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class);
-
-	private final ConsumerAPI consumerAPI;
-
-	public SuccessPolarisReporter(RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI) {
-		super(properties);
-		this.consumerAPI = consumerAPI;
-	}
-
-	@Override
-	public String getName() {
-		return SuccessPolarisReporter.class.getName();
-	}
-
-	@Override
-	public EnhancedFeignPluginType getType() {
-		return EnhancedFeignPluginType.POST;
-	}
-
-	@Override
-	public void run(EnhancedFeignContext context) {
-		if (!reportProperties.isEnabled()) {
-			return;
-		}
-
-		if (consumerAPI != null) {
-			Request request = context.getRequest();
-			Response response = context.getResponse();
-			RetStatus retStatus = RetStatus.RetSuccess;
-			if (apply(HttpStatus.resolve(response.status()))) {
-				retStatus = RetStatus.RetFail;
-			}
-			LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].", retStatus.name(), request, response);
-			ServiceCallResult resultRequest = ReporterUtils.createServiceCallResult(request, retStatus);
-			consumerAPI.updateServiceCallResult(resultRequest);
-			// update result without method for service circuit break.
-			resultRequest.setMethod("");
-			consumerAPI.updateServiceCallResult(resultRequest);
-		}
-	}
-
-	@Override
-	public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
-		Request request = context.getRequest();
-		Response response = context.getResponse();
-		LOG.error("SuccessPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable);
-	}
-
-	@Override
-	public int getOrder() {
-		return Ordered.HIGHEST_PRECEDENCE + 1;
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java
similarity index 61%
rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java
rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java
index dbaf7d580..ca34b2af1 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java
@@ -16,16 +16,13 @@
  *
  */
 
-package com.tencent.cloud.rpc.enhancement.feign;
+package com.tencent.cloud.rpc.enhancement.plugin;
 
 import java.util.Comparator;
 import java.util.List;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
 
 import org.springframework.util.CollectionUtils;
 
@@ -34,14 +31,14 @@ import org.springframework.util.CollectionUtils;
  *
  * @author Derek Yi 2022-08-16
  */
-public class DefaultEnhancedFeignPluginRunner implements EnhancedFeignPluginRunner {
+public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner {
 
-	private final Multimap<String, EnhancedFeignPlugin> pluginMap = ArrayListMultimap.create();
+	private final Multimap<String, EnhancedPlugin> pluginMap = ArrayListMultimap.create();
 
-	public DefaultEnhancedFeignPluginRunner(List<EnhancedFeignPlugin> enhancedFeignPlugins) {
-		if (!CollectionUtils.isEmpty(enhancedFeignPlugins)) {
-			enhancedFeignPlugins.stream()
-					.sorted(Comparator.comparing(EnhancedFeignPlugin::getOrder))
+	public DefaultEnhancedPluginRunner(List<EnhancedPlugin> enhancedPlugins) {
+		if (!CollectionUtils.isEmpty(enhancedPlugins)) {
+			enhancedPlugins.stream()
+					.sorted(Comparator.comparing(EnhancedPlugin::getOrder))
 					.forEach(plugin -> pluginMap.put(plugin.getType().name(), plugin));
 		}
 	}
@@ -53,8 +50,8 @@ public class DefaultEnhancedFeignPluginRunner implements EnhancedFeignPluginRunn
 	 * @param context context in enhanced feign client.
 	 */
 	@Override
-	public void run(EnhancedFeignPluginType pluginType, EnhancedFeignContext context) {
-		for (EnhancedFeignPlugin plugin : pluginMap.get(pluginType.name())) {
+	public void run(EnhancedPluginType pluginType, EnhancedPluginContext context) {
+		for (EnhancedPlugin plugin : pluginMap.get(pluginType.name())) {
 			try {
 				plugin.run(context);
 			}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java
similarity index 75%
rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java
rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java
index 1ecc3d355..39bce26a3 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java
@@ -15,7 +15,7 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.rpc.enhancement.feign.plugin;
+package com.tencent.cloud.rpc.enhancement.plugin;
 
 import org.springframework.core.Ordered;
 
@@ -24,7 +24,7 @@ import org.springframework.core.Ordered;
  *
  * @author Haotian Zhang
  */
-public interface EnhancedFeignPlugin extends Ordered {
+public interface EnhancedPlugin extends Ordered {
 
 	/**
 	 * Get name of plugin.
@@ -38,9 +38,9 @@ public interface EnhancedFeignPlugin extends Ordered {
 	/**
 	 * Get type of plugin.
 	 *
-	 * @return {@link EnhancedFeignPluginType}
+	 * @return {@link EnhancedPluginType}
 	 */
-	EnhancedFeignPluginType getType();
+	EnhancedPluginType getType();
 
 	/**
 	 * Run the plugin.
@@ -48,15 +48,15 @@ public interface EnhancedFeignPlugin extends Ordered {
 	 * @param context context in enhanced feign client.
 	 * @throws Throwable throwable thrown from run method.
 	 */
-	void run(EnhancedFeignContext context) throws Throwable;
+	void run(EnhancedPluginContext context) throws Throwable;
 
 	/**
-	 * Handler throwable from {@link EnhancedFeignPlugin#run(EnhancedFeignContext)}.
+	 * Handler throwable from {@link EnhancedPlugin#run(EnhancedPluginContext)}.
 	 *
 	 * @param context context in enhanced feign client.
 	 * @param throwable throwable thrown from run method.
 	 */
-	default void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
+	default void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
 
 	}
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java
new file mode 100644
index 000000000..fa4e891d0
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java
@@ -0,0 +1,90 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+
+import org.springframework.cloud.client.ServiceInstance;
+
+/**
+ * Context used by EnhancedPlugin.
+ *
+ * @author Haotian Zhang
+ */
+public class EnhancedPluginContext {
+
+	private EnhancedRequestContext request;
+
+	private EnhancedResponseContext response;
+
+	private Throwable throwable;
+
+	private long delay;
+
+	private ServiceInstance serviceInstance;
+
+	public EnhancedRequestContext getRequest() {
+		return request;
+	}
+
+	public void setRequest(EnhancedRequestContext request) {
+		this.request = request;
+	}
+
+	public EnhancedResponseContext getResponse() {
+		return response;
+	}
+
+	public void setResponse(EnhancedResponseContext response) {
+		this.response = response;
+	}
+
+	public Throwable getThrowable() {
+		return throwable;
+	}
+
+	public void setThrowable(Throwable throwable) {
+		this.throwable = throwable;
+	}
+
+	public long getDelay() {
+		return delay;
+	}
+
+	public void setDelay(long delay) {
+		this.delay = delay;
+	}
+
+	public ServiceInstance getServiceInstance() {
+		return serviceInstance;
+	}
+
+	public void setServiceInstance(ServiceInstance serviceInstance) {
+		this.serviceInstance = serviceInstance;
+	}
+
+	@Override
+	public String toString() {
+		return "EnhancedPluginContext{" +
+				"request=" + request +
+				", response=" + response +
+				", throwable=" + throwable +
+				", delay=" + delay +
+				", serviceInstance=" + serviceInstance +
+				'}';
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java
similarity index 73%
rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java
rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java
index b821827b2..e15af39e5 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java
@@ -16,17 +16,14 @@
  *
  */
 
-package com.tencent.cloud.rpc.enhancement.feign;
-
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
+package com.tencent.cloud.rpc.enhancement.plugin;
 
 /**
  * Plugin runner.
  *
  * @author Derek Yi 2022-08-16
  */
-public interface EnhancedFeignPluginRunner {
+public interface EnhancedPluginRunner {
 
 	/**
 	 * run the plugin.
@@ -34,5 +31,5 @@ public interface EnhancedFeignPluginRunner {
 	 * @param pluginType type of plugin
 	 * @param context context in enhanced feign client.
 	 */
-	void run(EnhancedFeignPluginType pluginType, EnhancedFeignContext context);
+	void run(EnhancedPluginType pluginType, EnhancedPluginContext context);
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java
similarity index 88%
rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java
rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java
index fef181d83..64dc2ecb9 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java
@@ -15,14 +15,14 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.rpc.enhancement.feign.plugin;
+package com.tencent.cloud.rpc.enhancement.plugin;
 
 /**
- * Type of EnhancedFeignPlugin.
+ * Type of EnhancedPlugin.
  *
  * @author Haotian Zhang
  */
-public enum EnhancedFeignPluginType {
+public enum EnhancedPluginType {
 
 	/**
 	 * Pre feign plugin.
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java
new file mode 100644
index 000000000..74c9aff63
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java
@@ -0,0 +1,107 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+import java.net.URI;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+/**
+ * EnhancedRequestContext.
+ *
+ * @author sean yu
+ */
+public class EnhancedRequestContext {
+
+	private HttpMethod httpMethod;
+
+	private HttpHeaders httpHeaders;
+
+	private URI url;
+
+	public HttpMethod getHttpMethod() {
+		return httpMethod;
+	}
+
+	public void setHttpMethod(HttpMethod httpMethod) {
+		this.httpMethod = httpMethod;
+	}
+
+	public HttpHeaders getHttpHeaders() {
+		return httpHeaders;
+	}
+
+	public void setHttpHeaders(HttpHeaders httpHeaders) {
+		this.httpHeaders = httpHeaders;
+	}
+
+	public URI getUrl() {
+		return url;
+	}
+
+	public void setUrl(URI url) {
+		this.url = url;
+	}
+
+	public static EnhancedContextRequestBuilder builder() {
+		return new EnhancedContextRequestBuilder();
+	}
+
+	@Override
+	public String toString() {
+		return "EnhancedRequestContext{" +
+				"httpMethod=" + httpMethod +
+				", httpHeaders=" + httpHeaders +
+				", url=" + url +
+				'}';
+	}
+
+	public static final class EnhancedContextRequestBuilder {
+		private HttpMethod httpMethod;
+		private HttpHeaders httpHeaders;
+		private URI url;
+
+		private EnhancedContextRequestBuilder() {
+		}
+
+		public EnhancedContextRequestBuilder httpMethod(HttpMethod httpMethod) {
+			this.httpMethod = httpMethod;
+			return this;
+		}
+
+		public EnhancedContextRequestBuilder httpHeaders(HttpHeaders httpHeaders) {
+			this.httpHeaders = httpHeaders;
+			return this;
+		}
+
+		public EnhancedContextRequestBuilder url(URI url) {
+			this.url = url;
+			return this;
+		}
+
+		public EnhancedRequestContext build() {
+			EnhancedRequestContext enhancedRequestContext = new EnhancedRequestContext();
+			enhancedRequestContext.httpMethod = this.httpMethod;
+			enhancedRequestContext.url = this.url;
+			enhancedRequestContext.httpHeaders = this.httpHeaders;
+			return enhancedRequestContext;
+		}
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java
new file mode 100644
index 000000000..c8773776a
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java
@@ -0,0 +1,86 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+import org.springframework.http.HttpHeaders;
+
+/**
+ * EnhancedResponseContext.
+ *
+ * @author sean yu
+ */
+public class EnhancedResponseContext {
+
+	private Integer httpStatus;
+
+	private HttpHeaders httpHeaders;
+
+	public Integer getHttpStatus() {
+		return httpStatus;
+	}
+
+	public void setHttpStatus(Integer httpStatus) {
+		this.httpStatus = httpStatus;
+	}
+
+	public HttpHeaders getHttpHeaders() {
+		return httpHeaders;
+	}
+
+	public void setHttpHeaders(HttpHeaders httpHeaders) {
+		this.httpHeaders = httpHeaders;
+	}
+
+	public static EnhancedContextResponseBuilder builder() {
+		return new EnhancedContextResponseBuilder();
+	}
+
+	@Override
+	public String toString() {
+		return "EnhancedResponseContext{" +
+				"httpStatus=" + httpStatus +
+				", httpHeaders=" + httpHeaders +
+				'}';
+	}
+
+	public static final class EnhancedContextResponseBuilder {
+		private Integer httpStatus;
+		private HttpHeaders httpHeaders;
+
+		private EnhancedContextResponseBuilder() {
+		}
+
+		public EnhancedContextResponseBuilder httpStatus(Integer httpStatus) {
+			this.httpStatus = httpStatus;
+			return this;
+		}
+
+		public EnhancedContextResponseBuilder httpHeaders(HttpHeaders httpHeaders) {
+			this.httpHeaders = httpHeaders;
+			return this;
+		}
+
+		public EnhancedResponseContext build() {
+			EnhancedResponseContext enhancedResponseContext = new EnhancedResponseContext();
+			enhancedResponseContext.setHttpStatus(httpStatus);
+			enhancedResponseContext.setHttpHeaders(httpHeaders);
+			return enhancedResponseContext;
+		}
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java
new file mode 100644
index 000000000..76c4250b3
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.rpc.enhancement.plugin.reporter;
+
+
+import java.util.Optional;
+
+import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.client.api.SDKContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.core.Ordered;
+
+/**
+ * Polaris reporter when feign call fails.
+ *
+ * @author Haotian Zhang
+ */
+public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class);
+
+	private final ConsumerAPI consumerAPI;
+
+	public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties,
+			SDKContext context,
+			ConsumerAPI consumerAPI) {
+		super(reporterProperties, context);
+		this.consumerAPI = consumerAPI;
+	}
+
+	@Override
+	public String getName() {
+		return ExceptionPolarisReporter.class.getName();
+	}
+
+	@Override
+	public EnhancedPluginType getType() {
+		return EnhancedPluginType.EXCEPTION;
+	}
+
+	@Override
+	public void run(EnhancedPluginContext context) {
+		if (!super.reportProperties.isEnabled()) {
+			return;
+		}
+
+		EnhancedRequestContext request = context.getRequest();
+		ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance());
+
+		ServiceCallResult resultRequest = createServiceCallResult(
+				serviceInstance.getServiceId(),
+				serviceInstance.getHost(),
+				serviceInstance.getPort(),
+				request.getUrl(),
+				request.getHttpHeaders(),
+				null,
+				null,
+				context.getDelay(),
+				context.getThrowable()
+		);
+
+		LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
+				resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay());
+
+		consumerAPI.updateServiceCallResult(resultRequest);
+
+	}
+
+	@Override
+	public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
+		LOG.error("ExceptionPolarisReporter runs failed. context=[{}].",
+				context, throwable);
+	}
+
+	@Override
+	public int getOrder() {
+		return Ordered.HIGHEST_PRECEDENCE + 1;
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java
new file mode 100644
index 000000000..4b35396da
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.rpc.enhancement.plugin.reporter;
+
+import java.util.Optional;
+
+import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.client.api.SDKContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.core.Ordered;
+
+/**
+ * Polaris reporter when feign call is successful.
+ *
+ * @author Haotian Zhang
+ */
+public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin {
+
+	private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class);
+
+	private final ConsumerAPI consumerAPI;
+
+	public SuccessPolarisReporter(RpcEnhancementReporterProperties properties,
+			SDKContext context,
+			ConsumerAPI consumerAPI) {
+		super(properties, context);
+		this.consumerAPI = consumerAPI;
+	}
+
+	@Override
+	public String getName() {
+		return SuccessPolarisReporter.class.getName();
+	}
+
+	@Override
+	public EnhancedPluginType getType() {
+		return EnhancedPluginType.POST;
+	}
+
+	@Override
+	public void run(EnhancedPluginContext context) {
+		if (!super.reportProperties.isEnabled()) {
+			return;
+		}
+
+		EnhancedRequestContext request = context.getRequest();
+		EnhancedResponseContext response = context.getResponse();
+		ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance());
+
+		ServiceCallResult resultRequest = createServiceCallResult(
+				serviceInstance.getServiceId(),
+				serviceInstance.getHost(),
+				serviceInstance.getPort(),
+				request.getUrl(),
+				request.getHttpHeaders(),
+				response.getHttpHeaders(),
+				response.getHttpStatus(),
+				context.getDelay(),
+				null
+		);
+
+		LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.",
+				resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay());
+
+		consumerAPI.updateServiceCallResult(resultRequest);
+
+	}
+
+	@Override
+	public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
+		LOG.error("SuccessPolarisReporter runs failed. context=[{}].",
+				context, throwable);
+	}
+
+	@Override
+	public int getOrder() {
+		return Ordered.HIGHEST_PRECEDENCE + 1;
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java
new file mode 100644
index 000000000..e67e241f2
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java
@@ -0,0 +1,105 @@
+/*
+ * 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.rpc.enhancement.resttemplate;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE;
+
+/**
+ * EnhancedRestTemplateInterceptor.
+ *
+ * @author sean yu
+ */
+public class EnhancedRestTemplateInterceptor implements ClientHttpRequestInterceptor {
+
+	private final EnhancedPluginRunner pluginRunner;
+
+	public EnhancedRestTemplateInterceptor(EnhancedPluginRunner pluginRunner) {
+		this.pluginRunner = pluginRunner;
+	}
+
+	@Override
+	public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
+
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+
+		EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
+				.httpHeaders(request.getHeaders())
+				.httpMethod(request.getMethod())
+				.url(request.getURI())
+				.build();
+		enhancedPluginContext.setRequest(enhancedRequestContext);
+
+		// Run pre enhanced plugins.
+		pluginRunner.run(PRE, enhancedPluginContext);
+		long startMillis = System.currentTimeMillis();
+		try {
+			ClientHttpResponse response = execution.execute(request, body);
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis);
+
+			EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+					.httpStatus(response.getRawStatusCode())
+					.httpHeaders(response.getHeaders())
+					.build();
+			enhancedPluginContext.setResponse(enhancedResponseContext);
+
+			Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
+			DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+			serviceInstance.setServiceId(request.getURI().getHost());
+			serviceInstance.setHost(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST));
+			if (loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT) != null) {
+				serviceInstance.setPort(Integer.parseInt(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)));
+			}
+			enhancedPluginContext.setServiceInstance(serviceInstance);
+
+			// Run post enhanced plugins.
+			pluginRunner.run(POST, enhancedPluginContext);
+			return response;
+		}
+		catch (IOException e) {
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis);
+			enhancedPluginContext.setThrowable(e);
+			// Run exception enhanced plugins.
+			pluginRunner.run(EXCEPTION, enhancedPluginContext);
+			throw e;
+		}
+		finally {
+			// Run finally enhanced plugins.
+			pluginRunner.run(FINALLY, enhancedPluginContext);
+		}
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java
deleted file mode 100644
index df1ec9907..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * 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.rpc.enhancement.resttemplate;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.util.List;
-import java.util.Map;
-
-import com.tencent.cloud.common.constant.RouterConstant;
-import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.metadata.MetadataContextHolder;
-import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.pojo.ServiceKey;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import com.tencent.polaris.api.utils.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.lang.NonNull;
-import org.springframework.web.client.DefaultResponseErrorHandler;
-import org.springframework.web.client.ResponseErrorHandler;
-
-import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
-
-/**
- * Extend ResponseErrorHandler to get request information.
- *
- * @author wh 2022/6/21
- */
-public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter implements ResponseErrorHandler, ApplicationContextAware {
-
-	static final String HEADER_HAS_ERROR = "X-SCT-Has-Error";
-	private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedRestTemplateReporter.class);
-	private final ConsumerAPI consumerAPI;
-	private ResponseErrorHandler delegateHandler;
-
-	public EnhancedRestTemplateReporter(RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI) {
-		super(properties);
-		this.consumerAPI = consumerAPI;
-	}
-
-	@Override
-	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-		String[] handlerBeanNames = applicationContext.getBeanNamesForType(ResponseErrorHandler.class);
-		if (handlerBeanNames.length == 1) {
-			if (this.delegateHandler == null) {
-				this.delegateHandler = new DefaultResponseErrorHandler();
-			}
-			return;
-		}
-
-		// inject user custom ResponseErrorHandler
-		for (String beanName : handlerBeanNames) {
-			// ignore self
-			if (StringUtils.equalsIgnoreCase("enhancedRestTemplateReporter", beanName)) {
-				continue;
-			}
-			this.delegateHandler = (ResponseErrorHandler) applicationContext.getBean(beanName);
-		}
-	}
-
-	@Override
-	public boolean hasError(@NonNull ClientHttpResponse response) throws IOException {
-		if (delegateHandler != null) {
-			// Preserve the delegated handler result
-			boolean hasError = delegateHandler.hasError(response);
-			response.getHeaders().add(HEADER_HAS_ERROR, String.valueOf(hasError));
-		}
-		return true;
-	}
-
-	@Override
-	public void handleError(@NonNull ClientHttpResponse response) throws IOException {
-		if (realHasError(response)) {
-			delegateHandler.handleError(response);
-		}
-
-		clear(response);
-	}
-
-	@Override
-	public void handleError(@NonNull URI url, @NonNull HttpMethod method, @NonNull ClientHttpResponse response) throws IOException {
-		// report result to polaris
-		if (reportProperties.isEnabled()) {
-			reportResult(url, response);
-		}
-
-		// invoke delegate handler
-		invokeDelegateHandler(url, method, response);
-	}
-
-	private void reportResult(URI url, ClientHttpResponse response) {
-		ServiceCallResult resultRequest = createServiceCallResult(url);
-		try {
-			Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
-
-			String targetHost = loadBalancerContext.get("host");
-			String targetPort = loadBalancerContext.get("port");
-
-			if (StringUtils.isBlank(targetHost) || StringUtils.isBlank(targetPort)) {
-				LOGGER.warn("Can not get target host or port from metadata context. host = {}, port = {}", targetHost, targetPort);
-				return;
-			}
-
-			resultRequest.setHost(targetHost);
-			resultRequest.setPort(Integer.parseInt(targetPort));
-
-			// checking response http status code
-			if (apply(response.getStatusCode())) {
-				resultRequest.setRetStatus(RetStatus.RetFail);
-			}
-
-			List<String> labels = response.getHeaders().get(RouterConstant.ROUTER_LABEL_HEADER);
-			if (CollectionUtils.isNotEmpty(labels)) {
-				String label = labels.get(0);
-				try {
-					label = URLDecoder.decode(label, UTF_8);
-				}
-				catch (UnsupportedEncodingException e) {
-					LOGGER.error("unsupported charset exception " + UTF_8, e);
-				}
-				resultRequest.setLabels(convertLabel(label));
-			}
-
-			// processing report with consumerAPI .
-			LOGGER.debug("Will report result of {}. URL=[{}]. Response=[{}].", resultRequest.getRetStatus().name(),
-					url, response);
-			consumerAPI.updateServiceCallResult(resultRequest);
-			// update result without method for service circuit break.
-			resultRequest.setMethod("");
-			consumerAPI.updateServiceCallResult(resultRequest);
-		}
-		catch (Exception e) {
-			LOGGER.error("RestTemplate response reporter execute failed of {} url {}", response, url, e);
-		}
-	}
-
-	private String convertLabel(String label) {
-		label = label.replaceAll("\"|\\{|\\}", "")
-				.replaceAll(",", "|");
-		return label;
-	}
-
-	private void invokeDelegateHandler(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
-		if (realHasError(response)) {
-			delegateHandler.handleError(url, method, response);
-		}
-
-		clear(response);
-	}
-
-	private Boolean realHasError(ClientHttpResponse response) {
-		if (delegateHandler == null) {
-			return false;
-		}
-
-		String hasErrorHeader = response.getHeaders().getFirst(HEADER_HAS_ERROR);
-		if (StringUtils.isBlank(hasErrorHeader)) {
-			return false;
-		}
-
-		return Boolean.parseBoolean(hasErrorHeader);
-	}
-
-	private void clear(ClientHttpResponse response) {
-		if (!response.getHeaders().containsKey(HEADER_HAS_ERROR)) {
-			return;
-		}
-		response.getHeaders().remove(HEADER_HAS_ERROR);
-	}
-
-	private ServiceCallResult createServiceCallResult(URI uri) {
-		ServiceCallResult resultRequest = new ServiceCallResult();
-		String serviceName = uri.getHost();
-		resultRequest.setService(serviceName);
-		resultRequest.setNamespace(MetadataContext.LOCAL_NAMESPACE);
-		resultRequest.setMethod(uri.getPath());
-		resultRequest.setRetStatus(RetStatus.RetSuccess);
-		String sourceNamespace = MetadataContext.LOCAL_NAMESPACE;
-		String sourceService = MetadataContext.LOCAL_SERVICE;
-		if (StringUtils.isNotBlank(sourceNamespace) && StringUtils.isNotBlank(sourceService)) {
-			resultRequest.setCallerService(new ServiceKey(sourceNamespace, sourceService));
-		}
-		return resultRequest;
-	}
-
-	protected ResponseErrorHandler getDelegateHandler() {
-		return this.delegateHandler;
-	}
-
-	protected void setDelegateHandler(ResponseErrorHandler delegateHandler) {
-		this.delegateHandler = delegateHandler;
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java
index 0eb2dfd7f..04ffac0cf 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java
@@ -17,7 +17,7 @@
 
 package com.tencent.cloud.rpc.enhancement.resttemplate;
 
-import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.constant.HeaderConstant;
 import com.tencent.cloud.common.metadata.MetadataContextHolder;
 import org.aspectj.lang.ProceedingJoinPoint;
 
@@ -37,9 +37,8 @@ public final class LoadBalancerClientAspectUtils {
 		Object server = joinPoint.getArgs()[0];
 		if (server instanceof ServiceInstance) {
 			ServiceInstance instance = (ServiceInstance) server;
-			MetadataContextHolder.get().putContext(MetadataContext.FRAGMENT_LOAD_BALANCER, "host", instance.getHost());
-			MetadataContextHolder.get()
-					.putContext(MetadataContext.FRAGMENT_LOAD_BALANCER, "port", String.valueOf(instance.getPort()));
+			MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST, instance.getHost());
+			MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT, String.valueOf(instance.getPort()));
 		}
 	}
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java
new file mode 100644
index 000000000..6f0a02615
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java
@@ -0,0 +1,116 @@
+/*
+ * 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.rpc.enhancement.scg;
+
+import java.net.URI;
+
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
+import org.springframework.cloud.gateway.route.Route;
+import org.springframework.core.Ordered;
+import org.springframework.web.server.ServerWebExchange;
+
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
+
+/**
+ * EnhancedGatewayGlobalFilter.
+ *
+ * @author sean yu
+ */
+public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered {
+
+	private final EnhancedPluginRunner pluginRunner;
+
+	public EnhancedGatewayGlobalFilter(EnhancedPluginRunner pluginRunner) {
+		this.pluginRunner = pluginRunner;
+	}
+
+	@Override
+	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+
+		EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
+				.httpHeaders(exchange.getRequest().getHeaders())
+				.httpMethod(exchange.getRequest().getMethod())
+				.url(exchange.getRequest().getURI())
+				.build();
+		enhancedPluginContext.setRequest(enhancedRequestContext);
+
+		// Run pre enhanced plugins.
+		pluginRunner.run(PRE, enhancedPluginContext);
+
+		long startTime = System.currentTimeMillis();
+		return chain.filter(exchange)
+				.doOnSubscribe(v -> {
+					DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+					Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
+					if (route != null) {
+						serviceInstance.setServiceId(route.getUri().getHost());
+					}
+					URI uri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
+					if (uri != null) {
+						serviceInstance.setHost(uri.getHost());
+						serviceInstance.setPort(uri.getPort());
+					}
+					enhancedPluginContext.setServiceInstance(serviceInstance);
+				})
+				.doOnSuccess(v -> {
+					enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime);
+					EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+							.httpStatus(exchange.getResponse().getRawStatusCode())
+							.httpHeaders(exchange.getResponse().getHeaders())
+							.build();
+					enhancedPluginContext.setResponse(enhancedResponseContext);
+
+					// Run post enhanced plugins.
+					pluginRunner.run(POST, enhancedPluginContext);
+				})
+				.doOnError(t -> {
+					enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime);
+					enhancedPluginContext.setThrowable(t);
+
+					// Run exception enhanced plugins.
+					pluginRunner.run(EXCEPTION, enhancedPluginContext);
+				})
+				.doFinally(v -> {
+					// Run finally enhanced plugins.
+					pluginRunner.run(FINALLY, enhancedPluginContext);
+				});
+	}
+
+	/**
+	 * {@link ReactiveLoadBalancerClientFilter}.LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150.
+	 */
+	@Override
+	public int getOrder() {
+		return 10150 + 1;
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java
new file mode 100644
index 000000000..2b62fc5d0
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java
@@ -0,0 +1,97 @@
+/*
+ * 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.rpc.enhancement.webclient;
+
+import java.util.Map;
+
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.ExchangeFunction;
+
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST;
+
+/**
+ * EnhancedWebClientReporter.
+ *
+ * @author sean yu
+ */
+public class EnhancedWebClientReporter implements ExchangeFilterFunction {
+	private final EnhancedPluginRunner pluginRunner;
+
+	public EnhancedWebClientReporter(EnhancedPluginRunner pluginRunner) {
+		this.pluginRunner = pluginRunner;
+	}
+
+	@Override
+	public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+
+		EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
+				.httpHeaders(request.headers())
+				.httpMethod(request.method())
+				.url(request.url())
+				.build();
+		enhancedPluginContext.setRequest(enhancedRequestContext);
+
+		long startTime = System.currentTimeMillis();
+		return next.exchange(request)
+				.doOnSubscribe(subscription -> {
+					Map<String, String> loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata();
+					DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+					serviceInstance.setServiceId(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID));
+					serviceInstance.setHost(request.url().getHost());
+					serviceInstance.setPort(request.url().getPort());
+					enhancedPluginContext.setServiceInstance(serviceInstance);
+				})
+				.doOnSuccess(response -> {
+					enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime);
+
+					EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+							.httpStatus(response.rawStatusCode())
+							.httpHeaders(response.headers().asHttpHeaders())
+							.build();
+					enhancedPluginContext.setResponse(enhancedResponseContext);
+
+					// Run post enhanced plugins.
+					pluginRunner.run(POST, enhancedPluginContext);
+				})
+				.doOnError(t -> {
+					enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime);
+					enhancedPluginContext.setThrowable(t);
+
+					// Run exception enhanced plugins.
+					pluginRunner.run(EXCEPTION, enhancedPluginContext);
+				})
+				.doFinally(v -> {
+					// Run finally enhanced plugins.
+					pluginRunner.run(FINALLY, enhancedPluginContext);
+				});
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java
new file mode 100644
index 000000000..4e6913164
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java
@@ -0,0 +1,42 @@
+/*
+ * 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.rpc.enhancement.webclient;
+
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer;
+import org.springframework.web.reactive.function.client.ClientRequest;
+
+/**
+ * PolarisLoadBalancerClientRequestTransformer.
+ *
+ * @author sean yu
+ */
+public class PolarisLoadBalancerClientRequestTransformer implements LoadBalancerClientRequestTransformer {
+
+	@Override
+	public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) {
+		if (instance != null) {
+			MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID, instance.getServiceId());
+		}
+		return request;
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java
new file mode 100644
index 000000000..362e9be0b
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java
@@ -0,0 +1,127 @@
+/*
+ * 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.rpc.enhancement.zuul;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+import com.tencent.cloud.common.constant.ContextConstant;
+import com.tencent.cloud.common.util.ZuulFilterUtils;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE;
+
+/**
+ * Polaris circuit breaker error-processing. Including reporting and fallback.
+ * This will remove throwable from Zuul context.
+ *
+ * @author Haotian Zhang
+ */
+public class EnhancedErrorZuulFilter extends ZuulFilter {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedErrorZuulFilter.class);
+
+	private final EnhancedPluginRunner pluginRunner;
+
+	private final Environment environment;
+
+	public EnhancedErrorZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) {
+		this.pluginRunner = pluginRunner;
+		this.environment = environment;
+	}
+
+	@Override
+	public String filterType() {
+		return ERROR_TYPE;
+	}
+
+	@Override
+	public int filterOrder() {
+		return Integer.MIN_VALUE;
+	}
+
+	@Override
+	public boolean shouldFilter() {
+		RequestContext ctx = RequestContext.getCurrentContext();
+		String enabled = environment.getProperty("spring.cloud.tencent.rpc-enhancement.reporter");
+		return ctx.getThrowable() != null && (StringUtils.isEmpty(enabled) || enabled.equals("true"));
+	}
+
+	@Override
+	public Object run() throws ZuulException {
+		RequestContext context = RequestContext.getCurrentContext();
+		Object enhancedPluginContextObj = context.get(ContextConstant.Zuul.ENHANCED_PLUGIN_CONTEXT);
+		EnhancedPluginContext enhancedPluginContext;
+		if (enhancedPluginContextObj == null || !(enhancedPluginContextObj instanceof EnhancedPluginContext)) {
+			enhancedPluginContext = new EnhancedPluginContext();
+		}
+		else {
+			enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj;
+		}
+
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		Object ribbonResponseObj = context.get("ribbonResponse");
+		Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME);
+		Throwable throwable = context.getThrowable();
+		RibbonApacheHttpResponse ribbonResponse;
+		if (throwable != null && ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse
+				&& startTimeMilliObject != null && startTimeMilliObject instanceof Long) {
+			HttpHeaders responseHeaders = new HttpHeaders();
+			Collection<String> names = context.getResponse().getHeaderNames();
+			for (String name : names) {
+				responseHeaders.put(name, new ArrayList<>(context.getResponse().getHeaders(name)));
+			}
+			EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+					.httpStatus(context.getResponse().getStatus())
+					.httpHeaders(responseHeaders)
+					.build();
+			enhancedPluginContext.setResponse(enhancedResponseContext);
+			Long startTimeMilli = (Long) startTimeMilliObject;
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli);
+			enhancedPluginContext.setThrowable(throwable);
+			ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj;
+			serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context));
+			serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost());
+			serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort());
+			enhancedPluginContext.setServiceInstance(serviceInstance);
+
+			// Run post enhanced plugins.
+			pluginRunner.run(EXCEPTION, enhancedPluginContext);
+
+			// Run finally enhanced plugins.
+			pluginRunner.run(FINALLY, enhancedPluginContext);
+		}
+		return null;
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java
new file mode 100644
index 000000000..ff1ba4095
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java
@@ -0,0 +1,124 @@
+/*
+ * 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.rpc.enhancement.zuul;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+import com.tencent.cloud.common.constant.ContextConstant;
+import com.tencent.cloud.common.util.ZuulFilterUtils;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;
+
+/**
+ * Polaris circuit breaker implement in Zuul.
+ *
+ * @author Haotian Zhang
+ */
+public class EnhancedPostZuulFilter extends ZuulFilter {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPostZuulFilter.class);
+
+	private final EnhancedPluginRunner pluginRunner;
+
+	private final Environment environment;
+
+	public EnhancedPostZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) {
+		this.pluginRunner = pluginRunner;
+		this.environment = environment;
+	}
+
+	@Override
+	public String filterType() {
+		return POST_TYPE;
+	}
+
+	@Override
+	public int filterOrder() {
+		return SEND_RESPONSE_FILTER_ORDER + 1;
+	}
+
+	@Override
+	public boolean shouldFilter() {
+		String enabled = environment.getProperty("spring.cloud.tencent.rpc-enhancement.reporter");
+		return StringUtils.isEmpty(enabled) || enabled.equals("true");
+	}
+
+	@Override
+	public Object run() throws ZuulException {
+		RequestContext context = RequestContext.getCurrentContext();
+		Object enhancedPluginContextObj = context.get(ContextConstant.Zuul.ENHANCED_PLUGIN_CONTEXT);
+		EnhancedPluginContext enhancedPluginContext;
+		if (enhancedPluginContextObj == null || !(enhancedPluginContextObj instanceof EnhancedPluginContext)) {
+			enhancedPluginContext = new EnhancedPluginContext();
+		}
+		else {
+			enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj;
+		}
+
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		Object ribbonResponseObj = context.get("ribbonResponse");
+		Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME);
+		RibbonApacheHttpResponse ribbonResponse;
+		if (ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse
+				&& startTimeMilliObject != null && startTimeMilliObject instanceof Long) {
+			HttpHeaders responseHeaders = new HttpHeaders();
+			Collection<String> names = context.getResponse().getHeaderNames();
+			for (String name : names) {
+				responseHeaders.put(name, new ArrayList<>(context.getResponse().getHeaders(name)));
+			}
+			EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
+					.httpStatus(context.getResponse().getStatus())
+					.httpHeaders(responseHeaders)
+					.build();
+			enhancedPluginContext.setResponse(enhancedResponseContext);
+			Long startTimeMilli = (Long) startTimeMilliObject;
+			enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli);
+			ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj;
+			serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context));
+			serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost());
+			serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort());
+			enhancedPluginContext.setServiceInstance(serviceInstance);
+
+			// Run post enhanced plugins.
+			pluginRunner.run(POST, enhancedPluginContext);
+
+			// Run finally enhanced plugins.
+			pluginRunner.run(FINALLY, enhancedPluginContext);
+		}
+		return null;
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java
new file mode 100644
index 000000000..65484c131
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java
@@ -0,0 +1,117 @@
+/*
+ * 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.rpc.enhancement.zuul;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+import com.tencent.cloud.common.constant.ContextConstant;
+import com.tencent.cloud.common.util.ZuulFilterUtils;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME;
+import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
+import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
+
+/**
+ * Polaris circuit breaker implement in Zuul.
+ *
+ * @author Haotian Zhang
+ */
+public class EnhancedPreZuulFilter extends ZuulFilter {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPreZuulFilter.class);
+
+	private final EnhancedPluginRunner pluginRunner;
+
+	private final Environment environment;
+
+	public EnhancedPreZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) {
+		this.pluginRunner = pluginRunner;
+		this.environment = environment;
+	}
+
+	@Override
+	public String filterType() {
+		return PRE_TYPE;
+	}
+
+	@Override
+	public int filterOrder() {
+		return PRE_DECORATION_FILTER_ORDER + 1;
+	}
+
+	@Override
+	public boolean shouldFilter() {
+		String enabled = environment.getProperty("spring.cloud.tencent.rpc-enhancement.reporter");
+		return StringUtils.isEmpty(enabled) || enabled.equals("true");
+	}
+
+	@Override
+	public Object run() throws ZuulException {
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+		RequestContext context = RequestContext.getCurrentContext();
+		context.set(ContextConstant.Zuul.ENHANCED_PLUGIN_CONTEXT, enhancedPluginContext);
+
+		try {
+			URI uri = new URI(context.getRequest()
+					.getScheme(), ZuulFilterUtils.getServiceId(context), ZuulFilterUtils.getPath(context), context.getRequest()
+					.getQueryString(), null);
+			HttpHeaders requestHeaders = new HttpHeaders();
+			Enumeration<String> names = context.getRequest().getHeaderNames();
+			while (names.hasMoreElements()) {
+				String name = names.nextElement();
+				requestHeaders.put(name, Collections.list(context.getRequest().getHeaders(name)));
+			}
+			EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
+					.httpHeaders(requestHeaders)
+					.httpMethod(HttpMethod.resolve(context.getRequest().getMethod()))
+					.url(uri)
+					.build();
+
+			enhancedPluginContext.setRequest(enhancedRequestContext);
+
+			// Run pre enhanced plugins.
+			pluginRunner.run(PRE, enhancedPluginContext);
+
+			Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME);
+			if (startTimeMilliObject == null || !(startTimeMilliObject instanceof Long)) {
+				context.set(POLARIS_PRE_ROUTE_TIME, Long.valueOf(System.currentTimeMillis()));
+			}
+		}
+		catch (URISyntaxException e) {
+			LOGGER.error("Generate URI failed.", e);
+		}
+		return null;
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index 9572b5ad7..a2a449b33 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -9,7 +9,7 @@
     {
       "name": "spring.cloud.tencent.rpc-enhancement.reporter.enabled",
       "type": "java.lang.Boolean",
-      "defaultValue": false,
+      "defaultValue": true,
       "description": "Whether report call result to polaris."
     },
     {
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java
index 4c9c8a4e9..825da246f 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java
@@ -17,29 +17,196 @@
 
 package com.tencent.cloud.rpc.enhancement;
 
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.constant.RouterConstant;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
 import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import org.assertj.core.api.Assertions;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.config.global.APIConfig;
+import com.tencent.polaris.api.config.global.GlobalConfig;
+import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
+import com.tencent.polaris.api.pojo.RetStatus;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
 
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
 /**
  * Test For {@link AbstractPolarisReporterAdapter}.
  *
  * @author <a href="mailto:iskp.me@gmail.com">Elve.Xu</a> 2022/7/11
  */
+@ExtendWith(MockitoExtension.class)
 public class AbstractPolarisReporterAdapterTest {
 
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	private final RpcEnhancementReporterProperties reporterProperties = new RpcEnhancementReporterProperties();
+	@Mock
+	private SDKContext sdkContext;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testServiceCallResult() throws URISyntaxException {
+		APIConfig apiConfig = mock(APIConfig.class);
+		doReturn("0.0.0.0").when(apiConfig).getBindIP();
+
+		GlobalConfig globalConfig = mock(GlobalConfig.class);
+		doReturn(apiConfig).when(globalConfig).getAPI();
+
+		Configuration configuration = mock(Configuration.class);
+		doReturn(globalConfig).when(configuration).getGlobal();
+
+		doReturn(configuration).when(sdkContext).getConfig();
+
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext);
+
+		ServiceCallResult serviceCallResult;
+
+		HttpHeaders requestHeaders = new HttpHeaders();
+		requestHeaders.add(RouterConstant.ROUTER_LABEL_HEADER, "{\"k1\":\"v1\"}");
+
+		serviceCallResult = adapter.createServiceCallResult(
+				"test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				requestHeaders,
+				new HttpHeaders(),
+				200,
+				0,
+				null
+		);
+		assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
+
+		serviceCallResult = adapter.createServiceCallResult(
+				"test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				requestHeaders,
+				new HttpHeaders(),
+				502,
+				0,
+				null
+		);
+		assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetFail);
+
+		serviceCallResult = adapter.createServiceCallResult(
+				"test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				requestHeaders,
+				null,
+				null,
+				0,
+				new SocketTimeoutException()
+		);
+		assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetTimeout);
+
+		serviceCallResult = adapter.createServiceCallResult(
+				"test",
+				"0.0.0.0",
+				8080,
+				new URI("/"),
+				requestHeaders,
+				new HttpHeaders(),
+				200,
+				0,
+				null
+		);
+		assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
+		assertThat(serviceCallResult.getHost()).isEqualTo("0.0.0.0");
+		assertThat(serviceCallResult.getPort()).isEqualTo(8080);
+	}
+
+	@Test
+	public void testResourceStat() throws URISyntaxException {
+
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext);
+
+		ResourceStat resourceStat;
+
+		resourceStat = adapter.createInstanceResourceStat("test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				200,
+				0,
+				null
+		);
+		assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
+
+		resourceStat = adapter.createInstanceResourceStat("test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				null,
+				0,
+				new SocketTimeoutException()
+		);
+		assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetTimeout);
+
+		resourceStat = adapter.createInstanceResourceStat("test",
+				null,
+				null,
+				new URI("http://0.0.0.0/"),
+				200,
+				0,
+				null
+		);
+		assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
+	}
+
 	@Test
 	public void testApplyWithDefaultConfig() {
 		RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties();
 		// Mock Condition
-		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties);
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
 
 		// Assert
-		Assertions.assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
 	}
 
 	@Test
@@ -49,12 +216,12 @@ public class AbstractPolarisReporterAdapterTest {
 		properties.getStatuses().clear();
 		properties.setIgnoreInternalServerError(false);
 
-		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties);
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
 
 		// Assert
-		Assertions.assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true);
-		Assertions.assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
 	}
 
 	@Test
@@ -64,12 +231,12 @@ public class AbstractPolarisReporterAdapterTest {
 		properties.getStatuses().clear();
 		properties.setIgnoreInternalServerError(true);
 
-		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties);
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
 
 		// Assert
-		Assertions.assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
 	}
 
 	@Test
@@ -79,12 +246,12 @@ public class AbstractPolarisReporterAdapterTest {
 		properties.getStatuses().clear();
 		properties.getSeries().clear();
 
-		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties);
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
 
 		// Assert
-		Assertions.assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true);
 	}
 
 	@Test
@@ -95,13 +262,56 @@ public class AbstractPolarisReporterAdapterTest {
 		properties.getSeries().clear();
 		properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR);
 
-		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties);
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
 
 		// Assert
-		Assertions.assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false);
-		Assertions.assertThat(adapter.apply(HttpStatus.FORBIDDEN)).isEqualTo(true);
+		assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false);
+		assertThat(adapter.apply(HttpStatus.FORBIDDEN)).isEqualTo(true);
+	}
+
+
+	@Test
+	public void testGetRetStatusFromRequest() {
+		RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties();
+		// Mock Condition
+		properties.getStatuses().clear();
+		properties.getSeries().clear();
+		properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR);
+
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
+
+		HttpHeaders headers = new HttpHeaders();
+		RetStatus ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail);
+		assertThat(ret).isEqualTo(RetStatus.RetFail);
+
+		headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
+		ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail);
+		assertThat(ret).isEqualTo(RetStatus.RetFlowControl);
+
+		headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetReject.getDesc());
+		ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail);
+		assertThat(ret).isEqualTo(RetStatus.RetReject);
+	}
+
+	@Test
+	public void testGetActiveRuleNameFromRequest() {
+		RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties();
+		// Mock Condition
+		properties.getStatuses().clear();
+		properties.getSeries().clear();
+		properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR);
+
+		SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext);
+
+		HttpHeaders headers = new HttpHeaders();
+		String ruleName = adapter.getActiveRuleNameFromRequest(headers);
+		assertThat(ruleName).isEqualTo("");
+
+		headers.set(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, "mock_rule");
+		ruleName = adapter.getActiveRuleNameFromRequest(headers);
+		assertThat(ruleName).isEqualTo("mock_rule");
 	}
 
 	/**
@@ -109,8 +319,8 @@ public class AbstractPolarisReporterAdapterTest {
 	 */
 	public static class SimplePolarisReporterAdapter extends AbstractPolarisReporterAdapter {
 
-		public SimplePolarisReporterAdapter(RpcEnhancementReporterProperties properties) {
-			super(properties);
+		protected SimplePolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) {
+			super(reportProperties, context);
 		}
 	}
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java
index 0b883096b..fe02ab397 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java
@@ -19,10 +19,10 @@ package com.tencent.cloud.rpc.enhancement.config;
 
 import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
 import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor;
-import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignPluginRunner;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter;
-import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateReporter;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
+import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor;
 import com.tencent.polaris.api.core.ConsumerAPI;
 import org.junit.jupiter.api.Test;
 
@@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.openfeign.loadbalancer.FeignLoadBalancerAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.client.RestTemplate;
@@ -47,21 +48,20 @@ public class RpcEnhancementAutoConfigurationTest {
 			.withConfiguration(AutoConfigurations.of(
 					PolarisContextAutoConfiguration.class,
 					RpcEnhancementAutoConfiguration.class,
-					PolarisRestTemplateAutoConfigurationTester.class))
-			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+					PolarisRestTemplateAutoConfigurationTester.class,
+					FeignLoadBalancerAutoConfiguration.class))
+			.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true", "spring.application.name=test", "spring.cloud.gateway.enabled=false");
 
 	@Test
 	public void testDefaultInitialization() {
 		this.contextRunner.run(context -> {
 			assertThat(context).hasSingleBean(ConsumerAPI.class);
-			assertThat(context).hasSingleBean(EnhancedFeignPluginRunner.class);
+			assertThat(context).hasSingleBean(EnhancedPluginRunner.class);
 			assertThat(context).hasSingleBean(EnhancedFeignBeanPostProcessor.class);
 			assertThat(context).hasSingleBean(SuccessPolarisReporter.class);
 			assertThat(context).hasSingleBean(ExceptionPolarisReporter.class);
-			assertThat(context).hasSingleBean(EnhancedRestTemplateReporter.class);
+			assertThat(context).hasSingleBean(EnhancedRestTemplateInterceptor.class);
 			assertThat(context).hasSingleBean(RestTemplate.class);
-			RestTemplate restTemplate = context.getBean(RestTemplate.class);
-			assertThat(restTemplate.getErrorHandler() instanceof EnhancedRestTemplateReporter).isTrue();
 		});
 	}
 
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java
index 48db48072..6ed9d8857 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java
@@ -38,7 +38,11 @@ import static org.springframework.http.HttpStatus.Series.SERVER_ERROR;
  * @author Haotian Zhang
  */
 @ExtendWith(SpringExtension.class)
-@SpringBootTest(classes = RpcEnhancementReporterPropertiesTest.TestApplication.class)
+@SpringBootTest(classes = RpcEnhancementReporterPropertiesTest.TestApplication.class, properties = {
+		"spring.application.name=test",
+		"spring.cloud.gateway.enabled=false",
+		"spring.cloud.tencent.rpc-enhancement.reporter=true"
+})
 @ActiveProfiles("test")
 public class RpcEnhancementReporterPropertiesTest {
 
@@ -55,6 +59,7 @@ public class RpcEnhancementReporterPropertiesTest {
 		assertThat(rpcEnhancementReporterProperties.getStatuses()).isNotEmpty();
 		assertThat(rpcEnhancementReporterProperties.getStatuses().get(0)).isEqualTo(MULTIPLE_CHOICES);
 		assertThat(rpcEnhancementReporterProperties.getStatuses().get(1)).isEqualTo(MOVED_PERMANENTLY);
+		assertThat(rpcEnhancementReporterProperties.isEnabled()).isEqualTo(true);
 	}
 
 	@SpringBootApplication
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java
index 76027f6dc..2ff9ff909 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java
@@ -22,9 +22,10 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
+import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
 import feign.Client;
 import feign.Request;
 import feign.RequestTemplate;
@@ -51,7 +52,7 @@ import static org.mockito.Mockito.mock;
  */
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(classes = EnhancedFeignClientTest.TestApplication.class,
-		properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"})
+		properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp", "spring.cloud.gateway.enabled=false"})
 public class EnhancedFeignClientTest {
 
 	@Test
@@ -72,9 +73,9 @@ public class EnhancedFeignClientTest {
 			fail("Exception encountered.", e);
 		}
 
-		List<EnhancedFeignPlugin> enhancedFeignPlugins = getMockEnhancedFeignPlugins();
+		List<EnhancedPlugin> enhancedPlugins = getMockEnhancedFeignPlugins();
 		try {
-			new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedFeignPluginRunner(enhancedFeignPlugins));
+			new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedPluginRunner(enhancedPlugins));
 		}
 		catch (Throwable e) {
 			fail("Exception encountered.", e);
@@ -103,7 +104,7 @@ public class EnhancedFeignClientTest {
 		RequestTemplate requestTemplate = new RequestTemplate();
 		requestTemplate.feignTarget(target);
 
-		EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedFeignPluginRunner(getMockEnhancedFeignPlugins()));
+		EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins()));
 
 		// 200
 		Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test",
@@ -127,22 +128,22 @@ public class EnhancedFeignClientTest {
 		}
 	}
 
-	private List<EnhancedFeignPlugin> getMockEnhancedFeignPlugins() {
-		List<EnhancedFeignPlugin> enhancedFeignPlugins = new ArrayList<>();
+	private List<EnhancedPlugin> getMockEnhancedFeignPlugins() {
+		List<EnhancedPlugin> enhancedPlugins = new ArrayList<>();
 
-		enhancedFeignPlugins.add(new EnhancedFeignPlugin() {
+		enhancedPlugins.add(new EnhancedPlugin() {
 			@Override
-			public EnhancedFeignPluginType getType() {
-				return EnhancedFeignPluginType.PRE;
+			public EnhancedPluginType getType() {
+				return EnhancedPluginType.PRE;
 			}
 
 			@Override
-			public void run(EnhancedFeignContext context) {
+			public void run(EnhancedPluginContext context) {
 
 			}
 
 			@Override
-			public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
+			public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
 
 			}
 
@@ -152,19 +153,19 @@ public class EnhancedFeignClientTest {
 			}
 		});
 
-		enhancedFeignPlugins.add(new EnhancedFeignPlugin() {
+		enhancedPlugins.add(new EnhancedPlugin() {
 			@Override
-			public EnhancedFeignPluginType getType() {
-				return EnhancedFeignPluginType.POST;
+			public EnhancedPluginType getType() {
+				return EnhancedPluginType.POST;
 			}
 
 			@Override
-			public void run(EnhancedFeignContext context) {
+			public void run(EnhancedPluginContext context) {
 
 			}
 
 			@Override
-			public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
+			public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
 
 			}
 
@@ -174,19 +175,19 @@ public class EnhancedFeignClientTest {
 			}
 		});
 
-		enhancedFeignPlugins.add(new EnhancedFeignPlugin() {
+		enhancedPlugins.add(new EnhancedPlugin() {
 			@Override
-			public EnhancedFeignPluginType getType() {
-				return EnhancedFeignPluginType.EXCEPTION;
+			public EnhancedPluginType getType() {
+				return EnhancedPluginType.EXCEPTION;
 			}
 
 			@Override
-			public void run(EnhancedFeignContext context) {
+			public void run(EnhancedPluginContext context) {
 
 			}
 
 			@Override
-			public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
+			public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
 
 			}
 
@@ -196,19 +197,19 @@ public class EnhancedFeignClientTest {
 			}
 		});
 
-		enhancedFeignPlugins.add(new EnhancedFeignPlugin() {
+		enhancedPlugins.add(new EnhancedPlugin() {
 			@Override
-			public EnhancedFeignPluginType getType() {
-				return EnhancedFeignPluginType.FINALLY;
+			public EnhancedPluginType getType() {
+				return EnhancedPluginType.FINALLY;
 			}
 
 			@Override
-			public void run(EnhancedFeignContext context) {
+			public void run(EnhancedPluginContext context) {
 
 			}
 
 			@Override
-			public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) {
+			public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) {
 
 			}
 
@@ -218,7 +219,7 @@ public class EnhancedFeignClientTest {
 			}
 		});
 
-		return enhancedFeignPlugins;
+		return enhancedPlugins;
 
 	}
 
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java
deleted file mode 100644
index 0143fc844..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin;
-
-import feign.Request;
-import feign.Response;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-/**
- * Test for {@link EnhancedFeignContext}.
- *
- * @author Haotian Zhang
- */
-public class EnhancedFeignContextTest {
-
-	@Test
-	public void testGetAndSet() {
-		EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext();
-		enhancedFeignContext.setRequest(mock(Request.class));
-		enhancedFeignContext.setOptions(mock(Request.Options.class));
-		enhancedFeignContext.setResponse(mock(Response.class));
-		enhancedFeignContext.setException(mock(Exception.class));
-		assertThat(enhancedFeignContext.getRequest()).isNotNull();
-		assertThat(enhancedFeignContext.getOptions()).isNotNull();
-		assertThat(enhancedFeignContext.getResponse()).isNotNull();
-		assertThat(enhancedFeignContext.getException()).isNotNull();
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java
deleted file mode 100644
index a123e8490..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin.reporter;
-
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import feign.Request;
-import feign.Response;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-/**
- * Test for {@link ExceptionPolarisReporter}.
- *
- * @author Haotian Zhang
- */
-@ExtendWith(MockitoExtension.class)
-public class ExceptionPolarisReporterTest {
-
-	private static MockedStatic<ReporterUtils> mockedReporterUtils;
-	@Mock
-	private ConsumerAPI consumerAPI;
-	@Mock
-	private RpcEnhancementReporterProperties reporterProperties;
-	@InjectMocks
-	private ExceptionPolarisReporter exceptionPolarisReporter;
-
-	@BeforeAll
-	static void beforeAll() {
-		mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class);
-		mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class)))
-				.thenReturn(mock(ServiceCallResult.class));
-	}
-
-	@AfterAll
-	static void afterAll() {
-		mockedReporterUtils.close();
-	}
-
-	@Test
-	public void testGetName() {
-		assertThat(exceptionPolarisReporter.getName()).isEqualTo(ExceptionPolarisReporter.class.getName());
-	}
-
-	@Test
-	public void testType() {
-		assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.EXCEPTION);
-	}
-
-	@Test
-	public void testRun() {
-		// mock request
-		Request request = mock(Request.class);
-		// mock response
-		Response response = mock(Response.class);
-
-		EnhancedFeignContext context = mock(EnhancedFeignContext.class);
-		doReturn(request).when(context).getRequest();
-		doReturn(response).when(context).getResponse();
-		// test not report
-		exceptionPolarisReporter.run(context);
-		verify(context, times(0)).getRequest();
-		// test do report
-		doReturn(true).when(reporterProperties).isEnabled();
-		exceptionPolarisReporter.run(context);
-		verify(context, times(1)).getRequest();
-	}
-
-	@Test
-	public void testHandlerThrowable() {
-		// mock request
-		Request request = mock(Request.class);
-		// mock response
-		Response response = mock(Response.class);
-
-		EnhancedFeignContext context = new EnhancedFeignContext();
-		context.setRequest(request);
-		context.setResponse(response);
-		exceptionPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java
deleted file mode 100644
index 841592986..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.rpc.enhancement.feign.plugin.reporter;
-
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext;
-import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import feign.Request;
-import feign.Response;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-/**
- * Test for {@link SuccessPolarisReporter}.
- *
- * @author Haotian Zhang
- */
-@ExtendWith(MockitoExtension.class)
-public class SuccessPolarisReporterTest {
-
-	private static MockedStatic<ReporterUtils> mockedReporterUtils;
-	@Mock
-	private ConsumerAPI consumerAPI;
-	@Mock
-	private RpcEnhancementReporterProperties reporterProperties;
-	@InjectMocks
-	private SuccessPolarisReporter successPolarisReporter;
-
-	@BeforeAll
-	static void beforeAll() {
-		mockedReporterUtils = Mockito.mockStatic(ReporterUtils.class);
-		mockedReporterUtils.when(() -> ReporterUtils.createServiceCallResult(any(Request.class), any(RetStatus.class)))
-				.thenReturn(mock(ServiceCallResult.class));
-	}
-
-	@AfterAll
-	static void afterAll() {
-		mockedReporterUtils.close();
-	}
-
-	@Test
-	public void testGetName() {
-		assertThat(successPolarisReporter.getName()).isEqualTo(SuccessPolarisReporter.class.getName());
-	}
-
-	@Test
-	public void testType() {
-		assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.POST);
-	}
-
-	@Test
-	public void testRun() {
-		// mock request
-		Request request = mock(Request.class);
-		// mock response
-		Response response = mock(Response.class);
-		doReturn(502).when(response).status();
-
-		EnhancedFeignContext context = mock(EnhancedFeignContext.class);
-		doReturn(request).when(context).getRequest();
-		doReturn(response).when(context).getResponse();
-		// test not report
-		successPolarisReporter.run(context);
-		verify(context, times(0)).getRequest();
-		// test do report
-		doReturn(true).when(reporterProperties).isEnabled();
-		successPolarisReporter.run(context);
-		verify(context, times(1)).getRequest();
-	}
-
-	@Test
-	public void testHandlerThrowable() {
-		// mock request
-		Request request = mock(Request.class);
-		// mock response
-		Response response = mock(Response.class);
-
-		EnhancedFeignContext context = new EnhancedFeignContext();
-		context.setRequest(request);
-		context.setResponse(response);
-		successPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java
new file mode 100644
index 000000000..a516483f1
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+import java.net.URI;
+import java.util.Arrays;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Test for {@link EnhancedPluginContext}.
+ *
+ * @author Haotian Zhang
+ */
+@ExtendWith(MockitoExtension.class)
+public class EnhancedPluginContextTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+	@Mock
+	private ConsumerAPI consumerAPI;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testGetAndSet() throws Throwable {
+		EnhancedRequestContext requestContext = new EnhancedRequestContext();
+		requestContext.setHttpHeaders(new HttpHeaders());
+		requestContext.setUrl(new URI("/"));
+		requestContext.setHttpMethod(HttpMethod.GET);
+
+		EnhancedRequestContext requestContext1 = EnhancedRequestContext.builder()
+				.httpHeaders(requestContext.getHttpHeaders())
+				.url(requestContext.getUrl())
+				.httpMethod(requestContext.getHttpMethod())
+				.build();
+		assertThat(requestContext1.getUrl()).isEqualTo(requestContext.getUrl());
+
+		EnhancedResponseContext responseContext = new EnhancedResponseContext();
+		responseContext.setHttpStatus(200);
+		responseContext.setHttpHeaders(new HttpHeaders());
+
+		EnhancedResponseContext responseContext1 = EnhancedResponseContext.builder()
+				.httpStatus(responseContext.getHttpStatus())
+				.httpHeaders(responseContext.getHttpHeaders())
+				.build();
+		assertThat(responseContext1.getHttpStatus()).isEqualTo(responseContext.getHttpStatus());
+
+		EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
+		enhancedPluginContext.setRequest(requestContext);
+		enhancedPluginContext.setResponse(responseContext);
+		enhancedPluginContext.setServiceInstance(new DefaultServiceInstance());
+		enhancedPluginContext.setThrowable(mock(Exception.class));
+		enhancedPluginContext.setDelay(0);
+		assertThat(enhancedPluginContext.getRequest()).isNotNull();
+		assertThat(enhancedPluginContext.getResponse()).isNotNull();
+		assertThat(enhancedPluginContext.getServiceInstance()).isNotNull();
+		assertThat(enhancedPluginContext.getThrowable()).isNotNull();
+		assertThat(enhancedPluginContext.getDelay()).isNotNull();
+
+		EnhancedPlugin enhancedPlugin = new SuccessPolarisReporter(reporterProperties, sdkContext, consumerAPI);
+		EnhancedPlugin enhancedPlugin1 = new ExceptionPolarisReporter(reporterProperties, sdkContext, consumerAPI);
+		EnhancedPluginRunner enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin, enhancedPlugin1));
+		enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext);
+
+		EnhancedPlugin enhancedPlugin2 = mock(EnhancedPlugin.class);
+		doThrow(new RuntimeException()).when(enhancedPlugin2).run(any());
+		doReturn(EnhancedPluginType.POST).when(enhancedPlugin2).getType();
+		enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin2));
+		enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext);
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java
new file mode 100644
index 000000000..21c61ef92
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+import java.net.URI;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.config.global.APIConfig;
+import com.tencent.polaris.api.config.global.GlobalConfig;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test for {@link ExceptionPolarisReporter}.
+ *
+ * @author Haotian Zhang
+ */
+@ExtendWith(MockitoExtension.class)
+public class ExceptionPolarisReporterTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+	@InjectMocks
+	private ExceptionPolarisReporter exceptionPolarisReporter;
+	@Mock
+	private ConsumerAPI consumerAPI;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testGetName() {
+		assertThat(exceptionPolarisReporter.getName()).isEqualTo(ExceptionPolarisReporter.class.getName());
+	}
+
+	@Test
+	public void testType() {
+		assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION);
+	}
+
+	@Test
+	public void testRun() {
+		EnhancedPluginContext context = mock(EnhancedPluginContext.class);
+		// test not report
+		exceptionPolarisReporter.run(context);
+		verify(context, times(0)).getRequest();
+
+		doReturn(true).when(reporterProperties).isEnabled();
+
+		APIConfig apiConfig = mock(APIConfig.class);
+		doReturn("0.0.0.0").when(apiConfig).getBindIP();
+
+		GlobalConfig globalConfig = mock(GlobalConfig.class);
+		doReturn(apiConfig).when(globalConfig).getAPI();
+
+		Configuration configuration = mock(Configuration.class);
+		doReturn(globalConfig).when(configuration).getGlobal();
+
+		doReturn(configuration).when(sdkContext).getConfig();
+
+		EnhancedPluginContext pluginContext = new EnhancedPluginContext();
+		EnhancedRequestContext request = EnhancedRequestContext.builder()
+				.httpMethod(HttpMethod.GET)
+				.url(URI.create("http://0.0.0.0/"))
+				.httpHeaders(new HttpHeaders())
+				.build();
+		EnhancedResponseContext response = EnhancedResponseContext.builder()
+				.httpStatus(200)
+				.build();
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		serviceInstance.setServiceId(SERVICE_PROVIDER);
+
+		pluginContext.setRequest(request);
+		pluginContext.setResponse(response);
+		pluginContext.setServiceInstance(serviceInstance);
+		pluginContext.setThrowable(new RuntimeException());
+
+		exceptionPolarisReporter.run(pluginContext);
+		exceptionPolarisReporter.getOrder();
+		exceptionPolarisReporter.getName();
+		exceptionPolarisReporter.getType();
+	}
+
+	@Test
+	public void testHandlerThrowable() {
+		// mock request
+		EnhancedRequestContext request = mock(EnhancedRequestContext.class);
+		// mock response
+		EnhancedResponseContext response = mock(EnhancedResponseContext.class);
+
+		EnhancedPluginContext context = new EnhancedPluginContext();
+		context.setRequest(request);
+		context.setResponse(response);
+		exceptionPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java
new file mode 100644
index 000000000..9af4ca019
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.rpc.enhancement.plugin;
+
+import java.net.URI;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.config.global.APIConfig;
+import com.tencent.polaris.api.config.global.GlobalConfig;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.http.HttpMethod;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test for {@link SuccessPolarisReporter}.
+ *
+ * @author Haotian Zhang
+ */
+@ExtendWith(MockitoExtension.class)
+public class SuccessPolarisReporterTest {
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private SDKContext sdkContext;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@InjectMocks
+	private SuccessPolarisReporter successPolarisReporter;
+	@Mock
+	private ConsumerAPI consumerAPI;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testGetName() {
+		assertThat(successPolarisReporter.getName()).isEqualTo(SuccessPolarisReporter.class.getName());
+	}
+
+	@Test
+	public void testType() {
+		assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.POST);
+	}
+
+	@Test
+	public void testRun() {
+
+		EnhancedPluginContext context = mock(EnhancedPluginContext.class);
+		// test not report
+		successPolarisReporter.run(context);
+		verify(context, times(0)).getRequest();
+
+		doReturn(true).when(reporterProperties).isEnabled();
+		APIConfig apiConfig = mock(APIConfig.class);
+		doReturn("0.0.0.0").when(apiConfig).getBindIP();
+
+		GlobalConfig globalConfig = mock(GlobalConfig.class);
+		doReturn(apiConfig).when(globalConfig).getAPI();
+
+		Configuration configuration = mock(Configuration.class);
+		doReturn(globalConfig).when(configuration).getGlobal();
+
+		doReturn(configuration).when(sdkContext).getConfig();
+
+		EnhancedPluginContext pluginContext = new EnhancedPluginContext();
+		EnhancedRequestContext request = EnhancedRequestContext.builder()
+				.httpMethod(HttpMethod.GET)
+				.url(URI.create("http://0.0.0.0/"))
+				.build();
+		EnhancedResponseContext response = EnhancedResponseContext.builder()
+				.httpStatus(200)
+				.build();
+		DefaultServiceInstance serviceInstance = new DefaultServiceInstance();
+		serviceInstance.setServiceId(SERVICE_PROVIDER);
+
+		pluginContext.setRequest(request);
+		pluginContext.setResponse(response);
+		pluginContext.setServiceInstance(serviceInstance);
+
+		successPolarisReporter.run(pluginContext);
+		successPolarisReporter.getOrder();
+		successPolarisReporter.getName();
+		successPolarisReporter.getType();
+	}
+
+	@Test
+	public void testHandlerThrowable() {
+		// mock request
+		EnhancedRequestContext request = mock(EnhancedRequestContext.class);
+		// mock response
+		EnhancedResponseContext response = mock(EnhancedResponseContext.class);
+
+		EnhancedPluginContext context = new EnhancedPluginContext();
+		context.setRequest(request);
+		context.setResponse(response);
+		successPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception."));
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java
similarity index 51%
rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java
rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java
index c39dd1633..82bf173ba 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ReporterUtilsTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java
@@ -15,29 +15,28 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.rpc.enhancement.feign.plugin.reporter;
+package com.tencent.cloud.rpc.enhancement.resttemplate;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import com.tencent.cloud.common.constant.RouterConstant;
+import com.tencent.cloud.common.constant.HeaderConstant;
 import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.common.metadata.StaticMetadataManager;
+import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
 import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
-import com.tencent.polaris.api.pojo.RetStatus;
-import com.tencent.polaris.api.rpc.ServiceCallResult;
-import feign.Request;
-import feign.RequestTemplate;
-import feign.Target;
+import org.aspectj.lang.ProceedingJoinPoint;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.context.ApplicationContext;
+
 import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
 import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -45,21 +44,26 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
-/**
- * Test for {@link ReporterUtils}.
- *
- * @author Haotian Zhang
- */
 @ExtendWith(MockitoExtension.class)
-public class ReporterUtilsTest {
+public class BlockingLoadBalancerClientAspectTest {
 
 	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private ProceedingJoinPoint proceedingJoinPoint;
+
+	private BlockingLoadBalancerClientAspect aspect = new BlockingLoadBalancerClientAspect();
 
 	@BeforeAll
 	static void beforeAll() {
 		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
 		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
 				.thenReturn("unit-test");
+		ApplicationContext applicationContext = mock(ApplicationContext.class);
+		MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class);
+		StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class);
+		doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class);
+		doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class);
+		mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext);
 	}
 
 	@AfterAll
@@ -74,35 +78,15 @@ public class ReporterUtilsTest {
 	}
 
 	@Test
-	public void testCreateServiceCallResult() {
-		// mock target
-		Target<?> target = mock(Target.class);
-		doReturn(SERVICE_PROVIDER).when(target).name();
-
-		// mock RequestTemplate.class
-		RequestTemplate requestTemplate = new RequestTemplate();
-		requestTemplate.feignTarget(target);
-		try {
-			requestTemplate.header(RouterConstant.ROUTER_LABEL_HEADER, URLEncoder.encode("{\"k1\":\"v1\",\"k2\":\"v2\"}", UTF_8));
-		}
-		catch (UnsupportedEncodingException e) {
-			throw new RuntimeException("unsupported charset exception " + UTF_8);
-		}
-
-		// mock request
-		Request request = mock(Request.class);
-		doReturn(requestTemplate).when(request).requestTemplate();
-		doReturn("http://1.1.1.1:2345/path").when(request).url();
-
-		ServiceCallResult serviceCallResult = ReporterUtils.createServiceCallResult(request, RetStatus.RetSuccess);
-		assertThat(serviceCallResult.getNamespace()).isEqualTo(NAMESPACE_TEST);
-		assertThat(serviceCallResult.getService()).isEqualTo(SERVICE_PROVIDER);
-		assertThat(serviceCallResult.getHost()).isEqualTo("1.1.1.1");
-		assertThat(serviceCallResult.getPort()).isEqualTo(2345);
-		assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
-		assertThat(serviceCallResult.getMethod()).isEqualTo("/path");
-		assertThat(serviceCallResult.getCallerService().getNamespace()).isEqualTo(NAMESPACE_TEST);
-		assertThat(serviceCallResult.getCallerService().getService()).isEqualTo(SERVICE_PROVIDER);
-		assertThat(serviceCallResult.getLabels()).isEqualTo("k1:v1|k2:v2");
+	public void test() throws Throwable {
+		ServiceInstance serviceInstance = mock(ServiceInstance.class);
+		doReturn("0.0.0.0").when(serviceInstance).getHost();
+		doReturn(80).when(serviceInstance).getPort();
+		doReturn(new Object[]{ serviceInstance }).when(proceedingJoinPoint).getArgs();
+		aspect.invoke(proceedingJoinPoint);
+		aspect.pointcut();
+		assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)).isEqualTo("0.0.0.0");
+		assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)).isEqualTo("80");
 	}
+
 }
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java
new file mode 100644
index 000000000..6b256f014
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.rpc.enhancement.resttemplate;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.StaticMetadataManager;
+import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpResponse;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+@ExtendWith(MockitoExtension.class)
+public class EnhancedRestTemplateInterceptorTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+	@Mock
+	private ClientHttpRequestExecution mockClientHttpRequestExecution;
+	@Mock
+	private ClientHttpResponse mockClientHttpResponse;
+	@Mock
+	private HttpRequest mockHttpRequest;
+	@Mock
+	private HttpHeaders mockHttpHeaders;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+		ApplicationContext applicationContext = mock(ApplicationContext.class);
+		MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class);
+		StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class);
+		doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class);
+		doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class);
+		mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext);
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testRun() throws IOException, URISyntaxException {
+
+		ClientHttpResponse actualResult;
+		final byte[] inputBody = null;
+
+		URI uri = new URI("http://0.0.0.0/");
+		doReturn(uri).when(mockHttpRequest).getURI();
+		doReturn(HttpMethod.GET).when(mockHttpRequest).getMethod();
+		doReturn(mockHttpHeaders).when(mockHttpRequest).getHeaders();
+		doReturn(mockClientHttpResponse).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody);
+
+		EnhancedRestTemplateInterceptor reporter = new EnhancedRestTemplateInterceptor(new DefaultEnhancedPluginRunner(new ArrayList<>()));
+		actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution);
+		assertThat(actualResult).isEqualTo(mockClientHttpResponse);
+
+		actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution);
+		assertThat(actualResult).isEqualTo(mockClientHttpResponse);
+
+		doThrow(new SocketTimeoutException()).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody);
+		assertThatThrownBy(() -> reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution)).isInstanceOf(SocketTimeoutException.class);
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java
deleted file mode 100644
index 2b54c25f0..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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.rpc.enhancement.resttemplate;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.tencent.cloud.common.metadata.MetadataContext;
-import com.tencent.cloud.common.metadata.MetadataContextHolder;
-import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
-import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
-import com.tencent.polaris.api.core.ConsumerAPI;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.client.AbstractClientHttpResponse;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.web.client.DefaultResponseErrorHandler;
-import org.springframework.web.client.ResponseErrorHandler;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Test for {@link EnhancedRestTemplateReporter}.
- *
- * @author lepdou 2022-09-06
- */
-@ExtendWith(MockitoExtension.class)
-public class EnhancedRestTemplateReporterTest {
-
-	private static MockedStatic<MetadataContextHolder> mockedMetadataContextHolder;
-	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
-	@Mock
-	private ConsumerAPI consumerAPI;
-	@Mock
-	private RpcEnhancementReporterProperties reporterProperties;
-	@Mock
-	private ResponseErrorHandler delegate;
-	@InjectMocks
-	private EnhancedRestTemplateReporter enhancedRestTemplateReporter;
-
-	@InjectMocks
-	private EnhancedRestTemplateReporter enhancedRestTemplateReporter2;
-
-	@BeforeAll
-	static void beforeAll() {
-		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
-		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
-				.thenReturn("caller");
-		MetadataContext metadataContext = Mockito.mock(MetadataContext.class);
-
-		// mock transitive metadata
-		Map<String, String> loadBalancerContext = new HashMap<>();
-		loadBalancerContext.put("host", "1.1.1.1");
-		loadBalancerContext.put("port", "8080");
-		when(metadataContext.getLoadbalancerMetadata()).thenReturn(loadBalancerContext);
-
-		mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class);
-		mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext);
-	}
-
-	@AfterAll
-	static void afterAll() {
-		mockedApplicationContextAwareUtils.close();
-		mockedMetadataContextHolder.close();
-	}
-
-	@BeforeEach
-	void setUp() {
-		enhancedRestTemplateReporter.setDelegateHandler(delegate);
-	}
-
-	@Test
-	public void testSetApplicationContext() {
-		ApplicationContext applicationContext = mock(ApplicationContext.class);
-
-		// test no ResponseErrorHandler
-		when(applicationContext.getBeanNamesForType(any(Class.class)))
-				.thenReturn(new String[] {"enhancedRestTemplateReporter"});
-		enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
-		assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(DefaultResponseErrorHandler.class);
-
-		// test one other ResponseErrorHandler
-		when(applicationContext.getBeanNamesForType(any(Class.class)))
-				.thenReturn(new String[] {"enhancedRestTemplateReporter", "mockedResponseErrorHandler"});
-		when(applicationContext.getBean(anyString())).thenReturn(mock(MockedResponseErrorHandler.class));
-		enhancedRestTemplateReporter2.setApplicationContext(applicationContext);
-		assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(MockedResponseErrorHandler.class);
-	}
-
-	@Test
-	public void testHasError() throws IOException {
-		when(delegate.hasError(any())).thenReturn(true);
-
-		MockedClientHttpResponse response = new MockedClientHttpResponse();
-		assertThat(enhancedRestTemplateReporter.hasError(response)).isTrue();
-
-		String realHasError = response.getHeaders().getFirst(EnhancedRestTemplateReporter.HEADER_HAS_ERROR);
-		assertThat(realHasError).isEqualTo("true");
-	}
-
-	@Test
-	public void testHandleHasError() throws IOException {
-		when(reporterProperties.isEnabled()).thenReturn(true);
-		when(delegate.hasError(any())).thenReturn(true);
-
-		MockedClientHttpResponse response = new MockedClientHttpResponse();
-		enhancedRestTemplateReporter.hasError(response);
-
-		URI uri = mock(URI.class);
-		enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
-
-		verify(consumerAPI, times(2)).updateServiceCallResult(any());
-		verify(delegate).handleError(uri, HttpMethod.GET, response);
-	}
-
-	@Test
-	public void testHandleHasNotError() throws IOException {
-		when(reporterProperties.isEnabled()).thenReturn(true);
-		when(delegate.hasError(any())).thenReturn(false);
-
-		MockedClientHttpResponse response = new MockedClientHttpResponse();
-		enhancedRestTemplateReporter.hasError(response);
-
-		URI uri = mock(URI.class);
-		enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
-
-		verify(consumerAPI, times(2)).updateServiceCallResult(any());
-		verify(delegate, times(0)).handleError(uri, HttpMethod.GET, response);
-	}
-
-	@Test
-	public void testReportSwitchOff() throws IOException {
-		when(reporterProperties.isEnabled()).thenReturn(false);
-		when(delegate.hasError(any())).thenReturn(true);
-
-		MockedClientHttpResponse response = new MockedClientHttpResponse();
-		enhancedRestTemplateReporter.hasError(response);
-
-		URI uri = mock(URI.class);
-		enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
-
-		verify(consumerAPI, times(0)).updateServiceCallResult(any());
-		verify(delegate).handleError(uri, HttpMethod.GET, response);
-	}
-
-	static class MockedClientHttpResponse extends AbstractClientHttpResponse {
-
-		private final HttpHeaders headers;
-
-		MockedClientHttpResponse() {
-			this.headers = new HttpHeaders();
-		}
-
-		@Override
-		public int getRawStatusCode() {
-			return 0;
-		}
-
-		@Override
-		public String getStatusText() {
-			return null;
-		}
-
-		@Override
-		public void close() {
-
-		}
-
-		@Override
-		public InputStream getBody() throws IOException {
-			return null;
-		}
-
-		@Override
-		public HttpHeaders getHeaders() {
-			return headers;
-		}
-
-		@Override
-		public HttpStatus getStatusCode() throws IOException {
-			return HttpStatus.OK;
-		}
-	}
-
-	private static class MockedResponseErrorHandler extends DefaultResponseErrorHandler {
-
-		@Override
-		public void handleError(@NonNull ClientHttpResponse response) {
-		}
-
-	}
-}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java
new file mode 100644
index 000000000..69867c6ab
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.rpc.enhancement.scg;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.StaticMetadataManager;
+import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.route.Route;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
+
+@ExtendWith(MockitoExtension.class)
+public class EnhancedGatewayGlobalFilterTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	ServerWebExchange exchange;
+	@Mock
+	GatewayFilterChain chain;
+	@Mock
+	ServerHttpResponse response;
+	@Mock
+	ServerHttpRequest request;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+		ApplicationContext applicationContext = mock(ApplicationContext.class);
+		MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class);
+		StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class);
+		doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class);
+		doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class);
+		mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext)
+				.thenReturn(applicationContext);
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void testRun() throws URISyntaxException {
+
+		doReturn(new URI("http://0.0.0.0/")).when(request).getURI();
+		doReturn(new HttpHeaders()).when(request).getHeaders();
+		doReturn(HttpMethod.GET).when(request).getMethod();
+		doReturn(new HttpHeaders()).when(response).getHeaders();
+		doReturn(Mono.empty()).when(chain).filter(exchange);
+		Route route = mock(Route.class);
+		URI uri = new URI("http://TEST/");
+		doReturn(uri).when(route).getUri();
+		doReturn(route).when(exchange).getAttribute(GATEWAY_ROUTE_ATTR);
+		doReturn(new URI("http://0.0.0.0/")).when(exchange).getAttribute(GATEWAY_REQUEST_URL_ATTR);
+		doReturn(request).when(exchange).getRequest();
+		doReturn(response).when(exchange).getResponse();
+
+		EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>()));
+		reporter.getOrder();
+
+		reporter.filter(exchange, chain).block();
+
+		doReturn(Mono.error(new RuntimeException())).when(chain).filter(exchange);
+
+		assertThatThrownBy(() -> reporter.filter(exchange, chain).block()).isInstanceOf(RuntimeException.class);
+
+	}
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java
index 7074a39b6..86c0c74a7 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/PolarisStatPropertiesTest.java
@@ -40,7 +40,8 @@ public class PolarisStatPropertiesTest {
 			.withPropertyValues("spring.cloud.polaris.stat.path=/xxx")
 			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.address=127.0.0.1:9091")
-			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.push-interval=1000");
+			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.push-interval=1000")
+			.withPropertyValues("spring.cloud.gateway.enabled=false");
 
 	@Test
 	public void testDefaultInitialization() {
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java
index ba55b6f2e..fbfdcc9f2 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/stat/config/StatConfigModifierTest.java
@@ -41,7 +41,9 @@ public class StatConfigModifierTest {
 			.withPropertyValues("spring.cloud.polaris.stat.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.stat.host=127.0.0.1")
 			.withPropertyValues("spring.cloud.polaris.stat.port=20000")
-			.withPropertyValues("spring.cloud.polaris.stat.path=/xxx");
+			.withPropertyValues("spring.cloud.polaris.stat.path=/xxx")
+			.withPropertyValues("spring.application.name=test")
+			.withPropertyValues("spring.cloud.gateway.enabled=false");
 
 	private final ApplicationContextRunner pushContextRunner = new ApplicationContextRunner()
 			.withConfiguration(AutoConfigurations.of(TestApplication.class))
@@ -49,12 +51,16 @@ public class StatConfigModifierTest {
 			.withPropertyValues("spring.cloud.polaris.stat.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.address=127.0.0.1:9091")
-			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.push-interval=1000");
+			.withPropertyValues("spring.cloud.polaris.stat.pushgateway.push-interval=1000")
+			.withPropertyValues("spring.application.name=test")
+			.withPropertyValues("spring.cloud.gateway.enabled=false");
 
 	private final ApplicationContextRunner disabledContextRunner = new ApplicationContextRunner()
 			.withConfiguration(AutoConfigurations.of(TestApplication.class))
 			.withPropertyValues("spring.cloud.polaris.enabled=true")
-			.withPropertyValues("spring.cloud.polaris.stat.enabled=false");
+			.withPropertyValues("spring.cloud.polaris.stat.enabled=false")
+			.withPropertyValues("spring.application.name=test")
+			.withPropertyValues("spring.cloud.gateway.enabled=false");
 
 	@Test
 	void testPull() {
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java
new file mode 100644
index 000000000..f8a4a673a
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.rpc.enhancement.webclient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.StaticMetadataManager;
+import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
+import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
+import com.tencent.polaris.client.api.SDKContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import reactor.core.publisher.Mono;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.ExchangeFunction;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+@ExtendWith(MockitoExtension.class)
+public class EnhancedWebClientReporterTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+	@Mock
+	private RpcEnhancementReporterProperties reporterProperties;
+	@Mock
+	private SDKContext sdkContext;
+	@Mock
+	private ClientRequest clientRequest;
+	@Mock
+	private ExchangeFunction exchangeFunction;
+	@Mock
+	private ClientResponse clientResponse;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+		ApplicationContext applicationContext = mock(ApplicationContext.class);
+		MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class);
+		StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class);
+		doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class);
+		doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class);
+		mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext);
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+	@Test
+	public void testRun() throws URISyntaxException {
+
+		doReturn(new URI("http://0.0.0.0/")).when(clientRequest).url();
+		doReturn(new HttpHeaders()).when(clientRequest).headers();
+		doReturn(HttpMethod.GET).when(clientRequest).method();
+		ClientResponse.Headers headers = mock(ClientResponse.Headers.class);
+		doReturn(headers).when(clientResponse).headers();
+		doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any());
+
+		EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(new DefaultEnhancedPluginRunner(new ArrayList<>()));
+		ClientResponse clientResponse1 = reporter.filter(clientRequest, exchangeFunction).block();
+		assertThat(clientResponse1).isEqualTo(clientResponse);
+
+		ClientResponse clientResponse2 = reporter.filter(clientRequest, exchangeFunction).block();
+		assertThat(clientResponse2).isEqualTo(clientResponse);
+
+		doReturn(Mono.error(new RuntimeException())).when(exchangeFunction).exchange(any());
+
+		assertThatThrownBy(() -> reporter.filter(clientRequest, exchangeFunction).block()).isInstanceOf(RuntimeException.class);
+
+
+	}
+
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java
new file mode 100644
index 000000000..811b7c5eb
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.rpc.enhancement.webclient;
+
+import com.tencent.cloud.common.constant.HeaderConstant;
+import com.tencent.cloud.common.metadata.MetadataContext;
+import com.tencent.cloud.common.metadata.MetadataContextHolder;
+import com.tencent.cloud.common.metadata.StaticMetadataManager;
+import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
+import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.reactive.function.client.ClientRequest;
+
+import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
+import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+@ExtendWith(MockitoExtension.class)
+public class PolarisLoadBalancerClientRequestTransformerTest {
+
+	private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
+
+	private PolarisLoadBalancerClientRequestTransformer transformer = new PolarisLoadBalancerClientRequestTransformer();
+
+	@Mock
+	private ClientRequest clientRequest;
+
+	@Mock
+	private ServiceInstance serviceInstance;
+
+	@BeforeAll
+	static void beforeAll() {
+		mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
+		mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
+				.thenReturn("unit-test");
+		ApplicationContext applicationContext = mock(ApplicationContext.class);
+		MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class);
+		StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class);
+		doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class);
+		doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class);
+		mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext);
+	}
+
+	@AfterAll
+	static void afterAll() {
+		mockedApplicationContextAwareUtils.close();
+	}
+
+	@BeforeEach
+	void setUp() {
+		MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST;
+		MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER;
+	}
+
+	@Test
+	public void test() throws Throwable {
+		doReturn("test").when(serviceInstance).getServiceId();
+		transformer.transformRequest(clientRequest, serviceInstance);
+		assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)).isEqualTo("test");
+	}
+}