RateLimiter限流


1、處理高並發

  1.1高並發處理方案: 

  • 緩存 緩存的目的是提升系統訪問速度和增大系統處理容量
  • 降級 降級是當服務出現問題或者影響到核心流程時,需要暫時屏蔽掉,待高峰或者問題解決后再打開
  • 限流 限流的目的是通過對並發訪問/請求進行限速,或者對一個時間窗口內的請求進行限速來保護系統,一旦達到限制速率則可以拒絕服務、排隊或等待、降級等處理

  1、2限流方式: mq、ratelimiter

   

2、ratelimiter是基於令牌桶算法來做的 

  guava的RateLimiter使用的是令牌桶算法,也就是以固定的頻率向桶中放入令牌,例如一秒鍾10枚令牌,實際業務在每次響應請求之前都從桶中獲取令牌,只有取到令牌的請求才會被成功響應,獲取的方式有兩種:阻塞等待令牌或者取不到立即返回失敗

                                                                                    

 另外簡單介紹漏銅算法:

  請求以一定速度進入漏桶中,如果請求速度>處理請求速度則溢出,漏桶算法能強行處理請求速率。但如果在處理高並發時,突然來大量請求這種方案不合適  

                                                                          

 

令牌桶代碼:create():每秒創建多少令牌

      tryacquire():嘗試獲取令牌,tryacquire():嘗試獲取一個令牌,如果獲取不到立即返回;tryacquire(int permits, long timeout, TimeUnit unit):嘗試獲取permits個令牌,如果獲取不到等待timeout時間

·核心算法:

package com.leolztang.sb.aop.ratelimiter;

import org.springframework.stereotype.Service;

import com.google.common.util.concurrent.RateLimiter;

@Service
public class AccessLimitService {
    RateLimiter rateLimiter=RateLimiter.create(100.0);
    //嘗試獲取令牌
    public boolean tryAcquire() {
        return rateLimiter.tryAcquire();
    }
}

測試類: 

package com.leolztang.sb.aop.ratelimiter;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/limit")
public class AccessLimiterController {
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(120);
    @Autowired
    private AccessLimitService accessLimitService;
    
    @RequestMapping(value="/ratelimit",method = RequestMethod.GET)
    @ResponseBody
    public void tryForVisit() {
        for(int i=0;i<200;i++) {
            fixedThreadPool.execute(new Runnable() {
                
                @Override
                public void run() {
                    String str=visitAccess();
                    System.out.println("output:"+str);
                }
            });
        }
    }
    
    
    
    public String visitAccess() {
        if(accessLimitService.tryAcquire()) {
            try {
                Thread.sleep(2000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            return "aceess success [" + sdf.format(new Date()) + "]";
        }else {
            return "aceess limit [" + sdf.format(new Date()) + "]";
        }
    }
}

pom文件引入guava依賴:

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>

 
3、


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM