diff --git a/pom.xml b/pom.xml
index a673ac4..1cffd89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,6 +14,7 @@
xservice-third-part
xservice-mysql-starter
xservice-schedule-starter
+ xservice-http-starter
diff --git a/xservice-http-starter/pom.xml b/xservice-http-starter/pom.xml
new file mode 100644
index 0000000..7fb0272
--- /dev/null
+++ b/xservice-http-starter/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ com.xiang
+ xservice-basic
+ 1.1-SNAPSHOT
+
+
+ xservice-http-starter
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.github.rholder
+ guava-retrying
+ 2.0.0
+
+
+
+
+
\ No newline at end of file
diff --git a/xservice-http-starter/src/main/java/com/xiang/xservice/http/config/HttpConfig.java b/xservice-http-starter/src/main/java/com/xiang/xservice/http/config/HttpConfig.java
new file mode 100644
index 0000000..55e25b1
--- /dev/null
+++ b/xservice-http-starter/src/main/java/com/xiang/xservice/http/config/HttpConfig.java
@@ -0,0 +1,25 @@
+package com.xiang.xservice.http.config;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ConfigurationProperties(prefix = "http")
+public class HttpConfig {
+
+ /**
+ * 最大重试次数
+ */
+ private int maxAttempts;
+
+ /**
+ * 重试等待时间 ms
+ */
+ private long sleepMs;
+
+}
diff --git a/xservice-http-starter/src/main/java/com/xiang/xservice/http/helper/HttpRequestHelper.java b/xservice-http-starter/src/main/java/com/xiang/xservice/http/helper/HttpRequestHelper.java
new file mode 100644
index 0000000..7c701fd
--- /dev/null
+++ b/xservice-http-starter/src/main/java/com/xiang/xservice/http/helper/HttpRequestHelper.java
@@ -0,0 +1,56 @@
+package com.xiang.xservice.http.helper;
+
+import com.github.rholder.retry.Retryer;
+import com.github.rholder.retry.RetryerBuilder;
+import com.github.rholder.retry.StopStrategies;
+import com.github.rholder.retry.WaitStrategies;
+import com.xiang.xservice.http.config.HttpConfig;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class HttpRequestHelper {
+
+ private final HttpConfig httpConfig;
+
+ /**
+ * 封装带重试和延迟的请求调用
+ *
+ * @param supplier 实际请求的逻辑
+ * @param logTag 日志标识(便于排查)
+ * @param 返回值类型
+ * @return 请求结果,如果失败则返回 null
+ */
+ public T fetchWithRetry(Supplier supplier, String logTag) {
+ Retryer retryer = RetryerBuilder.newBuilder()
+ .retryIfException()
+ .retryIfResult(Objects::isNull)
+ // 重试等待间隔
+ .withWaitStrategy(WaitStrategies.fixedWait(httpConfig.getSleepMs(), TimeUnit.MILLISECONDS))
+ // 最大重试次数
+ .withStopStrategy(StopStrategies.stopAfterAttempt(httpConfig.getMaxAttempts()))
+ .build();
+
+ Callable callable = () -> {
+ T result = supplier.get();
+ // 每次请求后固定等待,用于限速
+ Thread.sleep(httpConfig.getSleepMs());
+ return result;
+ };
+ try {
+ return retryer.call(callable);
+ } catch (Exception e) {
+ log.warn("[{}] 请求失败,重试 {} 次后仍未成功,错误: {}", logTag, httpConfig.getMaxAttempts(), e.getMessage(), e);
+ return null;
+ }
+ }
+}
diff --git a/xservice-http-starter/src/main/resources/META-INF/spring.factories b/xservice-http-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..3be09b5
--- /dev/null
+++ b/xservice-http-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.xiang.xservice.http.config.HttpConfig
\ No newline at end of file