Mariadb docker 容器无法使用 Python 连接到主机上的 MySQL 服务器(111 连接被拒绝)
Mariadb docker container Can't connect to MySQL server on host (111 Connection refused) with Python
我正在尝试使用 docker-compose:
与 python 连接 mariadb
docker-compose.yml
version: '2'
services:
mariadb:
image: bitnami/mariadb
ports:
- "3306:3306"
environment:
MARIADB_DATABASE: 'mary_db'
MARIADB_USER: user2
MARIADB_PASSWORD: 'pass1234'
consumer:
build: ./consumer
links:
- mariadb
consumer.py
import mysql.connector as mariadb1
mariadb_connection = mariadb1.connect(host='mariadb',
port=3306,
user='user2',
password='pass1234',
database='mary_db')
cursor = mariadb_connection.cursor(buffered=True)
try:
cursor.execute('DROP TABLE names')
except:
pass
comm = "CREATE TABLE names(id VARCHAR(20), location VARCHAR(100)," \
"PRIMARY KEY (mac,location)) ENGINE=InnoDB"
cursor.execute(comm)
print 'created'
Dockerfile 入口点只是调用 consumer.py 函数,如:
ENTRYPOINT python -u consumer.py
问题非常随机(超过 %90 次试验),python 代码无法连接数据库并打印此错误:
File "consumer.py", line 7, in
database='mary_db') File "/usr/local/lib/python2.7/dist-packages/mysql/connector/init.py",
line 179, in connect
return MySQLConnection(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py",
line 95, in init
self.connect(**kwargs) File "/usr/local/lib/python2.7/dist-packages/mysql/connector/abstracts.py",
line 719, in connect
self._open_connection() File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py",
line 206, in _open_connection
self._socket.open_connection() File "/usr/local/lib/python2.7/dist-packages/mysql/connector/network.py",
line 475, in open_connection
errno=2003, values=(self.get_address(), _strioerror(err))) mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL
server on 'mariadb:3306' (111 Connection refused)
知道发生了什么吗?
问题不在于数据库或Python代码;这是一个来自 Docker 的问题,因为数据库需要一些时间来加载并且 python (consumer.py) 容器启动速度比数据库快。
可能的解决方案:
docker 健康检查
等待时间 docker
向 python 消费者添加延迟
此问题是由于 python 容器在正确执行数据库容器之前执行的。
要解决此问题,请在 mysql 连接之前使用以下代码行。
import time
time.sleep(1)
您的代码应如下所示:
import time
time.sleep(1)
mydb = mysql.connector.connect(
host="<host>",
user="<user_name>",
passwd="<pswd>",
database = "<DB_name>",
buffered=True
)
cursor = mydb.cursor()
它对我有效。希望它也对你有用。
我正在尝试使用 docker-compose:
与 python 连接 mariadbdocker-compose.yml
version: '2'
services:
mariadb:
image: bitnami/mariadb
ports:
- "3306:3306"
environment:
MARIADB_DATABASE: 'mary_db'
MARIADB_USER: user2
MARIADB_PASSWORD: 'pass1234'
consumer:
build: ./consumer
links:
- mariadb
consumer.py
import mysql.connector as mariadb1
mariadb_connection = mariadb1.connect(host='mariadb',
port=3306,
user='user2',
password='pass1234',
database='mary_db')
cursor = mariadb_connection.cursor(buffered=True)
try:
cursor.execute('DROP TABLE names')
except:
pass
comm = "CREATE TABLE names(id VARCHAR(20), location VARCHAR(100)," \
"PRIMARY KEY (mac,location)) ENGINE=InnoDB"
cursor.execute(comm)
print 'created'
Dockerfile 入口点只是调用 consumer.py 函数,如:
ENTRYPOINT python -u consumer.py
问题非常随机(超过 %90 次试验),python 代码无法连接数据库并打印此错误:
File "consumer.py", line 7, in database='mary_db') File "/usr/local/lib/python2.7/dist-packages/mysql/connector/init.py", line 179, in connect return MySQLConnection(*args, **kwargs) File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 95, in init self.connect(**kwargs) File "/usr/local/lib/python2.7/dist-packages/mysql/connector/abstracts.py", line 719, in connect self._open_connection() File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 206, in _open_connection self._socket.open_connection() File "/usr/local/lib/python2.7/dist-packages/mysql/connector/network.py", line 475, in open_connection errno=2003, values=(self.get_address(), _strioerror(err))) mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'mariadb:3306' (111 Connection refused)
知道发生了什么吗?
问题不在于数据库或Python代码;这是一个来自 Docker 的问题,因为数据库需要一些时间来加载并且 python (consumer.py) 容器启动速度比数据库快。
可能的解决方案:
docker 健康检查
等待时间 docker
向 python 消费者添加延迟
此问题是由于 python 容器在正确执行数据库容器之前执行的。 要解决此问题,请在 mysql 连接之前使用以下代码行。
import time
time.sleep(1)
您的代码应如下所示:
import time
time.sleep(1)
mydb = mysql.connector.connect(
host="<host>",
user="<user_name>",
passwd="<pswd>",
database = "<DB_name>",
buffered=True
)
cursor = mydb.cursor()
它对我有效。希望它也对你有用。