无法使用JDBC连接到我的Sql docker容器

6
我使用 Docker Maven Plugin
当 test-integration 开始时,我可以使用以下命令在终端中连接到容器中的 mysql:
mysql -h 127.0.0.1 -P 32795 -uroot -p

一切都很顺利,但当我想用以下代码在Java应用程序中使用JDBC连接MySQL时:

Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection = DriverManager.getConnection(
    "jdbc:mysql://127.0.0.1:" + System.getProperty("mysqlPort") + "/dashboardmanager",
    "root",
    "root"
);

我遇到了这个错误:

org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (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.)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:615) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:866) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:927) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:937) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

我尝试了:

export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"

并且

System.setProperty("java.net.preferIPv4Stack" , "true");

但是没有任何改变。

Docker Maven 插件 配置:

<plugin>
            <groupId>org.jolokia</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>${docker-maven-plugin.version}</version>
            <configuration>
                <images>
                    <image>
                        <name>mysql:5.7.11</name>
                        <run>
                            <env>
                                <MYSQL_ROOT_PASSWORD>root</MYSQL_ROOT_PASSWORD>
                                <MYSQL_DATABASE>dashboardmanager</MYSQL_DATABASE>
                            </env>
                            <ports>
                                <port>mysqlPort:3306</port>
                            </ports>
                        </run>
                    </image>
                </images>
            </configuration>
            <executions>
                <execution>
                    <id>start</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                </execution>
                <execution>
                    <id>stop</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>stop</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

你是在 Docker 容器中运行测试,还是想要连接到 MySQL(从外部)容器? - Hendrik Jander
你需要找出容器的IP地址。很可能你需要使用 docker-machine ip YOUR_ENV 命令来查找该IP地址。 - Hendrik Jander
<port>mysqlPort:3306</port> 但是这段代码显示端口为3306。 - Python Basketball
你可以使用命令'mysql -h 127.0.0.1 -P 32795 -u root -p root -D dashboardmanager'连接服务器吗? - Python Basketball
是的,连接成功。 - Arman
显示剩余4条评论
2个回答

4
问题在于:
MySQL 启动过程需要大约 40 秒,因此我需要等待大约 40 秒后才能尝试连接 MySQL,如此简单 :)
或者我可以在 pom.xml 中使用以下设置:
<image>
    <name>mysql:5.7.11</name>
    <alias>mysqlContainer</alias>
    <run>
        <env>
            <MYSQL_ROOT_PASSWORD>root</MYSQL_ROOT_PASSWORD>
            <MYSQL_DATABASE>dashboard</MYSQL_DATABASE>
        </env>
        <ports>
            <port>mysqlPort:3306</port>
        </ports>
        <wait>
            <log>.*port: 3306  MySQL Community Server.*</log>
            <time>120000</time>
        </wait>
    </run>
</image>

很好的发现,非常好的反馈,比我的回答更精确。+1 - VonC

0
确保你的 MySQL 配置文件(my.cnf)在你的 mysql 容器中使用以下设置:
bind-address = 0.0.0.0

此答案所解释的(针对反向情况:从Docker容器连接到运行在主机上的mysql,但这里的思路是相同的),在桥接模式下,将bind-address设置为广播模式可以帮助验证mysql是否可达。

注意:如果您使用bind-address = 0.0.0.0,则您的MySQL服务器将侦听所有网络接口上的连接。这意味着您的MySQL服务器可以从Internet访问;请确保相应地设置防火墙规则。

进行此测试后,请检查“如何从主机机器连接到运行在容器中的mysql

默认情况下,root仅能从本地主机127.0.0.1和::1访问,您需要在用户设置中明确允许从192.168.99.1或任何地方使用“%”进行访问。
请参见“保护初始MySQL帐户”。


我使用 MYSQL,是否使用 bind-address = 0.0.0.0? 如果问题是IP地址,为什么我可以在主机终端上使用 mysql -h 127.0.0.1 -P 32795 -uroot -p 进行连接? - Arman
bind-address未设置。 my.cnf#bind-address = 127.0.0.1,但我认为问题不在这里,因为如前所述,我可以通过mysql -h 127.0.0.1 -P 32795 -uroot -p在主机终端上连接。 - Arman
@Arman,我认为你是从容器内部进行测试的,而不是从主机上进行测试(因此我建议这样做)。不过这仍然是一个很好的测试方法:bind-address = 0.0.0.0 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接