Maven依賴
1
2
3
4
5
|
< dependency > < groupId >com.google.guava</ groupId > < artifactId >guava</ artifactId > < version >31.0.1-jre</ version > </ dependency > |
代碼
上代碼,不廢話。
首先是限流器代碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
package com.huyi.csdn.tools.rate; import com.google.common.util.concurrent.Monitor; import com.google.common.util.concurrent.RateLimiter; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Consumer; /** * @Program: csdn @ClassName: RequestRateLimiter @Author: huyi @Date: 2021-10-30 22:16 @Description: * 請求限流器 @Version: V1.0 */ public class RequestRateLimiter { // 請求隊列 private final ConcurrentLinkedQueue<Request> bucket = new ConcurrentLinkedQueue<>(); // 隊列上限 private static final int BUCKET_CAPACITY = 100 ; // 漏桶下沿水流速度 private final RateLimiter rateLimiter = RateLimiter.create( 10 .0D); // 請求監視器 private final Monitor requestMoniter = new Monitor(); // 處理監視器 private final Monitor handleMoniter = new Monitor(); /** 請求實體 */ public static class Request { private int data; public Request( int data) { this .data = data; } @Override public String toString() { return "Request{" + "data=" + data + '}' ; } } public void submitRequest( int data) { this .submitRequest( new Request(data)); } public void submitRequest(Request request) { // 請求監視器,創建監視向導,隊列數據量小于上限 if (requestMoniter.enterIf(requestMoniter.newGuard(() -> bucket.size() < BUCKET_CAPACITY))) { try { boolean result = bucket.offer(request); if (result) { System.out.println( "成功向隊列加入新的請求!" + Thread.currentThread() + " request:" + request); } else { System.out.println( "加入新請求失敗!" ); } } finally { requestMoniter.leave(); } } else { // 隊列已滿 // System.out.println("請求隊列已經上限,請稍后重試!"); } } // 處理請求方法 public void handleRequest(Consumer<Request> consumer) { if (handleMoniter.enterIf(handleMoniter.newGuard(() -> !bucket.isEmpty()))) { try { // 勻速處理 rateLimiter.acquire(); consumer.accept(bucket.poll()); } finally { handleMoniter.leave(); } } } } |
代碼說明
1、有個長度100的任務隊列,增加了監視器。
2、添加了限流器,限流為10。
驗證代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package com.huyi.csdn.tools.rate; import java.time.LocalTime; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.IntStream; /** * @Program: csdn @ClassName: TestRateLimiter @Author: huyi @Date: 2021-10-30 * 22:35 @Description: @Version: V1.0 */ public class TestRateLimiter { private static final AtomicInteger DATA = new AtomicInteger( 0 ); private static final RequestRateLimiter HANDLE = new RequestRateLimiter(); public static void main(String[] args) { IntStream.range( 0 , 10 ) .forEach( (x) -> new Thread( () -> { while ( true ) { HANDLE.submitRequest(DATA.getAndIncrement()); try { TimeUnit.MILLISECONDS.sleep( 100 ); } catch (InterruptedException e) { e.printStackTrace(); } } }) .start()); IntStream.range( 0 , 20 ) .forEach( (x) -> new Thread( () -> { while ( true ) { HANDLE.handleRequest( y -> System.out.println( LocalTime.now() + ":處理數據 -> " + y.toString())); } }) .start()); } } |
驗證執行結果
總結
胸中一點浩然氣,天地千里快哉風。
如果本文對你有用的,請不要吝嗇你的贊,謝謝支持。
到此這篇關于Java 實現限流器處理Rest接口請求詳解流程的文章就介紹到這了,更多相關Java Rest接口請求內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://huyi-aliang.blog.csdn.net/article/details/121058445