Spring 引导无法与 docker 环境中的 MySQL 数据库通信
Spring Boot unable to communicate with MySQL DB in docker environment
我正在尝试 运行 一个 springboot 微服务 docker 图像。它从配置服务器获取数据库连接属性。但是它无法连接到容器。
错误:
JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata : 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 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.21.jar!/:8.0.21]
Caused by :
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_242]
2020-09-28 11:39:32.782 [ : ] WARN [task-1] o.h.e.j.s.SqlExceptionHelper - SQL Error: 0, SQLState: 08S01
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08S01
2020-09-28 11:39:32.791 [ : ] ERROR [task-1] o.h.e.j.s.SqlExceptionHelper - 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.
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : 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.
位于配置服务器的属性
shopping-service.datasource.url: jdbc:mysql://A.B.C.D:3306/shoppingCartDB
shopping-service.datasource.username: root
shopping-service.datasource.password: root
A.B.C.D
是我的 docker 主机 IP。
application.yaml
datasource:
url: ${shopping-service.datasource.url}
username: ${shopping-service.datasource.username}
password: ${shopping-service.datasource.password}
#driver-class-name: com.mysql.jdbc.Driver
jpa:
generate-ddl: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
show_sql: true
ddl-auto: create-drop
profiles:
active: dev
我已经从 docker 集线器中提取了 MySQL 8.0 docker 图像。
docker pull mysql/mysql-server:8.0
docker run --name=mysql-container -d mysql/mysql-server:8.0
已将密码更改为“root”。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
Query OK, 0 rows affected (0.02 sec)
创建数据库:
mysql> create DATABASE shoppingCartDB;
Query OK, 1 row affected (0.00 sec)
mysql> exit
Docker 运行
docker run -p 5000:5000 shoppingms:latest --env shopping-service.configserverurl=http://A.B.C.D:8888 --env shopping-service.eureka.url=http://A.B.C.D:4444/eureka
它能够从配置服务器获取属性。我检查了日志。错误来自这一行:
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
在我的本地环境中,我可以使用具有相同连接参数的本地安装的 MySQL Db。但是在 docker 中我得到了例外。我哪里出错了,谁能帮帮我。
更新:
将MySQL容器暴露到3306端口后,现在报错:
2020-09-28 12:07:43.942 [ : ] WARN [task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
1 --- [ task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
2020-09-28 12:07:49.219 [ : ] WARN [task-1] o.h.e.j.s.SqlExceptionHelper - SQL Error: 1130, SQLState: HY000
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1130, SQLState: HY000
2020-09-28 12:07:49.225 [ : ] ERROR [task-1] o.h.e.j.s.SqlExceptionHelper - null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
我建议 运行 使用 docker 撰写文件来描述您的应用程序设置。
作为指南,这是给定网络上 运行 phpMyAdmin、MySQL 8、tomcat 的撰写文件。我已经猜测了你的申请要求:
version: "3.5"
services:
# Update the below for your application
app:
image: shoppingms:latest
restart: always
ports:
- 5000:5000
links:
- db:db
environment:
- shopping-service.configserverurl=http://A.B.C.D:8888
- shopping-service.eureka.url=http://A.B.C.D:4444/eureka
networks:
- appnet
db:
image: mysql:8.0
restart: always
ports:
- 3306:3306
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: user123
MYSQL_ROOT_PASSWORD: user123
volumes:
- ./sql-init:/docker-entrypoint-initdb.d
- ./mysql/data:/var/lib/mysql
networks:
- appnet
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
links:
- db:db
ports:
- 8201:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: user123
MYSQL_ROOT_PASSWORD: user123
networks:
- appnet
tomcat:
image: library/tomcat:9
restart: always
links:
- db:db
ports:
- 8081:8080
volumes:
- ./tomcat/webapps:/usr/local/tomcat/webapps
- ./tomcat/logs:/usr/local/tomcat/logs
networks:
- appnet
networks:
appnet:
name: appnet
在这个应用程序中,我是 运行 一个外部托管的 tomcat 服务器,Spring webapp 卷入容器。为了便于外部访问,还公开了各种端口。
根据您的要求,您需要 configure/tweak 您的应用程序容器。
数据库在 DNS 名称 db
上公开,这是 phpMyAdmin 使用的名称。
现在可以解决问题了。
1. Identify the ip address from docker inspect command.
2. Create an user for that ip.
3. Need to alter the new user password.
4. Grant some privileges to the user.
5. Exit
现在运行你的容器又来了,这次它可以获取连接并成功创建表。
我正在尝试 运行 一个 springboot 微服务 docker 图像。它从配置服务器获取数据库连接属性。但是它无法连接到容器。
错误:
JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata : 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 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.21.jar!/:8.0.21]
Caused by :
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_242]
2020-09-28 11:39:32.782 [ : ] WARN [task-1] o.h.e.j.s.SqlExceptionHelper - SQL Error: 0, SQLState: 08S01
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08S01
2020-09-28 11:39:32.791 [ : ] ERROR [task-1] o.h.e.j.s.SqlExceptionHelper - 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.
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : 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.
位于配置服务器的属性
shopping-service.datasource.url: jdbc:mysql://A.B.C.D:3306/shoppingCartDB
shopping-service.datasource.username: root
shopping-service.datasource.password: root
A.B.C.D
是我的 docker 主机 IP。
application.yaml
datasource:
url: ${shopping-service.datasource.url}
username: ${shopping-service.datasource.username}
password: ${shopping-service.datasource.password}
#driver-class-name: com.mysql.jdbc.Driver
jpa:
generate-ddl: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
show_sql: true
ddl-auto: create-drop
profiles:
active: dev
我已经从 docker 集线器中提取了 MySQL 8.0 docker 图像。
docker pull mysql/mysql-server:8.0
docker run --name=mysql-container -d mysql/mysql-server:8.0
已将密码更改为“root”。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
Query OK, 0 rows affected (0.02 sec)
创建数据库:
mysql> create DATABASE shoppingCartDB;
Query OK, 1 row affected (0.00 sec)
mysql> exit
Docker 运行
docker run -p 5000:5000 shoppingms:latest --env shopping-service.configserverurl=http://A.B.C.D:8888 --env shopping-service.eureka.url=http://A.B.C.D:4444/eureka
它能够从配置服务器获取属性。我检查了日志。错误来自这一行:
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
在我的本地环境中,我可以使用具有相同连接参数的本地安装的 MySQL Db。但是在 docker 中我得到了例外。我哪里出错了,谁能帮帮我。
更新:
将MySQL容器暴露到3306端口后,现在报错:
2020-09-28 12:07:43.942 [ : ] WARN [task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
1 --- [ task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
2020-09-28 12:07:49.219 [ : ] WARN [task-1] o.h.e.j.s.SqlExceptionHelper - SQL Error: 1130, SQLState: HY000
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1130, SQLState: HY000
2020-09-28 12:07:49.225 [ : ] ERROR [task-1] o.h.e.j.s.SqlExceptionHelper - null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
1 --- [ task-1] o.h.engine.jdbc.spi.SqlExceptionHelper : null, message from server: "Host 'Some-IP' is not allowed to connect to this MySQL server"
我建议 运行 使用 docker 撰写文件来描述您的应用程序设置。
作为指南,这是给定网络上 运行 phpMyAdmin、MySQL 8、tomcat 的撰写文件。我已经猜测了你的申请要求:
version: "3.5"
services:
# Update the below for your application
app:
image: shoppingms:latest
restart: always
ports:
- 5000:5000
links:
- db:db
environment:
- shopping-service.configserverurl=http://A.B.C.D:8888
- shopping-service.eureka.url=http://A.B.C.D:4444/eureka
networks:
- appnet
db:
image: mysql:8.0
restart: always
ports:
- 3306:3306
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: user123
MYSQL_ROOT_PASSWORD: user123
volumes:
- ./sql-init:/docker-entrypoint-initdb.d
- ./mysql/data:/var/lib/mysql
networks:
- appnet
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
links:
- db:db
ports:
- 8201:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: user123
MYSQL_ROOT_PASSWORD: user123
networks:
- appnet
tomcat:
image: library/tomcat:9
restart: always
links:
- db:db
ports:
- 8081:8080
volumes:
- ./tomcat/webapps:/usr/local/tomcat/webapps
- ./tomcat/logs:/usr/local/tomcat/logs
networks:
- appnet
networks:
appnet:
name: appnet
在这个应用程序中,我是 运行 一个外部托管的 tomcat 服务器,Spring webapp 卷入容器。为了便于外部访问,还公开了各种端口。
根据您的要求,您需要 configure/tweak 您的应用程序容器。
数据库在 DNS 名称 db
上公开,这是 phpMyAdmin 使用的名称。
现在可以解决问题了。
1. Identify the ip address from docker inspect command.
2. Create an user for that ip.
3. Need to alter the new user password.
4. Grant some privileges to the user.
5. Exit
现在运行你的容器又来了,这次它可以获取连接并成功创建表。