【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

问题描述

App Service使用jdbc连接MySQL服务,出现大量的  Communications link failure:

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure


The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server

 

问题分析

最开始出现连接不上的原因,怀疑是MySQL服务的IP地址白名单没有配置正确的App Service 出站IP。但是根据错误提示,发现明显不对,因为如果是IP地址不允许访问,它的错误消息应该是:

Client with IP address '183.2xx.xx.xx' is not allowed to connect to this MySQL server.

所以不应该是MySQL服务器对IP白名单设置的问题。

 

为了深入找出问题,单独用Java Spring Boot来写一个简单的数据库连接代码,根据MySQL官方的代码:https://docs.azure.cn/zh-cn/mysql/connect-java

POM.XML内容为:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
    </dependencies>
</project>

注:这里使用的 mysql-connector-java 依赖版本为 8.0.20

Java Main函数代码:

public static void main(String[] args) {
        String url = "jdbc:mysql://xxxxxx.mysql.database.chinacloudapi.cn:3306/xxxxxx?useSSL=true&requireSSL=false&characterEncoding=utf8&serverTimezone=UTC";
        String username = "xxxxxx@xxxxxx";
        String password = "xxxxxxxxxxxx";
        try {
            Connection connection = DriverManager.getConnection(url, username, password);
            System.out.println(connection.getMetaData().getURL());
            connection.close();
            System.out.println("connected!");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            System.out.println(e.getMessage());
            return; // return because nothing can be done w/out a connection
        }
    }

同样的数据库连接字符串,运行结果正常。根据验证结果对比,出现 Communications link failure |  The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server, 的JDBC版本为 8.0.15, 所以瞬间定位问题原因:客户端jdbc的驱动问题。

 

根据这一判断,再次检查了MySQL的版本为8.0并且为单实例(Single Server)。而微软的官方文档中提示了 use 8.0.17+ with MySQL 8.0 (https://docs.microsoft.com/en-us/azure/mysql/concepts-compatibility#mysql-drivers)

 

随后,对mysql-connector jdbc的版本 8.0.17, 8.0.18, 8.0.19 这三个版本进行验证,看是否不会出现 Communications link failure 异常:

8.0.17 Error

8.0.18 Error

8.0.19 Successful

 

 

经过以上验证,得出微软官方文档中的 8.0.17+有问题,需要在8.0.19+的驱动版本后才能成功。(一个调查了三天的大坑)

 

附录一:JDBC Connector TLS 版本问题

老版本的JDBC connector存在几个issue。在老版本的connector上,这两项很明显冲突的配置可能会同时存在,结果就导致在连接开始阶段直接失败。

第一个issue是老版本的connector默认没有enable TLS 1.2,

第二个问题是这些老版本的connector在某些情况下还会错误的禁止使用TLS1.2以下的版本。

MySQL Connector版本的发布日志中发现,MySQL Driver 8.0.19及以后的版本中有关于TLS改变:https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/news-8-0-19.html

 

简单的解决方案是在连接串中启用TLS1.2(enabledTLSProtocols=TLSv1.2),也可以升级connector版本

 

参考资料

将 Java 和 JDBC 与 Azure Database for MySQL 配合使用 : https://docs.azure.cn/zh-cn/mysql/connect-java

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
25天前
|
存储 安全 Linux
【Azure App Service】在App Service中查看CA证书
在 Azure App Service 中,使用自签名或私有 CA 证书的远程服务可能会导致 SSL 握手失败。解决方法包括使用受信任 CA 签发的证书,或通过 App Service Environment 加载自定义根证书,实现安全连接。
|
15天前
|
API 网络架构 容器
【Azure Container App】查看当前 Container App Environment 中的 CPU 使用情况的API
在扩展 Azure Container Apps 副本时,因 Container App Environment 的 CPU 核心数已达上限(500 cores),导致扩展失败。本文介绍如何使用 `az rest` 命令调用 Azure China Cloud 管理 API,查询当前环境的 CPU 使用情况,并提供具体操作步骤及示例。
76 16
|
6天前
|
数据安全/隐私保护
【Azure Function App】PowerShell Function 执行 Get-AzAccessToken 的返回值类型问题:System.String 与 System.Security.SecureString
将PowerShell Function部署到Azure Function App后,Get-AzAccessToken返回值类型在不同环境中有差异。正常为SecureString类型,但部分情况下为System.String类型,导致后续处理出错。解决方法是在profile.ps1中设置环境变量$env:AZUREPS_OUTPUT_PLAINTEXT_AZACCESSTOKEN=false,以禁用明文输出。
|
2月前
|
存储 缓存 Serverless
【Azure Container App】如何在Consumption类型的容器应用环境中缓存Docker镜像
在 Azure 容器应用的 Consumption 模式下,容器每次启动均需重新拉取镜像,导致冷启动延迟。本文分析该机制,并提出优化方案:使用 ACR 区域复制加速镜像拉取、优化镜像体积、设置最小副本数减少冷启动频率,或切换至 Dedicated 模式实现镜像缓存,以提升容器启动效率和应用响应速度。
|
21天前
|
安全 关系型数据库 MySQL
MySQL安全最佳实践:保护你的数据库
本文深入探讨了MySQL数据库的安全防护体系,涵盖认证安全、访问控制、网络安全、数据加密、审计监控、备份恢复、操作系统安全、应急响应等多个方面。通过具体配置示例,为企业提供了一套全面的安全实践方案,帮助强化数据库安全,防止数据泄露和未授权访问,保障企业数据资产安全。
|
6天前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
39 3
|
13天前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
1月前
|
存储 运维 关系型数据库
从MySQL到云数据库,数据库迁移真的有必要吗?
本文探讨了企业在业务增长背景下,是否应从 MySQL 迁移至云数据库的决策问题。分析了 MySQL 的优势与瓶颈,对比了云数据库在存储计算分离、自动化运维、多负载支持等方面的优势,并提出判断迁移必要性的五个关键问题及实施路径,帮助企业理性决策并落地迁移方案。
|
1天前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
6天前
|
Ubuntu 安全 关系型数据库
安装与配置MySQL 8 on Ubuntu,包括权限授予、数据库备份及远程连接指南
以上步骤提供了在Ubuntu上从头开始设置、配置、授权、备份及恢复一个基础但完整的MySQL环境所需知识点。
140 7

热门文章

最新文章

推荐镜像

更多