add:反馈任务状态接口重试
This commit is contained in:
@@ -406,6 +406,11 @@
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<distributionManagement>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Integer> 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]);
|
||||
}
|
||||
}
|
||||
@@ -115,5 +115,5 @@ public interface AcsToWmsService {
|
||||
*/
|
||||
HttpResponse feedAgvTaskStatus(JSONArray from);
|
||||
|
||||
public HttpResponse test(JSONObject form);
|
||||
JSONObject test(JSONObject form);
|
||||
}
|
||||
|
||||
@@ -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<String, Object> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
33
acs/nladmin-system/src/main/resources/log/RetryableUtil.xml
Normal file
33
acs/nladmin-system/src/main/resources/log/RetryableUtil.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<included>
|
||||
<springProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
|
||||
<property name="LOG_HOME" value="${logPath}"/>
|
||||
<!-- 按照每天生成日志文件 -->
|
||||
<appender name="FILE12" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!--日志文件输出的文件名-->
|
||||
<FileNamePattern>${LOG_HOME}/接口重试/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
<!--单个日志最大容量 至少10MB才能看得出来-->
|
||||
<maxFileSize>200MB</maxFileSize>
|
||||
<!--所有日志最多占多大容量-->
|
||||
<totalSizeCap>2GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>${log.charset}</charset>
|
||||
</encoder>
|
||||
|
||||
</appender>
|
||||
|
||||
<!-- <logger name="org.nl.start.Init" level="info" additivity="false">
|
||||
<appender-ref ref="FILE3"/>
|
||||
</logger>-->
|
||||
|
||||
<!-- 打印sql -->
|
||||
<logger name="org.nl.acs.ext.wms.RetryableUtil" level="error" additivity="false">
|
||||
<appender-ref ref="FILE12"/>
|
||||
</logger>
|
||||
</included>
|
||||
@@ -34,12 +34,12 @@ https://juejin.cn/post/6844903775631572999
|
||||
<!--FILE 10开始+1-->
|
||||
<include resource="log/OneNDCSocketConnectionAutoRun.xml"/>
|
||||
<include resource="log/AgvNdcOneDeviceDriver.xml"/>
|
||||
<include resource="log/AcsToLk.xml"/>
|
||||
<include resource="log/LkToAcs.xml"/>
|
||||
<!-- <include resource="log/AcsToLk.xml"/>-->
|
||||
<!-- <include resource="log/LkToAcs.xml"/>-->
|
||||
<include resource="log/AcsToWms.xml"/>
|
||||
<include resource="log/WmsToAcs.xml"/>
|
||||
<include resource="log/OpcUtil.xml"/>
|
||||
|
||||
<include resource="log/RetryableUtil.xml"/>
|
||||
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
@@ -83,7 +83,9 @@ https://juejin.cn/post/6844903775631572999
|
||||
</http>
|
||||
<format>
|
||||
<label>
|
||||
<pattern>system=${SYSTEM_NAME},level=%level,logType=%X{log_file_type:-logType},device=%X{device_code_log:-device}</pattern>
|
||||
<pattern>
|
||||
system=${SYSTEM_NAME},level=%level,logType=%X{log_file_type:-logType},device=%X{device_code_log:-device}
|
||||
</pattern>
|
||||
</label>
|
||||
<message>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
@@ -117,21 +119,21 @@ https://juejin.cn/post/6844903775631572999
|
||||
<springProfile name="dev">
|
||||
<root level="info">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
<appender-ref ref="asyncFileAppender"/>
|
||||
</root>
|
||||
<!--logmanage -->
|
||||
<logger name="org.nl.acs.log.service.impl.DeviceExecuteLogServiceImpl" level="info" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<logger name="jdbc.resultsettable" level="ERROR" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<logger name="org.openscada.opc.lib.da.Server" level="ERROR" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<!--logmanage -->
|
||||
|
||||
@@ -171,20 +173,20 @@ https://juejin.cn/post/6844903775631572999
|
||||
<springProfile name="prod">
|
||||
<root level="info">
|
||||
<appender-ref ref="ERROR"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
<appender-ref ref="asyncFileAppender"/>
|
||||
</root>
|
||||
<!--logmanage -->
|
||||
<logger name="org.nl.acs.log.service.impl.DeviceExecuteLogServiceImpl" level="info" additivity="false">
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<logger name="jdbc.resultsettable" level="ERROR" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<logger name="org.openscada.opc.lib.da.Server" level="ERROR" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
<appender-ref ref="lokiAppender"/>
|
||||
</logger>
|
||||
<!--logmanage -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user