Enable configuration caching with separate names (#4151)

#### What type of PR is this?

/kind feature
/area core
/milestone 2.7.x

#### What this PR does / why we need it:

Refactor configuration properties to configure caching with separate names, so that we can enable / disable cache with name.

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/4144

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/4153/head
John Niang 2023-06-29 15:02:11 +08:00 committed by GitHub
parent baba8b9d24
commit 0d387eddf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 15 deletions

View File

@ -30,15 +30,15 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Slf4j
public class CacheWebFilter implements WebFilter, Ordered {
public class PageCacheWebFilter implements WebFilter, Ordered {
public static final String REQUEST_TO_CACHE = "RequestCacheWebFilterToCache";
public static final String CACHE_NAME = "page-cache";
public static final String CACHE_NAME = "page";
private final Cache cache;
public CacheWebFilter(CacheManager cacheManager) {
public PageCacheWebFilter(CacheManager cacheManager) {
this.cache = cacheManager.getCache(CACHE_NAME);
}

View File

@ -6,15 +6,15 @@ import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.WebFilter;
import run.halo.app.cache.CacheWebFilter;
import run.halo.app.cache.PageCacheWebFilter;
@EnableCaching
@Configuration
public class CacheConfiguration {
@Bean
@ConditionalOnProperty(name = "halo.cache.disabled", havingValue = "false")
WebFilter cacheWebFilter(CacheManager cacheManager) {
return new CacheWebFilter(cacheManager);
@ConditionalOnProperty(name = "halo.cache.page.disabled", havingValue = "false")
WebFilter pageCacheWebFilter(CacheManager cacheManager) {
return new PageCacheWebFilter(cacheManager);
}
}

View File

@ -5,6 +5,6 @@ import lombok.Data;
@Data
public class CacheProperties {
private boolean disabled = true;
private boolean disabled;
}

View File

@ -5,6 +5,8 @@ import jakarta.validation.constraints.NotNull;
import java.net.URL;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -59,7 +61,7 @@ public class HaloProperties implements Validator {
private final AttachmentProperties attachment = new AttachmentProperties();
@Valid
private final CacheProperties cache = new CacheProperties();
private final Map<String, CacheProperties> caches = new LinkedHashMap<>();
@Override
public boolean supports(Class<?> clazz) {

View File

@ -15,7 +15,7 @@ import org.thymeleaf.spring6.view.reactive.ThymeleafReactiveView;
import org.thymeleaf.spring6.view.reactive.ThymeleafReactiveViewResolver;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.app.cache.CacheWebFilter;
import run.halo.app.cache.PageCacheWebFilter;
import run.halo.app.theme.finders.FinderRegistry;
@Component("thymeleafReactiveViewResolver")
@ -53,7 +53,7 @@ public class HaloViewResolver extends ThymeleafReactiveViewResolver {
return themeResolver.getTheme(exchange).flatMap(theme -> {
// calculate the engine before rendering
setTemplateEngine(engineManager.getTemplateEngine(theme));
exchange.getAttributes().put(CacheWebFilter.REQUEST_TO_CACHE, true);
exchange.getAttributes().put(PageCacheWebFilter.REQUEST_TO_CACHE, true);
return super.render(model, contentType, exchange);
});
}

View File

@ -33,6 +33,10 @@ spring:
spec: expireAfterAccess=1h, maximumSize=10000
halo:
caches:
page:
# Disable page cache by default due to experimental feature
disabled: true
work-dir: ${user.home}/.halo2
plugin:
plugins-root: ${halo.work-dir}/plugins

View File

@ -173,7 +173,7 @@ const actions: Action[] = [
confirmText: t("core.common.buttons.confirm"),
cancelText: t("core.common.buttons.cancel"),
onConfirm: async () => {
await apiClient.cache.invalidCache({ name: "page-cache" });
await apiClient.cache.invalidCache({ name: "page" });
Toast.success(
t(
"core.dashboard.widgets.presets.quicklink.actions.refresh_page_cache.success_message"

27
docs/cache/page.md vendored
View File

@ -1,6 +1,21 @@
# 页面缓存
# 缓存
Halo 的主要应用以博客为主,页面更新不会特别频繁,大多数情况下,实时渲染的结果都是没有变化的。如果能够缓存这些不经常变更的页面,可减少数据库访问,加快访问速度。
缓存在各个领域用得非常广泛,例如 CPU 的三级缓存可加速从主内存中获取数据到处理器。Halo 的主要应用以博客为主,页面更新不会特别频繁,大多数情况下,实时渲染的结果都是没有变化的。如果能够缓存这些不经常变更的页面,可减少数据库访问,加快访问速度。
Halo 采用由 Spring 框架提供的 Caching 作为缓存框架。该缓存框架面对各种缓存实现,提供了统一的访问入口,后续更换缓存仅需修改少量代码和配置。
Halo 默认提供了 CacheProperties 用于启用/禁用缓存,示例如下:
```yaml
halo:
caches:
page:
disabled: true
others:
disabled: false
```
# 页面缓存
页面缓存包括缓存响应体、响应头和响应状态。页面缓存规则如下:
@ -9,4 +24,10 @@ Halo 的主要应用以博客为主,页面更新不会特别频繁,大多数
3. 仅缓存响应状态为 `HTTP 200OK`
4. 请求访问为 `GET`
默认缓存失效时间:距最新一次访问 `1` 小时。 默认最大缓存数量:`10,000` 个
缓存详情见下表:
| 术语 | 值 |
|------|----------------|
| 名称 | `page` |
| 失效时间 | 距最近一次访问 `1` 小时 |
| 缓存数量 | `10,000` 个 |