研究主题:tomcat链接mysqlhtml
一.tomcat链接mysql的两种链接方式:
简单链接(不使用链接池)
使用tomcat链接池java
二.简单分析:(简介部分摘自一篇博客,以为写得很是赞,读了很是有快感,就引用来与你们分享)python
对于一个简单的数据库应用,因为对于数据库的访问不是很频繁。这时能够简单地在须要访问数据库时,就建立一个链接,用完后就关闭它
这样也不会带来什么明显的性能上的开销。可是对于一个复杂的数据库应用,QPS和TPS都并发很大的时候状况就彻底不一样了。频繁的创建,关闭链接,会极大的下降系统
的性能,TCP的三次握手和四次断开每次都须要消耗系统资源来处理,所以对于链接的使用成了系统性能的瓶颈mysql
经过创建一个数据库链接池以及一套链接使管理策略,使得一个数据库链接上能够高效,安全的复用,避免了数据库链接的频繁创建,闭关的
开销,对于共享资源,有一个很著名的设计模式:资源池。该模式正式为了解决资源频繁分配,释放所形成的问题。把该模式应用到数据库
链接管理领域,就是建一个数据库链接池,提供一套高效的链接分配,使用策略,最终目标是实现链接的高效,安全的复用。linux
数据库链接池的基本原理是在内部对象池中维护必定数量的数据库链接,并对外提供数据库链接获取和返回方法,即API。如:
外部使用者能够经过getConnection()方法获取链接,使用完毕后再经过releaseConnection()方法将链接返回,注意此时链接并无关闭
而是由链接池管理器回收,并为下一次使用作好准备。nginx
数据库链接池技术带来的优点:程序员
资源重用,因为数据库链接获得重用,避免了频繁建立,释放链接引发的大量性能开销。在减小系统消耗的基础上,另外一方面也增进了系统运行环境
的平稳性(减小内存碎片及数据库临时进程/线程的数量)。更快的系统响应速度。数据库链接池在初始化过程当中,每每已经建立了若干数据库链接置于
池中备用。与httpd的三种MPM工做方式相似,提早作好请求接收准备相关工做,此时链接的初始化工做均已完成。对于业务请求处理而言,直接利用现有
的可用链接,避免了数据库链接初始化和释放过程的时间开销,以空间换时间,从而缩减了系统总体响应时间。新的资源分配手段。对于多应用共享同一
数据库的系统而言,可在应用层经过数据库链接的配置,实现数据库链接池技术,今年前也许仍是个新鲜的话题,对于目前的业务系统而言,若是设计中
尚未考虑到链接池的应用,那赶快在设计文档中加上这部分的内容把。某一应用最大可用数据库链接数的限制,避免某一应用独占全部数据库资源
统一的链接管理,避免数据库链接泄露。在较为完备的数据库链接池实现中,可根据预先的链接占用设定超时时间,强制收回被占用的链接。从而避免了
常规数据库操做中可能出现的资源泄露。web
三.tomcat链接mysql的组件JDBC,你能够简单的理解为tomcat链接mysql驱动,或者JDBC翻译只不过它会多国语言。不一样协议之间要实现互通必须加一个中间层redis
JDBC(JAVA Data Base Connectivity)数据库链接是一种用于执行SQL语句的Java API,能够为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
JDBC提供了一种基准,据此能够构建更高级的工具和接口,使数据库开发人员可以编写数据库应用程序
有了JDBC,向各类关系数据发送SQL语句就是一件很容易的事。换言之,有了JDBC API,就没必要为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写
一个程序,或为访问Informix数据库又编写另外一个程序等等,程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。同时,将Java语言和JDBC
结合起来使程序员没必要为不一样的平台编写不一样的应用程序,只须写一遍程序就可让它在任何平台上运行,这也是Java语言“编写一次,到处运行”的优点sql
四.配置
说明:$CATALINA_HOME 表示tomcat的安装根目录,也叫家目录,此处我实验的tomcat一个实例的家目录以下:(我这台机子跑的是tomcat多实例)
export CATALINA_HOME="/usr/local/tomcat/instance/tomcat8002"
export CATALINA_BASE="/usr/local/tomcat/instance/tomcat8002
Host: 172.18.100.98
Port: TCP 8002
Connector HTTP
appBase:/usr/local/tomcat8002/webapps
[root@Tomcat_A tomcat8002]# tree -L 1
.
├── bin
├── conf
├── lib
├── logs
├── temp
├── webapps
└── work
A.tomcat简单链接mysql(不须要专门设置tomcat,只需把jdbc jar包扔到tomcat家目录下的lib,而后由web应用程序经过java方法调用JDBC来链接MySQL,程序端实现)
Step1.下载JDBC并解压( Mysql官方地址 http://dev.mysql.com/downloads/connector/j/)
shell>cd /usr/local/tomcat8002
shell>wget -c http://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.39.tar.gz
shell>unzip mysql-connector-java-5.1.39.tar.gz
Step2.拷贝解压后的jdbc相关jar包到$CATALINA_HOME/lib下
shell>cp -ra mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar /usr/local/tomcat8002/lib
Step3.经过web app来访问测试与mysql的链接,此处经过提供一个jsp测试页来模拟应用程序,注意文件必须以.jsp结尾,不然当作文本处理,此处个人测试页叫mysql.jsp代码以下:
shell>mkdir webapps/DBTest # 提供一个经过URL访问此页面的对应的文件系统路径,放在tomcat的数据家目录(appBase所指)下便可
shell>vim /usr/local/tomcat8002/webapps/DBTest/mysql.jsp
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> #注意字符编码,若是此页面有打印汉字,请把字符集配置为UTF-8,不然请求后页面返回乱码
<%@ page import="java.util.*" %>
<%@ page import="com.mysql.jdbc.Driver" %> #导入jdbc的相关类
<%@ page import="java.sql.*" %>
<%
String driverName="com.mysql.jdbc.Driver";
String userName="admin"; # 访问Mysql的一个用户名,这里仅是为测试,随便一个普通用户就能够
String userPasswd="admin"; # 访问Mysql密码
String dbName="tomcatdb"; # 经过用户admin能够访问的数据库,此数据库必须实现存在
String url="jdbc:mysql://172.18.200.200/"+dbName+"?user="+userName+"&password="+userPasswd; #定义访问数据库的IP的地址,端口,默认库,用户名和密码
Class.forName("com.mysql.jdbc.Driver").newInstance();
try
{
Connection connection=DriverManager.getConnection(url); #调用字符串变量url,主要是上面定义访问数据库时的一些参数和选项
out.println("Mysql connect is OK !"); # 若是访问默认数据库tomcatdb成功,则打印“Mysql connect is OK!”
connection.close(); # 断开与数据库的链接,默认mysql与客户端通常是长链接
}
catch( Exception e )
{
out.println( "connent mysql error:" + e ); # 若是访问默认数据库失败,则打印错误信息
}
%>
Step5.测试经过JDBC访问mysql,即怎么知道tomcat链接数据库是否成功,给出如下几种方式
1 打开浏览器输入 http://172.18.100.98:8002/DBTest/mysql.jsp #若是访问成功,则会返回“Mysql connect is OK!”,不然报错
2 shell>curl -i http://172.18.100.98:8002/DBTest/mysql.jsp
3 在被访问的数据库上使用抓包工具tcpdump查看,具体以下:
shell>tcpdump -i eth0 tcp dst port 3306 and dst host 172.18.200.200 -ennvvAASs 0 # 若是刷新页面能成功,则会抓到一些信息,-i 后面的网卡应该为经过此网卡能访问到mysql的网络设备
4 在数据库服务器上经过一些网路监控命令,如iftop ,iptraf,nethogs # 若是访问成功,则会有四层TCP的mysql相关信息
B.使用tomcat链接池
Step1.下载JDBC并解压( Mysql官方地址 http://dev.mysql.com/downloads/connector/j/)
shell>cd /usr/local/tomcat8002
shell>wget -c http://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.39.tar.gz
shell>unzip mysql-connector-java-5.1.39.tar.gz
Step2.拷贝解压后的jdbc相关jar包到$CATALINA_HOME/lib下
shell>cp -ra mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar /usr/local/tomcat8002/lib
Step3.启用并初始化一个链接池,四种配置方式(按配置生效的做用域)
全局:即对每一个web app都生效
局部:只对某个或某些web app生效
# 是否全局或局部主要是看配置文件中引不引入新的docBase 或者 appBase,经过这两个参数能够指定web应用的数据根目录
习惯用来全局生效的配置文件
1>.$CATALINA_HOME/conf/context.xml # tomcat会监视此文件的修改,若是有修改会从新部署web应用,因此支持热部署
<?xml version='1.0' encoding='utf-8'?>
<Context> # Context 标签内不用指定appBase,固然你能够指定appBase,那就不是全局生效了,若是有appBase或docBase
... #那只要在appBase或docBase所指的路径下部署的应用才生效,此文件习惯不加appBase或docBase,纯属我的习惯
</Context>
2>.$CATALINA_NAME/conf/server.xml # tomcat的主配置文件中修改,修改此文件不会从新部署响应的web应用,便可以全局生效,又能够局部生效
通常须要经过Context这个标签引入
<Context path="/url" docBase="path/appname " reloadable="ture" privileged="true">
...
</Context>
习惯用来局部生效的配置文件
3>.$CATALINA_HOME/conf/Catalina/localhost/$appName.xml
#$appName.xml为你部署应用的项目名称,tomcat会监视此文件的修改,若是有修改会从新部署web应用,因此也支持热部署,通常须要本身手动建立$appName.xml
shell>vim $CATALINA_HOME/conf/Catalina/localhost/$appName.xml
4>$CATALINA_HOME/webapps/$appName/META-INF/context.xml
#tomcat会监视此文件的修改,若是有修改会从新部署web应用,因此支持热部署,通常须要在$CATALINA_HOME/webapps/$appName 手动建立META-INF目录
启用tomcat链接池的代码以下,你能够放在上面4种方式中的一种,本次实验推荐使用第三中配置方式,$appName=DBTest,这次我把测试页放到了DBTest这个目录下
shell>vim /usr/local/tomcat8002/conf/Catalina/localhost/DBTest.xml
<?xml version="1.0" encoding="UTF-8"?> # xml配置格式文件都该有这一行,和配置自己没有多大关系
<Context path="/DBTest" docBase="DBTest" crossContext="true">
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
username="admin"
password="admin"
maxActive="850"
maxidle="80"
maxWait="10000"
removeAbandoned="true"
removeAbandonedTimeout="5"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://172.18.200.200:3306/tomcatdb?autoReconnect=true"
minEvictableIdleTimeMillis="4000"
timeBetweenEvictionRunsMillis="5000"/>
</Context>
#对以上参数表明的含义作一下简单说明
name # 初始化一个链接池,name用来指定链接池名字 ,后续访问mysql须要向此链接池发出链接申请,即要调用此name
auth # 是链接池管理权属性,Container表示容器管理
type # 对象类型
username #链接mysql的用户名
password #链接mysql的密码
maxActive # 最大链接数据库链接数,设 0 为没有限制,即最大并发链接数
maxidle #最大等待链接中的数量,超过空闲时间,数据库连 接将被标记为不可用,而后被释放。设为0表示无限,即最多空闲链接数
maxWait:最大创建链接等待时间, 单位为 ms, 若是超过此时间将接到异常。设为-1表示 无限制
driverClassName # 驱动的类名
url="jdbc:mysql://172.18.200.200:3306/tomcatdb?autoReconnect=true" 链接数据库用到的参数
jdbc:mysql #表示经过jdbc链接数据库类型为mysql
172.18.200.200:3306 # 数据库的地址和监听端口
tomcatdb # 链接数据库的默认库名
?autoReconnect=true #链接失败后尝试重连的次数,默认为3次
Step4.修改项目WEB-INF/web.xml 配置文件(若无,请新建),在“</web-app>”之上添加以下代码:
shell>vim /usr/local/tomcat8002/DBTest/WEB-INF/web.xml
<web-app>
<resource-ref>
<description>DB Connection</description> # 链接池描述信息,随便但最好作到见名思意
<res-ref-name>jdbc/TestDB</res-ref-name> # 链接池引用的名字此处要和上面Resource name 保持一致
<res-type>javax.sql.DataSource</res-type> # 链接池类型和上面type保持一致
<res-auth>Container</res-auth> # 链接池管理权属性,和上面auth保持 一致
</resource-ref>
</web-app>
Step5.提供测试tomcat启用链接池后的jsp测试页,放到相应的web app应用下便可,此处我放到/usr/local/tomcat8002/DBTest/下 并命名为mysql-pool.jsp,代码以下
简单代码:只测试是否能链接,没有执行查询语句
<%@ page language="java" %>
<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="javax.sql.*" %>
<%@ page import="java.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
try
{
Context initContext = new InitialContext(); # 使用InitialContext new一个initContext 初始化对象
Context envContext = (Context)initContext.lookup("java:/comp/env"); # 链接池访问方式和下面的配置一块儿决定,完整路径:“java:/comp/env/jdbc/TestDB”
DataSource ds = (DataSource)envContext.lookup("jdbc/TestDB"); # 链接池名字要和Resource里的name一致
Connection connection = ds.getConnection(); # 使用ds对象的getConnection()方法请求经过链接池链接mysql
out.println("Mysql connect is OK !"); # 链接成功,则返回Mysql connect is OK !
connection.close(); # 关闭链接,注意此处关闭是指链接池收回链接,释放本次的请求链接
}
catch( Exception e )
{
out.println( "connent mysql error:" + e ); # 链接失败则,输出错误
}
%>
带select查询的jsp代码:
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page language="java" %>
<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="javax.sql.*" %>
<%@ page import="java.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
try
{
Context initContext = new InitialContext();
Connection conn=null;
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/TestDB");
conn = ds.getConnection();
Statement stmt=conn.createStatement(ResultSet.CONCUR_READ_ONLY,ResultSet.CONCUR_UPDATABLE);
ResultSet rs=stmt.executeQuery("select * from admin"); # 填写你的查询语句,前提是你在数据库服务器上有建立测试的数据库和表
while(rs.next()){
out.println(rs.getInt(1));
out.println(rs.getString(2));
out.println(rs.getString(3));
}
out.println("数据库操做成功!"); # 查询成功则返回 "数据库操做成功!"
rs.close();
stmt.close();
conn.close();
} catch( Exception e ){
out.println( "connent mysql error:" + e ); # 链接失败,输出错误信息,此处能够看到链接失败后尝试的次数
}
%>
Step6.在172.18.200.200的主机上建立测试数据库tomcatdb和表admin
shell>mysql -uroot -p # 使用root登陆
mysql>create database tomcatdb character set utf8;
mysql>use tomcatdb
mysql>create table admin(
->userid int(10) unsigned not null,
->username char(20) not null,
->userpass varchar(30) default null,
->primary key (userid)
)engine=InnoDB default charset=utf8;
mysql>desc admin;
+----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| userid | int(10) unsigned | NO | PRI | NULL | |
| username | char(20) | YES | | NULL | |
| userpass | varchar(30) | YES | | NULL | |
+----------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql>insert into admin value
->(1,"tomcat","tomcatpass"),
->(2,"redis","redispass"),
->(3,"nginx","nginxpass"),
->(4,"mysql","mysqlpass);
mysql> select * from admin where userid<=4 and userid>=1 and userpass like '%pass' order by userid desc limit 0,4;
+--------+----------+------------+
| userid | username | userpass |
+--------+----------+------------+
| 4 | mysql | mysqlpass |
| 3 | nginx | nginxpass |
| 2 | redis | redispass |
| 1 | tomcat | tomcatpass |
+--------+----------+------------+
4 rows in set (0.04 sec)
mysql> select count(*) from admin where userid<=4 and userid>=1 and userpass like '%pass' order by userid desc limit 0,4;
+----------+
| count(*) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
mysql> select * from admin where userid<=4 and userid>=3 and userpass like '%pass' order by userid desc limit 1;
+--------+----------+-----------+
| userid | username | userpass |
+--------+----------+-----------+
| 4 | mysql | mysqlpass |
| 3 | nginx | nginxpass |
+--------+----------+-----------+
2 rows in set (0.00 sec)
mysql> select count(*) from admin where userid<=4 and userid>=3 and userpass like '%pass' order by userid desc limit 1;
+----------+
| count(*) |
+----------+
| 2 |
+----------+
1 row in set (0.02 sec)
说明:当在mysql命令行模式输入多行命令时,很是有用的命令
mysql>
提示符 含义
mysql> 准备好接受新命令。
-> 等待多行命令的下一行。
‘> 等待下一行,等待以单引号(“’”)开始的字符串的结束。
“> 等待下一行,等待以双引号(“””)开始的字符串的结束。
`> 等待下一行,等待以反斜点(‘`’)开始的识别符的结束。
/*> 等待下一行,等待以/*开始的注释的结束
mysql>sdfsdfs \c #取消操做,回到mysql>
mysql>
mysql>123
->456
->789\e # 进入mysql的vi模式,和shell里的vi同样,能够修改以前的命令。很是强大
mysql>create database test
->use test
->create table student
->\p # 打印上一条命令,你能够复制下来,用的时候粘贴便可
--------------
create database test use test create table students
--------------
mysql> create database test use test create table students
->
mysql> create database test use test create table students bck:create
bck:create # 使用ctrl+r 而后输入历史命令里的关键字,它会帮你找出最近和此关键字匹配的命令,和shell同样用法
Step7.在172.18.200.200 数据库主机上使用tcpdump抓包,开始监控
shell>tcpdump -i eth0 tcp dst port 3306 and dst host 172.18.200.200 -ennvvAASs 0 # 若是用户访问http://172.18.100.98:8002/DBTest/mysql-pool.jsp 就会抓到SELECT 语句
Step8.访问测试页mysql-pool.jsp
tomcat8002 这台主机上使用curl工具访问
shell>curl -i http://172.18.100.98/DBTest/mysql-pool.jsp
访问成功返回以下信息:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=34A44B073DFE4923C96873D56BDE44FB.Tomcat_A8002; Path=/DBTest/; HttpOnly
Content-Type: text/html;charset=utf-8
Content-Length: 107
Date: Sun, 18 Sep 2016 02:59:30 GMT
1 <---------------userid=1
tomcat <---------------username=tomcat
tomcatpass <---------------userpass=tomcatpass
2
redis
redispass
3
nginx
nginxpass
4
mysql
mysqlpass
数据库操做成功!
主机 172.18.200.200 返回以下信息:
10:59:30.291334 00:0c:29:c2:00:82 > 00:0c:29:57:d6:0f, ethertype IPv4 (0x0800), length 90: (tos 0x0, ttl 64, id 16926, offset 0, flags [DF], proto TCP (6), length 76)
172.18.100.98.49261 > 172.18.200.200.3306: Flags [P.], cksum 0x73c1 (correct), seq 2606082206:2606082230, ack 1672819362, win 259, options [nop,nop,TS val 49144395 ecr 49129503], length 24
..)W....).....E..LB.@.@.s>..db.....m...U..c.2.....s......
...K.........select * from admin <-------------哈哈,看到了什么
10:59:30.292212 00:0c:29:c2:00:82 > 00:0c:29:57:d6:0f, ethertype IPv4 (0x0800), length 109: (tos 0x0, ttl 64, id 16927, offset 0, flags [DF], proto TCP (6), length 95)
172.18.100.98.49261 > 172.18.200.200.3306: Flags [P.], cksum 0x3cdd (correct), seq 2606082230:2606082273, ack 1672819651, win 289, options [nop,nop,TS val 49144397 ecr 49129503], length 43
..)W....).....E.._B.@.@.s*..db.....m...U..c.3....!<......
...M....'....SHOW KEYS FROM `admin` FROM `tomcatdb` <---------------还有这,因此tcpdump真的很强
模拟tomcat链接不到mysql
1.经过tcpwrap 和 /etc/hosts.deny,/etc/hosts.allow
查看服务的二进制程序是否依赖libwrap库,好比sshd
shell>ldd `which sshd` | grep -i "libwrap" # ldd 只能检查二进制可执行程序的动态库依赖关系
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007fea0adee000)
shell>echo "ssh:172.18.100.98 deny all" >> /etc/hosts.allow # 协议:IP/network deny all,表示只有172.18.100.98 能够经过ssh协议访问本机,其余都被拒绝
测试效果以下
[root@Slave1 ~]# ssh root@172.18.200.200
root@172.18.200.200's password:
Permission denied, please try again.
root@172.18.200.200's password:
查看mysql是否依赖libwrap库
shell>ldd `which mysqld` | grep -i "libwrap"
shell>echo $? # 查看上条命令执行结果状态,只有0表示成功。# mysqld 不依赖libwrap库
2.经过iptables,在filter表中input链上禁止来自172.18.100.98的用户访问本地tcp 3306提供的服务
shell>iptable -L -nv --line # 注意防火墙的默认策略和现有的防火墙规则。
shell>iptables -t filter -I INPUT 1 -p tcp -s 172.18.100.98 -d 172.18.200.200 --dport 3306 -j DROP #若是默认策略为DROP,就不用添加此条规则,若是默认策略为ACCEPT,则添加此规则到第一条
shell>watch -n 1 'iptables -L -nv --line'
Chain INPUT (policy ACCEPT 718 packets, 34988 bytes)
num pkts bytes target prot opt in out source destination
1 335 19925 DROP tcp -- * * 172.18.100.98 172.18.200.200 # pkts 335 表示此规则匹配到了335个包,都被拒掉了
tcp dpt:3306
tcpdump 结果以下:能看到来自172.18.100.98的请求但没有看到172.18.200.200到172.18.100.98 的响应,说明当数据包到达200.200这台主机的内核空间时,被linux netfilter模块过滤掉了,因此到不了用户空间3306所指的进程
11:46:38.880410 00:0c:29:c2:00:82 > 00:0c:29:57:d6:0f, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 31306, offset 0, flags [DF], proto TCP (6), length 60)
172.18.100.98.49336 > 172.18.200.200.3306: Flags [S], cksum 0xc5be (correct), seq 1018473209, win 14600, options [mss 1460,sackOK,TS val 51972993 ecr 0,nop,wscale 6], length 0
0x0000: 000c 2957 d60f 000c 29c2 0082 0800 4500 ..)W....).....E.
0x0010: 003c 7a4a 4000 4006 3b22 ac12 6462 ac12 .<zJ@.@.;"..db..
0x0020: c8c8 c0b8 0cea 3cb4 aaf9 0000 0000 a002 ......<.........
0x0030: 3908 c5be 0000 0204 05b4 0402 080a 0319 9...............
0x0040: 0b81 0000 0000 0103 0306 ..........
11:46:39.567454 00:0c:29:c2:00:82 > 00:0c:29:57:d6:0f, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 48704, offset 0, flags [DF], proto TCP (6), length 60)
172.18.100.98.49335 > 172.18.200.200.3306: Flags [S], cksum 0x1096 (correct), seq 1868180174, win 14600, options [mss 1460,sackOK,TS val 51973680 ecr 0,nop,wscale 6], length 0
0x0000: 000c 2957 d60f 000c 29c2 0082 0800 4500 ..)W....).....E.
0x0010: 003c be40 4000 4006 f72b ac12 6462 ac12 .<.@@.@..+..db..
0x0020: c8c8 c0b7 0cea 6f5a 2ace 0000 0000 a002 ......oZ*.......
curl结果:一开始curl一直卡着,实际上是等待链接池失败链接重试 一共重试三次,每次尝试时间maxWait="10000",即每次10s ,30s事后,都要返回给客户端结果,但链接池一直会尝试链接mysql,tcpdump里能够看到
[root@Tomcat_A tomcat8002]# curl -i http://172.18.100.98:8002/DBTest/mysql-pool2.jsp
HTTP/1.1 200 OK <-------------为何状态返回值仍是 200 由于你的测试页里有链接尝试失败后返回异常,只不过这是个错误页面,可是jsp的正常响应,只是经过你jsp里的方法访问不到mysql而已
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=A6813E97F41C523A41D733FD29DFD8FB.Tomcat_A8002; Path=/DBTest/; HttpOnly
Content-Type: text/html;charset=utf-8
Content-Length: 186
Date: Sun, 18 Sep 2016 03:40:37 GMT
connent mysql error:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
# Attempted reconnect 3 times ---> 可知重试了3次
tomcat日志
shell>tailf /usr/local/tomcat8002/logs/catalina.out # 反馈信息以下
com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195)
com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184)
com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200)
com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086)
com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073)
com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44)
com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
#明显抛出异常了,在172.18.200.200 执行iptables -D INPUT 1
总结:不作不知道,一作吓一跳,不要怕出错,不要怕看不懂代码,先作出效果来再说,写代码也不是天生的,只要一心向佛,总有一天你也是代码达人,不求写出多么优秀的代码,但求别人能看懂若是运维不去学一门正真意义上的编程语言,我只能说等待开发的小爷们给你翻白眼吧,建议jsp,python,lua,运维是一种任重而道远的背锅历程,哈哈不要轻易怀疑本身的智商,若是说点打击的话开发最终拼的是脑子,我本不想说这种话,怕大家给我攒人气,但毕竟那就是事实,一我的的聪明就决定了他可提高的高度,聪明的人尚且在哪里努力学习,像咱们这种天生脑子就转的不快的人就更应该拿出多于他几倍的时间来研究学习,以此来缩短咱们与这些本就聪明的大牛之间的距离,固然有的人也拿出了多于他几倍的时间,只不过是在发牢骚或者泡妞 ,我这里不是说不让你发牢骚不取媳妇,而是当你用羡慕的目光观望和你在同一个行业但薪水不同的大牛时,最起码你脑子里第一个想的应该是计划,我要在多长多长时间达到一个什么目标,而不是你累计吃了多少六个核桃。学习没有捷径,若是学习有统一范式,那么你不上清华北大你真冤。既然咱们不能垂直扩展,那咱们就想办法横向扩展。天道酬勤,不是不牛,只是时候未到