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、