Parcourir la source

集成mapdb,但速度有点慢,等后面看情况使用

cocoKnight il y a 1 an
Parent
commit
9c9a203130

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 0 - 3
app/src/main/resources/application-dev.yml

@@ -3,9 +3,6 @@ server:
 
   servlet:
     context-path: /api
-    multipart:
-      max-file-size: 2000MB
-      max-request-size: 2000MB
   tomcat:
     max-swallow-size: 5000MB #重要的一行,修改tomcat的吞吐量
 

+ 5 - 0
data/pom.xml

@@ -95,6 +95,11 @@
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-redis</artifactId>
         </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>org.mapdb</groupId>-->
+        <!--            <artifactId>mapdb</artifactId>-->
+        <!--            <version>3.0.10</version>-->
+        <!--        </dependency>-->
     </dependencies>
 
 </project>

+ 56 - 0
data/src/main/java/com/dongzili/data/mapdb/JsonSerializer.java

@@ -0,0 +1,56 @@
+package com.dongzili.data.mapdb;//package com.kqns.dataservice.common.mapdb;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import org.jetbrains.annotations.NotNull;
+//import org.mapdb.DataInput2;
+//import org.mapdb.DataOutput2;
+//import org.mapdb.Serializer;
+//
+//import java.io.IOException;
+//
+///**
+// * 基于 Jackson ObjectMapper 的 MapDB 序列化器
+// * 支持任意对象的 JSON 序列化/反序列化
+// */
+//public class JsonSerializer<T> implements Serializer<T> {
+//
+//    // 全局 ObjectMapper 实例(可配置序列化特性)
+//    private static final ObjectMapper objectMapper = new ObjectMapper();
+//
+//    // 目标对象的类型(用于反序列化时确定类型)
+//    private final Class<T> type;
+//
+//    public JsonSerializer(Class<T> type) {
+//        this.type = type;
+//    }
+//
+//    @Override
+//    public void serialize(@NotNull DataOutput2 out, @NotNull T value) throws IOException {
+//        // 序列化对象为 JSON 字节数组
+//        byte[] jsonBytes = objectMapper.writeValueAsBytes(value);
+//        // 先写入字节数组长度,再写入字节数组(便于反序列化时读取)
+//        out.writeInt(jsonBytes.length);
+//        out.write(jsonBytes);
+//    }
+//
+//    @Override
+//    public T deserialize(@NotNull DataInput2 in, int i) throws IOException {
+//        // 读取长度标记
+//        int length = in.readInt();
+//        if (length == -1) {
+//            // 对应 null 值
+//            return null;
+//        }
+//        // 读取 JSON 字节数组
+//        byte[] jsonBytes = new byte[length];
+//        in.readFully(jsonBytes);
+//        // 反序列化为目标类型对象
+//        return objectMapper.readValue(jsonBytes, type);
+//    }
+//
+//    @Override
+//    public int fixedSize() {
+//        // 非固定大小(返回 -1)
+//        return -1;
+//    }
+//}

+ 51 - 0
data/src/main/java/com/dongzili/data/mapdb/MapDBConfig.java

