Nacos 1.3.2 Docker 连接 Mysql 8 问题解决。

环境

  • Windows 10 20H1

  • Docker Desktop for Windows 2.4.0.0

  • MySQL Community 8.0.22.0

  • Nacos Docker Latest (Nacos 1.3.2)

背景

看到Spring Cloud Alibaba版本更新,于是就将自己的微服务架构,一整套进行了升级。

  • Spring Boot 升级到了 2.3.4
  • Spring Cloud 升级到 Hoxton.SR8
  • Spring Cloud Alibaba 升级到 2.2.3
  • Nacos升级到1.3.2

升级之后整体顺畅多了,而且解决了长久以来一直不敢使用 Spring Cloud Alibaba 2.2.1问题。

使用 Spring Cloud Alibaba 2.2.1,会导致Oauth 2 Token 验证返回的对象数据类型不对的问题。就是下面代码中,Boolean.TRUE.equals(map.get(“active”) 这一句验证不过的问题。主要原因是map里面的值全被转成了String类型,查了好久没有找到问题在哪。切换到Spring Cloud Alibaba 2.2.0,就不会有问题。现在升级到Spring Cloud Alibaba 2.2.3,问题就不存在了。开心!!!!

@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException {

	MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
	formData.add(tokenName, accessToken);
	HttpHeaders headers = new HttpHeaders();
	headers.set("Authorization", getAuthorizationHeader(clientId, clientSecret));
	Map<String, Object> map = postForMap(checkTokenEndpointUrl, formData, headers);

	if (map.containsKey("error")) {
		if (logger.isDebugEnabled()) {
			logger.debug("check_token returned error: " + map.get("error"));
		}
		throw new InvalidTokenException(accessToken);
	}

	// gh-838
	if (!Boolean.TRUE.equals(map.get("active"))) {
		logger.debug("check_token returned active attribute: " + map.get("active"));
		throw new InvalidTokenException(accessToken);
	}

	return tokenConverter.extractAuthentication(map);
}

问题

这次升级,主要问题出现在Nacos上面。

  • 一方面,Nacos 1.3.1以后,使用MySQL8,需要升级数据库
  • 另一方面,现在Latest的 Nacos Docker,访问外部MySQL 8 连接不上。

错误堆栈中会出现以下两个关键信息:

堆栈错误(一)

java.sql.SQLException: The server time zone value xxxxx is unrecognized or represents more than one time zone

这个错误,主要是因为时区不对,如果这个问题解决,就会出现下面的问题

堆栈错误(二)

Caused by: com.mysql.cj.exceptions.CJException: Public Key Retrieval is not allowed

解决

Nacos 容器运行起来之后,进入到Nacos 容器控制台。

输入:

~$ vim conf/application.properties

在数据库连接中增加以下参数解决:

// 在数据库连接中增加
allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8

完整参数:

···
db.num=${MYSQL_DATABASE_NUM:1}
db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&useSSL=${MYSQL_SSL_ENABLE:false}
db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&useSSL=${MYSQL_SSL_ENABLE:false}
db.user=${MYSQL_SERVICE_USER}
db.password=${MYSQL_SERVICE_PASSWORD
···

当然,这只是表现在Nacos端,并不是Nacos本身的问题。真正的解决办法还有待深入研究。

2020-12-31 更新

感谢Nacos Docker作者的快速响应。在最新版的Nacos Docker中,作者增加了一个参数 MYSQL_SERVICE_DB_PARAM,默认值为:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true

可以根据需要在默认参数后面增加配置,就可以解决问题:

characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8

我的Docker compose 配置为:

nacos:
  image: nacos/nacos-server:latest
  container_name: nacos
  restart: always
  environment:
    MODE: standalone
    SPRING_DATASOURCE_PLATFORM: mysql
    MYSQL_SERVICE_HOST: 192.168.101.10
    MYSQL_SERVICE_PORT: 3306
    MYSQL_SERVICE_USER: nacos
    MYSQL_SERVICE_PASSWORD: nacos
    MYSQL_SERVICE_DB_NAME: nacos_config
    MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
  volumes:
    - /D/LocalCaches/docker-volumes/nacos/datas:/home/nacos/data
  ports:
    - 8848:8848
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码匠君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值