Переглянути джерело

修改104秒级数据到内存版本

魏志亮 2 місяців тому
батько
коміт
02bd9fa0b0

+ 1 - 0
.gitignore

@@ -1,2 +1,3 @@
 /target/
 .idea
+.vscode

+ 53 - 8
pom.xml

@@ -1,19 +1,46 @@
 <?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">
+<project>
     <modelVersion>4.0.0</modelVersion>
-
     <groupId>com.zhzn.energy</groupId>
     <artifactId>energy-online-data-service</artifactId>
     <version>1.0-SNAPSHOT</version>
 
-    <properties>
-        <java.version>1.8</java.version>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
+    <!-- 添加Spring Boot父项目 -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.18</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
 
     <dependencies>
+        <!-- 新增Spring Boot基础依赖 -->
+        <!-- 在spring-boot-starter-web中排除logging -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        
+        <!-- 添加logback依赖 -->
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.12</version>
+        </dependency>
+
+        <!-- 保持原有依赖 -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.commons</groupId>
@@ -56,6 +83,24 @@
             <scope>compile</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.30</version>
+        </dependency>
+
+        <dependency>
+            <groupId>wei.yigulu</groupId>
+            <artifactId>protocol-iec104</artifactId>
+            <version>2.4.23</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.34</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 61 - 6
src/main/java/com/energy/online/data/OnlineDataMain.java

@@ -1,14 +1,69 @@
 package com.energy.online.data;
 
+// 新增Spring Boot相关导入
+
+import com.alibaba.fastjson2.JSON;
 import com.energy.online.data.dto.BaseConfig;
-import com.energy.online.data.service.listener.ListenerMainService;
-import com.energy.online.data.utils.MyConfigUtils;
+import com.energy.online.data.dto.Line;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.PulseTotalSummonType;
+import wei.yigulu.iec104.nettyconfig.Iec104MasterBuilder;
+import wei.yigulu.iec104.util.SendDataFrameHelper;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
 
