maven依赖
<!--限流--> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-ratelimiter</artifactId> </dependency> <!--隔离--> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-bulkhead</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId> </dependency>
消费者(服务调用方)
import com.sunxiao.cloud.apis.PayFeignApi;
import com.sunxiao.cloud.util.Result;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/feign")
public class OrderCircuitController {
@Resource
private PayFeignApi payFeignApi;
@GetMapping("/pay/circuit/get/{id}")
@CircuitBreaker(name = "cloud-payment-service", fallbackMethod = "fallback4CircuitBreaker")
public Result<String> getPayById4CircuitBreaker(@PathVariable("id") Integer id) {
return payFeignApi.myCircuit(id);
}
@GetMapping("/pay/semaphore/get/{id}")
@Bulkhead(name = "cloud-payment-service", fallbackMethod = "fallback4BulkheadThreadPool", type = Bulkhead.Type.THREADPOOL)
public CompletableFuture<Result<String>> getPayById4Bulkhead(@PathVariable("id") Integer id) {
System.out.println(Thread.currentThread().getName() + " into ...");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + " over ...");
return CompletableFuture.supplyAsync(() -> payFeignApi.mySemaphore(id));
}
@GetMapping("/pay/semaphore/get2/{id}")
@Bulkhead(name = "cloud-payment-service", fallbackMethod = "fallback4Bulkhead", type = Bulkhead.Type.SEMAPHORE)
public Result<String> getPayById4Bulkhead2(@PathVariable("id") Integer id) {
System.out.println(Thread.currentThread().getName() + " into ...");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + " over ...");
return payFeignApi.mySemaphore(id);
}
@GetMapping("/pay/rateLimit/get/{id}")
@RateLimiter(name = "cloud-payment-service", fallbackMethod = "fallback4RateLimit")
public Result<String> getPayById4RateLimit(@PathVariable("id") Integer id) {
return payFeignApi.mySemaphore(id);
}
public Result<String> fallback4CircuitBreaker(Throwable throwable) {
return Result.fail("系统繁忙, 请稍后重试.........熔断");
}
public Result<String> fallback4Bulkhead(Throwable throwable) {
return Result.fail("超出最大请求数量限制, 请稍后重试...");
}
public CompletableFuture<Result<String>> fallback4BulkheadThreadPool(Throwable throwable) {
return CompletableFuture.supplyAsync(() -> Result.fail("超出最大请求数量限制, 请稍后重试......线程池隔离"));
}
public Result<String> fallback4RateLimit(Throwable throwable) {
return Result.success("服务器限流, 请稍后重试...");
}
}
服务端
import cn.hutool.core.util.IdUtil;
import com.sunxiao.cloud.util.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* 测试Resilience4j用
* 服务端
*/
@RestController
public class PayCircuitController {
@GetMapping("/pay/circuit/{id}")
public Result<String> myCircuit(@PathVariable("id") Integer id) {
if (id < 0) {
throw new RuntimeException("Id不能为负数 ... ");
}
if (id == 9999) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
return Result.success("Hello" + id + IdUtil.simpleUUID());
}
@GetMapping("/pay/semaphore/{id}")
public Result<String> mySemaphore(@PathVariable("id") Integer id) {
System.out.println(Thread.currentThread().getName() + " into ...");
if (id < 0) {
throw new RuntimeException("Id不能为负数 ... ");
}
if (id == 9999) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " over ...");
return Result.success("Hello" + id + IdUtil.simpleUUID());
}
@GetMapping("/pay/rateLimit/{id}")
public Result<String> myRateLimit(@PathVariable("id") Integer id) {
return Result.success("Hello" + id + IdUtil.simpleUUID());
}
}