You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2021/04/27 07:56:01 UTC
[servicecomb-java-chassis] branch master updated:
[SCB-2257][SCB-2258]governance support http based match (#2361)
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new 09e5381 [SCB-2257][SCB-2258]governance support http based match (#2361)
09e5381 is described below
commit 09e538166a6902cd55cc0495d2439149b8f16d84
Author: bao liu <bi...@qq.com>
AuthorDate: Tue Apr 27 15:55:52 2021 +0800
[SCB-2257][SCB-2258]governance support http based match (#2361)
* [SCB-2257][SCB-2258]governance support http based match
* [SCB-2257][SCB-2258]add swagger arguments to header
* [SCB-2257][SCB-2258]ignore null value
---
.../core/definition/OperationConfig.java | 11 +++
.../demo/zeroconfig/client/GovernanceEndpoint.java | 12 ++++
.../src/main/resources/application.yml | 29 ++++++--
.../demo/zeroconfig/server/GovernanceEndpoint.java | 8 +++
.../demo/zeroconfig/tests/GovernanceTest.java | 30 ++++++--
.../src/main/resources/application.yml | 5 +-
.../governance/ConsumerGovernanceHandler.java | 10 +--
.../servicecomb/handler/governance/MatchType.java | 84 ++++++++++++++++++++++
.../governance/ProviderGovernanceHandler.java | 10 +--
9 files changed, 170 insertions(+), 29 deletions(-)
diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java b/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
index c210efd..17e5cf1 100644
--- a/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
+++ b/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
@@ -108,6 +108,9 @@ public class OperationConfig {
})
private String transport;
+ @InjectProperty(keys = {"governance.${op-any-priority}.matchType", "governance.matchType"}, defaultValue = "rest")
+ private String governanceMatchType;
+
public boolean isSlowInvocationEnabled() {
return slowInvocationEnabled;
}
@@ -195,6 +198,14 @@ public class OperationConfig {
this.nanoInvocationTimeout = TimeUnit.MILLISECONDS.toNanos(msInvocationTimeout);
}
+ public String getGovernanceMatchType() {
+ return governanceMatchType;
+ }
+
+ public void setGovernanceMatchType(String governanceMatchType) {
+ this.governanceMatchType = governanceMatchType;
+ }
+
public long getNanoInvocationTimeout() {
return this.nanoInvocationTimeout;
}
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
index 0d99ffe..8c77c7c 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
@@ -38,6 +38,11 @@ public class GovernanceEndpoint {
return restTemplate.getForObject(SERVER + "/governance/hello", String.class);
}
+ @GetMapping("/helloRpc")
+ public String helloRpc() {
+ return restTemplate.getForObject(SERVER + "/governance/hello", String.class);
+ }
+
@GetMapping("/retry")
public String retry(@RequestParam(name = "invocationID") String invocationID) {
return restTemplate
@@ -45,6 +50,13 @@ public class GovernanceEndpoint {
invocationID);
}
+ @GetMapping("/retryRpc")
+ public String retryRpc(@RequestParam(name = "invocationID") String invocationID) {
+ return restTemplate
+ .getForObject(SERVER + "/governance/retryRpc?invocationID={1}", String.class,
+ invocationID);
+ }
+
@GetMapping("/circuitBreaker")
public String circuitBreaker() throws Exception {
count++;
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
index c43c4ce..1eb345f 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
@@ -41,33 +41,54 @@ servicecomb:
Provider:
default: governance-provider
+ governance:
+ GovernanceEndpoint.helloRpc:
+ matchType: rpc
+ demo-zeroconfig-schemadiscovery-registry-server.GovernanceEndpoint.retryRpc:
+ matchType: rpc
matchGroup:
demo-rateLimiting: |
matches:
- apiPath:
- exact: "GovernanceEndpoint.hello"
+ exact: "/governance/hello"
+ demo-rateLimiting-rpc: |
+ matches:
+ - apiPath:
+ exact: "GovernanceEndpoint.helloRpc"
demo-retry: |
matches:
- apiPath:
- exact: "GovernanceEndpoint.retry"
+ exact: "/governance/retry"
+ demo-retry-rpc: |
+ matches:
+ - apiPath:
+ exact: "demo-zeroconfig-schemadiscovery-registry-server.GovernanceEndpoint.retryRpc"
demo-circuitBreaker: |
matches:
- apiPath:
- exact: "GovernanceEndpoint.circuitBreaker"
+ exact: "/governance/circuitBreaker"
demo-bulkhead: |
matches:
- apiPath:
- exact: "GovernanceEndpoint.bulkhead"
+ exact: "/governance/bulkhead"
rateLimiting:
demo-rateLimiting: |
rate: 10
## services is optional in configuration file
services: demo-zeroconfig-schemadiscovery-registry-client
+ demo-rateLimiting-rpc: |
+ rate: 10
+ ## services is optional in configuration file
+ services: demo-zeroconfig-schemadiscovery-registry-client
retry:
demo-retry: |
maxAttempts: 3
## services is optional in configuration file
services: demo-zeroconfig-schemadiscovery-registry-client
+ demo-retry-rpc: |
+ maxAttempts: 3
+ ## services is optional in configuration file
+ services: demo-zeroconfig-schemadiscovery-registry-client
circuitBreaker:
demo-circuitBreaker: |
minimumNumberOfCalls: 10
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
index 718a242..4e7e15f 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
@@ -60,6 +60,14 @@ public class GovernanceEndpoint {
throw new InvocationException(502, "retry", "retry");
}
+ @GetMapping("/retryRpc")
+ @ApiResponses({
+ @ApiResponse(code = 200, response = String.class, message = ""),
+ @ApiResponse(code = 502, response = String.class, message = "")})
+ public String retryRpc(@RequestParam(name = "invocationID") String invocationID) {
+ return retry(invocationID);
+ }
+
@GetMapping("/circuitBreaker")
public String circuitBreaker() {
throw new RuntimeException("circuitBreaker by provider.");
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
index 40161bf..dfb4bba 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
@@ -38,13 +38,23 @@ public class GovernanceTest implements CategorizedTestCase {
public void testRestTransport() throws Exception {
testCircuitBreaker();
testBulkhead();
- testRateLimiting();
- testRetry();
+ testRateLimitingRest();
+ testRateLimitingRpc();
+ testRetryRest();
+ testRetryRpc();
}
- private void testRetry() {
+ private void testRetryRest() {
+ testRetry("/retry");
+ }
+
+ private void testRetryRpc() {
+ testRetry("/retryRpc");
+ }
+
+ private void testRetry(String operation) {
String invocationID = UUID.randomUUID().toString();
- String result = template.getForObject(url + "/retry?invocationID={1}", String.class, invocationID);
+ String result = template.getForObject(url + operation + "?invocationID={1}", String.class, invocationID);
TestMgr.check(result, "try times: 3");
}
@@ -121,7 +131,15 @@ public class GovernanceTest implements CategorizedTestCase {
TestMgr.check(false, notExpectedFailed.get());
}
- private void testRateLimiting() throws Exception {
+ private void testRateLimitingRest() throws Exception {
+ testRateLimiting("/hello");
+ }
+
+ private void testRateLimitingRpc() throws Exception {
+ testRateLimiting("/helloRpc");
+ }
+
+ private void testRateLimiting(String operation) throws Exception {
CountDownLatch latch = new CountDownLatch(100);
AtomicBoolean expectedFailed = new AtomicBoolean(false);
AtomicBoolean notExpectedFailed = new AtomicBoolean(false);
@@ -132,7 +150,7 @@ public class GovernanceTest implements CategorizedTestCase {
new Thread(name) {
public void run() {
try {
- String result = template.getForObject(url + "/hello", String.class);
+ String result = template.getForObject(url + operation, String.class);
if (!"Hello world!".equals(result)) {
notExpectedFailed.set(true);
}
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
index 9d610e0..e139ef0 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
@@ -25,4 +25,7 @@ servicecomb:
handler:
chain:
Consumer:
- default: loadbalance
\ No newline at end of file
+ default: loadbalance
+ loadbalance:
+ isolation:
+ enabled: false
\ No newline at end of file
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
index 15e6b08..e52e4d2 100644
--- a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
@@ -63,7 +63,7 @@ public class ConsumerGovernanceHandler implements Handler {
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation);
DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);
- GovernanceRequest request = createGovHttpRequest(invocation);
+ GovernanceRequest request = MatchType.createGovHttpRequest(invocation);
try {
ServiceCombInvocationContext.setInvocationContext(invocation);
@@ -138,12 +138,4 @@ public class ConsumerGovernanceHandler implements Handler {
return result;
};
}
-
- private GovernanceRequest createGovHttpRequest(Invocation invocation) {
- GovernanceRequest request = new GovernanceRequest();
- request.setUri(invocation.getSchemaId() + "." + invocation.getOperationName());
- request.setMethod(invocation.getOperationMeta().getHttpMethod());
- request.setHeaders(invocation.getContext());
- return request;
- }
}
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java
new file mode 100644
index 0000000..f9f08bd
--- /dev/null
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.servicecomb.handler.governance;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.governance.marker.GovernanceRequest;
+
+public final class MatchType {
+ public static final String REST = "rest";
+
+ public static final String RPC = "rpc";
+
+ public static GovernanceRequest createGovHttpRequest(Invocation invocation) {
+ GovernanceRequest request = new GovernanceRequest();
+
+ if (MatchType.REST.equalsIgnoreCase(invocation.getOperationMeta().getConfig().getGovernanceMatchType())) {
+ if (invocation.isConsumer()) {
+ request.setUri(
+ invocation.getSchemaMeta().getSwagger().getBasePath() + invocation.getOperationMeta().getOperationPath());
+ request.setMethod(invocation.getOperationMeta().getHttpMethod());
+ request.setHeaders(getHeaderMap(invocation, true));
+ return request;
+ }
+ request.setUri(invocation.getRequestEx().getRequestURI());
+ request.setMethod(invocation.getRequestEx().getMethod());
+ request.setHeaders(getHeaderMap(invocation, false));
+ return request;
+ }
+
+ if (invocation.isConsumer()) {
+ request.setUri(invocation.getOperationMeta().getMicroserviceQualifiedName());
+ } else {
+ request.setUri(invocation.getOperationMeta().getSchemaQualifiedName());
+ }
+ request.setMethod(invocation.getOperationMeta().getHttpMethod());
+ request.setHeaders(getHeaderMap(invocation, true));
+
+ return request;
+ }
+
+ private static Map<String, String> getHeaderMap(Invocation invocation, boolean fromContext) {
+ Map<String, String> headers = new HashMap<>();
+ if (fromContext) {
+ headers.putAll(invocation.getContext());
+ } else {
+ Enumeration<String> names = invocation.getRequestEx().getHeaderNames();
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ if (invocation.getRequestEx().getHeader(name) != null) {
+ headers.put(name, invocation.getRequestEx().getHeader(name));
+ }
+ }
+ }
+
+ Map<String, Object> arguments = invocation.getSwaggerArguments();
+ if (arguments != null) {
+ arguments.forEach((k, v) -> {
+ if (v != null) {
+ headers.put(k, v.toString());
+ }
+ });
+ }
+ return headers;
+ }
+}
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
index fefae9f..e31cfd2 100644
--- a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
@@ -58,7 +58,7 @@ public class ProviderGovernanceHandler implements Handler {
Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation);
DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);
- GovernanceRequest request = createGovHttpRequest(invocation);
+ GovernanceRequest request = MatchType.createGovHttpRequest(invocation);
try {
ServiceCombInvocationContext.setInvocationContext(invocation);
@@ -136,12 +136,4 @@ public class ProviderGovernanceHandler implements Handler {
return result;
};
}
-
- private GovernanceRequest createGovHttpRequest(Invocation invocation) {
- GovernanceRequest request = new GovernanceRequest();
- request.setUri(invocation.getSchemaId() + "." + invocation.getOperationName());
- request.setMethod(invocation.getOperationMeta().getHttpMethod());
- request.setHeaders(invocation.getContext());
- return request;
- }
}