@@ -0,0 +1,51 @@
+package com.dongzili.data.mapdb;//package com.kqns.dataservice.common.mapdb;
+//
+//import com.kqns.dataservice.custom.user.entity.ApiAccessLog;
+//import org.mapdb.*;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.context.annotation.Scope;
+//
+//import java.util.concurrent.TimeUnit;
+//
+//@Configuration
+//public class MapDBConfig {
+//
+//    @Value("${mapdb.file-path:mapdb.db}")
+//    private String dbFilePath;
+//
+//    @Bean(destroyMethod = "close")
+//    public DB mapDB() {
+////        return DBMaker.fileDB(dbFilePath)
+////                .checksumHeaderBypass() // 绕过校验头问题(常见坑)
+////                .closeOnJvmShutdown()
+////                .fileChannelEnable() // 比mmap更稳定的方式
+////                .closeOnJvmShutdown() // JVM关闭时自动关闭
+////                .transactionEnable() // 启用事务
+////                .make();
+//        return DBMaker.fileDB(dbFilePath)
+//                .transactionEnable()
+//                .concurrencyScale(64) // 优化并发性能
+//                .make();
+//
+//    }
+//
+//    @Bean
+//    @Scope(value = "singleton") // 必须单例
+//    public HTreeMap<String, ApiAccessLog> dataMap(DB db) {
+//        return db.hashMap("dataMap")
+//                .keySerializer(Serializer.STRING)
+//                .valueSerializer(new JsonSerializer<>(ApiAccessLog.class))
+//                .expireAfterCreate(10, TimeUnit.MINUTES) // 基于创建时间过期
+//                .expireAfterUpdate(5, TimeUnit.MINUTES) // 基于最后更新时间过期
+//                .expireAfterGet(1, TimeUnit.MINUTES) // 基于最后访问时间过期
+//                .createOrOpen();
+//    }
+//
+//    @Bean
+//    public IndexTreeList<ApiAccessLog> dataList(DB db) {
+//        return db.indexTreeList("dataList", new JsonSerializer<>(ApiAccessLog.class)).createOrOpen();
+//    }
+//
+//}

+ 51 - 0
data/src/main/java/com/dongzili/data/mapdb/MapDBExample.java

@@ -0,0 +1,51 @@
+package com.dongzili.data.mapdb;//package com.kqns.dataservice.common.mapdb;
+//
+//import cn.hutool.core.lang.UUID;
+//import com.kqns.dataservice.custom.user.entity.ApiAccessLog;
+//import org.mapdb.DB;
+//import org.mapdb.DBMaker;
+//import org.mapdb.HTreeMap;
+//import org.mapdb.Serializer;
+//
+//import java.util.Map;
+//
+//public class MapDBExample {
+//    public static void main(String[] args) {
+//        // 创建一个新的基于内存的数据库实例
+////        DB db = DBMaker.memoryDB().make();
+//        DB db = DBMaker.fileDB("mapdb.db")
+//                .transactionEnable()
+//                .concurrencyScale(64) // 优化并发性能
+//                .make();
+//        ApiAccessLog log = new ApiAccessLog();
+//        log.setUniqueKey(UUID.fastUUID().toString(true));
+//        log.setTitle("test");
+//
+//        ApiAccessLog log2 = new ApiAccessLog();
+//        log2.setUniqueKey(UUID.fastUUID().toString(true));
+//        log2.setTitle("test2");
+//
+//        // 在数据库中创建一个名为 'myMap' 的HashMap
+//        HTreeMap<String, ApiAccessLog> myMap = db.hashMap("myMap").keySerializer(Serializer.STRING).valueSerializer(new JsonSerializer<>(ApiAccessLog.class)).createOrOpen();
+//
+//        try{
+//            myMap.put("key1", log);
+//        }catch (Exception e){
+//            System.out.println(e.getMessage());
+//            e.printStackTrace();
+//        }catch (Throwable e){
+//            System.out.println(e.getMessage());
+//            e.printStackTrace();
+//        }
+//        // 向Map中添加一些数据
+//
+//        myMap.put("key2", log2);
+//
+//        // 从Map中读取数据
+//        System.out.println("Value for key1: " + myMap.get("key1"));
+//        System.out.println("Value for key2: " + myMap.get("key2"));
+//
+//        // 关闭数据库连接
+//        db.close();
+//    }
+//}

+ 128 - 0
data/src/main/java/com/dongzili/data/mapdb/MapDbService.java

