|
|
@@ -2,6 +2,7 @@ package com.malk.service.personnel.impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.google.common.util.concurrent.RateLimiter;
|
|
|
import com.malk.server.aliwork.YDConf;
|
|
|
import com.malk.server.aliwork.YDParam;
|
|
|
import com.malk.server.dingtalk.DDR_New;
|
|
|
@@ -14,6 +15,8 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
@@ -44,6 +47,17 @@ public class PersonnelSyncServiceImpl implements PersonnelSyncService {
|
|
|
@Autowired
|
|
|
private PersonnelSyncConf conf;
|
|
|
|
|
|
+ /** 钉钉 user/get 限速器 (官方 60 QPS, 默认留 10 余量) */
|
|
|
+ private RateLimiter ddRateLimiter;
|
|
|
+ /** 宜搭写接口限速器 (防止并发线程合计超限) */
|
|
|
+ private RateLimiter yidaRateLimiter;
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ private void initRateLimiters() {
|
|
|
+ ddRateLimiter = RateLimiter.create(conf.getDdApiQps());
|
|
|
+ yidaRateLimiter = RateLimiter.create(conf.getYidaApiQps());
|
|
|
+ }
|
|
|
+
|
|
|
private static final String ACTION_CREATE = "CREATE";
|
|
|
private static final String ACTION_UPDATE = "UPDATE";
|
|
|
private static final String ACTION_MARK_OFF = "MARK_OFF";
|
|
|
@@ -515,6 +529,18 @@ public class PersonnelSyncServiceImpl implements PersonnelSyncService {
|
|
|
private void executeAction(Action a, WriteStats stats) {
|
|
|
int attempt = 0;
|
|
|
while (true) {
|
|
|
+ // 指数退避: 第 1 次不等, 之后 1s/2s/4s... 最长 8s
|
|
|
+ if (attempt > 0) {
|
|
|
+ long backoffMs = Math.min(1000L * (1L << (attempt - 1)), 8000L);
|
|
|
+ try {
|
|
|
+ Thread.sleep(backoffMs);
|
|
|
+ } catch (InterruptedException ie) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ stats.failed.incrementAndGet();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ yidaRateLimiter.acquire();
|
|
|
try {
|
|
|
if (ACTION_CREATE.equals(a.type)) {
|
|
|
ydClient.operateData(YDParam.builder()
|
|
|
@@ -548,6 +574,7 @@ public class PersonnelSyncServiceImpl implements PersonnelSyncService {
|
|
|
stats.failed.incrementAndGet();
|
|
|
return;
|
|
|
}
|
|
|
+ log.info("[PersonnelSync] 写入重试 userid={} action={} attempt={} err={}", a.userid, a.type, attempt, ex.getMessage());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -610,6 +637,7 @@ public class PersonnelSyncServiceImpl implements PersonnelSyncService {
|
|
|
Object uid = u.get("userid");
|
|
|
if (uid == null) continue;
|
|
|
try {
|
|
|
+ ddRateLimiter.acquire();
|
|
|
Map detail = ddClient_contacts.getUserInfoById(token, String.valueOf(uid));
|
|
|
Object mgr = detail == null ? null : detail.get("manager_userid");
|
|
|
if (mgr != null && notBlank(String.valueOf(mgr))) {
|