【問題解決】java.sql.SQLException: null, message from server: “Host ‘xxx.xx.xx.xxx‘ is blocked because of

於華_發表於2020-11-15

某臺伺服器專案連線不上mysql

java.sql.SQLException: null,  message from server: "Host 'xxx.xx.xx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:353)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
	at com.zaxxer.hikari.HikariDataSource$$FastClassBySpringCGLIB$$eeb1ae86.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)

問題原因:將如上錯誤搜尋後會出現很多答案,大體上是說因為請求mysql連線錯誤過多,導致mysql拒絕來自該伺服器ip的連線,多數解決方案如下:

1)修改mysql的最大連線錯誤數(max_connect_errors)

# 檢視某ip地址連結mysql的總連線錯誤數
mysql> select SUM_CONNECT_ERRORS as count from performance_schema.host_cache where ip='xxx.xx.xx.xx';
+-------+
| count |
+-------+
|   116 |
+-------+
1 row in set (0.00 sec)
# 通過修改my.cnf檔案將max_connect_errors連線數設定為1000(預設是100)
mysql> show variables like 'max_connect_errors';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 1000  |
+--------------------+-------+
1 row in set (0.01 sec)

2)重新重新整理mysql的host許可權

使用命令重新整理

[root@yumaster ~]# /usr/bin/mysqladmin flush-hosts -h ${mysqlIp} -uroot -p
# 不知道位置可通過whereis檢視
[root@yumaster ~]# whereis mysqladmin
mysqladmin: /usr/bin/mysqladmin /usr/share/man/man1/mysqladmin.1.gz

或者使用mysql命令重新整理

mysql> flush hosts;

或者重新給root使用者授權

mysql -u root -p

mysql>use mysql;

mysql>select 'host' from user where user='root';

mysql>update user set host = '%' where user ='root';

mysql>flush privileges;

mysql>select 'host'  from user where user='root';

以上一頓操作,結果還是躲不過0-5的結局。

解決方法:作者使用docker部署的後端服務,因為物理機故障問題導致虛擬機器當機,當虛擬機器重啟後發現但凡與mysql關聯的專案都起不來,報了以上錯誤,錯誤在解決方法中也是讓重新整理hosts。

java.sql.SQLException: null,  message from server: "Host 'xxx.xx.xx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"

但是並非如此,作者試用了以上幾種方法都不管用,又通過仔細看日誌發現日誌的列印時間是2018年(當前2020年),

2018-07-26 23:55:10 WARN  AIoT-TX-Manager main org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator HHH000342: Could not obtain
2018-07-26 23:55:10 WARN  AIoT-TX-Manager main org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext 
2018-07-26 23:55:10 INFO  AIoT-TX-Manager main org.apache.catalina.core.StandardService Stopping service [Tomcat]

隨即懷疑是因為兩臺伺服器時間不一致導致專案連線mysql失敗。

# mysql伺服器時間
[root@localhost ~]# date
2020年 10月 27日 星期二 18:53:17 CST
# 專案部署伺服器時間
[root@localhost ~]# date
The Jul 26 23:53:17 CST 2018

修改專案伺服器時區與校準為當前時間,問題完美解決。

#刪除當前預設時區的配置檔案,不建議直接刪除(出於操作安全考慮),最好是使用mv命令重新命名
mv /etc/localtime /etc/localtime.bak    
#建立軟連線檔案到配置檔案區,替換掉之前刪掉或備份的/etc/localtime 檔案
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
#檢視當前時區
timedatectl
#設定當前時區為上海,因為mysql伺服器時區也是用的上海
timedatectl set-timezone Asia/Shanghai  
 #安裝時間同步應用
yum install -y ntp 
#同步上海授時中心時間
ntpdate ntp.api.bz
#再次檢視時間
date
#開啟定時任務編輯器,設定每天晚上23:59同步時間(也可不設定)
crontab -e
59 23 * * *  ntpdate ntp.api.bz 

相關文章