⚠️ 注意

此版本由于升级了 SpringBoot 的版本并依赖了新的 H2 Database 版本,经过我们测试无法正常从旧版本 Halo 升级。所以如果你当前正在使用 H2 作为数据库,可能需要使用系统的备份恢复功能进行重新安装。

此外,不建议在生产环境使用 H2 作为数据库。

Halo 是一款强大易用的开源建站工具,它让你无需太多的技术知识就可以快速搭建一个博客、网站或者内容管理系统。具备可插拔架构、主题套用、富文本编辑器等多重特性,支持用户根据自己的喜好选择不同类型的插件及主题模板来定制化自己的站点功能及外观。让内容创作和发布更加便捷生动。

截至目前(2023 年 Q3 季度),Halo 已经在 Docker Hub 获得了超过 170 万次下载,GitHub Star 数突破 28 k,并拥有一百多名社区贡献者。

2023 年 12 月 01 日,强大易用的开源建站工具 Halo 正式发布 2.11.0 版本。

在这个版本中,Halo 主要支持了个人中心功能,以及其他 50 多项功能优化和问题修复。

亮点更新

个人中心

此版本全新加入了个人中心功能,并将所有和用户自身有关的功能移动到了个人中心,包括基本信息设置、消息通知等。此外,个人中心还支持管理自己的文章,管理员也可以根据自身的需求选择用户是否可以管理自己的文章。

有了个人中心之后,后续还可以通过插件为网站用户扩展出更多的功能,用于满足各式各样的网站需求。

个人中心页面:

2.11-uc-profile.png

我的文章页面:

2.11-uc-posts.png

优化内存占用

在这个版本我们使用 OpenJ9 作为基础镜像,可以显著的优化内存占用,经过测试,大约可以减少 20% - 30% 的内存消耗,以下是我们演示网站的内存占用对比。

2.102.11
compare-memory-2.10.pngcompare-memory-2.11.png

邮箱验证和密码重置

从 Halo 2.10 开始,我们支持了可配置的消息通知功能。在这个版本中,我们基于此完善了用户的邮箱验证和密码重置功能。

邮箱验证:

2.11-verify-email.png

密码重置:

2.11-send-reset-password-link.png

2.11-reset-password.png

完整更新日志

新特性

功能优化

问题修复

依赖更新

开发者相关

Docker升级失败
原版本:2.10
目标版本:2.11

原docker命令:

docker run -it -d --name halo \
-p 8090:8090 \
-e "spring.r2dbc.url=r2dbc:mysql://xxxx:3306/halo_blog" \
-e "spring.r2dbc.username=" \
-e "spring.r2dbc.password=" \
-e "spring.sql.init.platform=mysql" \
-v /www/wwwroot/xxx/data:/root/.halo2 \
halohub/halo:2.10

新docker命令:

docker run -it -d --name halo \
-p 8090:8090 \
-e "spring.r2dbc.url=r2dbc:mysql://xxxx:3306/halo_blog" \
-e "spring.r2dbc.username=" \
-e "spring.r2dbc.password=" \
-e "spring.sql.init.platform=mysql" \
-v /www/wwwroot/xxx/data:/root/.halo2 \
halohub/halo:2.11

错误日志

