zoukankan      html  css  js  c++  java
  • 【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

    当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

  • 相关阅读:
    将空值转换为实际值
    图像的几何变换(一)
    图像的代数运算
    灰度直方图均衡化的算数推导
    图像的点运算
    探索数据可视化,业务数据是核心
    Gazebo機器人仿真學習探索筆記(一)安裝與使用
    脐带血要不要保存?看了你就明白!
    linuxsvn源代码版本库建立
    svn(subversion)代码版本管理在linux下的一些常见使用命令
  • 原文地址:https://www.cnblogs.com/lulight/p/15604596.html
Copyright © 2011-2022 走看看