chenlongfei 5 years ago
commit
c6a0d3b789

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+*.iml
+# Windows shortcuts
+*.lnk
+/.idea
+/log
+/logs
+# =========================
+# Operating System Files
+# =========================
+target/

+ 168 - 0
pom.xml

@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.example</groupId>
+    <artifactId>moka-data</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <redis.version>3.1.0</redis.version>
+        <kafka.version>2.5.0</kafka.version>
+        <springboot.version>2.1.7.RELEASE</springboot.version>
+    </properties>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>2.1.7.RELEASE</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>${redis.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+            <version>${kafka.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.nekohtml</groupId>
+            <artifactId>nekohtml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.62</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.18.1</version>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>2.8.2</version>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.7.RELEASE</version>
+                <configuration>
+                    <fork>true</fork>
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- maven资源文件复制插件 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.7</version>
+                <executions>
+                    <execution>
+                        <id>copy-config</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>src/main/resources</directory>
+                                    <includes>
+                                        <exclude>**/*.xml</exclude>
+                                        <exclude>**/*.conf</exclude>
+                                        <exclude>**/*.properties</exclude>
+                                    </includes>
+                                    <filtering>true</filtering>
+                                </resource>
+                            </resources>
+                            <encoding>UTF-8</encoding>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <finalName>moka-data</finalName>
+                    <excludes>
+                        <exclude>*.properties</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 11 - 0
src/main/java/com/mokamrp/data/DataServerStart.java

@@ -0,0 +1,11 @@
+package com.mokamrp.data;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DataServerStart {
+    public static void main(String[] args) {
+        SpringApplication.run(DataServerStart.class, args);
+    }
+}

+ 30 - 0
src/main/java/com/mokamrp/data/config/ClientConfig.java

@@ -0,0 +1,30 @@
+package com.mokamrp.data.config;
+
+import com.mokamrp.data.kafka.KafkaProducerClient;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * className:RedisClientConfig
+ * description: TODO
+ * time:2020-07-02.15:51
+ *
+ * @author Tank
+ * @version 1.0.0
+ */
+@Configuration
+public class ClientConfig implements InitializingBean {
+
+    @Value("${kafka.hosts}")
+    private String kafkahosts;
+    @Bean
+    public KafkaProducerClient initKafkaProducer() {
+
+        return KafkaProducerClient.getInstance(kafkahosts,"lz4");
+    }
+    @Override
+    public void afterPropertiesSet() throws Exception {
+    }
+}

+ 43 - 0
src/main/java/com/mokamrp/data/controller/DataApiController.java

@@ -0,0 +1,43 @@
+package com.mokamrp.data.controller;
+
+import com.mokamrp.data.controller.dto.Message;
+import com.mokamrp.data.controller.vo.Result;
+import com.mokamrp.data.kafka.KafkaProducerClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@Slf4j
+public class DataApiController {
+    @Autowired
+    private KafkaProducerClient kafkaProducerClient;
+
+    @RequestMapping("/push")
+    public Result push(HttpServletRequest request, @RequestBody Message msg) {
+        String topic=msg.getTopic();
+        List<String> messages=msg.getMessage();
+        Result rs = new Result();
+        try {
+            kafkaProducerClient.putMessageList(topic, messages);
+            log.info("数据发送到kafka成功!");
+        } catch (Exception e) {
+            log.error("数据发送到kafka失败", e);
+            rs.setCode(0);
+            rs.setMessage("数据接收失败" + e.getMessage());
+            return rs;
+        }
+        rs.setCode(1);
+        rs.setMessage("数据接收成功");
+        log.info("数据接收成功");
+        return rs;
+    }
+
+}

+ 12 - 0
src/main/java/com/mokamrp/data/controller/dto/Message.java

@@ -0,0 +1,12 @@
+package com.mokamrp.data.controller.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class Message {
+
+    private String topic;
+    private List<String> message;
+}

+ 52 - 0
src/main/java/com/mokamrp/data/controller/vo/Result.java

@@ -0,0 +1,52 @@
+package com.mokamrp.data.controller.vo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * className:Result
+ * description:
+ * time:2020/6/10  19:20
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class Result {
+    private Integer code;
+    private String message;
+    private List<String> logs = new ArrayList<>();
+
+    public static Result UN_LOGIN = new Result(401);
+    public static Result INVALID_LOGIN = new Result(402);
+
+    public Result() {
+    }
+
+    public Result(Integer code) {
+        this.code = code;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public List<String> getLogs() {
+        return logs;
+    }
+
+    public void setLogs(List<String> logs) {
+        this.logs = logs;
+    }
+}

+ 25 - 0
src/main/java/com/mokamrp/data/exception/LogQueueConnectException.java

@@ -0,0 +1,25 @@
+package com.mokamrp.data.exception;
+
+/**
+ * className:LogQueueConnectException
+ * description:连接日志队列异常抛出,redis挂了,或者kafk挂了
+ * time:2020/6/5  11:14
+ *
+ * @author frank.chen
+ * @version 1.0.0
+ */
+public class LogQueueConnectException extends Exception{
+
+    public LogQueueConnectException(){
+        super();
+    }
+    public LogQueueConnectException(String message){
+        super(message);
+    }
+    public LogQueueConnectException(String message, Throwable cause){
+        super(message,cause);
+    }
+    public LogQueueConnectException(Throwable cause){
+        super(cause);
+    }
+}

+ 44 - 0
src/main/java/com/mokamrp/data/kafka/KafkaConsumerClient.java

@@ -0,0 +1,44 @@
+package com.mokamrp.data.kafka;
+
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.apache.kafka.common.serialization.StringDeserializer;
+
+import java.util.Properties;
+
+/**
+ * className:KafkaConsumerClient
+ * description:kafka Consumer instance
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class KafkaConsumerClient {
+    private static KafkaConsumerClient instance;
+    private KafkaConsumer kafkaConsumer;
+    public static KafkaConsumerClient getInstance(String hosts,String groupName,int maxPullSize) {
+        if (instance == null) {
+            synchronized (KafkaConsumerClient.class) {
+                if (instance == null) {
+                    instance = new KafkaConsumerClient(hosts,groupName,maxPullSize);
+                }
+            }
+        }
+        return instance;
+    }
+
+    public KafkaConsumer getKafkaConsumer() {
+        return kafkaConsumer;
+    }
+    KafkaConsumerClient(String hosts,String groupName,int maxPullSize){
+        Properties props = new Properties();
+        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, hosts);
+        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPullSize);
+        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
+        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
+        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupName);
+        kafkaConsumer = new KafkaConsumer<>(props);
+    }
+
+}

+ 65 - 0
src/main/java/com/mokamrp/data/kafka/KafkaProducerClient.java

@@ -0,0 +1,65 @@
+package com.mokamrp.data.kafka;
+
+import com.mokamrp.data.exception.LogQueueConnectException;
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+
+import java.util.List;
+
+/**
+ * className:KafkaProducerClient
+ * description:kafka Producer instance
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class KafkaProducerClient  {
+    private static KafkaProducerClient instance;
+    private KafkaProducerPool kafkaProducerPool;
+    public static KafkaProducerClient getInstance(String hosts, String compressionType) {
+        if (instance == null) {
+            synchronized (KafkaProducerClient.class) {
+                if (instance == null) {
+                    instance = new KafkaProducerClient(hosts, compressionType);
+                }
+            }
+        }
+        return instance;
+    }
+    private KafkaProducerClient(String hosts, String compressionType){
+        this.kafkaProducerPool = new KafkaProducerPool(hosts, compressionType);
+    }
+    public void pushMessage(String topic, String message) throws LogQueueConnectException {
+        KafkaProducer kafkaProducer=null;
+        try {
+            kafkaProducer=kafkaProducerPool.getResource();
+            kafkaProducer.send(new ProducerRecord<String, String>(topic, message));
+        }catch (Exception e){
+            throw new LogQueueConnectException("kafka 写入失败!",e);
+        }finally {
+            if(kafkaProducer!=null){
+                kafkaProducerPool.returnResource(kafkaProducer);
+            }
+        }
+
+    }
+    public void putMessageList(String topic, List<String> list) throws LogQueueConnectException {
+        KafkaProducer kafkaProducer=null;
+        try {
+            kafkaProducer=kafkaProducerPool.getResource();
+            for(int a=0;a<list.size();a++){
+                String message=list.get(a);
+                kafkaProducer.send(new ProducerRecord<String, String>(topic, message));
+            };
+        }catch (Exception e){
+            throw new LogQueueConnectException("kafka 写入失败!",e);
+        }finally {
+            if(kafkaProducer!=null){
+                kafkaProducerPool.returnResource(kafkaProducer);
+            }
+        }
+
+    }
+
+}

+ 53 - 0
src/main/java/com/mokamrp/data/kafka/KafkaProducerFactory.java

@@ -0,0 +1,53 @@
+package com.mokamrp.data.kafka;
+
+
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.PooledObjectFactory;
+import org.apache.commons.pool2.impl.DefaultPooledObject;
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.StringSerializer;
+
+import java.util.Properties;
+
+/**
+ * className:KafkaProducerFactory
+ * description:kafka Producer Factory
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class KafkaProducerFactory implements PooledObjectFactory<KafkaProducer> {
+    private Properties props=new Properties();
+    KafkaProducerFactory(String hosts, String compressionType){
+        this.props.put(ProducerConfig.ACKS_CONFIG, "0");
+        this.props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, hosts);
+        this.props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        this.props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        this.props.put(ProducerConfig.LINGER_MS_CONFIG,10);
+        this.props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, compressionType);
+    }
+    @Override
+    public void activateObject(PooledObject<KafkaProducer> kafkaProducer) throws Exception {
+
+    }
+    @Override
+    public void destroyObject(PooledObject<KafkaProducer> kafkaProducer) throws Exception{
+        kafkaProducer.getObject().close();
+    }
+    @Override
+    public PooledObject<KafkaProducer> makeObject() throws Exception {
+        KafkaProducer kafkaProducer=new KafkaProducer<>(props);
+        return new DefaultPooledObject<>(kafkaProducer);
+    }
+    @Override
+    public void passivateObject(PooledObject<KafkaProducer> kafkaProducer) throws Exception {
+        // TODO maybe should select db 0? Not sure right now.
+    }
+    @Override
+    public boolean validateObject(PooledObject<KafkaProducer> kafkaProducer) {
+        return true;
+    }
+
+}

+ 45 - 0
src/main/java/com/mokamrp/data/kafka/KafkaProducerPool.java

@@ -0,0 +1,45 @@
+package com.mokamrp.data.kafka;
+
+import com.mokamrp.data.util.Pool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.apache.kafka.clients.producer.KafkaProducer;
+
+/**
+ * className:KafkaProducerPool
+ * description:kafka Producer Pool
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class KafkaProducerPool extends Pool<KafkaProducer> {
+
+    public KafkaProducerPool(final GenericObjectPoolConfig poolConfig, final String hosts, final String compressionType) {
+        super(poolConfig,new KafkaProducerFactory(hosts, compressionType));
+    }
+    public KafkaProducerPool( final String hosts, final String compressionType) {
+        super(new GenericObjectPoolConfig(),new KafkaProducerFactory(hosts, compressionType));
+    }
+    @Override
+    public KafkaProducer getResource() {
+        KafkaProducer connection = super.getResource();
+        return connection;
+    }
+    @Override
+    public void returnBrokenResource(final KafkaProducer resource) {
+        if (resource != null) {
+            returnBrokenResourceObject(resource);
+        }
+    }
+    @Override
+    public void returnResource(final KafkaProducer resource) {
+        if (resource != null) {
+            try {
+                returnResourceObject(resource);
+            } catch (Exception e) {
+                returnBrokenResource(resource);
+            }
+        }
+    }
+    
+}

+ 667 - 0
src/main/java/com/mokamrp/data/util/DateUtil.java

@@ -0,0 +1,667 @@
+package com.mokamrp.data.util;
+
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * className:DateUtil
+ * description:DateUtil
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class DateUtil {
+
+    // ==格式到年==
+    /**
+     * 日期格式,年份,例如:2004,2008
+     */
+    public static final String DATE_FORMAT_YYYY = "yyyy";
+
+
+    // ==格式到年月 ==
+    /**
+     * 日期格式,年份和月份,例如:200707,200808
+     */
+    public static final String DATE_FORMAT_YYYYMM = "yyyyMM";
+
+    /**
+     * 日期格式,年份和月份,例如:200707,2008-08
+     */
+    public static final String DATE_FORMAT_YYYY_MM = "yyyy-MM";
+
+
+    // ==格式到年月日==
+    /**
+     * 日期格式,年月日,例如:050630,080808
+     */
+    public static final String DATE_FORMAT_YYMMDD = "yyMMdd";
+
+    /**
+     * 日期格式,年月日,用横杠分开,例如:06-12-25,08-08-08
+     */
+    public static final String DATE_FORMAT_YY_MM_DD = "yy-MM-dd";
+
+    /**
+     * 日期格式,年月日,例如:20050630,20080808
+     */
+    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";
+
+    /**
+     * 日期格式,年月日,用横杠分开,例如:2006-12-25,2008-08-08
+     */
+    public static final String DATE_FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
+
+    /**
+     * 日期格式,年月日,例如:2016.10.05
+     */
+    public static final String DATE_FORMAT_POINTYYYYMMDD = "yyyy.MM.dd";
+
+    /**
+     * 日期格式,年月日,例如:2016年10月05日
+     */
+    public static final String DATE_TIME_FORMAT_YYYY年MM月DD日 = "yyyy年MM月dd日";
+
+
+    // ==格式到年月日 时分 ==
+
+    /**
+     * 日期格式,年月日时分,例如:200506301210,200808081210
+     */
+    public static final String DATE_FORMAT_YYYYMMDDHHmm = "yyyyMMddHHmm";
+
+    /**
+     * 日期格式,年月日时分,例如:20001230 12:00,20080808 20:08
+     */
+    public static final String DATE_TIME_FORMAT_YYYYMMDD_HH_MI = "yyyyMMdd HH:mm";
+
+    /**
+     * 日期格式,年月日时分,例如:2000-12-30 12:00,2008-08-08 20:08
+     */
+    public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI = "yyyy-MM-dd HH:mm";
+
+
+    // ==格式到年月日 时分秒==
+    /**
+     * 日期格式,年月日时分秒,例如:20001230120000,20080808200808
+     */
+    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISS = "yyyyMMddHHmmss";
+
+    /**
+     * 日期格式,年月日时分秒,年月日用横杠分开,时分秒用冒号分开
+     * 例如:2005-05-10 23:20:00,2008-08-08 20:08:08
+     */
+    public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS = "yyyy-MM-dd HH:mm:ss";
+
+
+    // ==格式到年月日 时分秒 毫秒==
+    /**
+     * 日期格式,年月日时分秒毫秒,例如:20001230120000123,20080808200808456
+     */
+    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS = "yyyyMMddHHmmssSSS";
+
+
+    // ==特殊格式==
+    /**
+     * 日期格式,月日时分,例如:10-05 12:00
+     */
+    public static final String DATE_FORMAT_MMDDHHMI = "MM-dd HH:mm";
+
+
+	/* ************工具方法***************   */
+
+
+    public static Integer getYear(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        return cal.get(Calendar.YEAR);
+    }
+
+
+    public static Integer getMonth(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        return cal.get(Calendar.MONTH) + 1;
+    }
+
+
+    public static Integer getDay(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        int day = cal.get(Calendar.DATE);//获取日
+        return day;
+    }
+
+
+    public static String parseDateToStr(Date time, String timeFromat) {
+        DateFormat dateFormat = new SimpleDateFormat(timeFromat);
+        return dateFormat.format(time);
+    }
+
+
+    public static String parseTimestampToStr(Timestamp timestamp, String timeFromat) {
+        SimpleDateFormat df = new SimpleDateFormat(timeFromat);
+        return df.format(timestamp);
+    }
+
+
+    public static String parseDateToStr(Date time, String timeFromat, final Date defaultValue) {
+        try {
+            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
+            return dateFormat.format(time);
+        } catch (Exception e) {
+            if (defaultValue != null)
+                return parseDateToStr(defaultValue, timeFromat);
+            else
+                return parseDateToStr(new Date(), timeFromat);
+        }
+    }
+
+    /**
+     * 格式化Date时间
+     *
+     * @param time         Date类型时间
+     * @param timeFromat   String类型格式
+     * @param defaultValue 默认时间值String类型
+     * @return 格式化后的字符串
+     */
+    public static String parseDateToStr(Date time, String timeFromat, final String defaultValue) {
+        try {
+            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
+            return dateFormat.format(time);
+        } catch (Exception e) {
+            return defaultValue;
+        }
+    }
+
+
+    public static Date parseStrToDate(String time, String timeFromat) {
+        if (time == null || time.equals("")) {
+            return null;
+        }
+
+        Date date = null;
+        try {
+            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
+            date = dateFormat.parse(time);
+        } catch (Exception e) {
+
+        }
+        return date;
+    }
+
+
+    public static Date parseStrToDate(String strTime, String timeFromat,
+                                      Date defaultValue) {
+        try {
+            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
+            return dateFormat.parse(strTime);
+        } catch (Exception e) {
+            return defaultValue;
+        }
+    }
+
+    public static Date strToDate(String strTime) {
+        if (strTime == null || strTime.trim().length() <= 0)
+            return null;
+
+        Date date = null;
+        List<String> list = new ArrayList<String>(0);
+
+        list.add(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
+        list.add(DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
+        list.add(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI);
+        list.add(DATE_TIME_FORMAT_YYYYMMDD_HH_MI);
+        list.add(DATE_TIME_FORMAT_YYYYMMDDHHMISS);
+        list.add(DATE_FORMAT_YYYY_MM_DD);
+        //list.add(DATE_FORMAT_YY_MM_DD);
+        list.add(DATE_FORMAT_YYYYMMDD);
+        list.add(DATE_FORMAT_YYYY_MM);
+        list.add(DATE_FORMAT_YYYYMM);
+        list.add(DATE_FORMAT_YYYY);
+
+
+        for (Iterator iter = list.iterator(); iter.hasNext(); ) {
+            String format = (String) iter.next();
+            if (strTime.indexOf("-") > 0 && format.indexOf("-") < 0)
+                continue;
+            if (strTime.indexOf("-") < 0 && format.indexOf("-") > 0)
+                continue;
+            if (strTime.length() > format.length())
+                continue;
+            date = parseStrToDate(strTime, format);
+            if (date != null)
+                break;
+        }
+
+        return date;
+    }
+
+
+    public static List<String> getMonthListOfDate(String beginDateStr, String endDateStr) {
+        // 指定要解析的时间格式
+        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM");
+        // 返回的月份列表
+        String sRet = "";
+
+        // 定义一些变量
+        Date beginDate = null;
+        Date endDate = null;
+
+        GregorianCalendar beginGC = null;
+        GregorianCalendar endGC = null;
+        List<String> list = new ArrayList<String>();
+
+        try {
+            // 将字符串parse成日期
+            beginDate = f.parse(beginDateStr);
+            endDate = f.parse(endDateStr);
+
+            // 设置日历
+            beginGC = new GregorianCalendar();
+            beginGC.setTime(beginDate);
+
+            endGC = new GregorianCalendar();
+            endGC.setTime(endDate);
+
+            // 直到两个时间相同
+            while (beginGC.getTime().compareTo(endGC.getTime()) <= 0) {
+                sRet = beginGC.get(Calendar.YEAR) + "-"
+                        + (beginGC.get(Calendar.MONTH) + 1);
+                list.add(sRet);
+                // 以月为单位,增加时间
+                beginGC.add(Calendar.MONTH, 1);
+            }
+            return list;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public static List<String> getDayListOfDate(String beginDateStr, String endDateStr) {
+        // 指定要解析的时间格式
+        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
+
+        // 定义一些变量
+        Date beginDate = null;
+        Date endDate = null;
+
+        Calendar beginGC = null;
+        Calendar endGC = null;
+        List<String> list = new ArrayList<String>();
+
+        try {
+            // 将字符串parse成日期
+            beginDate = f.parse(beginDateStr);
+            endDate = f.parse(endDateStr);
+
+            // 设置日历
+            beginGC = Calendar.getInstance();
+            beginGC.setTime(beginDate);
+
+            endGC = Calendar.getInstance();
+            endGC.setTime(endDate);
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+            // 直到两个时间相同
+            while (beginGC.getTime().compareTo(endGC.getTime()) <= 0) {
+
+                list.add(sdf.format(beginGC.getTime()));
+                // 以日为单位,增加时间
+                beginGC.add(Calendar.DAY_OF_MONTH, 1);
+            }
+            return list;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public static List<Integer> getYearListOfYears(int before, int behind) {
+        if (before < 0 || behind < 0) {
+            return null;
+        }
+        List<Integer> list = new ArrayList<Integer>();
+        Calendar c = null;
+        c = Calendar.getInstance();
+        c.setTime(new Date());
+        int currYear = Calendar.getInstance().get(Calendar.YEAR);
+
+        int startYear = currYear - before;
+        int endYear = currYear + behind;
+        for (int i = startYear; i < endYear; i++) {
+            list.add(Integer.valueOf(i));
+        }
+        return list;
+    }
+
+
+    public static Integer getWeekthOfYear(Date date) {
+        Calendar c = new GregorianCalendar();
+        c.setFirstDayOfWeek(Calendar.MONDAY);
+        c.setMinimalDaysInFirstWeek(7);
+        c.setTime(date);
+
+        return c.get(Calendar.WEEK_OF_YEAR);
+    }
+
+    public static HashMap<Integer, String> getWeekTimeOfYear(int year) {
+        HashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
+        Calendar c = new GregorianCalendar();
+        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
+        int count = getWeekthOfYear(c.getTime());
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String dayOfWeekStart = "";
+        String dayOfWeekEnd = "";
+        for (int i = 1; i <= count; i++) {
+            dayOfWeekStart = sdf.format(getFirstDayOfWeek(year, i));
+            dayOfWeekEnd = sdf.format(getLastDayOfWeek(year, i));
+            map.put(Integer.valueOf(i), "第" + i + "周(从" + dayOfWeekStart + "至" + dayOfWeekEnd + ")");
+        }
+        return map;
+
+    }
+
+    public static Integer getWeekCountOfYear(int year) {
+        Calendar c = new GregorianCalendar();
+        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
+        int count = getWeekthOfYear(c.getTime());
+        return count;
+    }
+
+
+    public static Date getFirstDayOfWeek(Date date) {
+        Calendar c = new GregorianCalendar();
+        c.setFirstDayOfWeek(Calendar.MONDAY);
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
+        return c.getTime();
+    }
+
+    public static Date getLastDayOfWeek(Date date) {
+        Calendar c = new GregorianCalendar();
+        c.setFirstDayOfWeek(Calendar.MONDAY);
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
+        return c.getTime();
+    }
+
+
+    public static Date getFirstDayOfWeek(int year, int week) {
+        Calendar c = new GregorianCalendar();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, Calendar.JANUARY);
+        c.set(Calendar.DATE, 1);
+
+        Calendar cal = (GregorianCalendar) c.clone();
+        cal.add(Calendar.DATE, week * 7);
+
+        return getFirstDayOfWeek(cal.getTime());
+    }
+
+
+    public static Date getLastDayOfWeek(int year, int week) {
+        Calendar c = new GregorianCalendar();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, Calendar.JANUARY);
+        c.set(Calendar.DATE, 1);
+
+        Calendar cal = (GregorianCalendar) c.clone();
+        cal.add(Calendar.DATE, week * 7);
+
+        return getLastDayOfWeek(cal.getTime());
+    }
+
+    public static Date getFirstDayOfMonth(int year, int month) {
+        month = month - 1;
+        Calendar c = Calendar.getInstance();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month);
+
+        int day = c.getActualMinimum(c.DAY_OF_MONTH);
+
+        c.set(Calendar.DAY_OF_MONTH, day);
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c.getTime();
+    }
+
+    public static Date getLastDayOfMonth(int year, int month) {
+        month = month - 1;
+        Calendar c = Calendar.getInstance();
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month);
+        int day = c.getActualMaximum(c.DAY_OF_MONTH);
+        c.set(Calendar.DAY_OF_MONTH, day);
+        c.set(Calendar.HOUR_OF_DAY, 23);
+        c.set(Calendar.MINUTE, 59);
+        c.set(Calendar.SECOND, 59);
+        c.set(Calendar.MILLISECOND, 999);
+        return c.getTime();
+    }
+
+    public static String getDayWeekOfDate1(Date date) {
+        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+
+        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
+        if (w < 0)
+            w = 0;
+
+        return weekDays[w];
+    }
+
+
+    public static Integer getDayWeekOfDate2(Date date) {
+        Calendar aCalendar = Calendar.getInstance();
+        aCalendar.setTime(date);
+        int weekDay = aCalendar.get(Calendar.DAY_OF_WEEK);
+        return weekDay;
+    }
+
+
+    public static boolean validateIsDate(String strTime) {
+        if (strTime == null || strTime.trim().length() <= 0)
+            return false;
+
+        Date date = null;
+        List<String> list = new ArrayList<String>(0);
+
+        list.add(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
+        list.add(DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
+        list.add(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI);
+        list.add(DATE_TIME_FORMAT_YYYYMMDD_HH_MI);
+        list.add(DATE_TIME_FORMAT_YYYYMMDDHHMISS);
+        list.add(DATE_FORMAT_YYYY_MM_DD);
+        //list.add(DATE_FORMAT_YY_MM_DD);
+        list.add(DATE_FORMAT_YYYYMMDD);
+        //list.add(DATE_FORMAT_YYYY_MM);
+        //list.add(DATE_FORMAT_YYYYMM);
+        //list.add(DATE_FORMAT_YYYY);
+
+        for (Iterator iter = list.iterator(); iter.hasNext(); ) {
+            String format = (String) iter.next();
+            if (strTime.indexOf("-") > 0 && format.indexOf("-") < 0)
+                continue;
+            if (strTime.indexOf("-") < 0 && format.indexOf("-") > 0)
+                continue;
+            if (strTime.length() > format.length())
+                continue;
+            date = parseStrToDate(strTime.trim(), format);
+            if (date != null)
+                break;
+        }
+
+        if (date != null) {
+            System.out.println("生成的日期:" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS, "--null--"));
+            return true;
+        }
+        return false;
+    }
+
+    public static Date formatHhMmSsOfDate(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
+
+
+    public static Date addDate(Date date, int year, int month, int day, int hour, int minute, int second, int millisecond) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.add(Calendar.YEAR, year);//加减年数
+        c.add(Calendar.MONTH, month);//加减月数
+        c.add(Calendar.DATE, day);//加减天数
+        c.add(Calendar.HOUR, hour);//加减小时数
+        c.add(Calendar.MINUTE, minute);//加减分钟数
+        c.add(Calendar.SECOND, second);//加减秒
+        c.add(Calendar.MILLISECOND, millisecond);//加减毫秒数
+
+        return c.getTime();
+    }
+
+    public static Long getDistanceTimestamp(Date startDate, Date endDate) {
+        long daysBetween = (endDate.getTime() - startDate.getTime() + 1000000) / (3600 * 24 * 1000);
+        return daysBetween;
+    }
+
+    public static Boolean compareIsSameMonth(Date date1, Date date2) {
+        boolean flag = false;
+        int year1 = getYear(date1);
+        int year2 = getYear(date2);
+        if (year1 == year2) {
+            int month1 = getMonth(date1);
+            int month2 = getMonth(date2);
+            if (month1 == month2) flag = true;
+        }
+        return flag;
+    }
+
+    public static long[] getDistanceTime(Date one, Date two) {
+        long day = 0;
+        long hour = 0;
+        long min = 0;
+        long sec = 0;
+        try {
+
+            long time1 = one.getTime();
+            long time2 = two.getTime();
+            long diff;
+            if (time1 < time2) {
+                diff = time2 - time1;
+            } else {
+                diff = time1 - time2;
+            }
+            day = diff / (24 * 60 * 60 * 1000);
+            hour = (diff / (60 * 60 * 1000) - day * 24);
+            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
+            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        long[] times = {day, hour, min, sec};
+        return times;
+    }
+
+    public static long[] getDistanceTime(String str1, String str2) {
+        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
+        Date one;
+        Date two;
+        long day = 0;
+        long hour = 0;
+        long min = 0;
+        long sec = 0;
+        try {
+            one = df.parse(str1);
+            two = df.parse(str2);
+            long time1 = one.getTime();
+            long time2 = two.getTime();
+            long diff;
+            if (time1 < time2) {
+                diff = time2 - time1;
+            } else {
+                diff = time1 - time2;
+            }
+            day = diff / (24 * 60 * 60 * 1000);
+            hour = (diff / (60 * 60 * 1000) - day * 24);
+            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
+            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        long[] times = {day, hour, min, sec};
+        return times;
+    }
+
+
+    public static Long getDistanceDays(String str1, String str2) throws Exception {
+        DateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
+        Date one;
+        Date two;
+        long days = 0;
+        try {
+            one = df.parse(str1);
+            two = df.parse(str2);
+            long time1 = one.getTime();
+            long time2 = two.getTime();
+            long diff;
+            if (time1 < time2) {
+                diff = time2 - time1;
+            } else {
+                diff = time1 - time2;
+            }
+            days = diff / (1000 * 60 * 60 * 24);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return days;
+    }
+
+
+    public static Date getDayBeginTime(final Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c.getTime();
+    }
+
+    public static Date getDayEndTime(final Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.set(Calendar.HOUR_OF_DAY, 23);
+        c.set(Calendar.MINUTE, 59);
+        c.set(Calendar.SECOND, 59);
+        c.set(Calendar.MILLISECOND, 999);
+        return c.getTime();
+    }
+
+
+    public static void main(String[] args) {
+        try {
+            DateUtil dateUtil = new DateUtil();
+            System.out.println();
+
+        } catch (Exception e) {
+            // TODO: handle exception
+        }
+
+    }
+}

+ 88 - 0
src/main/java/com/mokamrp/data/util/GfJsonUtil.java

@@ -0,0 +1,88 @@
+package com.mokamrp.data.util;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.*;
+
+/**
+ * className:GfJsonUtil
+ * description:fastjson工具类
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public abstract class GfJsonUtil {
+
+    private GfJsonUtil() {
+    }
+    public static <T> T parseObject(String json, Class<T> clazz) {
+        if (json == null) {
+            return null;
+        }
+        return (T) JSON.parseObject(json, clazz);
+    }
+
+
+    public static <T> String toJSONString(T t) {
+        if (t == null) {
+            return null;
+        }
+        return JSON.toJSONString(t);
+    }
+
+
+    public static <T> List<T> parseList(Iterable<String> jsonList, Class<T> clazz) {
+        List<T> retList = new ArrayList<T>();
+        for (String json : jsonList) {
+            retList.add(parseObject(json, clazz));
+        }
+        return retList;
+    }
+
+
+    public static <T> List<List<T>> parseArrayList(Iterable<String> jsonList, Class<T> clazz) {
+        List<List<T>> retList = new ArrayList<List<T>>();
+        for (String json : jsonList) {
+            retList.add(parseArray(json, clazz));
+        }
+        return retList;
+    }
+
+    public static <T> List<T> parseArray(String json, Class<T> clazz) {
+        if (json == null) {
+            return Collections.emptyList();
+        }
+        return JSON.parseArray(json, clazz);
+    }
+
+
+    public static <T> Map<Long, T> parseMapByUid(List<String> jsonList, List<Long> uidList, Class<T> clazz, boolean isContainsNull) {
+        if (jsonList.size() != uidList.size()) {
+            return null;
+        }
+        Map<Long, T> uidMap = new HashMap<Long, T>(uidList.size());
+        for (int i = 0; i < uidList.size(); i++) {
+            T t = parseObject(jsonList.get(i), clazz);
+            if (isContainsNull || t != null) {
+                uidMap.put(uidList.get(i), t);
+            }
+        }
+        return uidMap;
+    }
+
+
+    public static <T> Map<Long, List<T>> parseArrayMapByUid(List<String> jsonList, List<Long> uidList, Class<T> clazz, boolean isContainsNull) {
+        if (jsonList.size() != uidList.size()) {
+            return null;
+        }
+        Map<Long, List<T>> uidMap = new HashMap<Long, List<T>>(uidList.size());
+        for (int i = 0; i < uidList.size(); i++) {
+            List<T> t = parseArray(jsonList.get(i), clazz);
+            if (isContainsNull || t != null) {
+                uidMap.put(uidList.get(i), t);
+            }
+        }
+        return uidMap;
+    }
+}

+ 133 - 0
src/main/java/com/mokamrp/data/util/IdWorker.java

@@ -0,0 +1,133 @@
+package com.mokamrp.data.util;
+
+/**
+ * className:IdWorker
+ * description:基于雪花算法的ID生成器
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class IdWorker {
+
+    //因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。
+
+    //机器ID  2进制5位  32位减掉1位 31个
+    private long workerId;
+    //机房ID 2进制5位  32位减掉1位 31个
+    private long datacenterId;
+    //代表一毫秒内生成的多个id的最新序号  12位 4096 -1 = 4095 个
+    private long sequence;
+    //设置一个时间初始值    2^41 - 1   差不多可以用69年
+    private long twepoch = 1585644268888L;
+    //5位的机器id
+    private long workerIdBits = 5L;
+    //5位的机房id
+    private long datacenterIdBits = 5L;
+    //每毫秒内产生的id数 2 的 12次方
+    private long sequenceBits = 12L;
+    // 这个是二进制运算,就是5 bit最多只能有31个数字,也就是说机器id最多只能是32以内
+    private long maxWorkerId = -1L ^ (-1L << workerIdBits);
+    // 这个是一个意思,就是5 bit最多只能有31个数字,机房id最多只能是32以内
+    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    private long workerIdShift = sequenceBits;
+    private long datacenterIdShift = sequenceBits + workerIdBits;
+    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+    private long sequenceMask = -1L ^ (-1L << sequenceBits);
+    //记录产生时间毫秒数,判断是否是同1毫秒
+    private long lastTimestamp = -1L;
+
+    public long getWorkerId() {
+        return workerId;
+    }
+
+    public long getDatacenterId() {
+        return datacenterId;
+    }
+
+    public long getTimestamp() {
+        return System.currentTimeMillis();
+    }
+
+
+    public IdWorker(long workerId, long datacenterId, long sequence) {
+
+        // 检查机房id和机器id是否超过31 不能小于0
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(
+                    String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+
+            throw new IllegalArgumentException(
+                    String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+        this.sequence = sequence;
+    }
+
+    // 这个是核心方法,通过调用nextId()方法,让当前这台机器上的snowflake算法程序生成一个全局唯一的id
+    public synchronized long nextId() {
+        // 这儿就是获取当前时间戳,单位是毫秒
+        long timestamp = timeGen();
+        if (timestamp < lastTimestamp) {
+
+            System.err.printf(
+                    "clock is moving backwards. Rejecting requests until %d.", lastTimestamp);
+            throw new RuntimeException(
+                    String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
+                            lastTimestamp - timestamp));
+        }
+
+        // 下面是说假设在同一个毫秒内,又发送了一个请求生成一个id
+        // 这个时候就得把seqence序号给递增1,最多就是4096
+        if (lastTimestamp == timestamp) {
+
+            // 这个意思是说一个毫秒内最多只能有4096个数字,无论你传递多少进来,
+            //这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围
+            sequence = (sequence + 1) & sequenceMask;
+            //当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID
+            if (sequence == 0) {
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+
+        } else {
+            sequence = 0;
+        }
+        // 这儿记录一下最近一次生成id的时间戳,单位是毫秒
+        lastTimestamp = timestamp;
+        // 这儿就是最核心的二进制位运算操作,生成一个64bit的id
+        // 先将当前时间戳左移,放到41 bit那儿;将机房id左移放到5 bit那儿;将机器id左移放到5 bit那儿;将序号放最后12 bit
+        // 最后拼接起来成一个64 bit的二进制数字,转换成10进制就是个long型
+        return ((timestamp - twepoch) << timestampLeftShift) |
+                (datacenterId << datacenterIdShift) |
+                (workerId << workerIdShift) | sequence;
+    }
+
+
+    private long tilNextMillis(long lastTimestamp) {
+
+        long timestamp = timeGen();
+
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    //获取当前时间戳
+    private long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+
+    public static void main(String[] args) {
+		IdWorker worker = new IdWorker(1,1,1);
+		for (int i = 0; i < 22; i++) {
+			System.out.println(worker.nextId());
+		}
+    }
+}

+ 158 - 0
src/main/java/com/mokamrp/data/util/IpGetter.java

@@ -0,0 +1,158 @@
+package com.mokamrp.data.util;
+
+
+import java.io.IOException;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+
+/**
+ * className:IpGetter
+ * description:本机IP获取工具类
+ * time:2020-05-11.16:17
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class IpGetter {
+
+    /**
+     * 当前IP。类初始化时调用一次就可以了
+     */
+    public final static String CURRENT_IP = findFirstNonLoopbackAddress();
+
+    /**
+     * 单网卡名称
+     */
+    private static final String NETWORK_CARD = "eth0";
+    /**
+     * 绑定网卡名称
+     */
+    private static final String NETWORK_CARD_BAND = "bond0";
+
+
+    public static String getLocalHostName() {
+        try {
+            InetAddress addr = InetAddress.getLocalHost();
+            return addr.getHostName();
+        } catch (Exception e) {
+            return "";
+        }
+    }
+
+
+    public static String getLocalIP() {
+        String ip = "";
+        try {
+            Enumeration<NetworkInterface> e1 = NetworkInterface.getNetworkInterfaces();
+            while (e1.hasMoreElements()) {
+                NetworkInterface ni = e1.nextElement();
+                //单网卡或者绑定双网卡
+                if ((NETWORK_CARD.equals(ni.getName())) || (NETWORK_CARD_BAND.equals(ni.getName()))) {
+                    Enumeration<InetAddress> e2 = ni.getInetAddresses();
+                    while (e2.hasMoreElements()) {
+                        InetAddress ia = e2.nextElement();
+                        if (ia instanceof Inet6Address) {
+                            continue;
+                        }
+                        ip = ia.getHostAddress();
+                    }
+                    break;
+                } else {
+                    continue;
+                }
+            }
+        } catch (SocketException e) {
+        }
+        return ip;
+    }
+    public static Collection<InetAddress> getAllHostAddress() {
+        try {
+            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+            Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+
+            while (networkInterfaces.hasMoreElements()) {
+                NetworkInterface networkInterface = networkInterfaces.nextElement();
+                Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
+                while (inetAddresses.hasMoreElements()) {
+                    InetAddress inetAddress = inetAddresses.nextElement();
+                    addresses.add(inetAddress);
+                }
+            }
+
+            return addresses;
+        } catch (SocketException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    public static String getIp(){
+        String localHostAddress = "127.0.0.1";
+        try {
+            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
+
+            while(allNetInterfaces.hasMoreElements()){
+                NetworkInterface networkInterface = allNetInterfaces.nextElement();
+                Enumeration<InetAddress> address = networkInterface.getInetAddresses();
+                while(address.hasMoreElements()){
+                    InetAddress inetAddress = address.nextElement();
+                    if(inetAddress != null
+                            && inetAddress instanceof Inet4Address
+                            && !"127.0.0.1".equals(inetAddress.getHostAddress())){
+                        localHostAddress = inetAddress.getHostAddress();
+                    }
+                }
+            }
+        }catch (Exception e){
+
+        }
+        return localHostAddress;
+    }
+
+    /**
+     * 参考SpringCloud获取IP的代码
+     *
+     * @return
+     */
+    public static String findFirstNonLoopbackAddress() {
+        InetAddress result = null;
+        try {
+            int lowest = Integer.MAX_VALUE;
+            for (Enumeration<NetworkInterface> nics = NetworkInterface
+                    .getNetworkInterfaces(); nics.hasMoreElements(); ) {
+                NetworkInterface ifc = nics.nextElement();
+                if (ifc.isUp()) {
+                    if (ifc.getIndex() < lowest || result == null) {
+                        lowest = ifc.getIndex();
+                    } else if (result != null) {
+                        continue;
+                    }
+
+                    for (Enumeration<InetAddress> addrs = ifc
+                            .getInetAddresses(); addrs.hasMoreElements(); ) {
+                        InetAddress address = addrs.nextElement();
+                        if (address instanceof Inet4Address
+                                && !address.isLoopbackAddress()) {
+                            result = address;
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (result != null) {
+            return result.getHostAddress();
+        }
+
+        try {
+            return InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+
+        return "127.0.0.1";
+    }
+}

+ 37 - 0
src/main/java/com/mokamrp/data/util/LZ4Util.java

@@ -0,0 +1,37 @@
+package com.mokamrp.data.util;
+
+import net.jpountz.lz4.LZ4Compressor;
+import net.jpountz.lz4.LZ4Factory;
+import net.jpountz.lz4.LZ4FastDecompressor;
+
+/**
+ * LZ4Util
+ *
+ * @Author caijian
+ * @Date 2021/1/26 6:10 下午
+ */
+public class LZ4Util {
+
+    /**
+     * @param srcByte 原始数据
+     * @return 压缩后的数据
+     */
+    public static byte[] compressedByte(byte[] srcByte) {
+        LZ4Factory factory = LZ4Factory.fastestInstance();
+        LZ4Compressor compressor = factory.fastCompressor();
+        return compressor.compress(srcByte);
+    }
+
+    /**
+     * @param compressorByte 压缩后的数据
+     * @param srcLength      压缩前的数据长度
+     * @return
+     */
+    public static byte[] decompressorByte(byte[] compressorByte, int srcLength) {
+        LZ4Factory factory = LZ4Factory.fastestInstance();
+        LZ4FastDecompressor decompressor = factory.fastDecompressor();
+        return decompressor.decompress(compressorByte, srcLength);
+    }
+
+
+}

+ 43 - 0
src/main/java/com/mokamrp/data/util/LogExceptionStackTrace.java

@@ -0,0 +1,43 @@
+package com.mokamrp.data.util;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * className:LogExceptionStackTrace
+ * description:获取堆栈信息字符串工具类
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class LogExceptionStackTrace {
+
+    public static Object erroStackTrace(Object obj) {
+        if (obj instanceof Exception) {
+            Exception eObj = (Exception) obj;
+            StringWriter sw = null;
+            PrintWriter pw = null;
+            try {
+                sw = new StringWriter();
+                pw = new PrintWriter(sw);
+                String exceptionStack = "\r\n";
+                eObj.printStackTrace(pw);
+                exceptionStack = sw.toString();
+                return exceptionStack;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return obj;
+            } finally {
+                try {
+                    pw.close();
+                    sw.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        } else {
+            return obj;
+        }
+    }
+}

+ 158 - 0
src/main/java/com/mokamrp/data/util/Pool.java

@@ -0,0 +1,158 @@
+package com.mokamrp.data.util;
+
+import org.apache.commons.pool2.PooledObjectFactory;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+import java.io.Closeable;
+
+/**
+ * className:Pool
+ * description:abstract Pool
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public abstract class Pool<T> implements Closeable {
+
+  protected GenericObjectPool<T> internalPool;
+
+  public Pool() {
+  }
+
+  public Pool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory<T> factory) {
+    poolConfig.setMinIdle(0);
+    poolConfig.setMaxIdle(8);
+    poolConfig.setMaxTotal(30);
+    poolConfig.setMaxWaitMillis(1000);
+    initPool(poolConfig, factory);
+  }
+
+  @Override
+  public void close() {
+    destroy();
+  }
+
+  public boolean isClosed() {
+    return this.internalPool.isClosed();
+  }
+
+  public void initPool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory<T> factory) {
+
+    if (this.internalPool != null) {
+      try {
+        closeInternalPool();
+      } catch (Exception e) {
+      }
+    }
+
+    this.internalPool = new GenericObjectPool<T>(factory, poolConfig);
+  }
+
+
+  public T getResource() {
+    try {
+      return internalPool.borrowObject();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+
+  protected void returnResourceObject(final T resource) {
+    if (resource == null) {
+      return;
+    }
+    try {
+      internalPool.returnObject(resource);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  protected void returnBrokenResource(final T resource) {
+    if (resource != null) {
+      returnBrokenResourceObject(resource);
+    }
+  }
+
+  protected void returnResource(final T resource) {
+    if (resource != null) {
+      returnResourceObject(resource);
+    }
+  }
+
+  public void destroy() {
+    closeInternalPool();
+  }
+
+  protected void returnBrokenResourceObject(final T resource) {
+    try {
+      internalPool.invalidateObject(resource);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  protected void closeInternalPool() {
+    try {
+      internalPool.close();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  public int getNumActive() {
+    if (poolInactive()) {
+      return -1;
+    }
+
+    return this.internalPool.getNumActive();
+  }
+
+  public int getNumIdle() {
+    if (poolInactive()) {
+      return -1;
+    }
+
+    return this.internalPool.getNumIdle();
+  }
+
+  public int getNumWaiters() {
+    if (poolInactive()) {
+      return -1;
+    }
+
+    return this.internalPool.getNumWaiters();
+  }
+
+  public long getMeanBorrowWaitTimeMillis() {
+    if (poolInactive()) {
+      return -1;
+    }
+
+    return this.internalPool.getMeanBorrowWaitTimeMillis();
+  }
+
+  public long getMaxBorrowWaitTimeMillis() {
+    if (poolInactive()) {
+      return -1;
+    }
+
+    return this.internalPool.getMaxBorrowWaitTimeMillis();
+  }
+
+  private boolean poolInactive() {
+    return this.internalPool == null || this.internalPool.isClosed();
+  }
+
+  public void addObjects(int count) {
+    try {
+      for (int i = 0; i < count; i++) {
+        this.internalPool.addObject();
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}

+ 29 - 0
src/main/java/com/mokamrp/data/util/ThreadPoolUtil.java

@@ -0,0 +1,29 @@
+package com.mokamrp.data.util;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * className:ThreadPoolUtil
+ * description:带阻塞队列的线程池
+ *
+ * @author Frank.chen
+ * @version 1.0.0
+ */
+public class ThreadPoolUtil {
+    public static ThreadPoolExecutor getPool() {
+        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
+                10,10,10,TimeUnit.SECONDS,
+                new ArrayBlockingQueue<Runnable>(1),
+                new ThreadPoolExecutor.DiscardOldestPolicy());
+        return threadPool;
+    }
+    public static ThreadPoolExecutor getPool(int corePoolSize,int maxPoolSize,int capacity) {
+        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
+                corePoolSize,maxPoolSize,10,TimeUnit.SECONDS,
+                new ArrayBlockingQueue<Runnable>(capacity),
+                new ThreadPoolExecutor.DiscardOldestPolicy());
+        return threadPool;
+    }
+}

+ 5 - 0
src/main/resources/application.properties

@@ -0,0 +1,5 @@
+spring.application.name=moka-data
+server.port=8080
+
+kafka.hosts=emr-header-1.cluster-211770:9092,emr-worker-2.cluster-211770:9092,emr-worker-1.cluster-211770:9092
+kafka.groupName=mokadata

+ 39 - 0
src/main/resources/logback.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
+    <property name="LOG_HOME" value="/log" />
+    <!-- 控制台输出 -->
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!--输出到控制台-->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件 -->
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>logs/moka-data.log.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <MaxHistory>3</MaxHistory>
+        </rollingPolicy>
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <!-- 日志输出级别 -->
+    <root level="INFO">
+<!--       <appender-ref ref="CONSOLE" />-->
+        <appender-ref ref="FILE" />
+    </root>
+</configuration>

+ 35 - 0
src/test/java/com/mokamrp/data/test/KafkaTest.java

@@ -0,0 +1,35 @@
+package com.mokamrp.data.test;
+
+import com.mokamrp.data.kafka.KafkaConsumerClient;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.junit.Test;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
+public class KafkaTest {
+    private String kafkaHosts="";
+
+    private String KAFKA_GROUP_NAME="";
+
+    private int MAX_SEND_SIZE=5000;
+
+    @Test
+    public void collectRuningLog() {
+        KafkaConsumer<String, String> kafkaConsumer= KafkaConsumerClient.getInstance(kafkaHosts,KAFKA_GROUP_NAME,MAX_SEND_SIZE).getKafkaConsumer();
+        while (true) {
+            List<String> logList = new ArrayList();
+            List<String> sendlogList = new ArrayList();
+            try {
+                ConsumerRecords<String, String> records = kafkaConsumer.poll(Duration.ofMillis(1000));
+                records.forEach(record -> {
+                    System.out.println("get log:" + record.value() + "  logType:" + record.topic());
+                });
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}