[34m
    __  __      __
   / / / /___ _/ /___
  / /_/ / __ `/ / __ \
 / __  / /_/ / / /_/ /
/_/ /_/\__,_/_/\____/
[93m
Version: 2.11.0[39m
[2m2023-12-01T16:34:19.405+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mrun.halo.app.Application                [0;39m [2m:[0;39m Starting Application v2.11.0 using Java 17.0.9 with PID 7 (/application/BOOT-INF/classes started by root in /application)
[2m2023-12-01T16:34:19.412+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mrun.halo.app.Application                [0;39m [2m:[0;39m No active profile set, falling back to 1 default profile: "default"
[2m2023-12-01T16:34:20.049+08:00[0;39m [33m WARN[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mo.s.c.a.AnnotationBeanNameGenerator     [0;39m [2m:[0;39m Support for convention-based stereotype names is deprecated and will be removed in a future version of the framework. Please annotate the 'value' attribute in @run.halo.app.theme.finders.Finder with @AliasFor(annotation=Component.class) to declare an explicit alias for @Component's 'value' attribute.
[2m2023-12-01T16:34:21.885+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Multiple Spring Data modules found, entering strict repository configuration mode
[2m2023-12-01T16:34:21.888+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
[2m2023-12-01T16:34:22.116+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36m.s.d.r.c.RepositoryConfigurationDelegate[0;39m [2m:[0;39m Finished Spring Data repository scanning in 213 ms. Found 1 R2DBC repository interface.
[2m2023-12-01T16:34:26.400+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36morg.pf4j.DefaultPluginStatusProvider    [0;39m [2m:[0;39m Enabled plugins: []
[2m2023-12-01T16:34:26.402+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36morg.pf4j.DefaultPluginStatusProvider    [0;39m [2m:[0;39m Disabled plugins: []
[2m2023-12-01T16:34:26.405+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36morg.pf4j.DefaultPluginManager           [0;39m [2m:[0;39m PF4J version 3.10.0 in 'deployment' mode
[2m2023-12-01T16:34:30.593+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mo.s.b.a.e.web.EndpointLinksResolver     [0;39m [2m:[0;39m Exposing 30 endpoint(s) beneath base path '/actuator'
[2m2023-12-01T16:34:31.454+08:00[0;39m [33m WARN[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36monfigReactiveWebServerApplicationContext[0;39m [2m:[0;39m Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'r2dbcScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.class]: Failed to execute database script
[2m2023-12-01T16:34:31.467+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mr.h.a.e.c.DefaultControllerManager      [0;39m [2m:[0;39m Shutting down 0 controllers...
[2m2023-12-01T16:34:31.468+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mr.h.a.e.c.DefaultControllerManager      [0;39m [2m:[0;39m Shutdown 0 controllers.
[2m2023-12-01T16:34:31.470+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mr.h.a.e.controller.DefaultController    [0;39m [2m:[0;39m Disposing controller garbage-collector-controller
[2m2023-12-01T16:34:31.471+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mr.h.a.e.controller.DefaultController    [0;39m [2m:[0;39m Controller garbage-collector-controller is disposed
[2m2023-12-01T16:34:31.565+08:00[0;39m [32m INFO[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36m.s.b.a.l.ConditionEvaluationReportLogger[0;39m [2m:[0;39m 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
[2m2023-12-01T16:34:31.587+08:00[0;39m [31mERROR[0;39m [35m7[0;39m [2m---[0;39m [2m[           main][0;39m [2m[0;39m[36mo.s.boot.SpringApplication              [0;39m [2m:[0;39m Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'r2dbcScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.class]: Failed to execute database script
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1775) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.1.1.jar:6.1.1]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:946) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616) ~[spring-context-6.1.1.jar:6.1.1]
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-3.2.0.jar:3.2.0]
	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149) ~[spring-boot-3.2.0.jar:3.2.0]
	at run.halo.app.Application.main(Application.java:28) ~[classes/:2.11.0]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[application/:na]
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[application/:na]
	at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[application/:na]
Caused by: org.springframework.r2dbc.connection.init.UncategorizedScriptException: Failed to execute database script
	at org.springframework.r2dbc.connection.init.DatabasePopulator.lambda$populate$4(DatabasePopulator.java:65) ~[spring-r2dbc-6.1.1.jar:6.1.1]
	at reactor.core.publisher.Mono.lambda$onErrorMap$27(Mono.java:3785) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.Mono.lambda$onErrorResume$29(Mono.java:3875) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoUsingWhen$ResourceSubscriber.onError(MonoUsingWhen.java:204) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.Operators.error(Operators.java:198) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4512) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxRetry$RetrySubscriber.onError(FluxRetry.java:96) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.pool.AbstractPool$Borrower.fail(AbstractPool.java:475) ~[reactor-pool-1.0.3.jar:1.0.3]
	at reactor.pool.SimpleDequePool.lambda$drainLoop$9(SimpleDequePool.java:433) ~[reactor-pool-1.0.3.jar:1.0.3]
	at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onError(FluxDoOnEach.java:186) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.onError(MonoSubscribeOn.java:152) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:142) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSupplier$MonoSupplierSubscription.request(MonoSupplier.java:134) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.trySchedule(MonoSubscribeOn.java:189) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.onSubscribe(MonoSubscribeOn.java:134) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSupplier.subscribe(MonoSupplier.java:48) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4512) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:126) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.6.0.jar:3.6.0]
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source) ~[na:na]
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na]
	at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
	Suppressed: java.lang.Exception: #block terminated with an error
		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:103) ~[reactor-core-3.6.0.jar:3.6.0]
		at reactor.core.publisher.Mono.block(Mono.java:1728) ~[reactor-core-3.6.0.jar:3.6.0]
		at org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer.runScripts(R2dbcScriptDatabaseInitializer.java:68) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer.runScripts(AbstractScriptDatabaseInitializer.java:146) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer.applyScripts(AbstractScriptDatabaseInitializer.java:108) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer.applySchemaScripts(AbstractScriptDatabaseInitializer.java:98) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer.initializeDatabase(AbstractScriptDatabaseInitializer.java:76) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer.afterPropertiesSet(AbstractScriptDatabaseInitializer.java:66) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1822) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.1.1.jar:6.1.1]
		at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:946) ~[spring-context-6.1.1.jar:6.1.1]
		at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616) ~[spring-context-6.1.1.jar:6.1.1]
		at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-3.2.0.jar:3.2.0]
		at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:149) ~[spring-boot-3.2.0.jar:3.2.0]
		at run.halo.app.Application.main(Application.java:28) ~[classes/:2.11.0]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
		at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
		at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[application/:na]
		at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[application/:na]
		at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[application/:na]
Caused by: org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection
	at org.springframework.r2dbc.connection.ConnectionFactoryUtils.lambda$getConnection$0(ConnectionFactoryUtils.java:100) ~[spring-r2dbc-6.1.1.jar:6.1.1]
	at reactor.core.publisher.Mono.lambda$onErrorMap$28(Mono.java:3799) ~[reactor-core-3.6.0.jar:3.6.0]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94) ~[reactor-core-3.6.0.jar:3.6.0]
	... 23 common frames omitted
Caused by: io.r2dbc.spi.R2dbcNonTransientResourceException: Unsupported database file version or invalid file header in file "/root/.halo2/db/halo-next.mv.db" [90048-224]
	at io.r2dbc.h2.H2DatabaseExceptionFactory.convert(H2DatabaseExceptionFactory.java:76) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
	at io.r2dbc.h2.H2ConnectionFactory.getSessionClient(H2ConnectionFactory.java:119) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
	at io.r2dbc.h2.H2ConnectionFactory.lambda$new$0(H2ConnectionFactory.java:53) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
	at reactor.core.publisher.MonoSupplier$MonoSupplierSubscription.request(MonoSupplier.java:126) ~[reactor-core-3.6.0.jar:3.6.0]
	... 14 common frames omitted
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Unsupported database file version or invalid file header in file "/root/.halo2/db/halo-next.mv.db" [90048-224]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:690) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.message.DbException.get(DbException.java:212) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.db.Store.convertMVStoreException(Store.java:158) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.db.Store.<init>(Store.java:142) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.engine.Database.<init>(Database.java:326) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.engine.Engine.openSession(Engine.java:92) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.engine.Engine.openSession(Engine.java:222) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.engine.Engine.createSession(Engine.java:201) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) ~[h2-2.2.224.jar:2.2.224]
	at io.r2dbc.h2.client.SessionClient.<init>(SessionClient.java:58) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
	at io.r2dbc.h2.H2ConnectionFactory.getSessionClient(H2ConnectionFactory.java:117) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
	... 16 common frames omitted
Caused by: org.h2.mvstore.MVStoreException: The write format 2 is smaller than the supported format 3 [2.2.224/5]
	at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.FileStore.getUnsupportedWriteFormatException(FileStore.java:943) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.FileStore.processCommonHeaderAttributes(FileStore.java:547) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.RandomAccessStore.readStoreHeader(RandomAccessStore.java:227) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.FileStore.start(FileStore.java:916) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.MVStore.<init>(MVStore.java:289) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035) ~[h2-2.2.224.jar:2.2.224]
	at org.h2.mvstore.db.Store.<init>(Store.java:133) ~[h2-2.2.224.jar:2.2.224]
	... 23 common frames omitted

    cr-zhichen

    此版本由于升级了 SpringBoot 的版本并依赖了新的 H2 Database 版本,经过我们测试无法正常从旧版本 Halo 升级。所以如果你当前正在使用 H2 作为数据库,可能需要使用系统的备份恢复功能进行重新安装。

    此外,不建议在生产环境使用 H2 作为数据库。

    PS:已经在最开头添加了提示

      大佬,我咨询了一个1panel的问题,能帮我回答一夏吗 感谢

      体验了一把个人中心,感觉上还有有不足之处的。可能先前2.0做权限设计的时候,没有考虑到多用户的情况。或者说多用户都是一个人的情况下,这就导致了不管什么用户都能管理整个网站的功能,而当前的权限只是做了:要么能做,要么不能做的限制。并没有针对不同用户可以管理自己的东西,比如说附件等具有私有属性的功能。而一些分类、标签这些倒是允许用户自行添加。

      1. 其他用户无法管理自己的附件
      2. 可以看到一些插件功能,比如导出导出那个插件。
      3. 个人中心感觉有点过于设计了,跳转到类似后台那样的界面,其实就论坛这个个人中心设计就挺不错的,就一个轻量页面。

        huasio 其他用户无法管理自己的附件

        这个后续可以加,并不是一个版本就要把所有东西都做的非常完美。并且目前考虑到即便是多用户,主要针对的还是同一个网站,并不是常见的那种 CSDN 之类的平台,区分不同的用户只是为了维护同一个网站。

        huasio 可以看到一些插件功能,比如导出导出那个插件。

        插件的问题,没有提供权限配置,目前你可以在角色配置里禁止访问 Console,那么这个用户就只能访问到个人中心。

        huasio 个人中心感觉有点过于设计了,跳转到类似后台那样的界面,其实就论坛这个个人中心设计就挺不错的,就一个轻量页面。

        恰恰相反,目前因为时间问题而沿用了 Console 的设计,但做了物理上的区分。后续会对个人中心做不同的 UI 和一些针对用户的个性化配置。

        Jason' 你说的是刚部署完那会吧,起来之后cpu就降下去了,稳定到2%左右,内存确实也优化了不少,现在基本上在400M,挺不错了

        发布文章后,搜索并搜索不到内容:

        更新完成后,网站504了,打不开怎么解决!!

        过个周末就这样了,现在改为halo 2.11,还是不行,请问具体怎么解决呢
        Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
        2023-12-04T13:38:19.394+08:00 WARN 7 --- [tor-tcp-epoll-4] i.a.r.mysql.client.ReactorNettyClient : Connection unexpectedly closed
        2023-12-04T13:38:19.405+08:00 ERROR 7 --- [ main] o.s.boot.SpringApplication : Application run failed

        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'r2dbcScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.class]: Failed to execute database script
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1775) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.1.1.jar:6.1.1]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.1.1.jar:6.1.1]

          Ryan Wang 👍 大佬,我已经发了“反馈和建议”,里面写全了代码和日志,麻烦抽空看一下

          使用H1到H6标题里,微软输入法莫名奇妙多出很多字符。类似这样
          ddidiedi'erdi'er'zdi'er'zhdi'er'zhodi'er'zhondi'er'zhong第二种
          开始以为输入法问题,在别的软件都没问题,用正常的文本,或者代码块里也没这个问题。就是在使用H1到H6输入标题的时候存在。重装输入法不管用啊

          Caused by: org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection
          at org.springframework.r2dbc.connection.ConnectionFactoryUtils.lambda$getConnection$0(ConnectionFactoryUtils.java:100) ~[spring-r2dbc-6.1.1.jar:6.1.1]
          at reactor.core.publisher.Mono.lambda$onErrorMap$28(Mono.java:3799) ~[reactor-core-3.6.0.jar:3.6.0]
          at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94) ~[reactor-core-3.6.0.jar:3.6.0]
          ... 23 common frames omitted
          Caused by: io.r2dbc.spi.R2dbcNonTransientResourceException: Unsupported database file version or invalid file header in file "/root/.halo2/db/halo-next.mv.db" [90048-224]
          at io.r2dbc.h2.H2DatabaseExceptionFactory.convert(H2DatabaseExceptionFactory.java:76) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
          at io.r2dbc.h2.H2ConnectionFactory.getSessionClient(H2ConnectionFactory.java:119) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
          at io.r2dbc.h2.H2ConnectionFactory.lambda$new$0(H2ConnectionFactory.java:53) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
          at reactor.core.publisher.MonoSupplier$MonoSupplierSubscription.request(MonoSupplier.java:126) ~[reactor-core-3.6.0.jar:3.6.0]
          ... 14 common frames omitted
          Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Unsupported database file version or invalid file header in file "/root/.halo2/db/halo-next.mv.db" [90048-224]
          at org.h2.message.DbException.getJdbcSQLException(DbException.java:690) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.message.DbException.get(DbException.java:212) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.mvstore.db.Store.convertMVStoreException(Store.java:158) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.mvstore.db.Store.(Store.java:142) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.engine.Database.(Database.java:326) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.engine.Engine.openSession(Engine.java:92) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.engine.Engine.openSession(Engine.java:222) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.engine.Engine.createSession(Engine.java:201) ~[h2-2.2.224.jar:2.2.224]
          at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) ~[h2-2.2.224.jar:2.2.224]
          at io.r2dbc.h2.client.SessionClient.(SessionClient.java:58) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
          at io.r2dbc.h2.H2ConnectionFactory.getSessionClient(H2ConnectionFactory.java:117) ~[r2dbc-h2-1.0.0.RELEASE.jar:1.0.0.RELEASE]
          ... 16 common frames omitted