輕量級(jí)Java分布式限流庫(kù)Throttle4j上手教程
什么是 Throttle4j?
Throttle4j 是一款為 Java 應(yīng)用設(shè)計(jì)的輕量級(jí)、高性能分布式限流庫(kù)。無(wú)論你是構(gòu)建 API 網(wǎng)關(guān)、微服務(wù)還是普通 Web 應(yīng)用,throttle4j 都能為你提供可靠的速率控制能力。
核心亮點(diǎn):
- 四大經(jīng)典限流算法:固定窗口、滑動(dòng)窗口、令牌桶、漏桶,開(kāi)箱即用
- 雙存儲(chǔ)后端:內(nèi)存模式(單機(jī))+ Redis 模式(分布式集群)
- Spring Boot 深度集成:一個(gè)
@RateLimit注解搞定一切 - 線程安全 & 高性能:基于原子操作和 Lua 腳本,無(wú)鎖設(shè)計(jì)
- 優(yōu)雅降級(jí):Redis 不可用時(shí)自動(dòng)降級(jí)到本地存儲(chǔ)
環(huán)境要求
- Java 11+
- Maven 3.6+ 或 Gradle 6+
- (可選)Redis 6+,僅分布式模式需要
一、添加依賴(lài)
Spring Boot 項(xiàng)目(推薦)
Maven:
<dependency>
<groupId>com.throttle4j</groupId>
<artifactId>throttle4j-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>Gradle:
implementation 'com.throttle4j:throttle4j-spring-boot-starter:0.1.0'
純 Java 項(xiàng)目(無(wú) Spring 依賴(lài))
<dependency>
<groupId>com.throttle4j</groupId>
<artifactId>throttle4j-core</artifactId>
<version>0.1.0</version>
</dependency>二、編程式使用(Pure Java)
不依賴(lài) Spring,你也可以直接使用 throttle4j 核心 API:
import com.throttle4j.algorithm.DefaultRateLimiterFactory;
import com.throttle4j.core.*;
import com.throttle4j.store.InMemoryStore;
public class QuickStartDemo {
public static void main(String[] args) {
// 1. 創(chuàng)建內(nèi)存存儲(chǔ)
try (InMemoryStore store = new InMemoryStore()) {
RateLimiterFactory factory = new DefaultRateLimiterFactory(store);
// 2. 配置限流器:令牌桶算法,容量5,每秒補(bǔ)充5個(gè)令牌
RateLimiterConfig config = RateLimiterConfig.builder()
.algorithm(Algorithm.TOKEN_BUCKET)
.limit(5)
.refillRate(5)
.build();
RateLimiter limiter = factory.create(config);
// 3. 嘗試獲取令牌
String key = "user:1001";
for (int i = 1; i <= 7; i++) {
RateLimitResult result = limiter.tryAcquire(key);
System.out.printf("請(qǐng)求 #%d -> 允許=%s, 剩余=%d%n",
i, result.isAllowed(), result.getRemaining());
}
}
}
}
運(yùn)行結(jié)果示例:
請(qǐng)求 #1 -> 允許=true, 剩余=4
請(qǐng)求 #2 -> 允許=true, 剩余=3
請(qǐng)求 #3 -> 允許=true, 剩余=2
請(qǐng)求 #4 -> 允許=true, 剩余=1
請(qǐng)求 #5 -> 允許=true, 剩余=0
請(qǐng)求 #6 -> 允許=false, 剩余=0
請(qǐng)求 #7 -> 允許=false, 剩余=0
三、Spring Boot 集成(5 分鐘上手)
3.1 添加配置
在 application.yml 中添加:
throttle4j: enabled: true default-algorithm: TOKEN_BUCKET default-limit: 100 default-window: 1m store-type: memory # 單機(jī)使用 memory,分布式使用 redis
3.2 使用 @RateLimit 注解
在 Controller 方法上加上 @RateLimit 注解即可啟用限流:
import com.throttle4j.core.Algorithm;
import com.throttle4j.spring.annotation.RateLimit;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class UserController {
// 滑動(dòng)窗口:10秒內(nèi)最多5次請(qǐng)求
@RateLimit(limit = 5, window = "10s", algorithm = Algorithm.SLIDING_WINDOW)
@GetMapping("/hello")
public String hello() {
return "Hello, Throttle4j!";
}
// 令牌桶:自定義key,每分鐘最多10次
@RateLimit(key = "'user:' + #userId", limit = 10, window = "1m", algorithm = Algorithm.TOKEN_BUCKET)
@GetMapping("/users/{userId}")
public String getUser(@PathVariable Long userId) {
return "User " + userId;
}
}3.3 注解參數(shù)詳解
| 參數(shù) | 說(shuō)明 | 默認(rèn)值 |
|---|---|---|
| key | 限流鍵,支持 SpEL 表達(dá)式(如 #userId) | ClassName.methodName |
| limit | 窗口內(nèi)允許的最大請(qǐng)求數(shù) | 100 |
| window | 時(shí)間窗口(支持 500ms、1s、30s、1m、1h) | 1m |
| algorithm | 限流算法 | SLIDING_WINDOW |
| permits | 每次調(diào)用消耗的許可數(shù) | 1 |
| fallbackMethod | 限流觸發(fā)時(shí)的降級(jí)方法名 | 無(wú) |
3.4 處理限流異常
當(dāng)請(qǐng)求超限時(shí),框架會(huì)拋出 RateExceededException。你可以用全局異常處理器優(yōu)雅返回 429 狀態(tài)碼:
import com.throttle4j.core.RateExceededException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RateExceededException.class)
public ResponseEntity<String> handleRateExceeded(RateExceededException e) {
long retryAfter = e.getResult() != null
? Math.max(1L, e.getResult().getRetryAfterMillis() / 1000L)
: 1L;
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.header("Retry-After", String.valueOf(retryAfter))
.body("請(qǐng)求過(guò)于頻繁,請(qǐng)稍后重試");
}
}
四、啟用全局 Web 攔截器
除了注解方式,你還可以對(duì)所有 URL 啟用全局限流攔截器:
throttle4j:
enabled: true
default-algorithm: SLIDING_WINDOW
default-limit: 200
default-window: 1m
store-type: memory
web:
enabled: true # 開(kāi)啟全局?jǐn)r截
include-patterns:
- /api/**
exclude-patterns:
- /api/health
- /api/public/**攔截器會(huì)自動(dòng)在響應(yīng)頭中注入標(biāo)準(zhǔn)限流信息:
X-RateLimit-Limit: 200 X-RateLimit-Remaining: 199 X-RateLimit-Reset: 1686000060 Retry-After: 5 (僅在被限流時(shí)返回)
五、切換到 Redis 分布式模式
在微服務(wù)/集群場(chǎng)景下,你需要讓多個(gè)節(jié)點(diǎn)共享限流狀態(tài)。只需兩步:
5.1 添加 Redis 依賴(lài)
<dependency>
<groupId>com.throttle4j</groupId>
<artifactId>throttle4j-redis</artifactId>
<version>0.1.0</version>
</dependency>5.2 修改配置
throttle4j:
enabled: true
store-type: redis
default-algorithm: TOKEN_BUCKET
default-limit: 100
default-window: 1m
redis:
host: 127.0.0.1
port: 6379
password: your-password # 無(wú)密碼可省略
database: 0
key-prefix: "throttle4j:"throttle4j 使用 Lettuce 客戶(hù)端 + Lua 腳本保證原子性,并內(nèi)置 優(yōu)雅降級(jí):當(dāng) Redis 不可用時(shí)自動(dòng)切換到本地內(nèi)存存儲(chǔ),恢復(fù)后再切回。
六、如何選擇限流算法?
| 算法 | 適用場(chǎng)景 | 特點(diǎn) |
|---|---|---|
| Token Bucket(令牌桶) | API 網(wǎng)關(guān)、允許突發(fā)流量 | 平滑限速,允許短時(shí)間突發(fā) |
| Sliding Window(滑動(dòng)窗口) | 需要精確配額控制 | 精度高,無(wú)邊界突刺問(wèn)題 |
| Fixed Window(固定窗口) | 簡(jiǎn)單計(jì)數(shù)場(chǎng)景 | 實(shí)現(xiàn)簡(jiǎn)單,有窗口邊界突刺風(fēng)險(xiǎn) |
| Leaky Bucket(漏桶) | 需要恒定速率輸出 | 勻速處理,適合下游敏感場(chǎng)景 |
推薦選擇:大多數(shù) API 限流場(chǎng)景使用 TOKEN_BUCKET;對(duì)公平性要求高用 SLIDING_WINDOW。
七、完整示例項(xiàng)目
throttle4j 提供了一個(gè)開(kāi)箱即用的示例模塊 throttle4j-examples,包含:
- 純 Java 編程式用法
- Spring Boot + @RateLimit 注解用法
- 全局異常處理示例
運(yùn)行示例:
git clone https://github.com/hqbhonker/throttle4j.git cd throttle4j mvn clean install -DskipTests cd throttle4j-examples mvn spring-boot:run
訪問(wèn)測(cè)試:
# 正常訪問(wèn)
curl http://localhost:8080/api/hello
# 快速連續(xù)請(qǐng)求,觀察限流效果
for i in {1..10}; do curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/api/hello; done八、生產(chǎn)環(huán)境部署注意事項(xiàng)
8.1 Redis 高可用配置
生產(chǎn)環(huán)境下 Redis 是限流狀態(tài)的核心存儲(chǔ),務(wù)必保證其可用性:
- 使用 Redis Sentinel 或 Cluster:避免單點(diǎn)故障,確保 Redis 掛掉后能自動(dòng)切換
- 啟用 fallback-on-error:throttle4j 的 FallbackRateLimitStore 會(huì)在 Redis 異常時(shí)自動(dòng)降級(jí)到本地內(nèi)存,但要注意此時(shí)限流變?yōu)楣?jié)點(diǎn)粒度
- 監(jiān)控降級(jí)次數(shù):通過(guò) FallbackRateLimitStore.getFallbackInvocations() 監(jiān)控降級(jí)頻率,及時(shí)發(fā)現(xiàn) Redis 問(wèn)題
throttle4j:
store-type: redis
redis:
host: redis-sentinel.internal
port: 26379
password: ${THROTTLE4J_REDIS_PASSWORD}
key-prefix: "prod:throttle4j:"8.2 Key 設(shè)計(jì)規(guī)范
- 避免熱點(diǎn) Key:如果所有請(qǐng)求都用同一個(gè) key,會(huì)造成 Redis 單 key 熱點(diǎn)。建議按用戶(hù)/租戶(hù)/接口維度拆分
- Key 命名規(guī)范:推薦 {service}:{resource}:{identifier} 格式,如 order-service:createOrder:user_123
- 注意 Key 總量:內(nèi)存模式下 InMemoryStore 有后臺(tái)清理線程(默認(rèn) 5 分鐘空閑后回收),但大量 key 仍會(huì)占用較多內(nèi)存
8.3 多節(jié)點(diǎn)部署
| 部署模式 | 推薦 store-type | 限流粒度 | 說(shuō)明 |
|---|---|---|---|
| 單節(jié)點(diǎn) | memory | 進(jìn)程級(jí) | 最高性能,無(wú)網(wǎng)絡(luò)開(kāi)銷(xiāo) |
| 多節(jié)點(diǎn)/K8s | redis | 集群級(jí) | 所有節(jié)點(diǎn)共享配額 |
| 混合模式 | redis + fallback | 主集群級(jí),故障時(shí)退化為節(jié)點(diǎn)級(jí) | 推薦生產(chǎn)使用 |
8.4 安全建議
- 不要暴露限流配置接口:避免攻擊者利用配置接口調(diào)整限流閾值
- 敏感信息外化:Redis 密碼等使用環(huán)境變量注入,不要硬編碼在
application.yml中 - 日志脫敏:限流 key 中如果包含用戶(hù) ID 等敏感信息,注意日志級(jí)別控制
九、性能調(diào)優(yōu)建議
9.1 算法選擇對(duì)性能的影響
| 算法 | 內(nèi)存占用 | 單次操作耗時(shí) | 適合 QPS |
|---|---|---|---|
| Fixed Window | 最低(1 個(gè)計(jì)數(shù)器) | ~O(1) | 百萬(wàn)級(jí) |
| Token Bucket | 低(幾個(gè)浮點(diǎn)數(shù)) | ~O(1) | 百萬(wàn)級(jí) |
| Sliding Window | 中等(10 個(gè) slot) | ~O(N) N=slot數(shù) | 十萬(wàn)級(jí) |
| Leaky Bucket | 低(1 個(gè)浮點(diǎn)數(shù)) | ~O(1) | 百萬(wàn)級(jí) |
9.2 InMemoryStore 調(diào)優(yōu)
InMemoryStore 內(nèi)置后臺(tái)清理線程,可以通過(guò)構(gòu)造參數(shù)調(diào)整:
// 高并發(fā)場(chǎng)景:縮短空閑 TTL 和清理間隔,減少內(nèi)存占用
InMemoryStore store = new InMemoryStore(
TimeUnit.MINUTES.toMillis(2), // idleMillis: 2分鐘無(wú)訪問(wèn)則回收
TimeUnit.SECONDS.toMillis(30) // cleanupInterval: 每30秒清理一次
);
調(diào)優(yōu)建議:
- 高并發(fā) + 大量不同 key:縮短
idleMillis到 1~2 分鐘 - 低并發(fā) + 少量固定 key:可以加大
idleMillis到 10 分鐘 - 不要將
cleanupInterval設(shè)置得過(guò)短(<10s),避免頻繁 GC 壓力
9.3 Redis Store 調(diào)優(yōu)
- 連接池大小:Lettuce 默認(rèn)使用單連接多路復(fù)用,高并發(fā)場(chǎng)景建議配置連接池
- Key 前綴長(zhǎng)度:保持較短的
key-prefix,減少網(wǎng)絡(luò)傳輸和 Redis 內(nèi)存開(kāi)銷(xiāo) - Lua 腳本原子性:所有限流操作通過(guò) Lua 腳本在 Redis 端執(zhí)行,無(wú)需客戶(hù)端加鎖
- 網(wǎng)絡(luò)延遲:Redis 與應(yīng)用部署在同一內(nèi)網(wǎng)/AZ,控制 RTT < 1ms
9.4 Spring AOP 開(kāi)銷(xiāo)優(yōu)化
@RateLimit注解基于 Spring AOP 攔截,首次調(diào)用有 SpEL 解析開(kāi)銷(xiāo),后續(xù)命中緩存- 對(duì)極高頻內(nèi)部方法(如批處理循環(huán)中),建議使用編程式 API 而非注解
- 如果不需要全局 Web 攔截器,將
throttle4j.web.enabled保持為false(默認(rèn)值),減少攔截器鏈開(kāi)銷(xiāo)
9.5 JVM 參數(shù)建議
# 高并發(fā)限流場(chǎng)景建議的 JVM 參數(shù) -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -Xms512m -Xmx512m # 根據(jù) key 數(shù)量適當(dāng)調(diào)整
十、常見(jiàn)問(wèn)題 FAQ
Q1: 為什么請(qǐng)求沒(méi)有被限流?
可能原因:
throttle4j.enabled設(shè)置為false或未配置@RateLimit注解放在了非 public 方法上(Spring AOP 只攔截 public 方法)- 同一個(gè) Bean 內(nèi)部調(diào)用(this 調(diào)用不經(jīng)過(guò)代理,AOP 不生效)
- 檢查 key 是否唯一:如果 SpEL 解析失敗,會(huì)回退到
ClassName.methodName,可能導(dǎo)致不同參數(shù)共享配額
解決方案:
// ? 內(nèi)部調(diào)用不生效
public void outer() {
this.inner(); // AOP 不攔截
}
@RateLimit(limit = 5, window = "1m")
public void inner() { ... }
// ? 通過(guò)注入自身或拆分到不同 Bean 解決
@Autowired
private MyService self;
public void outer() {
self.inner(); // 走代理,AOP 生效
}
Q2: Redis 掛了會(huì)怎樣?
如果使用了 throttle4j-redis 模塊,框架內(nèi)置了 FallbackRateLimitStore 降級(jí)機(jī)制:
- Redis 不可用時(shí),自動(dòng)切換到本地
InMemoryStore,限流依然生效(但變?yōu)楣?jié)點(diǎn)粒度) - 每次降級(jí)會(huì)記錄 WARN 日志:
Primary rate limit store unavailable, falling back - Redis 恢復(fù)后,下一次請(qǐng)求會(huì)自動(dòng)切回 Redis
注意:降級(jí)期間各節(jié)點(diǎn)獨(dú)立計(jì)數(shù),實(shí)際集群總流量可能超過(guò)配置閾值(= 閾值 × 節(jié)點(diǎn)數(shù))。
Q3:window參數(shù)支持哪些格式?
支持以下時(shí)間簡(jiǎn)寫(xiě)格式:
500ms— 500 毫秒1s/30s— 秒1m/5m— 分鐘1h— 小時(shí)
在編程式 API 中使用 windowSeconds(long) 或 windowMillis(long) 設(shè)置。
Q4: 如何實(shí)現(xiàn)按用戶(hù)/IP 維度限流?
利用 SpEL 表達(dá)式動(dòng)態(tài)設(shè)置 key:
// 按用戶(hù) ID 限流
@RateLimit(key = "'user:' + #userId", limit = 100, window = "1m")
@GetMapping("/api/data/{userId}")
public String getData(@PathVariable String userId) { ... }
// 按 IP 限流(需通過(guò) HttpServletRequest 獲?。?
@RateLimit(key = "'ip:' + #request.remoteAddr", limit = 60, window = "1m")
@GetMapping("/api/public")
public String publicApi(HttpServletRequest request) { ... }
Q5: 令牌桶的 refillRate 怎么配?
在 @RateLimit 注解中不直接暴露 refillRate,框架會(huì)自動(dòng)從 limit / windowSeconds 推導(dǎo):
limit = 100, window = "1m"→ refillRate ≈ 1.67 tokens/slimit = 10, window = "1s"→ refillRate = 10 tokens/s
如需自定義 refillRate,使用編程式 API:
RateLimiterConfig config = RateLimiterConfig.builder()
.algorithm(Algorithm.TOKEN_BUCKET)
.limit(50) // 桶容量
.refillRate(10) // 每秒補(bǔ)充 10 個(gè)令牌
.build();
Q6: 能否在同一個(gè)方法上疊加多個(gè)限流規(guī)則?
目前 @RateLimit 是單一注解,不支持重復(fù)標(biāo)注。如需多維度限流(如同時(shí)限制 IP 和用戶(hù)),建議:
- 使用編程式 API 組合多個(gè) limiter
- 在 Web 攔截器做全局 IP 限流 + 注解做用戶(hù)級(jí)限流,兩層疊加
Q7: 如何在測(cè)試中 mock 限流?
@SpringBootTest
class MyServiceTest {
@MockBean
private RateLimiterRegistry registry;
@Test
void testNormal() {
// Mock 一個(gè)始終允許的 limiter
RateLimiter mockLimiter = mock(RateLimiter.class);
when(mockLimiter.tryAcquire(anyString(), anyInt()))
.thenReturn(RateLimitResult.allowed(99, System.currentTimeMillis() + 60000));
when(registry.get(anyString())).thenReturn(mockLimiter);
// ... 正常測(cè)試邏輯
}
}
Q8: InMemoryStore 會(huì)導(dǎo)致 OOM 嗎?
InMemoryStore 內(nèi)置了后臺(tái)守護(hù)線程,默認(rèn)每 60 秒清理一次 5 分鐘內(nèi)無(wú)訪問(wèn)的 key。正常使用不會(huì) OOM,但如果:
- key 數(shù)量極大(百萬(wàn)級(jí)不同用戶(hù))且訪問(wèn)持續(xù)活躍
- 選擇了 Sliding Window(每個(gè) key 額外占用 10 個(gè) slot)
建議監(jiān)控 store.size() 并適當(dāng)縮短 idleMillis,或直接使用 Redis 存儲(chǔ)。
Q9: 限流觸發(fā)后客戶(hù)端應(yīng)該如何處理?
建議客戶(hù)端遵循標(biāo)準(zhǔn) HTTP 429 協(xié)議:
- 讀取響應(yīng)頭
Retry-After(秒數(shù)),等待后重試 - 實(shí)現(xiàn)指數(shù)退避策略,避免重試風(fēng)暴
- 在網(wǎng)關(guān)層可以使用
X-RateLimit-Remaining做客戶(hù)端預(yù)判,主動(dòng)降速
Q10: 支持哪些 Spring Boot 版本?
throttle4j 基于 Spring Boot 2.7.x 開(kāi)發(fā)和測(cè)試,兼容:
- Spring Boot 2.7.x ?
- Spring Boot 3.x ?(需使用 Jakarta 命名空間,但 throttle4j 不依賴(lài) Servlet API)
- Java 11、17 均通過(guò) CI 驗(yàn)證
總結(jié)
通過(guò)本教程,你學(xué)會(huì)了:
- 在純 Java 項(xiàng)目中使用 throttle4j 進(jìn)行編程式限流
- 在 Spring Boot 項(xiàng)目中通過(guò)
@RateLimit注解實(shí)現(xiàn)聲明式限流 - 配置全局 Web 攔截器進(jìn)行 URL 級(jí)別限流
- 切換到 Redis 實(shí)現(xiàn)分布式限流
- 根據(jù)業(yè)務(wù)場(chǎng)景選擇合適的限流算法
- 生產(chǎn)環(huán)境下的部署策略和高可用保障
- 針對(duì)不同場(chǎng)景的性能調(diào)優(yōu)方法
throttle4j 的設(shè)計(jì)理念是 簡(jiǎn)單、輕量、可插拔。如果你正在尋找一個(gè)不依賴(lài)重型框架的 Java 限流方案,throttle4j 是一個(gè)不錯(cuò)的選擇。
到此這篇關(guān)于輕量級(jí)Java分布式限流庫(kù)Throttle4j上手教程的文章就介紹到這了,更多相關(guān)Java分布式限流庫(kù)Throttle4j內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
application.yml和bootstrap.yml不生效的3種解決方案
SpringBoot默認(rèn)支持?properties(.properties) 和 YAML(.yml .yaml ) 配置文件,本文主要介紹了application.yml和bootstrap.yml不生效的3種解決方案,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
java實(shí)現(xiàn)table添加右鍵點(diǎn)擊事件監(jiān)聽(tīng)操作示例
這篇文章主要介紹了java實(shí)現(xiàn)table添加右鍵點(diǎn)擊事件監(jiān)聽(tīng)操作,結(jié)合實(shí)例形式分析了Java添加及使用事件監(jiān)聽(tīng)相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
一文掌握Spring中循環(huán)依賴(lài)與三級(jí)緩存
這篇文章主要介紹了Spring中循環(huán)依賴(lài)與三級(jí)緩存,Spring通過(guò)三級(jí)緩存解決了循環(huán)依賴(lài),其中一級(jí)緩存為單例池,二級(jí)緩存為早期曝光對(duì)象earlySingletonObjects,三級(jí)緩存為早期曝光對(duì)象工廠(singletonFactories),本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友參考下吧2023-09-09
SpringBoot居然有44種應(yīng)用啟動(dòng)器,你都知道嗎
很多人都不知道SpringBoot應(yīng)用啟動(dòng)器竟然有44個(gè),本文就一起來(lái)介紹一下,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Java數(shù)據(jù)結(jié)構(gòu)順序表用法詳解
順序表是計(jì)算機(jī)內(nèi)存中以數(shù)組的形式保存的線性表,線性表的順序存儲(chǔ)是指用一組地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)線性表中的各個(gè)元素、使得線性表中在邏輯結(jié)構(gòu)上相鄰的數(shù)據(jù)元素存儲(chǔ)在相鄰的物理存儲(chǔ)單元中,即通過(guò)數(shù)據(jù)元素物理存儲(chǔ)的相鄰關(guān)系來(lái)反映數(shù)據(jù)元素之間邏輯上的相鄰關(guān)系2021-10-10
java開(kāi)源項(xiàng)目jeecgboot的超詳細(xì)解析
JeecgBoot是一款基于BPM的低代碼平臺(tái),下面這篇文章主要給大家介紹了關(guān)于java開(kāi)源項(xiàng)目jeecgboot的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
Java設(shè)計(jì)模式編程之解釋器模式的簡(jiǎn)單講解
這篇文章主要介紹了Java設(shè)計(jì)模式編程之解釋器模式的講解,解釋器設(shè)計(jì)模式要注意其引發(fā)的性能問(wèn)題,需要的朋友可以參考下2016-04-04
淺談@FeignClient中name和value屬性的區(qū)別
這篇文章主要介紹了@FeignClient中name和value屬性的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
springboot運(yùn)行到dokcer中 dockerfile的場(chǎng)景分析
這篇文章主要介紹了springboot運(yùn)行到dokcer中 dockerfile,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03

