浏览代码

task和mq改造

wangliang 5 年之前
父节点
当前提交
3b9587afda
共有 32 个文件被更改,包括 363 次插入123 次删除
  1. 2 2
      themis-backend/pom.xml
  2. 0 1
      themis-backend/src/main/java/com/qmth/themis/backend/ThemisBackendApplication.java
  3. 1 1
      themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java
  4. 0 12
      themis-backend/src/main/java/com/qmth/themis/backend/config/DictionaryConfig.java
  5. 1 39
      themis-backend/src/main/resources/application.properties
  6. 8 8
      themis-business/pom.xml
  7. 1 1
      themis-business/src/main/java/com/qmth/themis/business/config/MapApiReader.java
  8. 1 1
      themis-business/src/main/java/com/qmth/themis/business/config/MybatisPlusConfig.java
  9. 10 10
      themis-business/src/main/java/com/qmth/themis/business/domain/QuartzConfigDomain.java
  10. 0 1
      themis-exam/src/main/java/com/qmth/themis/exam/ThemisExamApplication.java
  11. 22 0
      themis-exam/src/main/java/com/qmth/themis/exam/config/DictionaryConfig.java
  12. 48 13
      themis-exam/src/main/resources/application.properties
  13. 13 0
      themis-mq/README.md
  14. 1 1
      themis-mq/src/main/java/com/qmth/themis/mq/dto/MqDto.java
  15. 1 1
      themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketConsumerTranListener.java
  16. 1 1
      themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketConsumerTransaction.java
  17. 2 2
      themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketSessionConsumer.java
  18. 2 2
      themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketUserLogConsumer.java
  19. 3 2
      themis-mq/src/main/java/com/qmth/themis/mq/service/MqDtoService.java
  20. 2 2
      themis-mq/src/main/java/com/qmth/themis/mq/service/ProducerServer.java
  21. 4 4
      themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqDtoServiceImpl.java
  22. 3 3
      themis-mq/src/main/java/com/qmth/themis/mq/service/impl/ProducerServerImpl.java
  23. 7 0
      themis-task/Dockerfile
  24. 16 0
      themis-task/README.md
  25. 28 0
      themis-task/src/main/java/com/qmth/themis/task/config/DictionaryConfig.java
  26. 56 0
      themis-task/src/main/java/com/qmth/themis/task/config/DruidConfig.java
  27. 73 0
      themis-task/src/main/java/com/qmth/themis/task/config/SwaggerConfig.java
  28. 3 3
      themis-task/src/main/java/com/qmth/themis/task/quartz/MqJob.java
  29. 1 1
      themis-task/src/main/java/com/qmth/themis/task/service/QuartzService.java
  30. 4 4
      themis-task/src/main/java/com/qmth/themis/task/service/impl/QuartzServiceImpl.java
  31. 9 8
      themis-task/src/main/java/com/qmth/themis/task/start/StartRunning.java
  32. 40 0
      themis-task/src/main/resources/logback-spring.xml

+ 2 - 2
themis-backend/pom.xml

@@ -15,8 +15,8 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.qmth.themis.business</groupId>
-            <artifactId>themis-business</artifactId>
+            <groupId>com.qmth.themis.mq</groupId>
+            <artifactId>themis-mq</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 0 - 1
themis-backend/src/main/java/com/qmth/themis/backend/ThemisBackendApplication.java

@@ -30,7 +30,6 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 //主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中,做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中
 @EntityScan(basePackages = {"com.qmth.themis.business.entity"})//用来扫描和发现指定包及其子包中的Entity定义
 @EnableTransactionManagement //spring开启事务支持
