Skip to content

Commit 1a7fcad

Browse files
authored
Merge pull request #150 from chenneal/feature/circuit-breaker
Add circuit breaker demo
2 parents e78dd61 + ebf19b7 commit 1a7fcad

File tree

15 files changed

+330
-30
lines changed

15 files changed

+330
-30
lines changed

mse-simple-demo/A/build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ set -e
33

44
cd "$(dirname "$0")"
55

6-
docker build --platform linux/amd64 . -t ${REGISTRY}spring-cloud-a:2.0.1
6+
docker build --platform linux/amd64 . -t ${REGISTRY}spring-cloud-a:2.0.2
77

88
if [ -n "${REGISTRY}" ]; then
9-
docker push ${REGISTRY}spring-cloud-a:2.0.1
9+
docker push ${REGISTRY}spring-cloud-a:2.0.2
1010
fi

mse-simple-demo/A/src/main/java/com/alibabacloud/mse/demo/a/AController.java

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.alibabacloud.mse.demo.a;
22

3-
import com.alibabacloud.mse.demo.a.service.FeignClient;
3+
import com.alibabacloud.mse.demo.a.service.FeignClientTest;
44
import com.alibabacloud.mse.demo.b.service.HelloServiceB;
55
import com.alibaba.fastjson.JSON;
66
import io.swagger.annotations.Api;
@@ -19,7 +19,6 @@
1919
import org.springframework.cloud.commons.util.InetUtils;
2020
import org.springframework.http.HttpStatus;
2121
import org.springframework.http.ResponseEntity;
22-
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
2322
import org.springframework.web.bind.annotation.GetMapping;
2423
import org.springframework.web.bind.annotation.PathVariable;
2524
import org.springframework.web.bind.annotation.RestController;
@@ -40,7 +39,7 @@ class AController {
4039
private RestTemplate loadBalancedRestTemplate;
4140

4241
@Autowired
43-
private FeignClient feignClient;
42+
private FeignClientTest feignClient;
4443

4544
@Autowired
4645
@Qualifier("restTemplate")
@@ -280,6 +279,45 @@ public String dubbo_isolate(HttpServletRequest request) {
280279
helloServiceB.hello("isolate");
281280
}
282281

282+
@ApiOperation(value = "熔断 rt 测试", tags = {"流量防护"})
283+
@GetMapping("/circuit-breaker-rt")
284+
public String circuit_breaker_rt(HttpServletRequest request) throws ExecutionException, InterruptedException {
285+
StringBuilder headerSb = new StringBuilder();
286+
Enumeration<String> enumeration = request.getHeaderNames();
287+
while (enumeration.hasMoreElements()) {
288+
String headerName = enumeration.nextElement();
289+
Enumeration<String> val = request.getHeaders(headerName);
290+
while (val.hasMoreElements()) {
291+
String headerVal = val.nextElement();
292+
headerSb.append(headerName + ":" + headerVal + ",");
293+
}
294+
}
295+
296+
String result = feignClient.circuit_breaker_rt_b();
297+
298+
return "A" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" +
299+
"[config=" + configValue + "]" + " -> " + result;
300+
}
301+
302+
@ApiOperation(value = "熔断异常测试" , tags = {"流量防护"})
303+
@GetMapping("/circuit-breaker-exception")
304+
public String circuit_breaker_exception(HttpServletRequest request) throws ExecutionException, InterruptedException {
305+
StringBuilder headerSb = new StringBuilder();
306+
Enumeration<String> enumeration = request.getHeaderNames();
307+
while (enumeration.hasMoreElements()) {
308+
String headerName = enumeration.nextElement();
309+
Enumeration<String> val = request.getHeaders(headerName);
310+
while (val.hasMoreElements()) {
311+
String headerVal = val.nextElement();
312+
headerSb.append(headerName + ":" + headerVal + ",");
313+
}
314+
}
315+
316+
String result = feignClient.circuit_breaker_exception_b();
317+
318+
return "A" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" +
319+
"[config=" + configValue + "]" + " -> " + result;
320+
}
283321

284322
@GetMapping("swagger-demo")
285323
@ApiOperation(value = "这是一个演示swagger的接口 ", tags = {"首页操作页面"})
@@ -288,4 +326,49 @@ public String swagger(@ApiParam(name = "name", value = "我是姓名", required
288326
@ApiParam(name = "aliware-products", value = "我是购买阿里云原生产品列表", required = true) List<String> aliwareProducts) {
289327
return "hello swagger";
290328
}
329+
330+
@ApiOperation(value = "Dubbo rt 熔断测试", tags = {"入口应用"})
331+
@GetMapping("/dubbo-circuit-breaker-rt")
332+
public String dubbo_circuit_breaker_rt(HttpServletRequest request) {
333+
StringBuilder headerSb = new StringBuilder();
334+
Enumeration<String> enumeration = request.getHeaderNames();
335+
while (enumeration.hasMoreElements()) {
336+
String headerName = enumeration.nextElement();
337+
Enumeration<String> val = request.getHeaders(headerName);
338+
while (val.hasMoreElements()) {
339+
String headerVal = val.nextElement();
340+
headerSb.append(headerName + ":" + headerVal + ",");
341+
}
342+
}
343+
344+
return "A" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " -> " +
345+
helloServiceB.slow();
346+
}
347+
348+
@ApiOperation(value = "Dubbo 异常熔断测试", tags = {"入口应用"})
349+
@GetMapping("/dubbo-circuit-breaker-exception")
350+
public String dubbo_circuit_breaker_exception(HttpServletRequest request) {
351+
352+
StringBuilder headerSb = new StringBuilder();
353+
Enumeration<String> enumeration = request.getHeaderNames();
354+
while (enumeration.hasMoreElements()) {
355+
String headerName = enumeration.nextElement();
356+
Enumeration<String> val = request.getHeaders(headerName);
357+
while (val.hasMoreElements()) {
358+
String headerVal = val.nextElement();
359+
headerSb.append(headerName + ":" + headerVal + ",");
360+
}
361+
}
362+
String response = "";
363+
try {
364+
response = helloServiceB.exception();
365+
} catch (Exception ex) {
366+
if (ex.getClass().getName().contains("com.alibaba.csp.sentinel")) {
367+
response = "Service is in abnormal status now, and block by mse circuit rule!";
368+
} else {
369+
response = "Service is in abnormal status and throws exception by itself!";
370+
}
371+
}
372+
return "A" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " -> " + response;
373+
}
291374
}

mse-simple-demo/A/src/main/java/com/alibabacloud/mse/demo/a/service/FeignClient.java

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.alibabacloud.mse.demo.a.service;
2+
3+
import org.springframework.cloud.openfeign.FallbackFactory;
4+
import org.springframework.stereotype.Component;
5+
6+
@Component
7+
public class FeignClientFallback implements FallbackFactory<FeignClientTest> {
8+
9+
static class FeignClientTestFallback implements FeignClientTest {
10+
11+
private final String finalMsg;
12+
13+
public FeignClientTestFallback(String finalMsg) {
14+
this.finalMsg = finalMsg;
15+
}
16+
17+
@Override
18+
public String bByFeign(String s) {
19+
return finalMsg;
20+
}
21+
22+
@Override
23+
public String circuit_breaker_rt_b() {
24+
return finalMsg;
25+
}
26+
27+
@Override
28+
public String circuit_breaker_exception_b() {
29+
return finalMsg;
30+
}
31+
}
32+
33+
@Override
34+
public FeignClientTest create(Throwable throwable) {
35+
if (throwable == null) {
36+
return new FeignClientTestFallback("Unknown error");
37+
}
38+
if (throwable.getClass().getName().contains("com.alibaba.csp.sentinel")) {
39+
return new FeignClientTestFallback("Service is in abnormal status now, and block by mse circuit rule!");
40+
}
41+
42+
return new FeignClientTestFallback("Service is in abnormal status and throws exception by itself!");
43+
}
44+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.alibabacloud.mse.demo.a.service;
2+
3+
import org.springframework.cloud.openfeign.FeignClient;
4+
import org.springframework.stereotype.Component;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.RequestParam;
7+
8+
/**
9+
* @author yushan
10+
* @date 2023年02月21日
11+
*/
12+
@Component
13+
@FeignClient(name = "sc-B", fallbackFactory = FeignClientFallback.class)
14+
public interface FeignClientTest {
15+
16+
@GetMapping("/bByFeign")
17+
String bByFeign(@RequestParam("s") String s);
18+
19+
@GetMapping("/circuit-breaker-rt-b")
20+
String circuit_breaker_rt_b();
21+
22+
@GetMapping("/circuit-breaker-exception-b")
23+
String circuit_breaker_exception_b();
24+
}

mse-simple-demo/A/src/main/java/com/alibabacloud/mse/demo/b/service/HelloServiceB.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
public interface HelloServiceB {
44
String hello(String name);
5+
String slow();
6+
String exception();
57
}

mse-simple-demo/B/build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
cd "$(dirname "$0")"
44

5-
docker build --platform linux/amd64 . -t ${REGISTRY}spring-cloud-b:2.0.1
5+
docker build --platform linux/amd64 . -t ${REGISTRY}spring-cloud-b:2.0.2
66

77
if [ -n "${REGISTRY}" ]; then
8-
docker push ${REGISTRY}spring-cloud-b:2.0.1
8+
docker push ${REGISTRY}spring-cloud-b:2.0.2
99
fi

mse-simple-demo/B/src/main/java/com/alibabacloud/mse/demo/b/BController.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.alibaba.fastjson.JSON;
44
import com.alibabacloud.mse.demo.c.service.HelloServiceC;
55
import com.alibabacloud.mse.demo.entity.User;
6+
import com.alibabacloud.mse.demo.common.TrafficAttribute;
67
import org.apache.dubbo.config.annotation.Reference;
78
import org.apache.http.HttpResponse;
89
import org.apache.http.client.HttpClient;
@@ -103,6 +104,32 @@ public String bByFeign(String s) {
103104
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]";
104105
}
105106

107+
@GetMapping("/circuit-breaker-rt-b")
108+
public String circuit_breaker_rt_b() {
109+
110+
Integer rt = TrafficAttribute.getInstance().getRt();
111+
Integer ration = TrafficAttribute.getInstance().getSlowRation();
112+
113+
boolean isSlowRequest = RANDOM.nextInt(100) < ration ? true : false;
114+
if (isSlowRequest) {
115+
silentSleep(rt);
116+
}
117+
118+
String slowMessage = isSlowRequest ? " RT:" + rt : "";
119+
120+
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + slowMessage;
121+
}
122+
123+
@GetMapping("/circuit-breaker-exception-b")
124+
public String circuit_breaker_exception_b() {
125+
Integer ration = TrafficAttribute.getInstance().getExceptionRation();
126+
boolean isExceptionRequest = RANDOM.nextInt(100) < ration ? true : false;
127+
if (isExceptionRequest) {
128+
throw new RuntimeException("TestCircuitBreakerException");
129+
}
130+
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]";
131+
}
132+
106133
@GetMapping("/b-zone")
107134
public String bZone(HttpServletRequest request) {
108135
return "B" + serviceTag + "[" + currentZone + "]" + " -> " +
@@ -149,6 +176,41 @@ public String sql(HttpServletRequest request) {
149176
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " result:" + result;
150177
}
151178

179+
@GetMapping("/set-traffic-attribute")
180+
public String set_traffic_attribute(HttpServletRequest request) {
181+
String slowRT = request.getParameter("rt");
182+
String slowRation = request.getParameter("slowRation");
183+
String exceptionRation = request.getParameter("exceptionRation");
184+
185+
String responseMessage = "";
186+
187+
try {
188+
Integer iSlowRT = Integer.parseInt(slowRT);
189+
responseMessage += "Adjust RT " + iSlowRT + "ms ";
190+
TrafficAttribute.getInstance().setRt(iSlowRT);
191+
} catch (NumberFormatException e) {
192+
;
193+
}
194+
195+
try {
196+
Integer iSlowRation = Integer.parseInt(slowRation);
197+
TrafficAttribute.getInstance().setSlowRation(iSlowRation);
198+
responseMessage += "Adjust slow ration to " + iSlowRation + "% ";
199+
} catch (NumberFormatException e) {
200+
;
201+
}
202+
203+
try {
204+
Integer iExceptionRation = Integer.parseInt(exceptionRation);
205+
TrafficAttribute.getInstance().setExceptionRation(iExceptionRation);
206+
responseMessage += "Adjust exception ration to " + iExceptionRation + "% ";
207+
} catch (NumberFormatException e) {
208+
;
209+
}
210+
211+
return responseMessage;
212+
}
213+
152214

153215
private void silentSleep(long ms) {
154216
try {

mse-simple-demo/B/src/main/java/com/alibabacloud/mse/demo/b/service/HelloServiceB.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
public interface HelloServiceB {
44
String hello(String name);
5+
String slow();
6+
String exception();
57
}

mse-simple-demo/B/src/main/java/com/alibabacloud/mse/demo/b/service/HelloServiceBImpl.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.alibabacloud.mse.demo.b.service;
22

33
import com.alibabacloud.mse.demo.c.service.HelloServiceC;
4+
import com.alibabacloud.mse.demo.common.TrafficAttribute;
45
import org.apache.dubbo.config.annotation.Reference;
56
import org.apache.dubbo.config.annotation.Service;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.cloud.commons.util.InetUtils;
9+
import java.util.Random;
10+
import java.util.concurrent.TimeUnit;
811

912
@Service(version = "1.2.0")
1013
public class HelloServiceBImpl implements HelloServiceB {
@@ -18,10 +21,40 @@ public class HelloServiceBImpl implements HelloServiceB {
1821
@Reference(application = "${dubbo.application.id}", version = "1.2.0")
1922
private HelloServiceC helloServiceC;
2023

24+
private static final Random RANDOM = new Random();
25+
2126
@Override
2227
public String hello(String name) {
2328
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " params:" + name + " -> " +
2429
helloServiceC.hello(name);
2530
}
2631

32+
@Override
33+
public String slow() {
34+
Integer rt = TrafficAttribute.getInstance().getRt();
35+
Integer ration = TrafficAttribute.getInstance().getSlowRation();
36+
boolean isSlowRequest = RANDOM.nextInt(100) < ration ? true : false;
37+
if (isSlowRequest) {
38+
silentSleep(rt);
39+
}
40+
String slowMessage = isSlowRequest ? " slowRt:" + rt : "";
41+
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + slowMessage;
42+
}
43+
44+
@Override
45+
public String exception() {
46+
Integer ration = TrafficAttribute.getInstance().getExceptionRation();
47+
boolean isExceptionRequest = RANDOM.nextInt(100) < ration ? true : false;
48+
if (isExceptionRequest) {
49+
throw new RuntimeException("TestCircuitBreakerException");
50+
}
51+
return "B" + serviceTag + "[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " exceptionRation:" + ration;
52+
}
53+
54+
private void silentSleep(long ms) {
55+
try {
56+
TimeUnit.MILLISECONDS.sleep(ms);
57+
} catch (InterruptedException ignored) {
58+
}
59+
}
2760
}

0 commit comments

Comments
 (0)