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; import reactor.core.publisher.Mono;
@Slf4j @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 REQUEST_TO_CACHE = "RequestCacheWebFilterToCache";
public static final String CACHE_NAME = "page-cache"; public static final String CACHE_NAME = "page";
private final Cache cache; private final Cache cache;
public CacheWebFilter(CacheManager cacheManager) { public PageCacheWebFilter(CacheManager cacheManager) {
this.cache = cacheManager.getCache(CACHE_NAME); 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilter;
import run.halo.app.cache.CacheWebFilter; import run.halo.app.cache.PageCacheWebFilter;
@EnableCaching @EnableCaching
@Configuration @Configuration
public class CacheConfiguration { public class CacheConfiguration {
@Bean @Bean
@ConditionalOnProperty(name = "halo.cache.disabled", havingValue = "false") @ConditionalOnProperty(name = "halo.cache.page.disabled", havingValue = "false")
WebFilter cacheWebFilter(CacheManager cacheManager) { WebFilter pageCacheWebFilter(CacheManager cacheManager) {
return new CacheWebFilter(cacheManager); return new PageCacheWebFilter(cacheManager);
} }
} }

View File

@ -5,6 +5,6 @@ import lombok.Data;
@Data @Data
public class CacheProperties { 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.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -59,7 +61,7 @@ public class HaloProperties implements Validator {
private final AttachmentProperties attachment = new AttachmentProperties(); private final AttachmentProperties attachment = new AttachmentProperties();
@Valid @Valid
private final CacheProperties cache = new CacheProperties(); private final Map<String, CacheProperties> caches = new LinkedHashMap<>();
@Override @Override
public boolean supports(Class<?> clazz) { 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 org.thymeleaf.spring6.view.reactive.ThymeleafReactiveViewResolver;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import run.halo.app.cache.CacheWebFilter; import run.halo.app.cache.PageCacheWebFilter;
import run.halo.app.theme.finders.FinderRegistry; import run.halo.app.theme.finders.FinderRegistry;
@Component("thymeleafReactiveViewResolver") @Component("thymeleafReactiveViewResolver")
@ -53,7 +53,7 @@ public class HaloViewResolver extends ThymeleafReactiveViewResolver {
return themeResolver.getTheme(exchange).flatMap(theme -> { return themeResolver.getTheme(exchange).flatMap(theme -> {
// calculate the engine before rendering // calculate the engine before rendering
setTemplateEngine(engineManager.getTemplateEngine(theme)); 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); return super.render(model, contentType, exchange);
}); });
} }

View File

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

View File

@ -173,7 +173,7 @@ const actions: Action[] = [
confirmText: t("core.common.buttons.confirm"), confirmText: t("core.common.buttons.confirm"),
cancelText: t("core.common.buttons.cancel"), cancelText: t("core.common.buttons.cancel"),
onConfirm: async () => { onConfirm: async () => {
await apiClient.cache.invalidCache({ name: "page-cache" }); await apiClient.cache.invalidCache({ name: "page" });
Toast.success( Toast.success(
t( t(
"core.dashboard.widgets.presets.quicklink.actions.refresh_page_cache.success_message" "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` 3. 仅缓存响应状态为 `HTTP 200OK`
4. 请求访问为 `GET` 4. 请求访问为 `GET`
默认缓存失效时间:距最新一次访问 `1` 小时。 默认最大缓存数量:`10,000` 个 缓存详情见下表:
| 术语 | 值 |
|------|----------------|
| 名称 | `page` |
| 失效时间 | 距最近一次访问 `1` 小时 |
| 缓存数量 | `10,000` 个 |