这个基于Java SpringBoot+Vue3+MyBatis的在线文档管理系统,是我在2022年为一个中型企业知识管理项目开发的解决方案。当时客户需要替代他们使用了8年的老旧文档服务器,核心诉求是:支持200人同时在线协作、文档版本可追溯、权限控制到文件夹级别。经过技术评估,最终选择了这套技术栈,上线后文档处理效率提升了60%,运维成本降低了75%。
前后端分离架构让我们的团队可以并行开发——后端专注业务逻辑和数据处理,前端团队则能独立优化用户体验。MySQL作为关系型数据库保证了事务一致性,而MyBatis的灵活映射则完美适配了客户复杂的文档元数据结构。这个系统现在每天处理超过3000份文档的创建、编辑和审批流程。
SpringBoot 2.7的选择经过了严格测试对比。我们曾用2.5版本开发原型,但在高并发文档锁定时出现了线程阻塞。升级到2.7后,结合HikariCP连接池配置(最大连接数=CPU核心数*2 + 30),成功支撑住了早高峰300+的并发文档保存请求。
关键配置示例(application.yml节选):
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 50
connection-timeout: 30000
idle-timeout: 600000
servlet:
multipart:
max-file-size: 50MB
max-request-size: 100MB
重要提示:文档系统必须合理设置文件大小限制。我们曾遇到用户上传3D设计文档导致内存溢出,最终确定50MB是兼顾业务需求和系统稳定的平衡点。
最初考虑过Vue2+ElementUI方案,但在实现实时协同编辑时遇到性能瓶颈。切换到Vue3的组合式API+Pinia状态管理后,相同硬件条件下协同编辑响应时间从1200ms降至400ms。特别值得分享的是利用Vue3的Teleport组件实现的全局通知系统:
javascript复制// 协同编辑冲突提示组件
const showConflictAlert = (msg) => {
teleportToaster.value = h(ElNotification, {
title: '编辑冲突',
message: msg,
type: 'warning',
duration: 0,
showClose: true
})
}
文档系统的数据库设计有三大挑战:版本控制、权限继承、全文检索。我们的解决方案是:
sql复制CREATE TABLE doc_versions (
version_id BIGINT PRIMARY KEY,
doc_id BIGINT NOT NULL,
content LONGTEXT,
created_at DATETIME(6),
INDEX idx_doc (doc_id)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
sql复制CREATE TABLE folder_closure (
ancestor BIGINT NOT NULL,
descendant BIGINT NOT NULL,
depth INT NOT NULL,
PRIMARY KEY (ancestor, descendant)
);
采用Operational Transformation算法实现多人协同,关键点在于:
实测数据:20人同时编辑5万字文档时,网络带宽消耗约1.2Mbps,服务端CPU负载35%(4核8G配置)
不同于Git的完整版本控制,我们做了业务适配:
存储优化技巧:对.docx文件采用Delta编码后,版本存储空间减少78%
RBAC(基于角色的访问控制)结合ABAC(基于属性的访问控制)的混合模型:
权限检查代码示例:
java复制@PreAuthorize("hasPermission(#docId, 'DOCUMENT', 'EDIT')")
public Document saveDocument(Long docId, DocumentContent content) {
// 保存逻辑
}
javascript复制const Editor = defineAsyncComponent(() =>
import('monaco-editor').then(mod => mod.editor)
)
虚拟滚动处理长文档目录(实测5000项目录,渲染时间从12s→0.8s)
Service Worker缓存静态资源,首屏加载时间降低40%
xml复制<!-- 必须设置flushInterval防止内存泄漏 -->
<cache eviction="LRU" flushInterval="1800000" size="1024"/>
java复制@Bean
public CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager();
manager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES));
return manager;
}
sql复制ALTER TABLE doc_contents ROW_FORMAT=COMPRESSED;
sql复制CREATE INDEX idx_doc_search ON documents
(title, status, create_time)
INCLUDE (doc_id, creator_id);
Docker Compose编排文件关键配置:
yaml复制services:
app:
image: openjdk:17-jdk
deploy:
resources:
limits:
cpus: '2'
memory: 4G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
mysql:
image: mysql:8.0
command: --innodb_buffer_pool_size=1G
--innodb_log_file_size=256M
运维经验:MySQL的innodb_buffer_pool_size应设置为可用内存的70-80%,我们曾因默认配置导致磁盘IO过高。
xml复制<!-- logback.xml配置 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
java复制public String generateDownloadToken(Long fileId) {
return HmacUtils.hmacSha256Hex(secretKey,
fileId + "|" + System.currentTimeMillis());
}
sql复制CREATE TABLE security_audit (
id BIGINT AUTO_INCREMENT,
user_id BIGINT,
action VARCHAR(50),
target_id VARCHAR(100),
ip_address VARCHAR(45),
created_at TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=InnoDB;
现象:多人同时编辑未触发锁定机制
排查过程:
修复代码:
java复制public boolean tryLockDocument(Long docId) {
try {
return zooKeeperClient
.create()
.withMode(CreateMode.EPHEMERAL)
.forPath("/locks/docs/" + docId);
} catch (Exception e) {
log.error("获取锁失败", e);
return false;
}
}
现象:上传100MB+文件时服务崩溃
解决方案:
nginx复制location /api/upload {
client_max_body_size 100m;
proxy_request_buffering off;
proxy_pass http://backend;
}
错误日志:HikariPool-1 - Connection is not available
优化措施:
java复制@Bean
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
config.setLeakDetectionThreshold(30000);
return config;
}
这套系统经过一年多的生产环境验证后,我们正在三个方向进行增强:
特别分享一个性能数据:在华为云C6s(4核8G)的标准实例上,当前系统可以稳定支持:
所有功能模块都经过JMeter压力测试,确保在峰值负载下仍能保持服务可用性。对于想要自建文档系统的团队,建议从最小可行产品开始,优先实现核心的文档存储、版本管理和权限控制,再逐步扩展高级功能。