一、起因与原因分析过程
前端小伙伴儿告诉我,说服务器崩了。
请求数据接口,接口有响应,但报的json提示指向:数据库异常错误。
遂登陆云主机查看日志,核心记录显示如下:
2018-11-09 22:15:53.824 ERROR 26088 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization. com.mysql.jdbc.exceptions.jdbc4.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. Caused by: java.net.UnknownHostException: abc.cn: Temporary failure in name resolution【名称解析的临时失败】
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_151]
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) ~[na:1.8.0_151]
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) ~[na:1.8.0_151]
at java.net.InetAddress.getAllByName0(InetAddress.java:1276) ~[na:1.8.0_151]
at java.net.InetAddress.getAllByName(InetAddress.java:1192) ~[na:1.8.0_151]
at java.net.InetAddress.getAllByName(InetAddress.java:1126) ~[na:1.8.0_151]
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:188) ~[mysql-connector-java-5.1.47.jar!/:5.1.47]
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:301) ~[mysql-connector-java-5.1.47.jar!/:5.1.47]
... 67 common frames omitted 2018-11-09 22:15:53.825 WARN 26088 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : Communications link failure Caused by: java.net.UnknownHostException: abc.cn
at java.net.InetAddress.getAllByName0(InetAddress.java:1280) ~[na:1.8.0_151]
at java.net.InetAddress.getAllByName(InetAddress.java:1192) ~[na:1.8.0_151]
at java.net.InetAddress.getAllByName(InetAddress.java:1126) ~[na:1.8.0_151]
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:188) ~[mysql-connector-java-5.1.47.jar!/:5.1.47]
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:301) ~[mysql-connector-java-5.1.47.jar!/:5.1.47]
... 66 common frames omitted 2018-11-09 22:15:56.741 WARN 26088 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08S01
2018-11-09 22:15:56.742 ERROR 26088 --- [ main] 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.
2018-11-09 22:15:56.750 WARN 26088 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
2018-11-09 22:15:56.764 INFO 26088 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-11-09 22:15:56.877 INFO 26088 --- [ main] ConditionEvaluationReportLoggingListener :
第一次遇到这问题,有点懵,直接把所有的SpringBoot和tomcat相关进程kill了;重启SpringBoot项目(jar包);查看日志,项目启动失败。Excuse Me?
搜索该问题UnknownHostException: abc.cn: Temporary failure in name resolution,事情有了转机:怀疑确实是域名解析出了问题,DNS失败。
做出假(huai)设(yi):我的云主机所属云服务器提供商的服务器集群所处内网不能直接访问/解析外网的域名,导致DNS失败。
验证假设:
本地电脑Ping域名:ping abc.com ,成功响应IP地址 x.y.z.q【外网解析域名正常】
在云主机Ping域名abc.com,未成功响应,如下图。【云主机内网解析域名失败】
验证成功。
那么,如何解决: 云主机在云服务器提供商的内部不能解析域名(abc.com),从而DNS解析失败,导致不能连接数据库所致 的问题?
二、解决方案
原理:类似于平时我们在本地电脑fq或者破解某些软件的验证关时,更改windows的host文件,让主机的网络请求DNS优先解析本地的[IP 域名]解析配置。
扩展子问题1:DNS概念
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
扩展子问题2:DNS整套解析系统的原理?(忘了?就请去复习)
解决方法:
方法1:新增配置云主机
step1.HOST 本地DNS解析【仅此方法,已被亲测有效】
vi /etc/hosts
step2.添加<IP,域名>解析。例如:
223.231.234.33 www.baidu.com
方法2: 网卡配置文件DNS服务地址【特点:重启服务器不会被抹掉配置】
vi /etc/sysconfig/network-scripts/ifcfg-eth0
添加DNS服务器地址。例如:
DSN1='114.114.114.114'
【备注】免费公共的DNS有:(详见:DNS服务器地址)
Google DNS | 8.8.8.8,8.8.4.4 |
Public DNS+ | 119.29.29.29 |
阿里 DNS | 223.6.6.6,223.5.5.5 |
百度 DNS | 180.76.76.76 |
360 DNS | 电信:101.226.4.6 联通:123.125.81.6 移动:101.226.4.6 铁通:101.226.4.6 |
OpenDNS | 208.67.220.220 |
114DNS | 114.114.114.114,114.114.115.115 (有广告插入嫌疑) |
方法3:系统默认DNS配置【特点:重启服务器会被抹掉配置,非永久性】
vi /etc/resolv.conf
添加DNS服务器解析规则。例如:
nameserver 114.114.114.114
【小结】系统解析的优先级:方法1>方法2>方法3
方法4:项目不使用域名,直接使用IP地址【特点:治标不治本,不一定适用所有工程情况】
三、结果分析
1、Spring Boot的初始化肯定是先于Tomcat的,所以应该是Spring Boot的初始化过程中出现了阻塞导致应用启动过慢的问题。
2、Caused by: java.net.UnknownHostException: abc.cn:未知域名异常
3、Linux nano操作
保存 :Ctrl+O
退出:Ctrl+X
4、疑问:为什么之前项目部署就可以,且没有出问题呢?根本原因说明还没找到
四、参考文献
[1] LINUX DNS解析的3种修改方法~ 【推荐】
[2] DNS服务器地址 【推荐】
[3] Temporary failure in name resolution - DNS引发的问题和思考 【推荐:解题思路清晰】
[5] nano编辑器使用教程