Commit 2dfdc025a35902e578e012b6006c8a7f3d4a005a
1 parent
815273bb
新增 XXL-Job 分布式调度支持,完善订单自动派单、超时取消和 Webhook 重试任务逻辑
Showing
8 changed files
with
147 additions
and
37 deletions
pom.xml
| @@ -92,6 +92,13 @@ | @@ -92,6 +92,13 @@ | ||
| 92 | <version>3.6.6</version> | 92 | <version>3.6.6</version> |
| 93 | </dependency> | 93 | </dependency> |
| 94 | 94 | ||
| 95 | + <!-- XXL-Job 分布式调度 --> | ||
| 96 | + <dependency> | ||
| 97 | + <groupId>com.xuxueli</groupId> | ||
| 98 | + <artifactId>xxl-job-core</artifactId> | ||
| 99 | + <version>2.4.1</version> | ||
| 100 | + </dependency> | ||
| 101 | + | ||
| 95 | <!-- Test --> | 102 | <!-- Test --> |
| 96 | <dependency> | 103 | <dependency> |
| 97 | <groupId>org.springframework.boot</groupId> | 104 | <groupId>org.springframework.boot</groupId> |
src/main/java/com/diligrp/rider/config/XxlJobConfig.java
0 → 100644
| 1 | +package com.diligrp.rider.config; | ||
| 2 | + | ||
| 3 | +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.springframework.beans.factory.annotation.Value; | ||
| 6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 7 | +import org.springframework.context.annotation.Bean; | ||
| 8 | +import org.springframework.context.annotation.Configuration; | ||
| 9 | + | ||
| 10 | +@Slf4j | ||
| 11 | +@Configuration | ||
| 12 | +@ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true", matchIfMissing = true) | ||
| 13 | +public class XxlJobConfig { | ||
| 14 | + | ||
| 15 | + @Value("${xxl.job.admin.addresses:}") | ||
| 16 | + private String adminAddresses; | ||
| 17 | + | ||
| 18 | + @Value("${xxl.job.accessToken:default_token}") | ||
| 19 | + private String accessToken; | ||
| 20 | + | ||
| 21 | + @Value("${xxl.job.executor.appname:rider-service-executor}") | ||
| 22 | + private String appname; | ||
| 23 | + | ||
| 24 | + @Value("${xxl.job.executor.address:}") | ||
| 25 | + private String address; | ||
| 26 | + | ||
| 27 | + @Value("${xxl.job.executor.ip:}") | ||
| 28 | + private String ip; | ||
| 29 | + | ||
| 30 | + @Value("${xxl.job.executor.port:9999}") | ||
| 31 | + private int port; | ||
| 32 | + | ||
| 33 | + @Value("${xxl.job.executor.logpath:./logs/xxl-job/jobhandler}") | ||
| 34 | + private String logPath; | ||
| 35 | + | ||
| 36 | + @Value("${xxl.job.executor.logretentiondays:30}") | ||
| 37 | + private int logRetentionDays; | ||
| 38 | + | ||
| 39 | + @Bean(initMethod = "start", destroyMethod = "destroy") | ||
| 40 | + public XxlJobSpringExecutor xxlJobExecutor() { | ||
| 41 | + log.info("XXL-Job executor 启动 adminAddresses={} appname={} port={}", adminAddresses, appname, port); | ||
| 42 | + XxlJobSpringExecutor executor = new XxlJobSpringExecutor(); | ||
| 43 | + executor.setAdminAddresses(adminAddresses); | ||
| 44 | + executor.setAccessToken(accessToken); | ||
| 45 | + executor.setAppname(appname); | ||
| 46 | + executor.setAddress(address); | ||
| 47 | + executor.setIp(ip); | ||
| 48 | + executor.setPort(port); | ||
| 49 | + executor.setLogPath(logPath); | ||
| 50 | + executor.setLogRetentionDays(logRetentionDays); | ||
| 51 | + return executor; | ||
| 52 | + } | ||
| 53 | +} |
src/main/java/com/diligrp/rider/service/impl/DispatchServiceImpl.java
| @@ -14,10 +14,12 @@ import com.diligrp.rider.vo.DispatchRuleTemplateVO; | @@ -14,10 +14,12 @@ import com.diligrp.rider.vo.DispatchRuleTemplateVO; | ||
| 14 | import com.fasterxml.jackson.databind.ObjectMapper; | 14 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 15 | import lombok.RequiredArgsConstructor; | 15 | import lombok.RequiredArgsConstructor; |
| 16 | import lombok.extern.slf4j.Slf4j; | 16 | import lombok.extern.slf4j.Slf4j; |
| 17 | +import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 17 | import org.springframework.stereotype.Service; | 18 | import org.springframework.stereotype.Service; |
| 18 | import org.springframework.transaction.annotation.Transactional; | 19 | import org.springframework.transaction.annotation.Transactional; |
| 19 | 20 | ||
| 20 | import java.math.BigDecimal; | 21 | import java.math.BigDecimal; |
| 22 | +import java.time.Duration; | ||
| 21 | import java.time.LocalDate; | 23 | import java.time.LocalDate; |
| 22 | import java.time.ZoneId; | 24 | import java.time.ZoneId; |
| 23 | import java.time.format.DateTimeFormatter; | 25 | import java.time.format.DateTimeFormatter; |
| @@ -28,6 +30,9 @@ import java.util.*; | @@ -28,6 +30,9 @@ import java.util.*; | ||
| 28 | @RequiredArgsConstructor | 30 | @RequiredArgsConstructor |
| 29 | public class DispatchServiceImpl implements DispatchService { | 31 | public class DispatchServiceImpl implements DispatchService { |
| 30 | 32 | ||
| 33 | + private static final String DISPATCH_LOCK_PREFIX = "dispatch:lock:order:"; | ||
| 34 | + private static final Duration DISPATCH_LOCK_TTL = Duration.ofSeconds(10); | ||
| 35 | + | ||
| 31 | private final DispatchRuleService dispatchRuleService; | 36 | private final DispatchRuleService dispatchRuleService; |
| 32 | private final RiderMapper riderMapper; | 37 | private final RiderMapper riderMapper; |
| 33 | private final RiderLocationMapper locationMapper; | 38 | private final RiderLocationMapper locationMapper; |
| @@ -37,10 +42,26 @@ public class DispatchServiceImpl implements DispatchService { | @@ -37,10 +42,26 @@ public class DispatchServiceImpl implements DispatchService { | ||
| 37 | private final RiderHoldLimitService riderHoldLimitService; | 42 | private final RiderHoldLimitService riderHoldLimitService; |
| 38 | private final WebhookService webhookService; | 43 | private final WebhookService webhookService; |
| 39 | private final ObjectMapper objectMapper; | 44 | private final ObjectMapper objectMapper; |
| 45 | + private final StringRedisTemplate redisTemplate; | ||
| 40 | 46 | ||
| 41 | @Override | 47 | @Override |
| 42 | @Transactional | 48 | @Transactional |
| 43 | public Long dispatch(Orders order) { | 49 | public Long dispatch(Orders order) { |
| 50 | + String lockKey = DISPATCH_LOCK_PREFIX + order.getId(); | ||
| 51 | + Boolean locked = redisTemplate.opsForValue() | ||
| 52 | + .setIfAbsent(lockKey, "1", DISPATCH_LOCK_TTL); | ||
| 53 | + if (!Boolean.TRUE.equals(locked)) { | ||
| 54 | + log.debug("订单 {} 派单锁被占用,跳过", order.getId()); | ||
| 55 | + return null; | ||
| 56 | + } | ||
| 57 | + try { | ||
| 58 | + return doDispatch(order); | ||
| 59 | + } finally { | ||
| 60 | + redisTemplate.delete(lockKey); | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + private Long doDispatch(Orders order) { | ||
| 44 | DispatchRuleTemplateVO rule = dispatchRuleService.getActiveRule(order.getCityId()); | 65 | DispatchRuleTemplateVO rule = dispatchRuleService.getActiveRule(order.getCityId()); |
| 45 | if (rule == null) { | 66 | if (rule == null) { |
| 46 | log.debug("城市 {} 无生效调度规则,跳过派单", order.getCityId()); | 67 | log.debug("城市 {} 无生效调度规则,跳过派单", order.getCityId()); |
src/main/java/com/diligrp/rider/service/impl/WebhookServiceImpl.java
| 1 | package com.diligrp.rider.service.impl; | 1 | package com.diligrp.rider.service.impl; |
| 2 | 2 | ||
| 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 4 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 4 | import com.fasterxml.jackson.databind.ObjectMapper; | 5 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 5 | import com.diligrp.rider.entity.OpenApp; | 6 | import com.diligrp.rider.entity.OpenApp; |
| 6 | import com.diligrp.rider.entity.Orders; | 7 | import com.diligrp.rider.entity.Orders; |
| @@ -70,9 +71,21 @@ public class WebhookServiceImpl implements WebhookService { | @@ -70,9 +71,21 @@ public class WebhookServiceImpl implements WebhookService { | ||
| 70 | 71 | ||
| 71 | @Override | 72 | @Override |
| 72 | public void retry(Long logId) { | 73 | public void retry(Long logId) { |
| 73 | - WebhookLog log = webhookLogMapper.selectById(logId); | ||
| 74 | - if (log == null || log.getStatus() == 1) return; | ||
| 75 | - retry(log); | 74 | + WebhookLog webhookLog = webhookLogMapper.selectById(logId); |
| 75 | + if (webhookLog == null || webhookLog.getStatus() == 1) return; | ||
| 76 | + | ||
| 77 | + Integer prevRetryCount = webhookLog.getRetryCount() == null ? 0 : webhookLog.getRetryCount(); | ||
| 78 | + int updated = webhookLogMapper.update(null, new LambdaUpdateWrapper<WebhookLog>() | ||
| 79 | + .eq(WebhookLog::getId, logId) | ||
| 80 | + .eq(WebhookLog::getStatus, 0) | ||
| 81 | + .eq(WebhookLog::getRetryCount, prevRetryCount) | ||
| 82 | + .setSql("retry_count = retry_count + 1")); | ||
| 83 | + if (updated == 0) { | ||
| 84 | + log.debug("Webhook 重试抢占失败 logId={}(可能被其他实例处理或状态已变)", logId); | ||
| 85 | + return; | ||
| 86 | + } | ||
| 87 | + webhookLog.setRetryCount(prevRetryCount + 1); | ||
| 88 | + retry(webhookLog); | ||
| 76 | } | 89 | } |
| 77 | 90 | ||
| 78 | private void retry(WebhookLog webhookLog) { | 91 | private void retry(WebhookLog webhookLog) { |
| @@ -84,12 +97,13 @@ public class WebhookServiceImpl implements WebhookService { | @@ -84,12 +97,13 @@ public class WebhookServiceImpl implements WebhookService { | ||
| 84 | } | 97 | } |
| 85 | if (url == null || url.isBlank()) return; | 98 | if (url == null || url.isBlank()) return; |
| 86 | SendResult result = sendHttp(app, url, webhookLog.getEvent(), webhookLog.getPayload()); | 99 | SendResult result = sendHttp(app, url, webhookLog.getEvent(), webhookLog.getPayload()); |
| 87 | - webhookLog.setUrl(url); | ||
| 88 | - webhookLog.setResponseCode(result.responseCode()); | ||
| 89 | - webhookLog.setResponseBody(trimResponseBody(result.responseBody())); | ||
| 90 | - webhookLog.setStatus(result.status()); | ||
| 91 | - webhookLog.setRetryCount((webhookLog.getRetryCount() == null ? 0 : webhookLog.getRetryCount()) + 1); | ||
| 92 | - webhookLogMapper.updateById(webhookLog); | 100 | + // retry_count 已在 retry(Long) 入口的 CAS 中递增,这里只更新发送结果字段 |
| 101 | + webhookLogMapper.update(null, new LambdaUpdateWrapper<WebhookLog>() | ||
| 102 | + .eq(WebhookLog::getId, webhookLog.getId()) | ||
| 103 | + .set(WebhookLog::getUrl, url) | ||
| 104 | + .set(WebhookLog::getResponseCode, result.responseCode()) | ||
| 105 | + .set(WebhookLog::getResponseBody, trimResponseBody(result.responseBody())) | ||
| 106 | + .set(WebhookLog::getStatus, result.status())); | ||
| 93 | } | 107 | } |
| 94 | 108 | ||
| 95 | private void doSend(OpenApp app, String url, String event, Long bizId, String payload, int retryCount) { | 109 | private void doSend(OpenApp app, String url, String event, Long bizId, String payload, int retryCount) { |
src/main/java/com/diligrp/rider/task/DispatchScheduleTask.java
| @@ -8,17 +8,15 @@ import com.diligrp.rider.mapper.OrdersMapper; | @@ -8,17 +8,15 @@ import com.diligrp.rider.mapper.OrdersMapper; | ||
| 8 | import com.diligrp.rider.service.DispatchRuleService; | 8 | import com.diligrp.rider.service.DispatchRuleService; |
| 9 | import com.diligrp.rider.service.DispatchService; | 9 | import com.diligrp.rider.service.DispatchService; |
| 10 | import com.diligrp.rider.vo.DispatchRuleTemplateVO; | 10 | import com.diligrp.rider.vo.DispatchRuleTemplateVO; |
| 11 | +import com.xxl.job.core.handler.annotation.XxlJob; | ||
| 11 | import lombok.RequiredArgsConstructor; | 12 | import lombok.RequiredArgsConstructor; |
| 12 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 13 | -import org.springframework.scheduling.annotation.EnableScheduling; | ||
| 14 | -import org.springframework.scheduling.annotation.Scheduled; | ||
| 15 | import org.springframework.stereotype.Component; | 14 | import org.springframework.stereotype.Component; |
| 16 | 15 | ||
| 17 | import java.util.List; | 16 | import java.util.List; |
| 18 | 17 | ||
| 19 | @Slf4j | 18 | @Slf4j |
| 20 | @Component | 19 | @Component |
| 21 | -@EnableScheduling | ||
| 22 | @RequiredArgsConstructor | 20 | @RequiredArgsConstructor |
| 23 | public class DispatchScheduleTask { | 21 | public class DispatchScheduleTask { |
| 24 | 22 | ||
| @@ -29,9 +27,8 @@ public class DispatchScheduleTask { | @@ -29,9 +27,8 @@ public class DispatchScheduleTask { | ||
| 29 | 27 | ||
| 30 | /** | 28 | /** |
| 31 | * 抢单超时后自动派单 | 29 | * 抢单超时后自动派单 |
| 32 | - * 每3秒执行一次 | ||
| 33 | */ | 30 | */ |
| 34 | - @Scheduled(fixedDelay = 3_000) | 31 | + @XxlJob("autoDispatchTimeoutOrderHandler") |
| 35 | public void autoDispatchTimeoutOrders() { | 32 | public void autoDispatchTimeoutOrders() { |
| 36 | try { | 33 | try { |
| 37 | List<City> cities = cityMapper.selectList(new LambdaQueryWrapper<City>() | 34 | List<City> cities = cityMapper.selectList(new LambdaQueryWrapper<City>() |
| @@ -69,6 +66,7 @@ public class DispatchScheduleTask { | @@ -69,6 +66,7 @@ public class DispatchScheduleTask { | ||
| 69 | } | 66 | } |
| 70 | } catch (Exception e) { | 67 | } catch (Exception e) { |
| 71 | log.error("自动派单任务异常", e); | 68 | log.error("自动派单任务异常", e); |
| 69 | + throw new RuntimeException(e); | ||
| 72 | } | 70 | } |
| 73 | } | 71 | } |
| 74 | } | 72 | } |
src/main/java/com/diligrp/rider/task/OrderScheduleTask.java
| @@ -7,10 +7,9 @@ import com.diligrp.rider.entity.Orders; | @@ -7,10 +7,9 @@ import com.diligrp.rider.entity.Orders; | ||
| 7 | import com.diligrp.rider.mapper.OrdersMapper; | 7 | import com.diligrp.rider.mapper.OrdersMapper; |
| 8 | import com.diligrp.rider.service.WebhookService; | 8 | import com.diligrp.rider.service.WebhookService; |
| 9 | import com.diligrp.rider.service.AdminMessageService; | 9 | import com.diligrp.rider.service.AdminMessageService; |
| 10 | +import com.xxl.job.core.handler.annotation.XxlJob; | ||
| 10 | import lombok.RequiredArgsConstructor; | 11 | import lombok.RequiredArgsConstructor; |
| 11 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
| 12 | -import org.springframework.scheduling.annotation.EnableScheduling; | ||
| 13 | -import org.springframework.scheduling.annotation.Scheduled; | ||
| 14 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| 15 | 14 | ||
| 16 | import java.util.HashMap; | 15 | import java.util.HashMap; |
| @@ -18,12 +17,10 @@ import java.util.List; | @@ -18,12 +17,10 @@ import java.util.List; | ||
| 18 | import java.util.Map; | 17 | import java.util.Map; |
| 19 | 18 | ||
| 20 | /** | 19 | /** |
| 21 | - * 订单定时任务 | ||
| 22 | - * OrderhandleCron(每3秒执行) | 20 | + * 订单定时任务(XXL-Job handler) |
| 23 | */ | 21 | */ |
| 24 | @Slf4j | 22 | @Slf4j |
| 25 | @Component | 23 | @Component |
| 26 | -@EnableScheduling | ||
| 27 | @RequiredArgsConstructor | 24 | @RequiredArgsConstructor |
| 28 | public class OrderScheduleTask { | 25 | public class OrderScheduleTask { |
| 29 | 26 | ||
| @@ -34,10 +31,8 @@ public class OrderScheduleTask { | @@ -34,10 +31,8 @@ public class OrderScheduleTask { | ||
| 34 | 31 | ||
| 35 | /** | 32 | /** |
| 36 | * 超时未接单订单自动取消(30分钟) | 33 | * 超时未接单订单自动取消(30分钟) |
| 37 | - * Orders::cancel() | ||
| 38 | - * 每分钟执行一次 | ||
| 39 | */ | 34 | */ |
| 40 | - @Scheduled(fixedDelay = 60_000) | 35 | + @XxlJob("autoCancelTimeoutOrderHandler") |
| 41 | public void autoCancelTimeout() { | 36 | public void autoCancelTimeout() { |
| 42 | try { | 37 | try { |
| 43 | long expireTime = System.currentTimeMillis() / 1000 - 30 * 60; | 38 | long expireTime = System.currentTimeMillis() / 1000 - 30 * 60; |
| @@ -70,14 +65,14 @@ public class OrderScheduleTask { | @@ -70,14 +65,14 @@ public class OrderScheduleTask { | ||
| 70 | } | 65 | } |
| 71 | } catch (Exception e) { | 66 | } catch (Exception e) { |
| 72 | log.error("超时取消任务异常", e); | 67 | log.error("超时取消任务异常", e); |
| 68 | + throw new RuntimeException(e); | ||
| 73 | } | 69 | } |
| 74 | } | 70 | } |
| 75 | 71 | ||
| 76 | /** | 72 | /** |
| 77 | * 订单超时提醒(配送中的订单,距离预计送达时间还有5分钟) | 73 | * 订单超时提醒(配送中的订单,距离预计送达时间还有5分钟) |
| 78 | - * 每分钟执行一次 | ||
| 79 | */ | 74 | */ |
| 80 | - @Scheduled(fixedDelay = 60_000) | 75 | + @XxlJob("orderTimeoutReminderHandler") |
| 81 | public void timeoutReminder() { | 76 | public void timeoutReminder() { |
| 82 | try { | 77 | try { |
| 83 | long now = System.currentTimeMillis() / 1000; | 78 | long now = System.currentTimeMillis() / 1000; |
| @@ -107,7 +102,8 @@ public class OrderScheduleTask { | @@ -107,7 +102,8 @@ public class OrderScheduleTask { | ||
| 107 | } | 102 | } |
| 108 | } | 103 | } |
| 109 | } catch (Exception e) { | 104 | } catch (Exception e) { |
| 110 | - log.error("超时取消任务异常", e); | 105 | + log.error("订单超时提醒任务异常", e); |
| 106 | + throw new RuntimeException(e); | ||
| 111 | } | 107 | } |
| 112 | } | 108 | } |
| 113 | 109 |
src/main/java/com/diligrp/rider/task/WebhookRetryTask.java
| @@ -4,9 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | @@ -4,9 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 4 | import com.diligrp.rider.entity.WebhookLog; | 4 | import com.diligrp.rider.entity.WebhookLog; |
| 5 | import com.diligrp.rider.mapper.WebhookLogMapper; | 5 | import com.diligrp.rider.mapper.WebhookLogMapper; |
| 6 | import com.diligrp.rider.service.WebhookService; | 6 | import com.diligrp.rider.service.WebhookService; |
| 7 | +import com.xxl.job.core.handler.annotation.XxlJob; | ||
| 7 | import lombok.RequiredArgsConstructor; | 8 | import lombok.RequiredArgsConstructor; |
| 8 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 9 | -import org.springframework.scheduling.annotation.Scheduled; | ||
| 10 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 11 | 11 | ||
| 12 | import java.util.List; | 12 | import java.util.List; |
| @@ -19,19 +19,24 @@ public class WebhookRetryTask { | @@ -19,19 +19,24 @@ public class WebhookRetryTask { | ||
| 19 | private final WebhookLogMapper webhookLogMapper; | 19 | private final WebhookLogMapper webhookLogMapper; |
| 20 | private final WebhookService webhookService; | 20 | private final WebhookService webhookService; |
| 21 | 21 | ||
| 22 | - @Scheduled(fixedDelay = 300_000) | 22 | + @XxlJob("webhookRetryHandler") |
| 23 | public void retryFailedWebhooks() { | 23 | public void retryFailedWebhooks() { |
| 24 | - List<WebhookLog> logs = webhookLogMapper.selectList(new LambdaQueryWrapper<WebhookLog>() | ||
| 25 | - .eq(WebhookLog::getStatus, 0) | ||
| 26 | - .lt(WebhookLog::getRetryCount, 5) | ||
| 27 | - .orderByAsc(WebhookLog::getCreateTime) | ||
| 28 | - .last("LIMIT 20")); | ||
| 29 | - for (WebhookLog webhookLog : logs) { | ||
| 30 | - try { | ||
| 31 | - webhookService.retry(webhookLog.getId()); | ||
| 32 | - } catch (Exception e) { | ||
| 33 | - log.warn("Webhook 自动重试失败 logId={}", webhookLog.getId(), e); | 24 | + try { |
| 25 | + List<WebhookLog> logs = webhookLogMapper.selectList(new LambdaQueryWrapper<WebhookLog>() | ||
| 26 | + .eq(WebhookLog::getStatus, 0) | ||
| 27 | + .lt(WebhookLog::getRetryCount, 5) | ||
| 28 | + .orderByAsc(WebhookLog::getCreateTime) | ||
| 29 | + .last("LIMIT 20")); | ||
| 30 | + for (WebhookLog webhookLog : logs) { | ||
| 31 | + try { | ||
| 32 | + webhookService.retry(webhookLog.getId()); | ||
| 33 | + } catch (Exception e) { | ||
| 34 | + log.warn("Webhook 自动重试失败 logId={}", webhookLog.getId(), e); | ||
| 35 | + } | ||
| 34 | } | 36 | } |
| 37 | + } catch (Exception e) { | ||
| 38 | + log.error("Webhook 重试任务异常", e); | ||
| 39 | + throw new RuntimeException(e); | ||
| 35 | } | 40 | } |
| 36 | } | 41 | } |
| 37 | } | 42 | } |
src/main/resources/application.yml
| @@ -2,6 +2,8 @@ server: | @@ -2,6 +2,8 @@ server: | ||
| 2 | port: 8080 | 2 | port: 8080 |
| 3 | 3 | ||
| 4 | spring: | 4 | spring: |
| 5 | + application: | ||
| 6 | + name: rider-service | ||
| 5 | datasource: | 7 | datasource: |
| 6 | driver-class-name: com.mysql.cj.jdbc.Driver | 8 | driver-class-name: com.mysql.cj.jdbc.Driver |
| 7 | url: jdbc:mysql://mysql.diligrp.com:3306/dili_rider?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai | 9 | url: jdbc:mysql://mysql.diligrp.com:3306/dili_rider?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai |
| @@ -45,6 +47,20 @@ amap: | @@ -45,6 +47,20 @@ amap: | ||
| 45 | connect-timeout-millis: 3000 | 47 | connect-timeout-millis: 3000 |
| 46 | read-timeout-millis: 3000 | 48 | read-timeout-millis: 3000 |
| 47 | 49 | ||
| 50 | +xxl: | ||
| 51 | + job: | ||
| 52 | + enabled: false # 本地开发可用 -Dxxl.job.enabled=false 关闭 executor 自启 | ||
| 53 | + accessToken: default_token # 调度中心与执行器通信 token,生产环境务必修改 | ||
| 54 | + admin: | ||
| 55 | + addresses: http://localhost:8081/xxl-job-admin # 调度中心地址,多个用逗号分隔 | ||
| 56 | + executor: | ||
| 57 | + appname: rider-service-executor # 执行器 AppName,调度中心需要匹配 | ||
| 58 | + address: # 留空时由 ip+port 自动拼接 | ||
| 59 | + ip: # 留空时自动获取本机 IP(多网卡需显式指定) | ||
| 60 | + port: 9999 # 执行器内嵌服务端口 | ||
| 61 | + logpath: ./logs/xxl-job/jobhandler # 任务日志本地落盘路径 | ||
| 62 | + logretentiondays: 30 # 日志保留天数 | ||
| 63 | + | ||
| 48 | logging: | 64 | logging: |
| 49 | level: | 65 | level: |
| 50 | com.diligrp.rider: debug | 66 | com.diligrp.rider: debug |