文书档案管理系统随着数据量增长,本地磁盘IO将成为性能瓶颈。将非结构化数据(PDF、图片、OFD)剥离至对象存储是提升扩展性的第一步。这里选用MinIO,因为它兼容S3 API且支持分布式扩容。
直接使用Docker命令启动单节点模式,生产环境可通过增加节点实现分布式扩容。执行以下命令:
命令:
```bash
docker run -d \
-p 9000:9000 \
-p 9001:9001 \
--name minio \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=Strong@Pass123" \
-v /data/minio/data:/data \
minio/minio server /data --console-address ":9001"
```
在Spring Boot项目中引入MinIO Java SDK,实现文件上传服务的封装。
pom.xml依赖:
```xml
io.minio
minio
8.5.7
```
application.yml配置:
```yaml
minio:
endpoint: http://192.168.1.100:9000
accessKey: admin
secretKey: Strong@Pass123
bucketName: archives-files
```
上传工具类代码:
```java
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@Component
public class MinioUtil {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Value("${minio.bucketName}")
private String bucketName;
public String uploadFile(MultipartFile file) throws Exception {
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build());
return endpoint + "/" + bucketName + "/" + fileName;
}
}
```
档案查询频率远高于录入频率。通过ShardingSphere-JDBC实现MySQL读写分离,写操作走主库,读操作走从库,提升查询并发能力。
在pom.xml中添加ShardingSphere-JDBC依赖,版本选用5.x稳定版。
```xml
org.apache.shardingsphere
shardingsphere-jdbc-core-spring-boot-starter
5.4.1
mysql
mysql-connector-java
8.0.33
```
修改application.yml,配置数据源、负载均衡策略及路由规则。确保配置了主从两个数据源。

```yaml
spring:
shardingsphere:
datasource:
names: master,slave0
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.1.101:3306/archives_db?useSSL=false&serverTimezone=UTC
username: root
password: Root@123
slave0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.1.102:3306/archives_db?useSSL=false&serverTimezone=UTC
username: root
password: Root@123
rules:
readwrite-splitting:
data-sources:
readwrite_ds:
type: Static
props:
write-data-source-name: master
read-data-source-names: slave0
load-balancer-name: round_robin
load-balancers:
round_robin:
type: ROUND_ROBIN
props:
sql-show: true
```
档案录入后的OCR识别、全文索引构建、水印添加均为耗时操作。将这些操作异步化,通过消息队列解耦,可显著提升接口响应速度。
使用Docker快速启动RabbitMQ,并开启管理界面插件。
```bash
docker run -d --name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin@123 \
rabbitmq:3.12-management
```
配置交换机、队列及绑定关系,并编写消费者处理逻辑。
RabbitMQConfig.java:
```java
import org.springframework.amqp.core.;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
public static final String EXCHANGE = "archives.exchange";
public static final String QUEUE = "archives.ocr.queue";
public static final String ROUTING_KEY = "archives.ocr";
@Bean
public DirectExchange exchange() {
return new DirectExchange(EXCHANGE, true, false);
}
@Bean
public Queue queue() {
return new Queue(QUEUE, true);
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(exchange()).with(ROUTING_KEY);
}
}
```
OcrConsumer.java(消费者):
```java
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class OcrConsumer {
@RabbitListener(queues = RabbitMQConfig.QUEUE)
public void processOcr(String message) {
System.out.println("收到OCR任务,开始处理文件ID: " + message);
// 此处调用OCR引擎服务
try {
Thread.sleep(2000); // 模拟耗时处理
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("文件ID: " + message + " 处理完成");
}
}
```
单体应用难以维护。将系统拆分为API、Service、Common等模块,便于团队协作及功能扩展。
在父pom.xml中使用聚合子模块,并使用统一管理版本。
```xml
4.0.0
com.tech.expert
archives-parent
1.0.0
pom
archives-common
archives-api
archives-service
1.8
2.7.14
org.springframework.boot
spring-boot-starter-web
${spring-boot.version}
```
将应用打包为Docker镜像,配合Kubernetes或Docker Compose可实现秒级扩容。
在项目根目录创建Dockerfile,利用多阶段构建减小镜像体积。
```dockerfile
第一阶段:构建
FROM maven:3.8.6-openjdk-8-slim AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
第二阶段:运行
FROM openjdk:8-jre-alpine
WORKDIR /app
时区设置
RUN apk add --no-cache tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build /app/target/archives-service-1.0.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
```
构建并运行镜像的命令如下:
```bash
构建镜像
docker build -t archives-system:1.0.0 .
运行容器
docker run -d -p 8080:8080 --name archives-app archives-system:1.0.0
```