From aaea31dddb2ca9ac5a87b1ba068e8cf47f596505 Mon Sep 17 00:00:00 2001 From: gengby <858962040@qq.com> Date: Thu, 6 Jul 2023 16:36:37 +0800 Subject: [PATCH] =?UTF-8?q?add:=E5=8F=8D=E9=A6=88=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=8E=A5=E5=8F=A3=E9=87=8D=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- acs/nladmin-system/pom.xml | 5 + .../src/main/java/org/nl/AppRun.java | 2 + .../org/nl/acs/ext/wms/RetryableUtil.java | 72 +++++++++++++ .../acs/ext/wms/service/AcsToWmsService.java | 2 +- .../wms/service/impl/AcsToWmsServiceImpl.java | 102 ++++++++++-------- .../main/resources/config/application-dev.yml | 4 +- .../resources/config/application-prod.yml | 3 +- .../src/main/resources/log/RetryableUtil.xml | 33 ++++++ .../src/main/resources/logback-spring.xml | 26 ++--- 9 files changed, 192 insertions(+), 57 deletions(-) create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/RetryableUtil.java create mode 100644 acs/nladmin-system/src/main/resources/log/RetryableUtil.xml diff --git a/acs/nladmin-system/pom.xml b/acs/nladmin-system/pom.xml index e02d8fb..80f2473 100644 --- a/acs/nladmin-system/pom.xml +++ b/acs/nladmin-system/pom.xml @@ -406,6 +406,11 @@ UserAgentUtils 1.21 + + + org.springframework.retry + spring-retry + diff --git a/acs/nladmin-system/src/main/java/org/nl/AppRun.java b/acs/nladmin-system/src/main/java/org/nl/AppRun.java index 2fa3edd..cac91ec 100644 --- a/acs/nladmin-system/src/main/java/org/nl/AppRun.java +++ b/acs/nladmin-system/src/main/java/org/nl/AppRun.java @@ -12,6 +12,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.retry.annotation.EnableRetry; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.bind.annotation.GetMapping; @@ -35,6 +36,7 @@ import org.springframework.web.bind.annotation.RestController; @EnableJpaAuditing(auditorAwareRef = "auditorAware") @EnableMethodCache(basePackages = "org.nl") @EnableCreateCacheAnnotation +@EnableRetry public class AppRun { public static void main(String[] args) { diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/RetryableUtil.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/RetryableUtil.java new file mode 100644 index 0000000..1aee7b6 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/RetryableUtil.java @@ -0,0 +1,72 @@ +package org.nl.acs.ext.wms; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Recover; +import org.springframework.retry.annotation.Retryable; +import org.springframework.stereotype.Component; + +/** + * @author: geng by + * @createDate: 2023/7/6 + */ +@Component +@Slf4j +public class RetryableUtil { + private static ThreadLocal retryTimes = new ThreadLocal<>(); + @Autowired + private RedisUtils redisUtils; + @Autowired + private AcsToWmsService acsToWmsService; + + /** + * 只针对对接系统连接拒绝、连接超时进行重试机制 + * 如果系统连接成功 但是对方返回失败不进行重试 + * + * @param url + * @param param + */ + @Retryable(maxAttempts = 5, backoff = @Backoff(delay = 15000L, multiplier = 2)) + public void retryable(String url, String param) { + acsToWmsService.getTokenFromWms(); + HttpResponse httpResponse = null; + String respMessage = null; + try { + httpResponse = + HttpRequest + .post(url) + .header("Content-Type", "application/json;charset=UTF-8") + .header("Authorization", String.valueOf(redisUtils.get("wms_token"))) + .body(param) + .timeout(5000) + .execute(); + } catch (Exception e) { + respMessage = e.getMessage(); + } + if (retryTimes.get() == null) { + retryTimes.set(1); + } else { + retryTimes.set(retryTimes.get() + 1); + } + if (httpResponse == null) { + log.error("接口进行第{}次重试,请求路径:{},请求参数:{},响应参数:{}", retryTimes.get(), url, JSONObject.parse(param), respMessage); + throw new BadRequestException(url + "_" + param + "_" + retryTimes.get()); + } + retryTimes.remove(); + log.info("接口重试成功,请求路径:{},请求参数:{},重试次数:{}", url, JSONObject.parse(param), retryTimes.get()); + } + + @Recover + public void recover(RuntimeException e) { + retryTimes.remove(); + String[] excMessage = e.getMessage().split("_"); + log.error("请求路径:{},请求参数:{},已达到最大重试次数:{},停止重试!", excMessage[0], excMessage[1], excMessage[2]); + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java index b72fcec..53de2bd 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java @@ -115,5 +115,5 @@ public interface AcsToWmsService { */ HttpResponse feedAgvTaskStatus(JSONArray from); - public HttpResponse test(JSONObject form); + JSONObject test(JSONObject form); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java index a1639d0..a9dbb5f 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java @@ -16,6 +16,7 @@ import org.nl.acs.device.address.service.dto.AddressDto; import org.nl.acs.device.service.DeviceService; import org.nl.acs.ext.wms.data.*; import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.acs.ext.wms.RetryableUtil; import org.nl.modules.common.utils.RedisUtils; import org.nl.modules.system.service.ParamService; import org.slf4j.MDC; @@ -24,6 +25,7 @@ import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @Service @@ -42,6 +44,9 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Autowired private RedisUtils redisUtils; + @Autowired + private RetryableUtil retryableUtil; + /*@Value("${acsTowms.token}")*/ public String token; @@ -95,25 +100,28 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { MDC.put(log_file_type, log_type); if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) { log.info("开始反馈wms任务状态,请求参数:{}", JSON.toJSONString(data)); - if (redisUtils.getExpire("wms_token") == -1) { - this.getTokenFromWms(); - } + this.getTokenFromWms(); String wmsurl = paramService.findByCode(AcsConfig.WMSURL).getValue(); HttpResponse result = null; AddressDto addressDto = addressService.findByCode("feedbackTaskStatusToWms"); String methods_url = addressDto.getMethods_url(); + String url = wmsurl + methods_url; Map map = new HashMap<>(); map.put("payload", JSON.toJSONString(data)); try { result = HttpRequest - .post(wmsurl + methods_url) + .post(url) .header("Content-Type", "application/json;charset=UTF-8") .header("Authorization", String.valueOf(redisUtils.get("wms_token"))) .body(JSON.toJSONString(map)) + .timeout(3000) .execute(); - log.info("反馈wms任务状态成功,请求路径:{},请求参数:{}", wmsurl + methods_url, JSON.toJSONString(data)); + log.info("反馈wms任务状态成功,请求路径:{},请求参数:{},响应参数:{}", url, JSON.toJSONString(map), JSON.toJSONString(result.body())); } catch (Exception e) { - log.info("反馈wms任务状态失败,请求路径:{},失败原因:{}", wmsurl + methods_url, e.getMessage()); + log.error("反馈wms任务状态失败,请求路径:{},失败原因:{}", url, e.getMessage()); + CompletableFuture.runAsync(() -> { + retryableUtil.retryable(url, JSON.toJSONString(map)); + }); } return result; } @@ -126,32 +134,34 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Override public HttpResponse getTokenFromWms() { if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) { - log.info("acs开始向wms获取token......"); - String wmsUrl = paramService.findByCode(AcsConfig.WMSURL).getValue(); - AddressDto addressDto = addressService.findByCode("getTokenFromWms"); - String methods_url = addressDto.getMethods_url(); - String url = wmsUrl + methods_url; - HttpResponse result = null; - try { - result = HttpRequest.post(url) - .body(url + methods_url) - .execute(); - if (ObjectUtil.isNotEmpty(result) && result.getStatus() == 200) { - String body = result.body(); - if (StrUtil.isNotEmpty(body)) { - JSONObject jsonObject = JSONObject.parseObject(body); - String access_token = jsonObject.getString("access_token"); - String token_type = jsonObject.getString("token_type"); - String expires_in = jsonObject.getString("expires_in"); - String scope = jsonObject.getString("scope"); - redisUtils.setExpire("wms_token", token_type + " " + access_token, Long.valueOf(expires_in), TimeUnit.SECONDS); - log.info("acs向wms获取token成功,响应参数:{},已向redis中设置wms_token值", jsonObject); + if (redisUtils.getExpire("wms_token") == -1 || !redisUtils.hasKey("wms_token")) { + log.info("acs开始向wms获取token......"); + String wmsUrl = paramService.findByCode(AcsConfig.WMSURL).getValue(); + AddressDto addressDto = addressService.findByCode("getTokenFromWms"); + String methods_url = addressDto.getMethods_url(); + String url = wmsUrl + methods_url; + HttpResponse result = null; + try { + result = HttpRequest.post(url) + .body(url + methods_url) + .execute(); + if (ObjectUtil.isNotEmpty(result) && result.getStatus() == 200) { + String body = result.body(); + if (StrUtil.isNotEmpty(body)) { + JSONObject jsonObject = JSONObject.parseObject(body); + String access_token = jsonObject.getString("access_token"); + String token_type = jsonObject.getString("token_type"); + String expires_in = jsonObject.getString("expires_in"); + String scope = jsonObject.getString("scope"); + redisUtils.setExpire("wms_token", token_type + " " + access_token, Long.valueOf(expires_in), TimeUnit.SECONDS); + log.info("acs向wms获取token成功,响应参数:{},已向redis中设置wms_token值", jsonObject); + } } + } catch (Exception e) { + log.error("acs向wms获取token失败,失败原因:{}", e.getMessage()); } - } catch (Exception e) { - log.error("acs向wms获取token失败,失败原因:{}", e.getMessage()); + return result; } - return result; } return null; } @@ -549,9 +559,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { public HttpResponse feedAgvTaskStatus(JSONArray from) { if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) { log.info("开始反馈WMS AGV取放货状态,请求参数:{}", from); - if (redisUtils.getExpire("wms_token") == -1) { - this.getTokenFromWms(); - } + this.getTokenFromWms(); String wmsUrl = paramService.findByCode(AcsConfig.WMSURL).getValue(); AddressDto addressDto = addressService.findByCode("feedAgvTaskStatus"); String methods_url = addressDto.getMethods_url(); @@ -564,6 +572,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { .header("Content-Type", "application/json;charset=UTF-8") .header("Authorization", String.valueOf(redisUtils.get("wms_token"))) .body(JSON.toJSONString(from)) + .timeout(3000) .execute(); log.info("反馈WMS AGV取放货状态成功,请求路径:{},请求结果:{}", url, result.body()); } catch (Exception e) { @@ -575,16 +584,25 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { } @Override - public HttpResponse test(JSONObject form) { - if (redisUtils.getExpire("wms_token") == -1) { - this.getTokenFromWms(); - } + public JSONObject test(JSONObject form) { + this.getTokenFromWms(); String url = "https://zoneda.onestep-cloud.com/lwmss/v1/41/chsv-unqualified-products/execute-inspection-ng"; - HttpResponse result = HttpRequest - .post(url) - .header("Authorization", String.valueOf(redisUtils.get("wms_token"))) - .body(JSON.toJSONString(form)) - .execute(); - return result; + JSONObject resp = null; + try { + HttpResponse result = HttpRequest + .post(url) + .header("Content-Type", "application/json;charset=UTF-8") + .header("Authorization", String.valueOf(redisUtils.get("wms_token"))) + .body(JSON.toJSONString(form)) + .timeout(3000) + .execute(); + } catch (Exception e) { + CompletableFuture.runAsync(() -> { + retryableUtil.retryable(url, JSON.toJSONString(form)); + }); + } + return resp; } + + } diff --git a/acs/nladmin-system/src/main/resources/config/application-dev.yml b/acs/nladmin-system/src/main/resources/config/application-dev.yml index d135cf0..e9a67a5 100644 --- a/acs/nladmin-system/src/main/resources/config/application-dev.yml +++ b/acs/nladmin-system/src/main/resources/config/application-dev.yml @@ -13,7 +13,7 @@ spring: driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy # url: jdbc:log4jdbc:mysql://${DB_HOST:10.1.3.91}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true # url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:lzhl_one_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wzgj_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wzgj_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true username: ${DB_USER:root} # password: ${DB_PWD:P@ssw0rd} # password: ${DB_PWD:Root.123456} @@ -162,3 +162,5 @@ sa-token: loki: url: http://127.0.0.1:3100/loki/api/v1 systemName: acs + + diff --git a/acs/nladmin-system/src/main/resources/config/application-prod.yml b/acs/nladmin-system/src/main/resources/config/application-prod.yml index e22d641..d064404 100644 --- a/acs/nladmin-system/src/main/resources/config/application-prod.yml +++ b/acs/nladmin-system/src/main/resources/config/application-prod.yml @@ -11,7 +11,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:10.1.3.91}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wzgj_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true username: ${DB_USER:root} password: ${DB_PWD:123456} # 初始连接数 @@ -166,3 +166,4 @@ sa-token: loki: url: http://localhost:3100/loki/api/v1 systemName: acs + diff --git a/acs/nladmin-system/src/main/resources/log/RetryableUtil.xml b/acs/nladmin-system/src/main/resources/log/RetryableUtil.xml new file mode 100644 index 0000000..fb7d4ce --- /dev/null +++ b/acs/nladmin-system/src/main/resources/log/RetryableUtil.xml @@ -0,0 +1,33 @@ + + + + + + + + + ${LOG_HOME}/接口重试/%d{yyyy-MM-dd}.%i.log + + 15 + + 200MB + + 2GB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + ${log.charset} + + + + + + + + + + + diff --git a/acs/nladmin-system/src/main/resources/logback-spring.xml b/acs/nladmin-system/src/main/resources/logback-spring.xml index 15d2500..8748d8c 100644 --- a/acs/nladmin-system/src/main/resources/logback-spring.xml +++ b/acs/nladmin-system/src/main/resources/logback-spring.xml @@ -34,12 +34,12 @@ https://juejin.cn/post/6844903775631572999 - - + + - + @@ -83,7 +83,9 @@ https://juejin.cn/post/6844903775631572999 ${log.pattern} @@ -117,21 +119,21 @@ https://juejin.cn/post/6844903775631572999 - + - + - + - + @@ -171,20 +173,20 @@ https://juejin.cn/post/6844903775631572999 - + - + - + - +