大話tomcat之tomcat鏈接mysql

研究主題: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,運維是一種任重而道遠的背鍋歷程,哈哈不要輕易懷疑本身的智商,若是說點打擊的話開發最終拼的是腦子,我本不想說這種話,怕大家給我攢人氣,但畢竟那就是事實,一我的的聰明就決定了他可提高的高度,聰明的人尚且在哪裏努力學習,像咱們這種天生腦子就轉的不快的人就更應該拿出多於他幾倍的時間來研究學習,以此來縮短咱們與這些本就聰明的大牛之間的距離,固然有的人也拿出了多於他幾倍的時間,只不過是在發牢騷或者泡妞 ,我這裏不是說不讓你發牢騷不取媳婦,而是當你用羨慕的目光觀望和你在同一個行業但薪水不同的大牛時,最起碼你腦子裏第一個想的應該是計劃,我要在多長多長時間達到一個什麼目標,而不是你累計吃了多少六個核桃。學習沒有捷徑,若是學習有統一範式,那麼你不上清華北大你真冤。既然咱們不能垂直擴展,那咱們就想辦法橫向擴展。天道酬勤,不是不牛,只是時候未到

相關文章
相關標籤/搜索