Java使用Semaphore對單接口進行限流

一、實戰說明

1.1 效果說明

本篇主要講如何使用Semaphore對單接口進行限流,例如有如下場景
a. A系統的有a接口主要給B系統調用,現在希望對B系統進行限流,例如處理峰值在100,超過100的請求快速失敗
b. 接口作為總閘入口,希望限制所有外來訪問,例如某個房間隻能同時100個玩傢在線,隻有前面的處理完後面的才能繼續請求
c. 其他類型場景,也就是資源固定的情況下需要輪流使用資源的可以采用Semaphore

不適用場景
a. 由於是針對總入口進行限流,所以不能根據IP或者token等進行限流,適用場景比較固定
b. 後續的博客中會介紹如何使用其他的針對IP/Token級別的限流,例如AOP+Redis+Lua進行限流

優點主要有
a. 相比針對IP級別的限流,Semaphore實現相對簡單,對上述場景能快速實現限流效果

實現難度:3顆星

1.2 核心知識點

主要使用以下技術點
a. springboot
b. juc包中的Semaphore(tryAcquire、release方法)

Semaphore主要說明
a. Semaphore中可以通過tryAcquire和acquire獲取到一個許可證(默認),通過release釋放許可證
b. 兩個獲取許可證的主要區別就是前者是非阻塞而後者阻塞,如果我們要實現快速失敗的效果,就必須使用非阻塞獲取許可證方法
註意點
a. 一定要確保release方法被調用,例如放到finally中,否則許可證得不到釋放,將會導致接口被全部陷死,無法接收請求

二、 環境搭建

環境使用idea+spring initializr創建
新建springboot web項目

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

包目錄說明

在這裡插入圖片描述

新建SemaphoreController,請求路徑為limit
a. 註意點已經代碼註釋說明

package com.codecoord.semaphore.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Semaphore;

/**
 * 限流側測試
 *
 * @author [email protected]
 * @since 2020-08-06
 */
@RestController
public class SemaphoreController {
    /**
     * 最大信號量,例如此處3,生成環境可以做成可配置項,通過註入方式進行註入
     */
    private static final int MAX_SEMAPHORE = 3;
    /**
     * Semaphore主限流,全局就行
     */
    private static final Semaphore SEMAPHORE = new Semaphore(MAX_SEMAPHORE);

    @RequestMapping("/limit")
    public String limit() {
        // 01.使用非阻塞tryAcquire,如果獲取不到就快速返回失敗
        if (!SEMAPHORE.tryAcquire()) {
            return "請求頻率超過限制:" + MAX_SEMAPHORE;
        }

        // 02. 如果能進入到這裡,說明一定獲取到瞭許可證
        /// todo 可能的參數校驗,註意如果參數校驗不通過,一定要調用release方法
        /*if (valid(xxx)) {
            SEMAPHORE.release();
        }*/

        try {
            // 03. 模擬業務處理,假如需要1s
            Thread.sleep(1000);
            return "業務處理成功";
        } catch (InterruptedException e) {
            // 錯誤處理
            return "業務處理失敗";
        } finally {
            // 04. 一定要釋放,否則導致接口假死無法處理請求
            SEMAPHORE.release();
        }
    }
}

三、限流演示

3.1 並發請求工具

 並發請求將基於apache-jmeter-5.2.1進行測試,jmeter的使用相對簡單,請讀者自行百度

此處線程組的線程數量為10個,真實環境中根據需要調整配置大小

在這裡插入圖片描述

在這裡插入圖片描述 

3.2 效果示例圖

啟動測試,可以看到處理成功的隻有三個,剩下7個全部失敗
a. 請求成功

在這裡插入圖片描述

b. 請求失敗

在這裡插入圖片描述

到此這篇關於Java使用Semaphore對單接口進行限流的文章就介紹到這瞭,更多相關Java 單接口限流內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: