运用 Freemarker 模板引擎为文章生成静态文件,将文件存放在分布式文件系统 MinIO 中,以及 Non-XML response from server问题的解决
描述:
前端传输数据给服务端,服务端保存数据库后将数据渲染到freemark文件内,生成静态文件html文件,将静态文件保存到minio中,将对应的静态文件的minio中地址保存到数据库中,来访问这个博客文章
遇到的问题(Non-XML response from server问题)
yml配置
要记住新版本minio和老版本一点也不同!!!尤其是yml相关配置~~~去看注释!!!!
老版本配置教程
首先docker拉取镜像
1
docker pull minio/minio:RELEASE.2021-06-17T00-10-46Z
构建容器
1
2
3
4
5
6docker run -p 9000:9000 --name minio -di --restart=always \
-e "MINIO_ROOT_USER=minio" \
-e "MINIO_ROOT_PASSWORD=minio@123" \
-v /usr/local/minio/data:/data \
-v /usr/local/minio/config:/root/.minio \
minio/minio:RELEASE.2021-06-17T00-10-46Z server /data访问 ip + 端口号
思路实现
引入依赖
1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>yml配置
1
2
3
4
5minio:
accessKey: minio
secretKey: minio@123
bucket: articles #老版本是登录账号和密码 新版本这俩是service account生成的,不是登录账号和密码
endpoint: http://8.130.97.224:9000 #老版本是访问地址 新版本注意是api地址,不是访问网址前端发送请求
1
2
3
4
5
6
7{
"id": 1,
"title": "123",
"content": "dada",
"author": "kzy",
"url": ""
}后端接收请求
1 |
|
创建模板文件
1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
<title>${article.title}</title>
</head>
<body>
<h1>${article.title}</h1>
<p>${article.content}</p>
<footer>Written by ${article.author}</footer>
</body>
</html>渲染文件和保存到minio中
1 |
|
修改和删除
采用的是删除minio中文件的文件和数据库中的url,并生成新的保存
疑问
删除比较快,但是更新比较慢,那已经删除了,那用户怎么访问到数据呢?
遇到更新操作比删除操作慢,并且担心在更新过程中旧文件被删除后新文件还未生成时,用户可能会访问到不存在的文件,这确实是一个需要考虑的问题。以下是一些策略来解决这个问题:
1. 使用版本控制
MinIO支持对象版本控制,开启版本控制后,删除操作实际上不会立即删除文件,而是将其标记为删除,同时保留历史版本。这样,在新文件生成之前,用户仍然可以访问到旧版本的文件。
2. 临时重定向
在删除旧文件后,可以设置一个临时的重定向机制,将用户请求重定向到一个占位页面或一个加载状态,直到新文件生成并上传成功。
3. 原子操作
确保更新操作的原子性,即要么完全更新成功,要么完全不更新。这通常涉及到事务管理或使用数据库和文件存储的原子操作。
4. 异步处理
将更新操作异步化,首先删除旧文件,然后立即返回成功响应给用户,后台异步生成新文件并上传到MinIO。在新文件生成之前,可以使用缓存或临时文件来处理用户请求。
5. 预生成静态文件
在更新数据库文章内容的同时,预生成新的静态文件并保存在临时位置。在确认新文件已经生成并上传成功后,再删除旧文件。
6. 使用锁机制
在更新过程中,使用锁机制来防止并发访问。当一个文件正在被更新时,其他请求会被阻塞或重定向,直到更新完成。
7. 设置合理的缓存策略
设置MinIO的缓存策略,使得即使文件被删除,用户在短时间内仍然可以从缓存中获取到内容。
8. 使用状态标记
在数据库中为文章设置一个状态标记,如pending_update
,在更新过程中将状态设置为pending_update
,前端根据状态决定是否显示加载提示或重定向。
例子:异步处理
1 | // 更新文章的方法,异步生成和上传新文件 使用缓存和临时文件来访问 |