cgp 5 дней назад
Родитель
Сommit
0942832382
1 измененных файлов с 17 добавлено и 8 удалено
  1. 17 8
      fs-service/src/main/java/com/fs/feishu/service/FeishuClientPool.java

+ 17 - 8
fs-service/src/main/java/com/fs/feishu/service/FeishuClientPool.java

@@ -75,18 +75,27 @@ public class FeishuClientPool {
     }
 
     public Client getClient() {
-        String indexStr = stringRedisTemplate.opsForList()
-                .rightPopAndLeftPush(POOL_KEY, POOL_KEY);
-        if (indexStr == null) {
-            log.warn("账号池为空,尝试重新初始化");
-            resetPoolIndexes(clients.size());
-            indexStr = stringRedisTemplate.opsForList()
+        while (true) {
+            // 1. 从 Redis 循环队列取出索引(原子操作)
+            String indexStr = stringRedisTemplate.opsForList()
                     .rightPopAndLeftPush(POOL_KEY, POOL_KEY);
             if (indexStr == null) {
-                throw new CustomException("无法获取飞书账号索引,账号池不可用");
+                log.warn("账号池为空,尝试重新初始化");
+                resetPoolIndexes(clients.size());
+                continue;
+            }
+            int index = Integer.parseInt(indexStr);
+
+            // 2. 获取当前 clients 快照(volatile 读)
+            List<Client> currentClients = this.clients;
+
+            // 3. 如果索引越界(说明列表已被其他线程缩小),丢弃该索引并重试
+            if (index >= currentClients.size()) {
+                log.warn("索引 {} 已失效(当前账号数 {}),重试", index, currentClients.size());
+                continue;
             }
+            return currentClients.get(index);
         }
-        return clients.get(Integer.parseInt(indexStr));
     }
 
     /**