+@SpringBootApplication
+@EnableAsync
+@EnableScheduling
 public class OnlineDataMain {
-    public static void main(String[] args) {
 
-        BaseConfig config = MyConfigUtils.getBaseConfig();
-        ListenerMainService listenerMainService = new ListenerMainService();
-        listenerMainService.onApplicationEvent(config);
+    @Autowired
+    private BaseConfig baseConfig;
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @PostConstruct
+    public void init() {
+        List<Line> lines = baseConfig.getLines();
+        for (Line line : lines) {
+            taskExecutor.execute(() -> runDeviceConnection(line));
+        }
     }
+
+    private void runDeviceConnection(Line line) {
+        try {
+            Iec104MasterBuilder master = new Iec104MasterBuilder(line.getIp(), line.getPort());
+            master.createByUnBlock();
+
+            while (!Thread.currentThread().isInterrupted()) {
+                System.out.println(JSON.toJSONString(line));
+                Thread.sleep(3000L);
+                SendDataFrameHelper.sendTotalSummonFrame(master.getFuture().channel(), 10, 6, master.getLog());
+                PulseTotalSummonType pulseTotalSummonType = new PulseTotalSummonType();
+                Asdu asdu = pulseTotalSummonType.generateBack();
+                Apdu apdu = new Apdu();
+                apdu.setAsdu(asdu);
+                master.sendFrameToOpposite(apdu.encode());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public static void main(String[] args) {
+        SpringApplication.run(OnlineDataMain.class, args);
+    }
+
 }

+ 38 - 0
src/main/java/com/energy/online/data/common/CommonData.java

@@ -0,0 +1,38 @@
+package com.energy.online.data.common;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+@Slf4j
+public class CommonData {
+
+    public static final Map<String, Object> map = new TreeMap<>();
+
+    public static final List<Map<String, Object>> list = new ArrayList<>();
+
+    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    public static void addList() {
+        // -1 表示时间
+//        log.info("数据长度(包含时间):" + map.size());
+        if (!map.isEmpty()) {
+            map.put("-1", sdf.format(System.currentTimeMillis()));
+            list.add(new TreeMap<>(map));
+        }
+    }
+
+    public static void put(String key, Object value) {
+        map.put(key, value);
+    }
+
+    public static List<Map<String, Object>> getListAndClean() {
+        List<Map<String, Object>> nowList = new ArrayList<>(list);
+        list.clear();
+        return nowList;
+    }
+}

+ 28 - 0
src/main/java/com/energy/online/data/config/AppConfig.java

@@ -0,0 +1,28 @@
+package com.energy.online.data.config;
+
+import com.energy.online.data.dto.BaseConfig;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+public class AppConfig {
+
+    @Bean
+    @ConfigurationProperties(prefix = "iec104")
+    public BaseConfig baseConfig() {
+        return new BaseConfig();
+    }
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(10);
+        executor.setMaxPoolSize(20);
+        executor.setQueueCapacity(500);
+        return executor;
+    }
+
+}

+ 43 - 0
src/main/java/com/energy/online/data/crontab/TimeSaveScheduled.java

@@ -0,0 +1,43 @@
+package com.energy.online.data.crontab;
+
+import com.alibaba.fastjson2.JSON;
+import com.energy.online.data.common.CommonData;
+import com.energy.online.data.dto.BaseConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class TimeSaveScheduled {
+
+    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+    @Autowired
+    private BaseConfig baseConfig;
+
+    //    @Scheduled(cron = "0/1 * * * * *")
+    @Scheduled(fixedRate = 1000)
+    public void collectData() {
+        CommonData.addList();
+    }
+
+    @Scheduled(cron = "0 0/1 * * * *")
+    public void saveToFile() {
+        List<Map<String, Object>> datas = CommonData.getListAndClean();
+        if (!datas.isEmpty()) {
+            String timestamp = sdf.format(System.currentTimeMillis());
+            String fileName = baseConfig.getSaveDir() + timestamp + ".json";
+            try (PrintWriter writer = new PrintWriter(fileName)) {
+                writer.write(JSON.toJSONString(datas));
+                writer.flush();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 5 - 27
src/main/java/com/energy/online/data/dto/BaseConfig.java

@@ -1,38 +1,16 @@
 package com.energy.online.data.dto;
 
+import lombok.Data;
+
 import java.util.List;
 
+@Data
 public class BaseConfig {
 
-    private List<WindFarm> windFarms;
-
-    private List<Measurepoint> measurepoints;
-
-    private Integer measurepointCount;
-
-    public List<WindFarm> getWindFarms() {
-        return windFarms;
-    }
-
-    public void setWindFarms(List<WindFarm> windFarms) {
-        this.windFarms = windFarms;
-    }
-
-    public List<Measurepoint> getMeasurepoints() {
-        return measurepoints;
-    }
-
-    public void setMeasurepoints(List<Measurepoint> measurepoints) {
-        this.measurepoints = measurepoints;
-    }
+    private List<Line> lines;
 
-    public Integer getMeasurepointCount() {
-        return measurepointCount;
-    }
+    private String saveDir;
 
-    public void setMeasurepointCount(Integer measurepointCount) {
-        this.measurepointCount = measurepointCount;
-    }
 }
 
 

+ 14 - 0
src/main/java/com/energy/online/data/dto/Line.java

@@ -0,0 +1,14 @@
+package com.energy.online.data.dto;
+
+import lombok.Data;
+
+@Data
+public class Line {
+
+    private String ip;
+
+    private Integer port;
+
+    private Integer coa;
+
+}

+ 0 - 50
src/main/java/com/energy/online/data/dto/Measurepoint.java

@@ -1,50 +0,0 @@
-package com.energy.online.data.dto;
-
-public class Measurepoint {
-    private Integer ioa;
-    private String chineseName;
-    private String standerName;
-    private Integer enable;
-
-    public Integer getIoa() {
-        return ioa;
-    }
-
-    public void setIoa(Integer ioa) {
-        this.ioa = ioa;
-    }
-
-    public String getChineseName() {
-        return chineseName;
-    }
-
-    public void setChineseName(String chineseName) {
-        this.chineseName = chineseName;
-    }
-
-    public String getStanderName() {
-        return standerName;
-    }
-
-    public void setStanderName(String standerName) {
-        this.standerName = standerName;
-    }
-
-    public Integer getEnable() {
-        return enable;
-    }
-
-    public void setEnable(Integer enable) {
-        this.enable = enable;
-    }
-
-    @Override
-    public String toString() {
-        return "Measurepoint{" +
-                "ioa=" + ioa +
-                ", chineseName='" + chineseName + '\'' +
-                ", standerName='" + standerName + '\'' +
-                ", enable=" + enable +
-                '}';
-    }
-}

+ 0 - 60
src/main/java/com/energy/online/data/dto/WindFarm.java

@@ -1,60 +0,0 @@
-package com.energy.online.data.dto;
-
-public class WindFarm {
-    private String ip;
-    private Integer port;
-    private Integer coa;
-    private String windFarmCode;
-    private String windFarmName;
-
-    public String getIp() {
-        return ip;
-    }
-
-    public void setIp(String ip) {
-        this.ip = ip;
-    }
-
-    public Integer getPort() {
-        return port;
-    }
-
-    public void setPort(Integer port) {
-        this.port = port;
-    }
-
-    public Integer getCoa() {
-        return coa;
-    }
-
-    public void setCoa(Integer coa) {
-        this.coa = coa;
-    }
-
-    public String getWindFarmCode() {
-        return windFarmCode;
-    }
-
-    public void setWindFarmCode(String windFarmCode) {
-        this.windFarmCode = windFarmCode;
-    }
-
-    public String getWindFarmName() {
-        return windFarmName;
-    }
-
-    public void setWindFarmName(String windFarmName) {
-        this.windFarmName = windFarmName;
-    }
-
-    @Override
-    public String toString() {
-        return "WindFarm{" +
-                "ip='" + ip + '\'' +
-                ", port=" + port +
-                ", coa=" + coa +
-                ", windFarmCode='" + windFarmCode + '\'' +
-                ", windFarmName='" + windFarmName + '\'' +
-                '}';
-    }
-}

+ 48 - 0
src/main/java/com/energy/online/data/handle/HandleShortFloat.java

@@ -0,0 +1,48 @@
+package com.energy.online.data.handle;
+
+import com.energy.online.data.common.CommonData;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.asdudataframe.ShortFloatType;
+import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@AsduType(typeId = 13)
+public class HandleShortFloat extends ShortFloatType {
+
+    /**
+     * 处理短浮点数据
+     *
+     * @param apdu
+     * @return
+     */
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) {
+        log.debug("----------处理短浮点数据---------");
+        HandleShortFloat handleShortFloat = (HandleShortFloat) apdu.getAsdu().getDataFrame();
+        List<InformationBodyAddress> address = handleShortFloat.getAddresses();
+        Map<IeMeasuredQuality, Float> datas = handleShortFloat.getDatas();
+        int i = 0;
+        //存入共享服务端
+        if (apdu.getAsdu().getVsq().getSq() == 0) {
+            log.debug("------处理短浮点单一寻址-----");
+            for (Map.Entry<IeMeasuredQuality, Float> e : datas.entrySet()) {
+                CommonData.put(address.get(i++).getAddress() + "", e.getValue());
+            }
+        } else if (apdu.getAsdu().getVsq().getSq() == 1) {
+            log.debug("------处理短浮点连续寻址-----");
+            i = address.get(0).getAddress();
+            for (Map.Entry<IeMeasuredQuality, Float> e : datas.entrySet()) {
+                CommonData.put(i++ + "", e.getValue());
+            }
+        }
+
+        //如果有需要返回数据帧可以创建byte数据  向内置入要返回的数据帧encode()后的数组
+        return null;
+    }
+}

+ 49 - 0
src/main/java/com/energy/online/data/handle/HandleShortInteger.java

@@ -0,0 +1,49 @@
+package com.energy.online.data.handle;
+
+import com.energy.online.data.common.CommonData;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.asdudataframe.ShortIntegerType;
+import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@AsduType(typeId = 11)
+public class HandleShortInteger extends ShortIntegerType {
+
+    /**
+     * 处理短整型数据
+     *
+     * @param apdu
+     * @return
+     */
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) {
+        log.debug("----------处理短整型数据---------");
+        HandleShortInteger handleShortFloat = (HandleShortInteger) apdu.getAsdu().getDataFrame();
+        List<InformationBodyAddress> address = handleShortFloat.getAddresses();
+        Map<IeMeasuredQuality, Integer> datas = handleShortFloat.getDatas();
+        int i = 0;
+        //存入共享服务端
+//        log.info("获取到数据{}个", address.size());
+        if (apdu.getAsdu().getVsq().getSq() == 0) {
+            log.debug("------处理短整型单一寻址-----");
+            for (Map.Entry<IeMeasuredQuality, Integer> e : datas.entrySet()) {
+                CommonData.put(address.get(i++).getAddress() + "", e.getValue());
+            }
+        } else if (apdu.getAsdu().getVsq().getSq() == 1) {
+            log.debug("------处理短整型连续寻址-----");
+            i = address.get(0).getAddress();
+            for (Map.Entry<IeMeasuredQuality, Integer> e : datas.entrySet()) {
+                CommonData.put(i++ + "", e.getValue());
+            }
+        }
+
+        //如果有需要返回数据帧可以创建byte数据  向内置入要返回的数据帧encode()后的数组
+        return null;
+    }
+}

+ 0 - 221
src/main/java/com/energy/online/data/service/listener/J60870ClientListener.java

@@ -1,221 +0,0 @@
-package com.energy.online.data.service.listener;
-
-import com.energy.online.data.dto.BaseConfig;
-import com.energy.online.data.dto.Measurepoint;
-import com.energy.online.data.dto.WindFarm;
-import com.energy.online.data.utils.MyConfigUtils;
-import org.openmuc.j60870.ASdu;
-import org.openmuc.j60870.ConnectionEventListener;
-import org.openmuc.j60870.ie.InformationElement;
-import org.openmuc.j60870.ie.InformationObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class J60870ClientListener implements ConnectionEventListener {
-
-    private static final Logger log = LoggerFactory.getLogger(J60870ClientListener.class);
-
-    private final Map<Long, Map<Integer, Object>> dataMap;
-    private final Map<Integer, Measurepoint> measurepointMap;
-    private final WindFarm windFarm;
-    private final BaseConfig baseConfig;
-    private final List<String> standardList = new ArrayList<>();
-
-    private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
-
-    private static final int BATCH_SIZE = 1000;
-    private final Map<String, List<Map<String, Object>>> dateBuffers = new ConcurrentHashMap<>();
-    private final ExecutorService csvExecutor = Executors.newSingleThreadExecutor();
-
-    public J60870ClientListener(Map<Long, Map<Integer, Object>> dataMap, WindFarm windFarm, BaseConfig baseConfig) {
-        this.dataMap = dataMap;
-        this.windFarm = windFarm;
-        this.baseConfig = baseConfig;
-        this.measurepointMap = MyConfigUtils.getEnableMeasurepoints(baseConfig.getMeasurepoints());
-
-        this.standardList.add("time_stamp");
-        this.standardList.add("wind_turbine_name");
-        for (Measurepoint measurepoint : measurepointMap.values()) {
-            this.standardList.add(measurepoint.getStanderName());
-        }
-    }
-
-    public final String title = "104协议数据服务 - ";
-
-
-    /**
-     * 监听从站发来的数据
-     */
-    @Override
-    public void newASdu(ASdu aSdu) {
-        if (aSdu.getCommonAddress() == windFarm.getCoa()) {
-            List<InformationObject> list = new ArrayList<>(Arrays.asList(aSdu.getInformationObjects()));
-            //  获取当前时刻,验证是否是同一秒数据,数据进行合并
-            Instant now = Instant.now();
-            // 获取当前时刻的秒数
-            long epochSecond = now.getEpochSecond();
-            Long receiptTime = dataMap.keySet().isEmpty() ? null : dataMap.keySet().iterator().next();
-            long receiptTimeLong = receiptTime == null ? 0 : receiptTime;
-
-            // 当前秒时间大于数据库最新秒时间并且数据库不等于0
-            if (epochSecond > receiptTimeLong && receiptTimeLong != 0) {
-                // 保存临时表
-                List<Map<String, Object>> resultDatas = transToStandarData(receiptTimeLong);
-                asyncSaveToCsv(resultDatas, receiptTimeLong);
-            }
-            //添加新的数据
-            saveMeasurementTemp(list, epochSecond);
-        }
-    }
-
-    private List<Map<String, Object>> transToStandarData(long receiptTimeLong) {
-        List<Map<String, Object>> resultDatas = new ArrayList<>();
-        Map<Integer, Object> integerObjectMap = dataMap.get(receiptTimeLong);
-        if (null == integerObjectMap || integerObjectMap.isEmpty()) {
-            return Collections.emptyList();
-        }
-
-        Map<Integer, Map<String, Object>> map = new HashMap<>();
-        for (Map.Entry<Integer, Object> entry : integerObjectMap.entrySet()) {
-            Integer ioa = entry.getKey();
-            Integer windCode = ioa / baseConfig.getMeasurepointCount() + 1;
-            String standardName = measurepointMap.get(ioa % baseConfig.getMeasurepointCount()).getStanderName();
-
-            if (map.containsKey(windCode)) {
-                map.get(windCode).put(standardName, entry.getValue());
-            } else {
-                Map<String, Object> windMap = new HashMap<>();
-                windMap.put(standardName, entry.getValue());
-                windMap.put("wind_turbine_name", windCode);
-                windMap.put("time_stamp", dateTimeFormat.format(Date.from(Instant.ofEpochSecond(receiptTimeLong))));
-                map.put(windCode, windMap);
-            }
-        }
-
-        for (Map<String, Object> data : map.values()) {
-            Set<String> keys = data.keySet();
-
-            standardList.forEach(point -> {
-                if (!keys.contains(point)) {
-                    data.put(point, null);
-                }
-            });
-            resultDatas.add(data);
-        }
-        // 清理一秒的数据
-        dataMap.clear();
-        return resultDatas;
-    }
-
-    private void asyncSaveToCsv(List<Map<String, Object>> resultDatas, long receiptTimeLong) {
-        csvExecutor.execute(() -> {
-            synchronized (dateBuffers) {
-                String dateKey = dateFormat.format(Date.from(Instant.ofEpochSecond(receiptTimeLong)));
-                if (dateBuffers.containsKey(dateKey)) {
-                    dateBuffers.get(dateKey).addAll(resultDatas);
-                } else {
-                    saveLessThenBatchSizeData();
-                    dateBuffers.put(dateKey, resultDatas);
-                }
-                List<Map<String, Object>> buffer = dateBuffers.get(dateKey);
-
-                if (buffer.size() >= BATCH_SIZE) {
-                    List<Map<String, Object>> toSave = new ArrayList<>(buffer.subList(0, BATCH_SIZE));
-                    buffer.subList(0, BATCH_SIZE).clear();
-                    flushToCsv(toSave, dateKey);
-                }
-            }
-        });
-    }
-
-    private void saveLessThenBatchSizeData() {
-        if (!dateBuffers.isEmpty()) {
-            String key = dateBuffers.keySet().iterator().next();
-            List<Map<String, Object>> buffer = new ArrayList<>(dateBuffers.get(key));
-            flushToCsv(buffer, key);
-            dateBuffers.clear();
-        }
-    }
-
-    private void flushToCsv(List<Map<String, Object>> data, String dateStr) {
-        log.info(windFarm.getWindFarmName() + "保存" + data.size() + "条数据,日期为:" + dateStr);
-        String csvFile = String.format("%s_%s_%s.csv", windFarm.getWindFarmName(),
-                windFarm.getWindFarmCode(), dateStr);
-        boolean existsTitle = Files.exists(Paths.get(csvFile));
-        synchronized (csvFile) {
-            try (FileWriter writer = new FileWriter(csvFile, true)) {
-                if (!data.isEmpty() && !existsTitle) {
-                    writer.append(String.join(",", standardList));
-                    writer.append('\n');
-                }
-
-                for (Map<String, Object> row : data) {
-                    List<String> values = new ArrayList<>();
-                    for (String standerName : standardList) {
-                        Object value = row.get(standerName);
-                        values.add(value != null ? value.toString() : "");
-                    }
-                    writer.append(String.join(",", values));
-                    writer.append('\n');
-                }
-            } catch (IOException e) {
-                e.printStackTrace();
-                log.error(e.getMessage());
-            }
-        }
-    }
-
-    private static final String split = "Short float value:";
-
-    private void saveMeasurementTemp(List<InformationObject> informationObjects, long epochSecond) {
-        if (!dataMap.containsKey(epochSecond)) {
-            dataMap.put(epochSecond, new HashMap<>());
-        }
-
-        for (InformationObject item : informationObjects) {
-            int ioa = item.getInformationObjectAddress();
-
-            if (measurepointMap.containsKey(ioa % baseConfig.getMeasurepointCount())) {
-                // 一秒中多条数据整理
-                InformationElement[][] valData = item.getInformationElements();
-                if (valData.length > 0) {
-                    InformationElement[] informationElementSet;
-                    for (InformationElement[] valDatum : valData) {
-                        informationElementSet = valDatum;
-                        for (InformationElement informationElement : informationElementSet) {
-                            String dataStr = informationElement.toString();
-                            if (dataStr.contains(split)) {
-                                dataMap.get(epochSecond).put(item.getInformationObjectAddress(), dataStr.split(split)[1].trim());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    /**
-     * 监听连接关闭
-     */
-    @Override
-    public void connectionClosed(IOException cause) {
-        log.info("connectionClosed: " + dateBuffers.get(dateBuffers.keySet().iterator().next()).size());
-        saveLessThenBatchSizeData();
-        log.info(this.title + "J60870ClientListener ConnectionClosed :" + cause.getMessage());
-        log.info("Thread.activeCount :" + Thread.activeCount());
-    }
-}
-

+ 0 - 99
src/main/java/com/energy/online/data/service/listener/JClient.java

@@ -1,99 +0,0 @@
-package com.energy.online.data.service.listener;
-
-import com.energy.online.data.dto.BaseConfig;
-import com.energy.online.data.dto.WindFarm;
-import org.openmuc.j60870.ClientConnectionBuilder;
-import org.openmuc.j60870.Connection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-
-public class JClient implements Callable<String> {
-
-    private static final Logger log = LoggerFactory.getLogger(JClient.class);
-
-    public static String title = "104协议数据服务 - ";
-
-    private final WindFarm windFarm;
-
-    private final BaseConfig baseConfig;
-
-    //监听类,后面代码会给出
-    private J60870ClientListener listener;
-    //连接类
-    private Connection connection;
-
-    //连接参数,可以配置的参数有好多,比如t0,t1,t2等等
-    private ClientConnectionBuilder clientConnectionBuilder;
-
-    @Override
-    public String call() throws Exception {
-        while (!Thread.currentThread().isInterrupted()) {
-            try {
-                // 使用Builder创建连接
-                connection = clientConnectionBuilder.build();
-                log.info(String.format("成功连接至%s:%s%n", windFarm.getIp(), windFarm.getPort()));
-
-                // 配置数据监听
-                Map<Long, Map<Integer, Object>> dataMap = new HashMap<>();
-                listener = new J60870ClientListener(dataMap, windFarm, baseConfig);
-                connection.startDataTransfer(listener);
-
-                // 修改连接状态检查方式
-                while (connection != null && !connection.isClosed()) {
-                    Thread.sleep(1000);
-                }
-
-            } catch (IOException e) {
-                log.info("连接异常:" + e.getMessage());
-            } finally {
-                closeConnection();
-            }
-
-            if (!Thread.currentThread().isInterrupted()) {
-                log.info("1秒后尝试重连...");
-                Thread.sleep(1000);
-            }
-        }
-        return "连接任务终止";
-    }
-
-    public JClient(WindFarm windFarm, BaseConfig baseConfig) throws UnknownHostException {
-        this.windFarm = windFarm;
-        this.baseConfig = baseConfig;
-        init();
-    }
-
-    /**
-     * 初始化
-     */
-    public void init() throws UnknownHostException {
-
-        //获取server端、从站的ip地址对象,这里使用本地ip
-        InetAddress address = InetAddress.getByName(windFarm.getIp());
-        //创建连接参数对象
-        clientConnectionBuilder = new ClientConnectionBuilder(address);
-
-        //设置socket的连接超时时间
-        clientConnectionBuilder.setConnectionTimeout(1000);
-
-        //设置socket的连接端口
-        clientConnectionBuilder.setPort(windFarm.getPort());
-
-        log.info(title + "J60870Client Init Success By Host " + windFarm);
-    }
-
-    private void closeConnection() {
-        if (connection != null && !connection.isClosed()) {
-            connection.close();
-            log.info("连接已正常关闭");
-        }
-    }
-}

+ 0 - 67
src/main/java/com/energy/online/data/service/listener/ListenerMainService.java

@@ -1,67 +0,0 @@
-package com.energy.online.data.service.listener;
-
-import com.energy.online.data.dto.BaseConfig;
-import com.energy.online.data.dto.WindFarm;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.PreDestroy;
-import java.net.UnknownHostException;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import static java.util.concurrent.Executors.newFixedThreadPool;
-
-public class ListenerMainService {
-
-    private static final Logger log = LoggerFactory.getLogger(ListenerMainService.class);
-
-    private ExecutorService executor = null;
-    private final List<Future<?>> futures = new CopyOnWriteArrayList<>();
-
-    public void onApplicationEvent(BaseConfig baseConfig) {
-        log.info("启动监听到 J60870Client...");
-        List<WindFarm> windFarms = baseConfig.getWindFarms();
-        int taskNum = windFarms.size();
-
-        // 修正线程池大小(确保不小于任务数量)
-        int poolSize = Math.max(Runtime.getRuntime().availableProcessors() * 2, taskNum);
-        executor = newFixedThreadPool(poolSize);
-
-        for (WindFarm windFarm : windFarms) {
-            log.info("Task " + windFarm);
-            Future<String> future = null;
-            try {
-                future = executor.submit(new JClient(windFarm, baseConfig));
-            } catch (UnknownHostException e) {
-                e.printStackTrace();
-                log.error(e.getMessage());
-            }
-            futures.add(future);
-            log.info("监听地址:" + windFarm.getIp());
-        }
-    }
-
-
-    @PreDestroy
-    public void shutdown() {
-        futures.forEach(future -> {
-            if (!future.isDone()) {
-                future.cancel(true);
-            }
-        });
-        executor.shutdown();
-        try {
-            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
-                executor.shutdownNow();
-            }
-        } catch (InterruptedException e) {
-            executor.shutdownNow();
-            Thread.currentThread().interrupt();
-        }
-    }
-}
-

+ 0 - 15
src/main/java/com/energy/online/data/utils/MyConfigUtils.java

@@ -1,14 +1,9 @@
 package com.energy.online.data.utils;
 
 import com.energy.online.data.dto.BaseConfig;
-import com.energy.online.data.dto.Measurepoint;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.InputStream;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 public class MyConfigUtils {
 
@@ -18,14 +13,4 @@ public class MyConfigUtils {
         InputStream inputStream = MyConfigUtils.class.getClassLoader().getResourceAsStream("config.yml");
         return yaml.loadAs(inputStream, BaseConfig.class);
     }
-
-    public static Map<Integer, Measurepoint> getEnableMeasurepoints(List<Measurepoint> measurepoints) {
-        return measurepoints.stream().filter(data -> data.getEnable() == 1).collect(Collectors.toMap(Measurepoint::getIoa, o -> o, (o1, o2) -> o2, LinkedHashMap::new));
-    }
-
-    public static void main(String[] args) {
-
-        BaseConfig config = getBaseConfig();
-        getEnableMeasurepoints(config.getMeasurepoints()).values().forEach(System.out::println);
-    }
 }

+ 20 - 0
src/main/resources/application.yml

@@ -0,0 +1,20 @@
+spring:
+  application:
+    name: energy-online-service
+
+iec104:
+  saveDir: "/data/104data/"
+  lines:
+    - ip: 192.168.50.242
+      port: 2404
+      coa: 10
+    - ip: 192.168.50.242
+      port: 2405
+      coa: 1
+
+  #lines:
+  #  - ip: 172.21.6.36
+  #    port: 2404
+  #
+  #  - ip: 172.21.6.36
+  #    port: 2405

+ 0 - 531
src/main/resources/config.yml

@@ -1,531 +0,0 @@
-windFarms:
-  - ip: 192.168.50.242
-    port: 2404
-    coa: 10
-    windFarmName: 山西风电场
-    windFarmCode: test001
-
-  - ip: 192.168.50.242
-    port: 2404
-    coa: 11
-    windFarmName: 运城风电场
-    windFarmCode: test002
-
-
-measurepointCount: 103
-
-measurepoints:
-  - ioa: 0
-    chineseName: 网侧L1相功率因数
-    standerName:
-    enable: 0
-
-  - ioa: 1
-    chineseName: 网侧L1相电流
-    standerName:
-    enable: 0
-
-  - ioa: 2
-    chineseName: 网侧L2相电流
-    standerName:
-    enable: 0
-
-  - ioa: 3
-    chineseName: 网侧L3相电流
-    standerName:
-    enable: 0
-
-  - ioa: 4
-    chineseName: 变频器水冷入口压力
-    standerName:
-    enable: 0
-
-  - ioa: 5
-    chineseName: 变频器水冷出口压力
-    standerName:
-    enable: 0
-
-  - ioa: 6
-    chineseName: 变频器水冷入口温度
-    standerName:
-    enable: 0
-
-  - ioa: 7
-    chineseName: 变频器水冷出口温度
-    standerName:
-    enable: 0
-
-  - ioa: 8
-    chineseName: 电网频率
-    standerName:
-    enable: 0
-
-  - ioa: 9
-    chineseName: 网侧L1相电压
-    standerName:
-    enable: 0
-
-  - ioa: 10
-    chineseName: 网侧L2相电压
-    standerName:
-    enable: 0
-
-  - ioa: 11
-    chineseName: 网侧L3相电压
-    standerName:
-    enable: 0
-
-  - ioa: 12
-    chineseName: 外测有功功率
-    standerName:
-    enable: 0
-
-  - ioa: 13
-    chineseName: 发电机进风口前部温度
-    standerName:
-    enable: 0
-
-  - ioa: 14
-    chineseName: 发电机压差传感器
-    standerName:
-    enable: 0
-
-  - ioa: 15
-    chineseName: 发电机进风口后部温度
-    standerName:
-    enable: 0
-
-  - ioa: 16
-    chineseName: 发电机出风口温度
-    standerName:
-    enable: 0
-
-  - ioa: 17
-    chineseName: 风机有功功率
-    standerName: active_power
-    enable: 1
-
-  - ioa: 18
-    chineseName: 发电机水冷入口压力
-    standerName:
-    enable: 0
-
-  - ioa: 19
-    chineseName: 发电机水冷出口压力
-    standerName:
-    enable: 0
-
-  - ioa: 20
-    chineseName: 发电机无功功率
-    standerName:
-    enable: 0
-
-  - ioa: 21
-    chineseName: 发电机转速
-    standerName: generator_speed
-    enable: 1
-
-  - ioa: 22
-    chineseName: 发电机水冷入口温度
-    standerName:
-    enable: 0
-
-  - ioa: 23
-    chineseName: 发电机水冷出口温度
-    standerName:
-    enable: 0
-
-  - ioa: 24
-    chineseName: 发电机驱动端轴承温度
-    standerName: generatordrive_end_bearing_temperature
-    enable: 1
-
-  - ioa: 25
-    chineseName: 发电机非驱动端轴承温度
-    standerName: generatornon_drive_end_bearing_temperature
-    enable: 1
-
-  - ioa: 26
-    chineseName: 发电机滑环室温度
-    standerName:
-    enable: 0
-
-  - ioa: 27
-    chineseName: 发电机定子U相线圈温度
-    standerName: generator_winding1_temperature
-    enable: 1
-
-  - ioa: 28
-    chineseName: 发电机定子V相线圈温度
-    standerName: generator_winding2_temperature
-    enable: 1
-
-  - ioa: 29
-    chineseName: 发电机定子W相线圈温度
-    standerName: generator_winding3_temperature
-    enable: 1
-
-  - ioa: 30
-    chineseName: 机舱水冷齿轮箱冷却液温度1min
-    standerName:
-    enable: 0
-
-  - ioa: 31
-    chineseName: 机舱水冷发电机冷却液温度1min
-    standerName:
-    enable: 0
-
-  - ioa: 32
-    chineseName: 机舱冷却系统水泵入口压力
-    standerName:
-    enable: 0
-
-  - ioa: 33
-    chineseName: 机舱水冷泵出口压力1min
-    standerName:
-    enable: 0
-
-  - ioa: 34
-    chineseName: 塔底水冷变频器入口水温
-    standerName:
-    enable: 0
-
-  - ioa: 35
-    chineseName: 塔底水冷变频器出口水温
-    standerName:
-    enable: 0
-
-  - ioa: 36
-    chineseName: 塔底湿度
-    standerName:
-    enable: 0
-
-  - ioa: 37
-    chineseName: 塔底水冷三通阀设置实际值
-    standerName:
-    enable: 0
-
-  - ioa: 38
-    chineseName: 塔底水冷三通阀反馈值
-    standerName:
-    enable: 0
-
-  - ioa: 39
-    chineseName: 塔外湿度
-    standerName:
-    enable: 0
-
-  - ioa: 40
-    chineseName: 塔底水冷泵入口压力
-    standerName:
-    enable: 0
-
-  - ioa: 41
-    chineseName: 塔底水冷泵出口压力
-    standerName:
-    enable: 0
-
-  - ioa: 42
-    chineseName: 舱内温度
-    standerName: cabin_temperature
-    enable: 1
-
-  - ioa: 43
-    chineseName: 机舱控制柜温度
-    standerName:
-    enable: 0
-
-  - ioa: 44
-    chineseName: 舱外温度
-    standerName: outside_cabin_temperature
-    enable: 1
-
-  - ioa: 45
-    chineseName: 塔底温度
-    standerName:
-    enable: 0
-
-  - ioa: 46
-    chineseName: 塔底控制柜温度
-    standerName:
-    enable: 0
-
-  - ioa: 47
-    chineseName: 风向
-    standerName: true_wind_direction
-    enable: 1
-
-  - ioa: 48
-    chineseName: 风速
-    standerName: wind_velocity
-    enable: 1
-
-  - ioa: 49
-    chineseName: 机舱中轴线与风向夹角
-    standerName: yaw_error1
-    enable: 1
-
-  - ioa: 50
-    chineseName: 变桨电池1电压
-    standerName:
-    enable: 0
-
-  - ioa: 51
-    chineseName: 变桨电池2电压
-    standerName:
-    enable: 0
-
-  - ioa: 52
-    chineseName: 变桨电池3电压
-    standerName:
-    enable: 0
-
-  - ioa: 53
-    chineseName: 变桨电机1电流
-    standerName:
-    enable: 0
-
-  - ioa: 54
-    chineseName: 变桨电机2电流
-    standerName:
-    enable: 0
-
-  - ioa: 55
-    chineseName: 变桨电机3电流
-    standerName:
-    enable: 0
-
-  - ioa: 56
-    chineseName: 1#桨电机温度
-    standerName:
-    enable: 0
-
-  - ioa: 57
-    chineseName: 2#桨电机温度
-    standerName:
-    enable: 0
-
-  - ioa: 58
-    chineseName: 3#桨电机温度
-    standerName:
-    enable: 0
-
-  - ioa: 59
-    chineseName: 变桨驱动器1温度
-    standerName:
-    enable: 0
-
-  - ioa: 60
-    chineseName: 变桨驱动器2温度
-    standerName:
-    enable: 0
-
-  - ioa: 61
-    chineseName: 变桨驱动器3温度
-    standerName:
-    enable: 0
-
-  - ioa: 62
-    chineseName: 轮毂内温度
-    standerName:
-    enable: 0
-
-  - ioa: 63
-    chineseName: 变桨电池柜1温度
-    standerName:
-    enable: 0
-
-  - ioa: 64
-    chineseName: 变桨电池柜2温度
-    standerName:
-    enable: 0
-
-  - ioa: 65
-    chineseName: 变桨电池柜3温度
-    standerName:
-    enable: 0
-
-  - ioa: 66
-    chineseName: 动力电缆温度监控1
-    standerName:
-    enable: 0
-
-  - ioa: 67
-    chineseName: 动力电缆温度监控2
-    standerName:
-    enable: 0
-
-  - ioa: 68
-    chineseName: 辅变绕组温度
-    standerName:
-    enable: 0
-
-  - ioa: 69
-    chineseName: 主变绕组温度
-    standerName:
-    enable: 0
-
-  - ioa: 70
-    chineseName: 齿轮箱入口油压
-    standerName:
-    enable: 0
-
-  - ioa: 71
-    chineseName: 齿轮箱油路滤网前油压
-    standerName:
-    enable: 0
-
-  - ioa: 72
-    chineseName: 液压站预充压力
-    standerName:
-    enable: 0
-
-  - ioa: 73
-    chineseName: 主轴转速
-    standerName: rotor_speed
-    enable: 1
-
-  - ioa: 74
-    chineseName: 齿轮箱油路入口温度
-    standerName:
-    enable: 0
-
-  - ioa: 75
-    chineseName: 齿轮箱散热器出口温度
-    standerName:
-    enable: 0
-
-  - ioa: 76
-    chineseName: 齿轮箱高速轴HSS_GSGS端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 77
-    chineseName: 齿轮箱高速轴HSS_GSRS端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 78
-    chineseName: 齿轮箱中速轴HSS_RS端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 79
-    chineseName: 齿轮箱中速轴IMS_GSRS端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 80
-    chineseName: 齿轮箱高速轴驱动端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 81
-    chineseName: 齿轮箱高速轴非驱动端轴承温度
-    standerName: gearbox_high_speed_shaft_bearing_temperature
-    enable: 1
-
-  - ioa: 82
-    chineseName: 齿轮箱油池温度
-    standerName: gearbox_oil_temperature
-    enable: 1
-
-  - ioa: 83
-    chineseName: 齿轮箱中速轴驱动端轴承温度
-    standerName:
-    enable: 0
-
-  - ioa: 84
-    chineseName: 齿轮箱中速轴非驱动端轴承温度
-    standerName: gearboxmedium_speed_shaftbearing_temperature
-    enable: 1
-
-  - ioa: 85
-    chineseName: 主轴承温度
-    standerName: main_bearing_temperature
-    enable: 1
-
-  - ioa: 86
-    chineseName: 主轴承内圈温度
-    standerName:
-    enable: 0
-
-  - ioa: 87
-    chineseName: 主轴承外圈温度
-    standerName:
-    enable: 0
-
-  - ioa: 88
-    chineseName: 主控有功设置值
-    standerName: set_value_of_active_power
-    enable: 1
-
-  - ioa: 89
-    chineseName: 主控无功设置值
-    standerName:
-    enable: 0
-
-  - ioa: 90
-    chineseName: 主控次要SC
-    standerName:
-    enable: 0
-
-  - ioa: 91
-    chineseName: 主控有功限值上限
-    standerName:
-    enable: 0
-
-  - ioa: 92
-    chineseName: 对外AI型状态1
-    standerName:
-    enable: 0
-
-  - ioa: 93
-    chineseName: 机舱侧向振动(已滤波)
-    standerName: side_to_side_vibration_of_the_cabin
-    enable: 1
-
-  - ioa: 94
-    chineseName: 机舱轴向振动(已滤波)
-    standerName: front_back_vibration_of_the_cabin
-    enable: 1
-
-  - ioa: 95
-    chineseName: 后方摩擦片距离
-    standerName:
-    enable: 0
-
-  - ioa: 96
-    chineseName: 前方摩擦片距离
-    standerName:
-    enable: 0
-
-  - ioa: 97
-    chineseName: 机舱角度
-    standerName: cabin_position
-    enable: 1
-
-  - ioa: 98
-    chineseName: 机舱电流
-    standerName:
-    enable: 0
-
-  - ioa: 99
-    chineseName: 扭揽角度
-    standerName: twisted_cable_angle
-    enable: 1
-
-  - ioa: 100
-    chineseName: 偏航电机转速1
-    standerName:
-    enable: 0
-
-  - ioa: 101
-    chineseName: 偏航电机转速2
-    standerName:
-    enable: 0
-
-  - ioa: 102
-    chineseName: 偏航角度
-    standerName:
-    enable: 0

+ 15 - 0
src/main/resources/geli.cer

@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWjCCAgOgAwIBAgIB+DAMBggqgRzPVQGDdQUAME8xCzAJBgNVBAYTAkNOMQswC
+QYDVQQKDAJLRDELMAkGA1UECwwCQkoxCzAJBgNVBAMMAkNBMQ0wCwYDVQQHDAQyU2
+VjMQowCAYDVQQIDAEgMB4XDTI1MDMxMTA2MzEyMVoXDTMwMDMxMTA2MzEyMVowaDE
+LMAkGA1UEBhMCQ04xCzAJBgNVBAcMAnR5MQswCQYDVQQKDAJnaDEMMAoGA1UECwwD
+emdoMQswCQYDVQQDDAJnbDEkMCIGCSqGSIb3DQEJARYVbGkxODczNTAwNTIyNEAxM
+jYuY29tMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5rkgmF/1DseUOfJIMivBkQ
+tNZsfmKqPcJlPd9V+GikMxXcFsGcGA4S5P5GL7ZuM0ZGpevLq+njUp4TdzRC1d+6O
+BtDCBsTAdBgNVHQ4EFgQU9hdiqr1LDIFq9sAps3RaZd8Pjf4wdQYDVR0jBG4wbIAU
+nb8yH+NG8CIqu4UDbMSb6KTfwC6hQqRAMD4xCzAJBgNVBAYTAkNOMQwwCgYDVQQKD
+ANHREQxDzANBgNVBAsMBjAwMDAwMDEQMA4GA1UEAwwHcm9vdFNNMoIQBAAAAAAAAA
+AAAAAAAAAABDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAMBggqgRzPVQGDdQU
+AA0MAMECih/wp6ccvPZ4G+qJVozNUD8SZCb8u/HDue0SOSK6PIAsLUv1lODqYuSfr
+6zmwaKcgu9xaicMZRXKruiTJ9Z/S
+-----END CERTIFICATE-----

+ 0 - 17
src/main/resources/log4j.properties

@@ -1,17 +0,0 @@
-### \u5C06\u7B49\u7EA7\u4E3Adebug\u7684\u65E5\u5FD7\u8F93\u51FA\u5230console\u548Cfile\uFF0C console\u548Cfile\u7684\u5B9A\u4E49\u5728\u4E0B\u9762 ###
-log4j.rootLogger=DEBUG,console,file
-### console \u914D\u7F6E\u8F93\u51FA\u5230\u63A7\u5236\u53F0 ###
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.Target=System.out
-log4j.appender.console.Threshold=DEBUG
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=[%c] - %m%n
-### file \u914D\u7F6E\u8F93\u51FA\u5230\u6587\u4EF6 ###
-### DailyRollingFileAppender: \u4EE5\u65E5\u671F\u5206\u5272\u6BCF\u5929\u4EA7\u751F\u4E00\u4E2A\u6587\u4EF6,  DatePattern: \u65E5\u5FD7\u6587\u4EF6\u540D\u79F0\u683C\u5F0F ###
-log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
-log4j.appender.file.DatePattern='_'yyyy-MM-dd'.log'
-log4j.appender.file.File=/data/logs/104/log.log
-log4j.appender.file.Threshold=DEBUG
-log4j.appender.file.Append=true
-log4j.appender.file.layout=org.apache.log4j.PatternLayout
-log4j.appender.file.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH:mm:ss}] [%c]%m%n

+ 21 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
+    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
+
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>/data/logs/104/104.log</file>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>104.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="FILE"/>
+    </root>
+</configuration>