-@EnableScheduling //spring quartz开启
 @EnableAsync //开启异步任务
 @EnableCaching//开启缓存注解
 public class ThemisBackendApplication {

+ 1 - 1
themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java

@@ -16,7 +16,6 @@ import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.enums.RoleEnum;
 import com.qmth.themis.business.enums.SystemOperationEnum;
 import com.qmth.themis.business.service.EhcacheService;
-import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TBUserService;
 import com.qmth.themis.business.util.EhcacheUtil;
 import com.qmth.themis.business.util.RedisUtil;
@@ -31,6 +30,7 @@ import com.qmth.themis.common.signature.SignatureType;
 import com.qmth.themis.common.util.AesUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.mq.service.MqDtoService;
 import io.swagger.annotations.*;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.slf4j.Logger;

+ 0 - 12
themis-backend/src/main/java/com/qmth/themis/backend/config/DictionaryConfig.java

@@ -80,16 +80,4 @@ public class DictionaryConfig {
     public MqConfigDomain mqConfigDomain() {
         return new MqConfigDomain();
     }
-
-
-    /**
-     * quartz配置
-     *
-     * @return
-     */
-    @Bean
-    @ConfigurationProperties(prefix = "quartz.config", ignoreUnknownFields = false)
-    public QuartzConfigDomain quartzConfigDomain() {
-        return new QuartzConfigDomain();
-    }
 }

+ 1 - 39
themis-backend/src/main/resources/application.properties

@@ -65,7 +65,7 @@ spring.main.allow-bean-definition-overriding=false
 logging.level.root=info
 
 # MyBatis-Plus\u914D\u7F6E
-mybatis-plus.typeAliasesPackage=com.qmth.themis.backend.entity
+mybatis-plus.typeAliasesPackage=com.qmth.themis.business.entity
 mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml
 mybatis-plus.global-config.id-type=1
 mybatis-plus.configuration.map-underscore-to-camel-case=true
@@ -169,44 +169,6 @@ mq.config.userLogConsumerStudentGroup=${mq.config.userLogConsumerGroup}-${mq.con
 #dlq\u6B7B\u4FE1\u961F\u5217
 #mq.config.sessionConsumerGroupDlq=${mq.config.sessionConsumerGroup}-dlq
 #mq.config.sessionTopicDlq=%DLQ%${mq.config.sessionConsumerGroup}
-#============================================================================
-# \u914D\u7F6EJobStore
-#============================================================================
-spring.quartz.job-store-type=jdbc
-spring.quartz.jdbc.initialize-schema=never
-# JobDataMaps\u662F\u5426\u90FD\u4E3AString\u7C7B\u578B\uFF0C\u9ED8\u8BA4false
-spring.quartz.properties.org.quartz.jobStore.useProperties=false
-# \u8868\u7684\u524D\u7F00\uFF0C\u9ED8\u8BA4QRTZ_
-spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
-# \u662F\u5426\u52A0\u5165\u96C6\u7FA4
-spring.quartz.properties.org.quartz.jobStore.isClustered=true
-# \u8C03\u5EA6\u5B9E\u4F8B\u5931\u6548\u7684\u68C0\u67E5\u65F6\u95F4\u95F4\u9694 ms
-spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=5000
-# \u5F53\u8BBE\u7F6E\u4E3A\u201Ctrue\u201D\u65F6\uFF0C\u6B64\u5C5E\u6027\u544A\u8BC9Quartz \u5728\u975E\u6258\u7BA1JDBC\u8FDE\u63A5\u4E0A\u8C03\u7528setTransactionIsolation\uFF08Connection.TRANSACTION_READ_COMMITTED\uFF09\u3002
-spring.quartz.properties.org.quartz.jobStore.txIsolationLevelReadCommitted=true
-# \u6570\u636E\u4FDD\u5B58\u65B9\u5F0F\u4E3A\u6570\u636E\u5E93\u6301\u4E45\u5316
-spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
-# \u6570\u636E\u5E93\u4EE3\u7406\u7C7B\uFF0C\u4E00\u822Corg.quartz.impl.jdbcjobstore.StdJDBCDelegate\u53EF\u4EE5\u6EE1\u8DB3\u5927\u90E8\u5206\u6570\u636E\u5E93
-spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-#============================================================================
-# Scheduler \u8C03\u5EA6\u5668\u5C5E\u6027\u914D\u7F6E
-#============================================================================
-# \u8C03\u5EA6\u6807\u8BC6\u540D \u96C6\u7FA4\u4E2D\u6BCF\u4E00\u4E2A\u5B9E\u4F8B\u90FD\u5FC5\u987B\u4F7F\u7528\u76F8\u540C\u7684\u540D\u79F0
-spring.quartz.properties.org.quartz.scheduler.instanceName=ClusterQuartz
-# ID\u8BBE\u7F6E\u4E3A\u81EA\u52A8\u83B7\u53D6 \u6BCF\u4E00\u4E2A\u5FC5\u987B\u4E0D\u540C
-spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
-
-#============================================================================
-# \u914D\u7F6EThreadPool
-#============================================================================
-# \u7EBF\u7A0B\u6C60\u7684\u5B9E\u73B0\u7C7B\uFF08\u4E00\u822C\u4F7F\u7528SimpleThreadPool\u5373\u53EF\u6EE1\u8DB3\u51E0\u4E4E\u6240\u6709\u7528\u6237\u7684\u9700\u6C42\uFF09
-spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
-# \u6307\u5B9A\u7EBF\u7A0B\u6570\uFF0C\u4E00\u822C\u8BBE\u7F6E\u4E3A1-100\u76F4\u63A5\u7684\u6574\u6570\uFF0C\u6839\u636E\u7CFB\u7EDF\u8D44\u6E90\u914D\u7F6E
-spring.quartz.properties.org.quartz.threadPool.threadCount=10
-# \u8BBE\u7F6E\u7EBF\u7A0B\u7684\u4F18\u5148\u7EA7(\u53EF\u4EE5\u662FThread.MIN_PRIORITY\uFF08\u53731\uFF09\u548CThread.MAX_PRIORITY\uFF08\u8FD9\u662F10\uFF09\u4E4B\u95F4\u7684\u4EFB\u4F55int \u3002\u9ED8\u8BA4\u503C\u4E3AThread.NORM_PRIORITY\uFF085\uFF09\u3002)
-spring.quartz.properties.org.quartz.threadPool.threadPriority=5
-quartz.config.jobName=backendJob
-quartz.config.jobGroupName=backendGroupName
 
 #api\u524D\u7F00
 prefix.url.admin=api/admin

+ 8 - 8
themis-business/pom.xml

@@ -87,13 +87,13 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-aop</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.rocketmq</groupId>
-            <artifactId>rocketmq-spring-boot-starter</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-quartz</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.rocketmq</groupId>-->
+<!--            <artifactId>rocketmq-spring-boot-starter</artifactId>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-quartz</artifactId>-->
+<!--        </dependency>-->
     </dependencies>
 </project>

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/config/MapApiReader.java

@@ -51,7 +51,7 @@ public class MapApiReader implements ParameterBuilderPlugin {
         }
     }
 
-    private final static String basePackage = "com.qmth.themis.backend.entity.";  //动态生成的Class名
+    private final static String basePackage = "com.qmth.themis.business.entity.";  //动态生成的Class名
 
     /**
      * 根据propertys中的值动态生成含有Swagger注解的javaBeen

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/config/MybatisPlusConfig.java

@@ -7,7 +7,7 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-@MapperScan(basePackages={"com.qmth.themis.backend.mapper"})
+@MapperScan(basePackages={"com.qmth.themis.business.dao"})
 public class MybatisPlusConfig {
 	
     /**

+ 10 - 10
themis-business/src/main/java/com/qmth/themis/business/domain/QuartzConfigDomain.java

@@ -9,22 +9,22 @@ package com.qmth.themis.business.domain;
  */
 public class QuartzConfigDomain {
 
-    private String jobName;
-    private String jobGroupName;
+    private String backendJobName;
+    private String backendJobGroupName;
 
-    public String getJobName() {
-        return jobName;
+    public String getBackendJobName() {
+        return backendJobName;
     }
 
-    public void setJobName(String jobName) {
-        this.jobName = jobName;
+    public void setBackendJobName(String backendJobName) {
+        this.backendJobName = backendJobName;
     }
 
-    public String getJobGroupName() {
-        return jobGroupName;
+    public String getBackendJobGroupName() {
+        return backendJobGroupName;
     }
 
-    public void setJobGroupName(String jobGroupName) {
-        this.jobGroupName = jobGroupName;
+    public void setBackendJobGroupName(String backendJobGroupName) {
+        this.backendJobGroupName = backendJobGroupName;
     }
 }

+ 0 - 1
themis-exam/src/main/java/com/qmth/themis/exam/ThemisExamApplication.java

@@ -30,7 +30,6 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 //主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中,做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中
 @EntityScan(basePackages = {"com.qmth.themis.business.entity"})//用来扫描和发现指定包及其子包中的Entity定义
 @EnableTransactionManagement //spring开启事务支持
-@EnableScheduling //spring quartz开启
 @EnableAsync //开启异步任务
 @EnableCaching//开启缓存注解
 public class ThemisExamApplication {

+ 22 - 0
themis-exam/src/main/java/com/qmth/themis/exam/config/DictionaryConfig.java

@@ -69,4 +69,26 @@ public class DictionaryConfig {
     public AliYunOssDomain aliYunOssDomain() {
         return new AliYunOssDomain();
     }
+
+//    /**
+//     * mq配置
+//     *
+//     * @return
+//     */
+//    @Bean
+//    @ConfigurationProperties(prefix = "mq.config", ignoreUnknownFields = false)
+//    public MqConfigDomain mqConfigDomain() {
+//        return new MqConfigDomain();
+//    }
+
+//    /**
+//     * quartz配置
+//     *
+//     * @return
+//     */
+//    @Bean
+//    @ConfigurationProperties(prefix = "quartz.config", ignoreUnknownFields = false)
+//    public QuartzConfigDomain quartzConfigDomain() {
+//        return new QuartzConfigDomain();
+//    }
 }

+ 48 - 13
themis-exam/src/main/resources/application.properties

@@ -65,7 +65,7 @@ spring.main.allow-bean-definition-overriding=false
 logging.level.root=info
 
 # MyBatis-Plus\u914D\u7F6E
-mybatis-plus.typeAliasesPackage=com.qmth.themis.backend.entity
+mybatis-plus.typeAliasesPackage=com.qmth.themis.business.entity
 mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml
 mybatis-plus.global-config.id-type=1
 mybatis-plus.configuration.map-underscore-to-camel-case=true
@@ -97,18 +97,53 @@ spring.jackson.time-zone=GMT+8
 #============================================================================
 # \u914D\u7F6Erocketmq
 #============================================================================
-rocketmq.name-server=127.0.0.1:9876
-rocketmq.producer.send-message-timeout=300000
-rocketmq.producer.group=my-group
-rocketmq.producer.compress-message-body-threshold=4096
-rocketmq.producer.max-message-size=4194304
-rocketmq.producer.retry-times-when-send-async-failed=0
-rocketmq.producer.retry-next-server=true
-rocketmq.producer.retry-times-when-send-failed=3
-rocketmq.producer.access-key=AK
-rocketmq.producer.secret-key=SK
-rocketmq.producer.enable-msg-trace=true
-rocketmq.producer.customized-trace-topic=my-trace-topic
+##namesrv\u5730\u5740
+#rocketmq.name-server=127.0.0.1:9876
+##\u53D1\u9001\u6D88\u606F\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u6BEB\u79D2\u3002\u9ED8\u8BA410000
+#rocketmq.producer.send-message-timeout=300000
+##Producer\u7EC4\u540D\uFF0C\u591A\u4E2AProducer\u5982\u679C\u5C5E\u4E8E\u4E00\u4E2A\u5E94\u7528\uFF0C\u53D1\u9001\u540C\u6837\u7684\u6D88\u606F\uFF0C\u5219\u5E94\u8BE5\u5C06\u5B83\u4EEC\u5F52\u4E3A\u540C\u4E00\u7EC4\u3002\u9ED8\u8BA4DEFAULT_PRODUCER
+#rocketmq.producer.group=my-group
+##\u5BA2\u6237\u7AEF\u9650\u5236\u7684\u6D88\u606F\u5927\u5C0F\uFF0C\u8D85\u8FC7\u62A5\u9519\uFF0C\u540C\u65F6\u670D\u52A1\u7AEF\u4E5F\u4F1A\u9650\u5236\uFF0C\u9700\u8981\u8DDF\u670D\u52A1\u7AEF\u914D\u5408\u4F7F\u7528\u3002\u9ED8\u8BA44MB
+#rocketmq.producer.compress-message-body-threshold=4096
+#rocketmq.producer.max-message-size=4194304
+##\u5982\u679C\u6D88\u606F\u53D1\u9001\u5931\u8D25\uFF0C\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF0C\u8BE5\u53C2\u6570\u53EA\u5BF9\u5F02\u6B65\u53D1\u9001\u6A21\u5F0F\u8D77\u4F5C\u7528\u3002\u9ED8\u8BA42
+#rocketmq.producer.retry-times-when-send-async-failed=3
+##\u5982\u679C\u6D88\u606F\u53D1\u9001\u5931\u8D25\uFF0C\u662F\u5426\u7EE7\u7EED\u53D1\u4E0B\u4E00\u6761
+#rocketmq.producer.retry-next-server=true
+##\u5982\u679C\u6D88\u606F\u53D1\u9001\u5931\u8D25\uFF0C\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF0C\u8BE5\u53C2\u6570\u53EA\u5BF9\u540C\u6B65\u53D1\u9001\u6A21\u5F0F\u8D77\u4F5C\u7528\u3002\u9ED8\u8BA42
+#rocketmq.producer.retry-times-when-send-failed=3
+##ACK
+#rocketmq.producer.access-key=AK
+#rocketmq.producer.secret-key=SK
+#rocketmq.producer.enable-msg-trace=true
+#rocketmq.producer.customized-trace-topic=my-trace-topic
+#
+#mq.config.server=themis
+##session_topic\u76D1\u542C
+#mq.config.sessionTopic=${mq.config.server}-topic-session
+#mq.config.sessionConsumerGroup=${mq.config.server}-group-session
+#
+#mq.config.sessionTopicWebTag=web
+#mq.config.sessionConsumerWebGroup=${mq.config.sessionConsumerGroup}-${mq.config.sessionTopicWebTag}
+#
+#mq.config.sessionTopicWxappVideoTag=wxapp_video
+#mq.config.sessionConsumerWxappVideoGroup=${mq.config.sessionConsumerGroup}-${mq.config.sessionTopicWxappVideoTag}
+#
+#mq.config.sessionTopicWxappAnswerTag=wxapp_answer
+#mq.config.sessionConsumerWxappAnswerGroup=${mq.config.sessionConsumerGroup}-${mq.config.sessionTopicWxappAnswerTag}
+#
+#mq.config.sessionTopicPcTag=pc
+#mq.config.sessionConsumerPcGroup=${mq.config.sessionConsumerGroup}-${mq.config.sessionTopicPcTag}
+#
+##user_login\u76D1\u542C
+#mq.config.userLogTopic=${mq.config.server}-topic-userLog
+#mq.config.userLogConsumerGroup=${mq.config.server}-group-userLog
+#
+#mq.config.userLogTopicUserTag=user
+#mq.config.userLogConsumerUserGroup=${mq.config.userLogConsumerGroup}-${mq.config.userLogTopicUserTag}
+#
+#mq.config.userLogTopicStudentTag=student
+#mq.config.userLogConsumerStudentGroup=${mq.config.userLogConsumerGroup}-${mq.config.userLogTopicStudentTag}
 
 #\u963F\u91CC\u4E91OSS\u914D\u7F6E
 aliyun.oss.name=oss-cn-shenzhen.aliyuncs.com

+ 13 - 0
themis-mq/README.md

@@ -0,0 +1,13 @@
+在线考试平台-rocketmq
+
+项目模块:
+rocketmq
+
+项目框架:
+java8,spring boot2.3.0,rocketmq
+
+数据库:
+mysql8.0
+
+附件:
+本地或oss存储

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/dto/MqDto.java → themis-mq/src/main/java/com/qmth/themis/mq/dto/MqDto.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.dto;
+package com.qmth.themis.mq.dto;
 
 import com.qmth.themis.business.enums.MqEnum;
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/listener/RocketConsumerTranListener.java → themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketConsumerTranListener.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.listener;
+package com.qmth.themis.mq.listener;
 
 import com.qmth.themis.business.constant.SystemConstant;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/listener/RocketConsumerTransaction.java → themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketConsumerTransaction.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.listener;
+package com.qmth.themis.mq.listener;
 
 import com.alibaba.fastjson.JSONObject;
 import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/listener/RocketSessionConsumer.java → themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketSessionConsumer.java

@@ -1,13 +1,13 @@
-package com.qmth.themis.business.listener;
+package com.qmth.themis.mq.listener;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.service.TBSessionService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.mq.dto.MqDto;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/listener/RocketUserLogConsumer.java → themis-mq/src/main/java/com/qmth/themis/mq/listener/RocketUserLogConsumer.java

@@ -1,13 +1,13 @@
-package com.qmth.themis.business.listener;
+package com.qmth.themis.mq.listener;
 
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.enums.SystemOperationEnum;
 import com.qmth.themis.business.service.TEUserLogService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.mq.dto.MqDto;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

+ 3 - 2
themis-business/src/main/java/com/qmth/themis/business/service/MqDtoService.java → themis-mq/src/main/java/com/qmth/themis/mq/service/MqDtoService.java

@@ -1,6 +1,7 @@
-package com.qmth.themis.business.service;
+package com.qmth.themis.mq.service;
 
-import com.qmth.themis.business.dto.MqDto;
+
+import com.qmth.themis.mq.dto.MqDto;
 
 /**
  * @Description: mqdto 服务类

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/service/ProducerServer.java → themis-mq/src/main/java/com/qmth/themis/mq/service/ProducerServer.java

@@ -1,7 +1,7 @@
-package com.qmth.themis.business.service;
+package com.qmth.themis.mq.service;
 
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.common.util.Result;
+import com.qmth.themis.mq.dto.MqDto;
 
 /**
  * @Description: mq 服务类

+ 4 - 4
themis-business/src/main/java/com/qmth/themis/business/service/impl/MqDtoServiceImpl.java → themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqDtoServiceImpl.java

@@ -1,11 +1,11 @@
-package com.qmth.themis.business.service.impl;
+package com.qmth.themis.mq.service.impl;
 
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.enums.MqEnum;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.ProducerServer;
 import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.mq.service.MqDtoService;
+import com.qmth.themis.mq.service.ProducerServer;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;

+ 3 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/ProducerServerImpl.java → themis-mq/src/main/java/com/qmth/themis/mq/service/impl/ProducerServerImpl.java

@@ -1,12 +1,12 @@
-package com.qmth.themis.business.service.impl;
+package com.qmth.themis.mq.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
-import com.qmth.themis.business.service.ProducerServer;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.mq.service.ProducerServer;
 import org.apache.rocketmq.client.producer.SendCallback;
 import org.apache.rocketmq.client.producer.SendResult;
 import org.apache.rocketmq.client.producer.TransactionSendResult;

+ 7 - 0
themis-task/Dockerfile

@@ -0,0 +1,7 @@
+FROM openjdk:8
+MAINTAINER luoshi luoshi@qmth.com.cn
+ENV TZ Asia/Shanghai
+
+ARG JAR_FILE
+COPY ${JAR_FILE} /opt/app.jar
+CMD java -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=50.0 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m $JAVA_OPTS -jar /opt/app.jar

+ 16 - 0
themis-task/README.md

@@ -0,0 +1,16 @@
+在线考试平台-任务管理
+
+项目模块:
+task
+
+项目框架:
+java8,spring boot2.3.0,rocketmq
+
+数据库:
+mysql8.0
+
+部署:
+docker
+
+附件:
+本地或oss存储

+ 28 - 0
themis-task/src/main/java/com/qmth/themis/task/config/DictionaryConfig.java

@@ -0,0 +1,28 @@
+package com.qmth.themis.task.config;
+
+import com.qmth.themis.business.domain.*;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @Description: 数据字典
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/4/10
+ */
+@Configuration
+public class DictionaryConfig {
+
+    /**
+     * quartz配置
+     *
+     * @return
+     */
+    @Bean
+    @ConfigurationProperties(prefix = "quartz.config", ignoreUnknownFields = false)
+    public QuartzConfigDomain quartzConfigDomain() {
+        return new QuartzConfigDomain();
+    }
+}

+ 56 - 0
themis-task/src/main/java/com/qmth/themis/task/config/DruidConfig.java

@@ -0,0 +1,56 @@
+//package com.qmth.themis.task.config;
+//
+//import com.alibaba.druid.pool.DruidDataSource;
+//import com.alibaba.druid.support.http.StatViewServlet;
+//import com.alibaba.druid.support.http.WebStatFilter;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.boot.web.servlet.FilterRegistrationBean;
+//import org.springframework.boot.web.servlet.ServletRegistrationBean;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+//import javax.sql.DataSource;
+//
+///**
+// * @Description: druid数据源配置
+// * @Param:
+// * @return:
+// * @Author: wangliang
+// * @Date: 2019/10/11
+// */
+//@Configuration
+//public class DruidConfig {
+//
+//    @Bean
+//    public ServletRegistrationBean druidServlet() {
+//        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
+//        // IP白名单
+//        servletRegistrationBean.addInitParameter("allow", "*");
+//        // IP黑名单(共同存在时,deny优先于allow)
+////        servletRegistrationBean.addInitParameter("deny", "192.168.1.206");
+//        //控制台管理用户
+//        servletRegistrationBean.addInitParameter("loginUsername", "admin");
+//        servletRegistrationBean.addInitParameter("loginPassword", "admin");
+//        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
+//        servletRegistrationBean.addInitParameter("resetEnable", "false");
+//        return servletRegistrationBean;
+//    }
+//
+//    @Bean
+//    public FilterRegistrationBean filterRegistrationBean() {
+//        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
+//        filterRegistrationBean.addUrlPatterns("/*");
+//        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
+//        return filterRegistrationBean;
+//    }
+//
+//    /**
+//     * 单数据源可以直接放开以下注释行
+//     */
+//    @Bean
+//    @ConfigurationProperties(prefix = "spring.datasource")
+//    public DataSource druid() {
+//        return new DruidDataSource();
+//    }
+//}
+//

+ 73 - 0
themis-task/src/main/java/com/qmth/themis/task/config/SwaggerConfig.java

@@ -0,0 +1,73 @@
+package com.qmth.themis.task.config;
+
+import com.google.common.base.Predicates;
+import com.qmth.themis.common.contanst.Constants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Description: swagger配置类
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2019/9/21
+ */
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+    @Bean
+    public Docket createRestApi() {
+        ParameterBuilder tokenPar = new ParameterBuilder();
+        ParameterBuilder tokenPar1 = new ParameterBuilder();
+        ParameterBuilder tokenPar2 = new ParameterBuilder();
+        ParameterBuilder tokenPar3 = new ParameterBuilder();
+        List<Parameter> pars = new ArrayList<>();
+        tokenPar.name(Constants.HEADER_PLATFORM).description("平台").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+        tokenPar1.name(Constants.HEADER_DEVICE_ID).description("设备id").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+        tokenPar2.name(Constants.HEADER_AUTHORIZATION).description("鉴权token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+        tokenPar3.name(Constants.HEADER_TIME).description("时间戳").modelRef(new ModelRef("long")).parameterType("header").required(false).build();
+        pars.add(tokenPar.build());
+        pars.add(tokenPar1.build());
+        pars.add(tokenPar2.build());
+        pars.add(tokenPar3.build());
+
+        return new Docket(DocumentationType.SWAGGER_2)
+                .groupName("themis-task")
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.qmth.themis.task"))
+//                .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                // 不显示错误的接口地址 
+                .paths(Predicates.not(PathSelectors.regex("/error.*")))// 错误路径不监控
+                .build()
+                .globalOperationParameters(pars)
+                .apiInfo(apiInfo());
+    }
+
+    private ApiInfo apiInfo() {
+        ApiInfo apiInfo = new ApiInfo(
+                "在线考试平台-考试管理 - api",
+                "Some custom description of API.",
+                "API TOS",
+                "Terms of service",
+                "myeaddress@company.com",
+                "License of API",
+                "API license URL");
+        return apiInfo;
+    }
+}
+ 
+

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/quartz/MqJob.java → themis-task/src/main/java/com/qmth/themis/task/quartz/MqJob.java

@@ -1,10 +1,10 @@
-package com.qmth.themis.backend.quartz;
+package com.qmth.themis.task.quartz;
 
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
-import com.qmth.themis.business.service.ProducerServer;
 import com.qmth.themis.business.threadPool.MyThreadPool;
 import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.mq.service.ProducerServer;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/service/QuartzService.java → themis-task/src/main/java/com/qmth/themis/task/service/QuartzService.java

@@ -1,4 +1,4 @@
-package com.qmth.themis.business.service;
+package com.qmth.themis.task.service;
 
 import org.springframework.scheduling.quartz.QuartzJobBean;
 

+ 4 - 4
themis-business/src/main/java/com/qmth/themis/business/service/impl/QuartzServiceImpl.java → themis-task/src/main/java/com/qmth/themis/task/service/impl/QuartzServiceImpl.java

@@ -1,6 +1,6 @@
-package com.qmth.themis.business.service.impl;
+package com.qmth.themis.task.service.impl;
 
-import com.qmth.themis.business.service.QuartzService;
+import com.qmth.themis.task.service.QuartzService;
 import org.quartz.*;
 import org.quartz.impl.matchers.GroupMatcher;
 import org.springframework.scheduling.quartz.QuartzJobBean;
@@ -200,7 +200,7 @@ public class QuartzServiceImpl implements QuartzService {
                     map.put("description", "触发器:" + trigger.getKey());
                     Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                     map.put("jobStatus", triggerState.name());
-                    if (trigger instanceof CronTrigger) {
+                    if (trigger instanceof org.springframework.scheduling.support.CronTrigger) {
                         CronTrigger cronTrigger = (CronTrigger) trigger;
                         String cronExpression = cronTrigger.getCronExpression();
                         map.put("jobTime", cronExpression);
@@ -235,7 +235,7 @@ public class QuartzServiceImpl implements QuartzService {
                 map.put("description", "触发器:" + trigger.getKey());
                 Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                 map.put("jobStatus", triggerState.name());
-                if (trigger instanceof CronTrigger) {
+                if (trigger instanceof org.springframework.scheduling.support.CronTrigger) {
                     CronTrigger cronTrigger = (CronTrigger) trigger;
                     String cronExpression = cronTrigger.getCronExpression();
                     map.put("jobTime", cronExpression);

+ 9 - 8
themis-backend/src/main/java/com/qmth/themis/backend/start/StartRunning.java → themis-task/src/main/java/com/qmth/themis/task/start/StartRunning.java

@@ -1,15 +1,15 @@
-package com.qmth.themis.backend.start;
+package com.qmth.themis.task.start;
 
-import com.qmth.themis.backend.config.DictionaryConfig;
-import com.qmth.themis.backend.quartz.MqJob;
-import com.qmth.themis.business.service.QuartzService;
-import org.assertj.core.util.Maps;
+import com.qmth.themis.task.config.DictionaryConfig;
+import com.qmth.themis.task.quartz.MqJob;
+import com.qmth.themis.task.service.QuartzService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -33,9 +33,10 @@ public class StartRunning implements CommandLineRunner {
     public void run(String... args) throws Exception {
         log.info("服务器启动时执行 start");
         log.info("增加mqjob start");
-        Map map = Maps.newHashMap("name", MqJob.class.getName());
-        quartzService.deleteJob(dictionaryConfig.quartzConfigDomain().getJobName(), dictionaryConfig.quartzConfigDomain().getJobGroupName());
-        quartzService.addJob(MqJob.class, dictionaryConfig.quartzConfigDomain().getJobName(), dictionaryConfig.quartzConfigDomain().getJobGroupName(), "0 0/1 * * * ?", map);
+        Map map = new HashMap();
+        map.put("name", MqJob.class.getName());
+        quartzService.deleteJob(dictionaryConfig.quartzConfigDomain().getBackendJobName(), dictionaryConfig.quartzConfigDomain().getBackendJobGroupName());
+        quartzService.addJob(MqJob.class, dictionaryConfig.quartzConfigDomain().getBackendJobName(), dictionaryConfig.quartzConfigDomain().getBackendJobGroupName(), "0 0/1 * * * ?", map);
         log.info("增加mqjob end");
         log.info("服务器启动时执行 end");
     }

+ 40 - 0
themis-task/src/main/resources/logback-spring.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="true" scan="true" scanPeriod="30 seconds">
+
+    <springProperty scope="context" name="logLevel" source="logging.level.root" />
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- debug 日志 -->
+    <appender name="DEBUG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>logs/themis-task.log</file>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %thread | %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>logs/themis-task.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxHistory>100</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+        </rollingPolicy>
+    </appender>
+
+    <logger name="org.springframework" level="${logLevel}" additivity="false">
+        <appender-ref ref="DEBUG_APPENDER"/>
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="com.qmth.themis.task" level="${logLevel}" additivity="false">
+        <appender-ref ref="DEBUG_APPENDER" />
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <root level="INFO">
+        <appender-ref ref="DEBUG_APPENDER" />
+        <appender-ref ref="STDOUT" />
+    </root>
+
+</configuration>