r2dbc指定时区问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL DuckDB 分析主实例,集群系列 8核16GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: r2dbc指定时区问题

政治能把一个人突然变老——巴尔扎克

今天看见这个警告

我的配置项如下:

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.JdbcUtils;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.Map;
import static io.r2dbc.spi.ConnectionFactoryOptions.*;
@Configuration
public class R2dbcConfig {
  @Bean
    public ConnectionFactory connectionFactory(DynamicDataSourceProperties dataSource) {
        Map<String, DataSourceProperty> datasourceMap = dataSource.getDatasource();
        DataSourceProperty master = datasourceMap.get("master");
        String host = StrUtil.subBetween(master.getUrl(), "mysql://", ":");
        String port = StrUtil.subBetween(master.getUrl(), host + ":", "/");
        String database = StrUtil.subBetween(master.getUrl(), port + "/", "?");
        ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
                .option(DRIVER, JdbcUtils.MYSQL)
                .option(HOST, host)
                .option(USER, master.getUsername())
                .option(PORT, Integer.valueOf(port))  // optional, default 3306
                .option(PASSWORD, master.getPassword()) // optional, default null, null means has no password
                .option(DATABASE, database) // optional, default null, null means not specifying the database
                .option(CONNECT_TIMEOUT, Duration.ofSeconds(3)) // optional, default null, null means no timeout
                .option(Option.valueOf("socketTimeout"), Duration.ofSeconds(4)) // optional, default null, null means no timeout
                .option(SSL, false) // optional, default sslMode is "preferred", it will be ignore if sslMode is set
                .option(Option.valueOf("zeroDate"), "use_null") // optional, default "use_null"
                .option(Option.valueOf("useServerPrepareStatement"), true) // optional, default false
                .option(Option.valueOf("tcpKeepAlive"), true) // optional, default false
                .option(Option.valueOf("tcpNoDelay"), true) // optional, default false
                .option(Option.valueOf("autodetectExtensions"), false) // optional, default false
                .build();
        ConnectionFactory connectionFactory = ConnectionFactories.get(options);
        return connectionFactory;
    }
}

我想到能在这里配置时区,于是按照警告提示的timezone配置发现不生效、换成serverTimezone依旧不行

issue,没有(这里其实是搜错仓库了,正确的仓库是这个https://github.com/mirromutth/r2dbc-mysql ,在readme里就提到了时区配置)

翻阅文档,没找到:https://r2dbc.io/

看警告的代码行数dev.miku.r2dbc.mysql.MySqlConnection:451

然后发现调用convertZoneId的地方在97100

于是debug,这个timeZonesystemTimeZone都是从row获取到的

看到确实拿到的是乱码

row里找到了zeroDateOption,因为我们上面配置了zeroDateuse_null,我有印象

所以看到这里的serverZoneId,就试着配置了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Bean
public ConnectionFactory connectionFactory(DynamicDataSourceProperties dataSource) {
    Map<String, DataSourceProperty> datasourceMap = dataSource.getDatasource();
DataSourcePropertymaster= datasourceMap.get("master");
Stringhost= StrUtil.subBetween(master.getUrl(), "mysql://", ":");
Stringport= StrUtil.subBetween(master.getUrl(), host + ":", "/");
Stringdatabase= StrUtil.subBetween(master.getUrl(), port + "/", "?");
ConnectionFactoryOptionsoptions= ConnectionFactoryOptions.builder()
            .option(DRIVER, JdbcUtils.MYSQL)
            .option(HOST, host)
            .option(USER, master.getUsername())
            .option(PORT, Integer.valueOf(port))  // optional, default 3306
            .option(PASSWORD, master.getPassword()) // optional, default null, null means has no password
            .option(DATABASE, database) // optional, default null, null means not specifying the database
            .option(CONNECT_TIMEOUT, Duration.ofSeconds(3)) // optional, default null, null means no timeout
            .option(Option.valueOf("socketTimeout"), Duration.ofSeconds(4)) // optional, default null, null means no timeout
            .option(SSL, false) // optional, default sslMode is "preferred", it will be ignore if sslMode is set
            .option(Option.valueOf("zeroDate"), "use_null") // optional, default "use_null"
            .option(Option.valueOf("useServerPrepareStatement"), true) // optional, default false
            .option(Option.valueOf("tcpKeepAlive"), true) // optional, default false
            .option(Option.valueOf("tcpNoDelay"), true) // optional, default false
            .option(Option.valueOf("autodetectExtensions"), false) // optional, default false
            .option(Option.valueOf("serverZoneId"), TimeZone.getTimeZone("GMT+8").getID()) // optional
            .build();
ConnectionFactoryconnectionFactory= ConnectionFactories.get(options);
return connectionFactory;
}

然后生效了,不再打印该警告

后来发现github人家写了配置项,我自己没找到

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
人工智能 JSON Rust
用 Rust 实现敏感信息拦截插件,提升 AI 网关安全防护能力
本⽂对敏感信息拦截插件的使用方式和实现原理进行了简单介绍,它能够自动检测并处理请求和响应中的敏感词,有效防止敏感信息泄露。通过对不同数据范围的支持和灵活的配置选项,该插件能够适应各种应用场景,确保数据的安全性和合规性。
561 99
|
分布式计算 Java 数据库连接
了解Spring R2DBC的声明式事务实现机制
# Spring非反应式事务实现原理 Spring基于注解和AOP的声明式事务(@Transactional)已经是业务开发的常用工具,默认是采用同步的方式基于ThreadLocal(保存连接信息和会话信息等)实现,在具体数据库操作时就使用同一个数据库连接,并手动提交事务,保证数据正确性。 # 基于反应式的Spring事务有何不同 Spring的反应式实现是基于Reactor框架,该框架
3044 0
|
前端开发 Java 数据库连接
Spring Boot 升级 3.2 报错 Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String
Spring Boot 升级 3.2 报错 Invalid value type for attribute ‘factoryBeanObjectType‘: java.lang.String
|
Java 应用服务中间件 Spring
记录SpringCloudGateway的一个隐藏问题
线上生产环境中,一个SCG接口偶发性出现“Connection reset by peer”错误。排查发现问题是由于Netty的HTTP客户端连接池保持了已由服务端关闭的连接。解决方案是配置连接池以在超时后回收连接(超时时间应小于Tomcat的连接超时时间),并考虑将连接池获取策略从FIFO改为LIFO,以减少使用无效连接的可能性。通过修改Spring Cloud Gateway的HTTP客户端连接池配置和添加JVM启动参数可以实现这一修复。
3724 1
|
存储 算法 NoSQL
(三)漫谈分布式之集群篇:探寻N个9高可用与PB级数据存储的实现原理!
本文来详细聊聊集群的各方面知识,为诸位量身打造出结构化的集群知识体系。
582 0
|
SQL 监控 druid
SpringBoot配置Druid
SpringBoot配置Druid
|
网络虚拟化
VLANIF配置
VLANIF配置
322 0
|
监控 druid Java
Spring Boot3整合Druid(监控功能)
Spring Boot3整合Druid(监控功能)
1141 1
|
Prometheus 运维 监控
Prometheus AlertManager 生产实践 - 直接根据 to_email label 发 alert 到对应邮箱
Prometheus AlertManager 生产实践 - 直接根据 to_email label 发 alert 到对应邮箱
|
SQL druid 关系型数据库
druid配置详解表
druid配置详解表
915 0