Implementation of current limiting in java distributed applications
Inscription
As we all know, there are many distributed current-limiting tools nowadays, and the support for different application frameworks is not the same. It is the most suitable to choose the current-limiting technology that suits the current project architecture.
distributed
What is distributed
Distributed system ( distributed system
) is a software system built on the network. It is precisely because of the characteristics of software that distributed systems are highly cohesive and transparent. Therefore, the difference between a network and a distributed system lies more in high-level software (especially operating systems) rather than hardware.
Advantages of distributed system
Increasing the concurrency and throughput rate of the system, in layman's terms, is the difference between a single machine and multiple machines working at the same time.
Distributed core problem
System problems caused by concurrency, the famous CAP
theory is the interpretation of distributed system problems: consistency, availability, partition fault tolerance
Data consistency solution
The simplest and most common method is to implement distributed locks, such as: using database implementation, using Zookeeper
implementation, using Redis
implementation, etc.
The methods summarized above are solutions to distributed concurrency problems. This article mainly optimizes and solves current limiting in high concurrency scenarios.
Limiting
java
Concurrent current limit
Java concurrency tools (four) Semaphore
Java concurrency tools (three) Exchanger
Java concurrency tools (two) CyclicBarrier
Java Concurrency Tools (1) CountDownLatch
java
The current limit refers to the restriction on the interface execution in the stand-alone scenario, which can meet the specified scenario. But it is out of date for systems with distributed architecture.
Distributed application current limit
There are many ideas for implementing distributed current limiting
Based on Redis
current limiting
Redis
The setnx
operation
A fixed time window size will not have the effect of a sliding window, unless it is in accordance with N:N
that, that is, N unit time corresponds to N
one key
, and the counting is realized dynamically.
Redis
Data structurezset
public boolean limitZset(){
int currentTime = Helper.getCurrentTime();
int intervalTime = 10 * 1000;
System.err.println("开始时间:" + currentTime);
if(redisTemplate.hasKey("limit_key")) {
Integer count = redisTemplate.opsForZSet().rangeByScore("limit_key", currentTime - intervalTime, currentTime).size(); // intervalTime是限流的时间
System.out.println(count);
if (count != null && count > 5) {
return false;
}
}
redisTemplate.opsForZSet().add("limit_key",UUID.randomUUID().toString(),currentTime);
System.err.println("结束时间:" + Helper.getCurrentTime());
return true;
}
Redis
Token bucket algorithm
public boolean limitLeakyBuckets (){
Object result = redisTemplate.opsForList().leftPop("limit_leaky_buckets");
if(result == null){
return false;
}
return true;
}
@Scheduled(fixedDelay = 10000,initialDelay = 0)
public void setToken(){
redisTemplate.opsForList().rightPush("limit_leaky_buckets",UUID.randomUUID().toString());
}
}
Based on Hystrix
current limiting
Netflix
Under the practice of the distributed microservice architecture, the company calls its client fuse and circuit breaker solutions designed to protect the stability of the service Hystrix
.
Future
Current limit realization
public class FutureDemo {
private static final Random random = new Random();
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(()->{
int nextInt = random.nextInt(200);
System.out.printf("Thread : %s,睡眠时间: %s ms \n", Thread.currentThread().getName(),nextInt);
try {
Thread.sleep(nextInt);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
executorService.shutdown();
}
return "hello world";
});
try {
future.get(100, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
System.out.println("服务熔断保护");
e.printStackTrace();
}
}
}
Hystrix
achieve
@RestController
public class HelloWorldController {
private final Random random = new Random();
@GetMapping("/hello")
@HystrixCommand(fallbackMethod = "errorOfHello",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")
}
)
public String hello() throws InterruptedException {
int nextInt = random.nextInt(200);
System.out.printf("Thread : %s,睡眠时间: %s ms \n", Thread.currentThread().getName(), nextInt);
Thread.sleep(nextInt);
return "hello world";
}
@GetMapping("/hello2")
public String hello2() throws InterruptedException {
return new HystrixCommendDemo().execute();
}
public String errorOfHello() {
return "error of hello world";
}
}
Based on Sentinel
current limiting
Sentinel
It is an open-source, lightweight and highly available flow control component for distributed service architecture by the Ali middleware team. It mainly uses flow as the entry point to help users protect services from multiple dimensions such as flow control, fuse degradation, and system load protection. stability.
public static void main(String[] args) {
initFlowRules(); //初始化规则
while(true){
Entry entry=null;
try{
entry= SphU.entry(resource); //准入判断
System.out.println("Hello Word");
}catch (BlockException e){
//异常处理
e.printStackTrace();
}finally {
if(entry!=null){
entry.exit();// 资源释放
}
}
}
}
Sentinel
Compared Hystrix
Contrast content | Sentinel | Hystrix |
---|---|---|
Isolation strategy | Semaphore isolation | Thread pool isolation/semaphore isolation |
Fuse downgrade strategy | Based on response time or failure rate | Based on failure rate |
Real-time indicator realization | Sliding window | Sliding window (based on RxJava) |
Rule configuration | Support multiple data sources | Support multiple data sources |
Scalability | Multiple extension points | Plug-in form |
Annotation-based support | stand by | stand by |
Limiting | Based on QPS, support current limit based on call relationship | not support |
Traffic shaping | Support slow start, uniform speed mode | not support |
System load protection | stand by | not support |
Console | Out of the box, you can configure rules, view second-level monitoring, machine discovery, etc. | imperfect |
Adaptation of common frameworks | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |