Browse Source

修改空投实现方式 使用队列在app端实现

xudm 2 months ago
parent
commit
85e1d2c6e4

+ 5 - 0
continew-common/pom.xml

@@ -147,5 +147,10 @@
             <groupId>top.continew</groupId>
             <artifactId>continew-starter-json-jackson</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 32 - 0
continew-common/src/main/java/top/continew/admin/common/config/mq/RabbitMQConfig.java

@@ -0,0 +1,32 @@
+package top.continew.admin.common.config.mq;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+    public static final String AIRDROP_QUEUE = "gold.coin.airdrop.queue";
+    public static final String AIRDROP_EXCHANGE = "gold.coin.airdrop.exchange";
+
+    @Bean
+    public Queue airdropQueue() {
+        return new Queue(AIRDROP_QUEUE, true, false, false);
+    }
+
+
+    @Bean
+    public DirectExchange airdropExchange() {
+        return new DirectExchange(AIRDROP_EXCHANGE, true, false);
+    }
+
+    @Bean
+    public Binding bindingAirdrop() {
+        return BindingBuilder.bind(airdropQueue())
+                .to(airdropExchange())
+                .with(AIRDROP_QUEUE);
+    }
+}

+ 4 - 0
continew-module-system/src/main/java/top/continew/admin/business/model/req/AirdropManagerReq.java

@@ -21,6 +21,7 @@ import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.time.LocalDateTime;
 
 @Data
 @Schema(description = "创建或修改空投参数")
@@ -37,4 +38,7 @@ public class AirdropManagerReq implements Serializable {
     @Schema(description = "操作类型【0 新增空投 1 减去空投】")
     @NotNull(message = "操作类型不能为空")
     private Integer operationType;
+
+    @Schema(description = "操作人")
+    private String operationUser;
 }

+ 24 - 0
continew-module-system/src/main/java/top/continew/admin/business/mq/AirdropMessageProducer.java

@@ -0,0 +1,24 @@
+package top.continew.admin.business.mq;
+
+import com.alibaba.fastjson2.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.stereotype.Component;
+import top.continew.admin.business.model.req.AirdropManagerReq;
+import top.continew.admin.common.config.mq.RabbitMQConfig;
+
+@Component
+@Slf4j
+public class AirdropMessageProducer {
+    @Autowired
+    private RabbitTemplate rabbitTemplate;
+
+    @Retryable(backoff = @org.springframework.retry.annotation.Backoff(delay = 1000, multiplier = 2))
+    public void sendMessage(AirdropManagerReq message) {
+        log.info("发送消息:{}", message);
+        String jsonString = JSON.toJSONString(message);
+        rabbitTemplate.convertAndSend(RabbitMQConfig.AIRDROP_EXCHANGE, RabbitMQConfig.AIRDROP_QUEUE, jsonString);
+    }
+}

+ 6 - 26
continew-module-system/src/main/java/top/continew/admin/business/service/Impl/AirdropManagerServiceImpl.java

@@ -21,16 +21,14 @@ import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import top.continew.admin.business.model.entity.AirdropRecord;
 import top.continew.admin.business.model.entity.TgUser;
 import top.continew.admin.business.model.req.AirdropManagerReq;
+import top.continew.admin.business.mq.AirdropMessageProducer;
 import top.continew.admin.business.service.AirdropManagerService;
 import top.continew.admin.business.service.IAirdropRecordService;
 import top.continew.admin.business.service.ITgUserService;
 import top.continew.starter.core.validation.CheckUtils;
 
-import java.time.LocalDateTime;
-
 @Service
 @AllArgsConstructor
 @Slf4j
@@ -38,6 +36,8 @@ public class AirdropManagerServiceImpl implements AirdropManagerService {
     private final IAirdropRecordService recordService;
     private final ITgUserService userService;
 
+    private AirdropMessageProducer airdropMessageProducer;
+
     @Override
     @Transactional
     public void airdropManager(AirdropManagerReq req) {
@@ -45,28 +45,8 @@ public class AirdropManagerServiceImpl implements AirdropManagerService {
         TgUser user = userService.getById(req.getTargetUser());
         CheckUtils.throwIfNull(user, "空投目标用户为空");
 
-        Integer goldCoinNum = req.getGoldCoinNum();
-        Integer airdropCoin = user.getAirdropCoin();
-        Integer preDropNum = user.getAirdropCoin();
-
-        //用户表新增或者减去空投金币数量
-        if (req.getOperationType().equals(1)) {
-            airdropCoin -= goldCoinNum;
-        } else {
-            airdropCoin += goldCoinNum;
-        }
-        user.setAirdropCoin(airdropCoin);
-        //记录操作日志
-        AirdropRecord record = new AirdropRecord();
-        record.setAirdropTime(LocalDateTime.now());
-        record.setTargetUser(user.getId());
-        record.setPreDropNum(preDropNum);
-        record.setPostDropNum(airdropCoin);
-        record.setGoldCoinNum(goldCoinNum);
-        record.setCreatedBy(String.valueOf(loginId));
-        record.setCreatedTime(LocalDateTime.now());
-        //同时更新
-        userService.updateById(user);
-        recordService.save(record);
+        req.setOperationUser(String.valueOf(loginId));
+        //使用队列的方式进行异步处理 在app端进行异步处理
+        airdropMessageProducer.sendMessage(req);
     }
 }

+ 31 - 6
continew-webapi/src/main/resources/config/application-dev.yml

@@ -15,11 +15,11 @@ spring.datasource:
   username: ${DB_USER:root}
   password: ${DB_PWD:123456}
   driver-class-name: com.p6spy.engine.spy.P6SpyDriver
-#  # PostgreSQL 配置
-#  url: jdbc:p6spy:postgresql://${DB_HOST:127.0.0.1}:${DB_PORT:5432}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
-#  username: ${DB_USER:root}
-#  password: ${DB_PWD:123456}
-#  driver-class-name: com.p6spy.engine.spy.P6SpyDriver
+  #  # PostgreSQL 配置
+  #  url: jdbc:p6spy:postgresql://${DB_HOST:127.0.0.1}:${DB_PORT:5432}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
+  #  username: ${DB_USER:root}
+  #  password: ${DB_PWD:123456}
+  #  driver-class-name: com.p6spy.engine.spy.P6SpyDriver
   # Hikari 连接池配置(完整配置请参阅:https://github.com/brettwooldridge/HikariCP)
   hikari:
     # 最大连接数量(默认 10,根据实际环境调整)
@@ -315,4 +315,29 @@ snail-job:
     # 时间单位
     timeUnit: SECONDS
     # 队列容量
-    queueCapacity: 10000
+    queueCapacity: 10000
+
+spring.rabbitmq:
+  virtual-host: /
+  host: 192.168.241.132
+  port: 5672
+  username: admin
+  password: admin
+  listener:
+    simple:
+      acknowledge-mode: manual
+      concurrency: 5
+      max-concurrency: 10
+      prefetch: 1
+      retry:
+        enabled: true
+        initial-interval: 1000
+        max-attempts: 3
+        multiplier: 2
+  # 重试配置
+  template:
+    retry:
+      enabled: true
+      initial-interval: 1000
+      max-attempts: 3
+      multiplier: 2

+ 1 - 1
continew-webapi/src/main/resources/config/application.yml

@@ -253,7 +253,7 @@ spring:
   ## 环境配置
   profiles:
     # 启用的环境
-    active: prod
+    active: dev
 #    include:
 #      - generator
   ## 线程池配置(默认启用扩展配置,如未指定 corePoolSize、maxPoolSize 则根据机器配置自动设置)