解决 Spring Boot 3.5.0 后 Jasypt 无法解析环境变量中的加密字符串问题
当 Spring Boot 项目升级到 3.5.0 及更高版本后,使用 jasypt-spring-boot-starter
会遇到一个问题:应用程序无法正确解析环境变量中配置的加密字符串。具体表现为,在应用程序运行期间,读取到的配置值仍然是加密后的字符串(例如
ENC(加密字符串)),而非解密后的原始值。
当 Spring Boot 项目升级到 3.5.0 及更高版本后,使用 jasypt-spring-boot-starter
会遇到一个问题:应用程序无法正确解析环境变量中配置的加密字符串。具体表现为,在应用程序运行期间,读取到的配置值仍然是加密后的字符串(例如
ENC(加密字符串)),而非解密后的原始值。
本文主要介绍升级到spring-boot-3.1.0后native-image启动报错以及对应问题的解决方案
默认情况下,spring-data-jpa
使用hibernate
作为jpa
的实现, 当并发量较大时, 由于框架的一些默认配置可能会引发性能瓶颈,
下面将介绍一些常见的配置项来改善并发量较大时的性能问题.
OpenEntityManagerInViewInterceptor
是spring
中的一个拦截器,它的作用是在整个请求上下文复用同一个EntityManager
,从而避免在一个请求中多次创建一个EntityManager
, 从而提高性能.
但是如果在一个请求的处理代码中请求了下游服务,而下游服务响应缓慢,那么在下游服务响应之前,EntityManager
会一直被占用,直到整个请求处理完成,这样会导致当服务并发请求量较大时,数据库连接被占用完.
为了避免这种情况,可以通过关闭OpenEntityManagerInViewInterceptor
来确保当下游服务响应缓慢时不会导致数据库连接被占用完.
下面将介绍如何关闭OpenEntityManagerInViewInterceptor
.
本文主要整理了在构建spring-boot
应用为native
的过程中遇到的问题.
本文主要整理了在升级springboot3
的过程中遇到的问题.
基于graalvm
的spring boot
项目打包好后调用/scheduling/api/v1/taskDefinitions
接口返回如下数据, 其中triggerStrategy
字段是空json
对象
[
{
"id": "BILLING_SYNC_FOR_DEPLOYMENT_127",
"triggerStrategy": {},
"tags": {
"EXECUTOR": "com.fastonetech.billing.sync.scheduling.BillingSyncTaskExecutor"
},
"variables": {
"SOURCE_RCLONE_CONFIG": "TENCENT_ap-beijing",
"SOURCE_BUCKET": "cheng1201-1310454728",
"SOURCE_PATH": "",
"TARGET_RCLONE_CONFIG": "aggregation",
"TARGET_BUCKET": "billing-aggregation",
"TARGET_PATH": "TENCENT/ap-beijing/cheng1201-1310454728"
}
}
]
如果在application.yml
中配置duration值时不给定单位的话, 那么解析出的单位为毫秒, 如果需要自定义单位的话需要提供@DurationUnit
,
建议配置Duration单位, 强制指定单位确保行为符合期望
BindConverter
List<ConversionService> delegates
List<Converter> converters
StringToDurationConverter (SpringBoot)
NumberToDurationConverter (SpringBoot) 此处会根据注解去判断单位
DurationStyle.SIMPLE.parse
Camunda调用Delegate时会开启事务(为了保证失败时可以回滚数据), Spring的@Transaction propagation = Propagation.REQUIRED , 然后就用了Camunda的那个事务, Camunda的事务中修改是对DB不生效的所以你看不到事务过程中修改的数据提交的结果
@Component
class StartClusterDelegate(
private val clusterOperator: ClusterOperator
) : JavaDelegate, LogCapability {
override fun execute(execution: DelegateExecution) {
clusterOperator.start(execution.getVariableAs(VARNAME_CLUSTER_ID))
}
}
@Component
class ClusterOperator(
private val clusterService: ClusterService,
private val csClusterOperator: CsClusterOperator,
private val csStorageOperator: CsStorageOperator,
private val clusterBastionUserOperator: ClusterBastionUserOperator,
private val netEnvOperator: NetEnvOperator
) : LongTimeOperationCapability {
override fun start(id: Long) {
clusterService.get(id).orNull()!!.let { cluster ->
clusterService.patch(id) {
state = ClusterState.STARTING
}
logger.info("Begin start cluster $id")
csStorageOperator.start(cluster.csStorageId)
csClusterOperator.start(cluster.csClusterId!!)
clusterBastionUserOperator.start(cluster.id)
logger.info("Successful to start cluster $id")
clusterService.patch(id) {
state = ClusterState.RUNNING
}
}
}
}
@Service
class ClusterService(
private val engine: ProcessEngine,
private val clusterRepo: ClusterRepository,
private val client: DeployService
) : LogCapability {
@Transactional(propagation = Propagation.REQUIRES_NEW)
fun patch(id: Long, patchFun: PatchClusterDto.() -> Unit): Either<ClusterOperationError, ClusterDetail> =
clusterRepo.findById(id).map { originCluster ->
val patch = PatchClusterDto(patchFun).apply {
logger.info("patch request {}", this)
}
val patchedCluster = originCluster.copy(
cloudAccount = patch.cloudAccount ?: originCluster.cloudAccount,
csNetEnvId = patch.csNetEnvId ?: originCluster.csNetEnvId,
csStorageId = patch.csStoreId ?: originCluster.csStorageId,
csClusterId = patch.csClusterId ?: originCluster.csClusterId,
isDelivered = when (patch.deliveryCluster) {
DeliveryCluster.YES -> true
DeliveryCluster.NO -> false
DeliveryCluster.NONE -> originCluster.isDelivered
},
state = patch.state ?: originCluster.state
)
patchedCluster.apply {
logger.info("patched cluster {}", this)
}
}.map {
clusterRepo.save(it)
get(it.id)
}.orElseGet {
Either.left(ClusterOperationError.NoSuchCluster(id))
}
}
在项目中添加rest依赖项
implementation("org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter-rest:7.14.0")