@@ -0,0 +1,128 @@
+package com.dongzili.data.mapdb;//package com.kqns.dataservice.common.mapdb;
+//
+//import com.kqns.dataservice.custom.user.entity.ApiAccessLog;
+//import lombok.RequiredArgsConstructor;
+//import org.mapdb.DB;
+//import org.mapdb.HTreeMap;
+//import org.mapdb.IndexTreeList;
+//import org.springframework.scheduling.annotation.Async;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.concurrent.locks.ReadWriteLock;
+//import java.util.concurrent.locks.ReentrantReadWriteLock;
+//
+//@Service
+//@RequiredArgsConstructor
+//public class MapDbService {
+//    private final DB db; // 直接注入DB对象
+//    private final HTreeMap<String, ApiAccessLog> dataMap;
+//    private final IndexTreeList<ApiAccessLog> dataList;
+//
+//    // 使用读写锁确保线程安全
+//    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
+//
+//    public void put(String key, ApiAccessLog value) {
+//        rwLock.writeLock().lock();
+//        try {
+//            dataMap.put(key, value);
+//            db.commit(); // 显式提交
+//        } catch (Exception e) {
+//            db.rollback(); // 回滚事务
+//            throw new RuntimeException("Transaction failed", e);
+//        } finally {
+//            rwLock.writeLock().unlock();
+//        }
+//    }
+//    public void batchUpdate(Map<String, ApiAccessLog> entries) {
+//        rwLock.writeLock().lock();
+//        try {
+//            dataMap.putAll(entries);
+//            db.commit(); // 提交事务
+//        } catch (Exception e) {
+//            db.rollback(); // 回滚事务
+//            throw new RuntimeException("Transaction failed", e);
+//        }finally {
+//            rwLock.writeLock().lock();
+//        }
+//    }
+//
+//    public Object get(String key) {
+//        rwLock.readLock().lock();
+//        try {
+//            return dataMap.get(key);
+//        } finally {
+//            rwLock.readLock().unlock();
+//        }
+//    }
+//
+//    @Async
+//    public void add(ApiAccessLog value){
+//        rwLock.writeLock().lock();
+//        try{
+//            dataList.add(value);
+//            db.commit(); // 提交事务
+//        }catch (Exception e){
+//            db.rollback(); // 回滚事务
+//            throw new RuntimeException("Transaction failed", e);
+//        } finally {
+//            rwLock.writeLock().unlock();
+//        }
+//    }
+//
+//    public void addBatch(List<ApiAccessLog> values){
+//        rwLock.writeLock().lock();
+//        try{
+//            dataList.addAll(values);
+//            db.commit(); // 提交事务
+//        }catch (Exception e){
+//            db.rollback(); // 回滚事务
+//            throw new RuntimeException("Transaction failed", e);
+//        } finally {
+//            rwLock.writeLock().unlock();
+//        }
+//    }
+//
+//    public List<ApiAccessLog> getAll(){
+//        rwLock.readLock().lock();
+//        try{
+//            List<ApiAccessLog> returnList = new ArrayList<>(dataList);
+//            dataList.clear();
+//            return returnList;
+//        } finally {
+//            rwLock.readLock().unlock();
+//        }
+//    }
+//
+//    public List<ApiAccessLog> getList(int from, int to){
+//        rwLock.readLock().lock();
+//        try{
+//            return dataList.subList(from, to);
+//        } finally {
+//            rwLock.readLock().unlock();
+//        }
+//    }
+//
+//    public List<ApiAccessLog> getList(int size){
+//        rwLock.readLock().lock();
+//        try{
+//            List<ApiAccessLog> list = dataList.subList(0, Math.min(size, dataList.size()));
+//            List<ApiAccessLog> returnList = new ArrayList<>(list);
+//            dataList.removeAll(list);
+//            return returnList;
+//        } finally {
+//            rwLock.readLock().unlock();
+//        }
+//    }
+//
+//
+//    @Scheduled(cron = "0/5 * * * * ?")
+//    public void doHandlerApiAccessLog(){
+//
+//        System.out.println("size: "+dataList.size());
+//    }
+//
+//}