Implementation of current limiting in java distributed applications

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 CAPtheory 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 Zookeeperimplementation, using Redisimplementation, etc.

The methods summarized above are solutions to distributed concurrency problems. This article mainly optimizes and solves current limiting in high concurrency scenarios.

Limiting

javaConcurrent current limit

Java concurrency tools (four) Semaphore
Java concurrency tools (three) Exchanger
Java concurrency tools (two) CyclicBarrier
Java Concurrency Tools (1) CountDownLatch

javaThe 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 Rediscurrent limiting
RedisThe setnxoperation

A fixed time window size will not have the effect of a sliding window, unless it is in accordance with N:Nthat, that is, N unit time corresponds to None key, and the counting is realized dynamically.

RedisData 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;

    }
RedisToken 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 Hystrixcurrent limiting

NetflixUnder 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.

FutureCurrent 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();
        }
    }
}

Hystrixachieve

@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 Sentinelcurrent limiting

SentinelIt 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();// 资源释放
                }
            }
        }
    }
SentinelCompared 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

Guess you like

Origin blog.csdn.net/shang_xs/article/details/108449708