當(dāng)前的連接數(shù):
mysql> show status like '%Threads_connected%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 27 |
+-------------------+-------+
1 row in set (0.00 sec)
最大連接數(shù):
show variables like '%max_connections%';
set GLOBAL max_connections=800;
flush privileges
也可以修改/etc/my.cnf中的max_connections:
max_connections = 1000
關(guān)于php應(yīng)該在何時(shí)調(diào)用mysql_close()以及pconnect方式和傳統(tǒng)方式有何種區(qū)別收藏
以前我一直認(rèn)為,當(dāng)php的頁面執(zhí)行結(jié)束時(shí),會(huì)自動(dòng)釋放掉一切。相信很多人都跟我想的一樣。但事實(shí)證明并不是這樣。比如session就不會(huì)隨著頁面執(zhí)行完畢而釋放。
php的垃圾回收機(jī)制,其實(shí)只針對(duì)于php本身。對(duì)于mysql,php沒權(quán)利去自動(dòng)去釋放它的東西。如果你在頁面執(zhí)行完畢前不調(diào)用mysql_close(),那么mysql那邊是不會(huì)關(guān)閉這個(gè)連接的。如果你是用的是pconnect方式,即使你在頁面執(zhí)行完畢前調(diào)用mysql_close(),也無法另mysql關(guān)閉這個(gè)連接。
也許在負(fù)載低的情況下,你感受不到有何不妥。但是,一旦負(fù)載很高,就回出現(xiàn)很多的死鏈接,于是得殺掉它們,現(xiàn)象:
在php中使用pconnect方式建立連接,然后到mysql客戶端下執(zhí)行show processlist;如果你的負(fù)載到一定程度的話,你可以看到很多sleep的進(jìn)程,這些進(jìn)程就是人們常說的死連接,它們會(huì)一直保持sleep,直到my.cnf里面設(shè)置的wait_timeout這個(gè)參數(shù)值的時(shí)間到了,mysql才會(huì)自己殺死它。在殺死它的時(shí)候,mysql還會(huì)在error-log里面記錄一條Aborted connection xxx to db: 'xxx' user: 'xxx' host: 'xxx'的日志,用google翻譯一下,會(huì)得到一個(gè)相當(dāng)強(qiáng)悍的解釋"胎死腹中的連接"!
那么造成sleep的原因,有三個(gè),下面是mysql手冊(cè)給出的解釋:
1.客戶端程序在退出之前沒有調(diào)用mysql_close().[寫程序的疏忽,或者數(shù)據(jù)庫的db類庫沒有自動(dòng)關(guān)閉每次的連接。。。]
2.客戶端sleep的時(shí)間在wait_timeout或interactive_timeout規(guī)定的秒內(nèi)沒有發(fā)出任何請(qǐng)求到服務(wù)器. [類似常連,類似于不完整的tcp ip協(xié)議構(gòu)造,服務(wù)端一直認(rèn)為客戶端仍然存在(有可能客戶端已經(jīng)斷掉了)]
3.客戶端程序在結(jié)束之前向服務(wù)器發(fā)送了請(qǐng)求還沒得到返回結(jié)果就結(jié)束掉了. [參看:tcp ip協(xié)議的三次握手]
網(wǎng)上有一個(gè)哥們寫了一個(gè),如下:
<?php
define('MAX_SLEEP_TIME', 120);
$hostname = "localhost";
$username = "root";
$password = "password";
$connect = mysql_connect($hostname, $username, $password);
$result = mysql_query("SHOW PROCESSLIST", $connect);
while ($proc = mysql_fetch_assoc($result)) {
if ($proc["Command"] == "Sleep" && $proc["Time"] > MAX_SLEEP_TIME) {
@mysql_query("KILL " . $proc["Id"], $connect);
}
}
mysql_close($connect);
?>
將它當(dāng)中的 $password 改成你實(shí)際的數(shù)據(jù)庫密碼,死連接的時(shí)間也可以修改。然后加入計(jì)劃任務(wù)就可以了。比如用 crontab -e 命令加入:
*/2 * * * * php /usr/local/sbin/kill-mysql-sleep-proc.php就可以每隔 2 分鐘檢查并清除一次數(shù)據(jù)庫中的死連接了。
我結(jié)合自己的實(shí)際改寫如下:
<?php
require_once 'services/UserServices*.class.php';
define('MAX_SLEEP_TIME', 120);//注意調(diào)試的時(shí)候這兒只能修改120,而不能在重新定義,常量一旦定義好,就不能被重新定義了。PHP預(yù)先定義了幾個(gè)常量,并提供了一種機(jī)制在運(yùn)行時(shí)自己定義。常量和變量基本上是一樣的,不同的是:常量必須用DEFINE函數(shù)定義,常量一旦定義好,就不能被重新定義了。
$scoreServ = new TMService ( );
$sql = "SHOW PROCESSLIST";
$proc = $scoreServ*->query($sql);
foreach($proc as $oneproc)
{
if ($oneproc["Command"] == "Sleep" && $oneproc["Time"] >= MAX_SLEEP_TIME)
{
$query = "KILL " . $oneproc["Id"];
echo $query."\n";
@$scoreServ*->query($query);
}
}
?>
crontab 加入:
*/2 * * * * /usr/local/php/bin/php /usr/local/tads/htdocs/*/src/crontable/killmysqlsleepproc.php
聽說可以做mysql的設(shè)置也可以的如下:
配置MYSQL里的參數(shù)。超時(shí)時(shí)間設(shè)置。
max_connections:
允許的同時(shí)客戶的數(shù)量。負(fù)載過大時(shí),你將經(jīng)常看到 too many connections 錯(cuò)誤。已達(dá)到最大鏈接數(shù),所以會(huì)出現(xiàn)這種情況。 我們服務(wù)器數(shù)值是200。
wait_timeout
服務(wù)器在關(guān)閉連接之前在一個(gè)連接上等待行動(dòng)的秒數(shù),默認(rèn)數(shù)值是28800,即如果沒有事情發(fā)生,服務(wù)器在 8個(gè)小時(shí)后關(guān)閉連接。防止sleep過而導(dǎo)致出現(xiàn)too many connections
如果你的sleep進(jìn)程數(shù)在同一時(shí)間內(nèi)過多,再加上其他狀態(tài)的連接,總數(shù)超過了max_connection的值,那mysql除了root用戶外,就無法再繼續(xù)處理任何請(qǐng)求無法與任何請(qǐng)求建立連接或者直接down了。所以,這個(gè)問題在大負(fù)載的情況下還是相當(dāng)嚴(yán)重的。如果發(fā)現(xiàn)你的mysql有很多死連接存在,首先要先檢查你的程序是否使用的是pconnect的方式,其次,檢查在頁面執(zhí)行完畢前是否及時(shí)調(diào)用了mysql_close(),
還有一個(gè)辦法,你可以在my.cnf里面加上wait_timeout和interactive_timeout,把他們的值設(shè)的小一些,默認(rèn)情況下wait_timeout的值是8小時(shí)的時(shí)間,你可以改成1個(gè)小時(shí),或半個(gè)小時(shí)。這樣mysql會(huì)更快的殺死死連接。防止連接總數(shù)超過max_connection的值。或者把max_connection的值設(shè)置的更大,不過這樣顯然不妥,連接的數(shù)量越多,對(duì)你服務(wù)器的壓力越大。實(shí)際上那些連接都是冗余的,把它們盡快殺死才是上策。
以前總是說,在使用php連接mysql的時(shí)候,盡量不要使用pconnect的方式,看完我上面所說的那些,應(yīng)該可以明白為什么了吧,因?yàn)槲覀兪褂胮hp大多數(shù)情況下都是做web開發(fā),web開發(fā)是面向多用戶,那么用戶的數(shù)量與mysql連接數(shù)是成正比的。使用pconnect的方式,即使你的調(diào)用mysql_close()也是無法釋放數(shù)據(jù)庫連接的,那么mysql中的死連接的數(shù)量就會(huì)越來越多了。
我認(rèn)為,只有當(dāng)你的應(yīng)用屬于那種點(diǎn)對(duì)點(diǎn)方式,或者你能保證連接數(shù)量很少的情況,才有必要去采用pconnect的方式,因?yàn)檫B接數(shù)量少,那么讓它一直處于連接狀態(tài),避免了重復(fù)打開關(guān)閉的過程。這樣可能會(huì)比傳統(tǒng)方式更好一些。
至于何時(shí)該去調(diào)用mysql_close(),最正確的做法是如果下面不再執(zhí)行mysql的操作了,在你上一次執(zhí)行完mysql操作后,立刻就調(diào)用mysql_close()。這才是最正確的做法,并不是總要把mysql_close()寫在頁面最后一行就可以了。
如果你沒有修改過MySQL的配置,缺省情況下,wait_timeout的初始值是28800。
wait_timeout過大有弊端,其體現(xiàn)就是MySQL里大量的SLEEP進(jìn)程無法及時(shí)釋放,拖累系統(tǒng)性能,不過也不能把這個(gè)指設(shè)置的過小,否則你可能會(huì)遭遇到“MySQL has gone away”之類的問題,通常來說,我覺得把wait_timeout設(shè)置為10是個(gè)不錯(cuò)的選擇,但某些情況下可能也會(huì)出問題,比如說有一個(gè)CRON腳本,其中兩次SQL查詢的間隔時(shí)間大于10秒的話,那么這個(gè)設(shè)置就有問題了(當(dāng)然,這也不是不能解決的問題,你可以在程序里時(shí)不時(shí)mysql_ping一下,以便服務(wù)器知道你還活著,重新計(jì)算wait_timeout時(shí)間): # vi /etc/my.cnf
[mysqld]
wait_timeout=10
# /etc/init.d/mysql restart
復(fù)制代碼不過這個(gè)方法太生硬了,線上服務(wù)重啟無論如何都應(yīng)該盡可能避免,看看如何在MySQL命令行里通過SET來設(shè)置: mysql> set global wait_timeout=10;
mysql> show global variables like '%timeout';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| wait_timeout | 10 |
+----------------------------+-------+
復(fù)制代碼這里一個(gè)容易把人搞蒙的地方是如果查詢時(shí)使用的是show variables的話,會(huì)發(fā)現(xiàn)設(shè)置好像并沒有生效,這是因?yàn)閱渭兪褂胹how variables的話就等同于使用的是show session variables,查詢的是會(huì)話變量,只有使用show global variables,查詢的才是全局變量。
網(wǎng)絡(luò)上很多人都抱怨說他們set global之后使用show variables查詢沒有發(fā)現(xiàn)改變,原因就在于混淆了會(huì)話變量和全局變量,如果僅僅想修改會(huì)話變量的話,可以使用類似set wait_timeout=10;或者set session wait_timeout=10;這樣的語法。
另一個(gè)值得注意的是會(huì)話變量wait_timeout初始化的問題,這一點(diǎn)在手冊(cè)里已經(jīng)明確指出了,我就直接拷貝了:
On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()).
MySQL大拿Jeremy Zawodny曾在他的文章Fixing Poor MySQL Default Configuration Values里面列出了幾個(gè)很惡心的MySQL缺省設(shè)置,不過沒包含wait_timeout,但我覺得它也應(yīng)該算一個(gè),每次新裝MySQL后最好都記得修改它。
以上的修改配置來源網(wǎng)頁:
http://www.tech-q.cn/redirect.php?tid=4005&goto=lastpost
mysql>show variables like '%timeout';
打印結(jié)果如下:
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| connect_timeout | 5 |
| delayed_insert_timeout | 300 |
| interactive_timeout | 28800 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+----------------------------+-------+
interactive_timeout 需在mysql_connect()設(shè)置CLIENT_INTERACTIVE選項(xiàng)后起作用,并被賦值為wait_timeout;
mysql>set wait_timeout = 10; 對(duì)當(dāng)前交互鏈接有效;
mysql>set interactive_timeout = 10; 對(duì)后續(xù)起的交互鏈接有效;
該超時(shí)時(shí)間單位是秒,從變量從上次SQL執(zhí)行后算起;當(dāng)前空閑若超過該時(shí)間,則也會(huì)被強(qiáng)制斷開。
想把mysql的連接斷開時(shí)間改長一些,以前只改了connect_timeout變量的值,還不夠。現(xiàn)在又改了這兩個(gè),不知夠不夠。不夠再繼續(xù)查吧。
注意:對(duì)兩個(gè)值都做修改才生效:set interactive_timeout=120; set wait_timeout=120;
mysql> show variables like '%timeout';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| connect_timeout | 5 |
| delayed_insert_timeout | 300 |
| interactive_timeout | 28800 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| table_lock_wait_timeout | 50 |
| wait_timeout | 28800 |
+-------------------------+-------+
mysql> set interactive_timeout=120; set wait_timeout=120;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%timeout';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| connect_timeout | 5 |
| delayed_insert_timeout | 300 |
| interactive_timeout | 120 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| table_lock_wait_timeout | 50 |
| wait_timeout | 120 |
+-------------------------+-------+
修改全局變量:
set global interactive_timeout=120;set global wait_timeout=120;
mysql> show global variables like '%timeout';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| connect_timeout | 5 |
| delayed_insert_timeout | 300 |
| interactive_timeout | 120 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| table_lock_wait_timeout | 50 |
| wait_timeout | 120 |
+-------------------------+-------+
特別注意全局和一般變量時(shí)不一樣的兩個(gè)變量,這也就是為何導(dǎo)致修改沒有起作用的原因!!!!
配置修改:
直接的修改 /etc/my.cnf這個(gè)文件中
-------------------------------------------
[mysqld]
wait_timeout = 86400
interactive_timeout = 86400
--------------------------------------------
添加這兩行,然后重新啟動(dòng)mysql服務(wù)就OK了
文章來源:
http://blog.chinaunix.net/u2/60332/showart_2096857.html
近一段時(shí)間,部門同事反映在使用mysql的過程出現(xiàn)數(shù)據(jù)庫連接問題
應(yīng)用程序和數(shù)據(jù)庫建立連接,如果超過8小時(shí)應(yīng)用程序不去訪問數(shù)據(jù)庫,數(shù)據(jù)庫就斷掉連接 。這時(shí)再次訪問就會(huì)拋出異常,如下所示:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
...
查了一下發(fā)現(xiàn)應(yīng)用程序和mysql數(shù)據(jù)庫建立連接,如果超過8小時(shí)應(yīng)用程序不去訪問數(shù)據(jù)庫,數(shù)據(jù)庫就斷掉連接 。這時(shí)再次訪問就會(huì)拋出異常。
關(guān)于mysql自動(dòng)斷開的問題研究結(jié)果如下,在mysql中有相關(guān)參數(shù)設(shè)定,當(dāng)數(shù)據(jù)庫連接空閑一定時(shí)間后,服務(wù)器就會(huì)斷開等待超時(shí)的連接:
1、相關(guān)參數(shù),紅色部分
mysql> show variables like '%timeout%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| connect_timeout | 5 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 50 |
| interactive_timeout | 28800 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+--------------------------+-------+
同一時(shí)間,這兩個(gè)參數(shù)只有一個(gè)起作用。到底是哪個(gè)參數(shù)起作用,和用戶連接時(shí)指定的連接參數(shù)相關(guān),缺省情況下是使用wait_timeout。我建議是將這兩個(gè)參數(shù)都修改,以免引起不必要的麻煩。
2、修改參數(shù)
這兩個(gè)參數(shù)的默認(rèn)值是8小時(shí)(60*60*8=28800)。我測試過將這兩個(gè)參數(shù)改為0,結(jié)果出人意料,系統(tǒng)自動(dòng)將這個(gè)值設(shè)置為1。換句話說,不能將該值設(shè)置為永久。
將這2個(gè)參數(shù)設(shè)置為24小時(shí)(60*60*24=604800)即可。
set interactive_timeout=604800;
set wait_timeout=604800;
也可以修改my.cof,修改后重起mysql
打開/etc/my.cnf,在屬性組mysqld下面添加參數(shù)如下:
[mysqld]
interactive_timeout=28800000
wait_timeout=28800000
如果一段時(shí)間內(nèi)沒有數(shù)據(jù)庫訪問則mysql自身將切斷連接,之后訪問java訪問連接池時(shí)對(duì)數(shù)據(jù)庫的數(shù)據(jù)通道早就關(guān)閉了,因?yàn)閐bcp連接池?zé)o法時(shí)時(shí)維護(hù)與數(shù)據(jù)庫的連接關(guān)系,mysql5以后即使在dbcp配置中加入autoReconnect=true也沒有效果。
言歸正傳,接著來,shell腳本實(shí)現(xiàn)如下:
#!/bin/sh
注:這個(gè)腳本運(yùn)行后會(huì)每五秒去檢測一次 mysql的sleep進(jìn)程數(shù)
while :
do
n=`/usr/bin/mysqladmin processlist | grep -i sleep | wc -l`
date=`date +%Y%m%d\[%H:%M:%S]`
echo $n
if [ "$n" -gt 10 ]
then
for i in `/usr/bin/mysqladmin processlist | grep -i sleep | awk '{print $2}'`
do
/usr/bin/mysqladmin kill $i
done
echo "sleep is too many i killed it" >> /tmp/sleep.log
echo "$date : $n" >> /tmp/sleep.log
fi
sleep 5
done
crontab實(shí)現(xiàn):不會(huì)循環(huán)的腳本(配合crontab使用)
#!/bin/sh
n=`/usr/bin/mysqladmin processlist | grep -i sleep | wc -l`
date=`date +%Y%m%d\[%H:%M:%S]`
echo $n
if [ "$n" -gt 10 ]
then
for i in `/usr/bin/mysqladmin processlist | grep -i sleep | awk '{print $2}'`
do
/usr/bin/mysqladmin kill $i
done
echo "sleep is too many i killed it" >> /tmp/sleep.log
echo "$date : $n" >> /tmp/sleep.log
fi
你可能還會(huì)用到查詢mysql當(dāng)前連接數(shù):
1.show status
Threads_connected 當(dāng)前的連接數(shù)
Connections 試圖連接到(不管是否成功)MySQL服務(wù)器的連接數(shù)。
Max_used_connections 服務(wù)器啟動(dòng)后已經(jīng)同時(shí)使用的連接的最大數(shù)量。
2.set GLOBAL max_connections=連接數(shù);
flush privileges
3.修改/etc/my.cnf中的max_connections
4.show processlist 顯示當(dāng)前正在執(zhí)行的mysql連接
5.mysqladmin -u<user> -p<pwd> -h<host> status
顯示當(dāng)前mysql狀態(tài)
Uptime: 13131 Threads: 1 Questions: 22 Slow queries: 0 Opens: 16 Flush tables: 1 Open tables: 1 Queries per second avg: 0.1
mysqladmin -u<user> -p<pwd> -h<host> extended-status
顯示mysql的其他狀態(tài)
+-----------------------------------+----------+
| Variable_name | Value |
+-----------------------------------+----------+
| Aborted_clients | 0 |
| Aborted_connects | 1 |
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Bytes_received | 1152 |
| Bytes_sent | 10400 |
| Com ......
參看:
http://www.justwinit.cn/post/2262/
http://www.coolcode.cn/?action=show&id=237
http://www.eb163.com/club/thread-1708-1-1.html
http://hualulu.com/blog/?p=16
http://www.51testing.com/?uid-199-action-viewspace-itemid-76740
補(bǔ)充:
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
會(huì)得到類似下面的結(jié)果,具體數(shù)字會(huì)有所不同:
LAST_ACK 1
SYN_RECV 14
ESTABLISHED 79
FIN_WAIT1 28
FIN_WAIT2 3
CLOSING 5
TIME_WAIT 1669
狀態(tài):描述
CLOSED:無連接是活動(dòng)的或正在進(jìn)行
LISTEN:服務(wù)器在等待進(jìn)入呼叫
SYN_RECV:一個(gè)連接請(qǐng)求已經(jīng)到達(dá),等待確認(rèn)
SYN_SENT:應(yīng)用已經(jīng)開始,打開一個(gè)連接
ESTABLISHED:正常數(shù)據(jù)傳輸狀態(tài)
FIN_WAIT1:應(yīng)用說它已經(jīng)完成
FIN_WAIT2:另一邊已同意釋放
ITMED_WAIT:等待所有分組死掉
CLOSING:兩邊同時(shí)嘗試關(guān)閉
TIME_WAIT:另一邊已初始化一個(gè)釋放
LAST_ACK:等待所有分組死掉
也就是說,這條命令可以把當(dāng)前系統(tǒng)的網(wǎng)絡(luò)連接狀態(tài)分類匯總。
下面解釋一下為啥要這樣寫:
一個(gè)簡單的管道符連接了netstat和awk命令。
------------------------------------------------------------------
先來看看netstat:
netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 123.123.123.123:80 234.234.234.234:12345 TIME_WAIT
你實(shí)際執(zhí)行這條命令的時(shí)候,可能會(huì)得到成千上萬條類似上面的記錄,不過我們就拿其中的一條就足夠了。
------------------------------------------------------------------
再來看看awk:
/^tcp/
濾出tcp開頭的記錄,屏蔽udp, socket等無關(guān)記錄。
state[]
相當(dāng)于定義了一個(gè)名叫state的數(shù)組
NF
表示記錄的字段數(shù),如上所示的記錄,NF等于6
$NF
表示某個(gè)字段的值,如上所示的記錄,$NF也就是$6,表示第6個(gè)字段的值,也就是TIME_WAIT
state[$NF]
表示數(shù)組元素的值,如上所示的記錄,就是state[TIME_WAIT]狀態(tài)的連接數(shù)
++state[$NF]
表示把某個(gè)數(shù)加一,如上所示的記錄,就是把state[TIME_WAIT]狀態(tài)的連接數(shù)加一
END
表示在最后階段要執(zhí)行的命令
for(key in state)
遍歷數(shù)組
print key,"\t",state[key]
打印數(shù)組的鍵和值,中間用\t制表符分割,美化一下。
如發(fā)現(xiàn)系統(tǒng)存在大量TIME_WAIT狀態(tài)的連接,通過調(diào)整內(nèi)核參數(shù)解決,
vim /etc/sysctl.conf
編輯文件,加入以下內(nèi)容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后執(zhí)行 /sbin/sysctl -p 讓參數(shù)生效。
net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當(dāng)出現(xiàn)SYN等待隊(duì)列溢出時(shí),啟用cookies來處理,可防范少量SYN攻擊,默認(rèn)為0,表示關(guān)閉;
net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認(rèn)為0,表示關(guān)閉;
net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認(rèn)為0,表示關(guān)閉。
net.ipv4.tcp_fin_timeout 修改系統(tǒng)默認(rèn)的 TIMEOUT 時(shí)間
下面附上TIME_WAIT狀態(tài)的意義:
客戶端與服務(wù)器端建立TCP/IP連接后關(guān)閉SOCKET后,服務(wù)器端連接的端口
狀態(tài)為TIME_WAIT
是不是所有執(zhí)行主動(dòng)關(guān)閉的socket都會(huì)進(jìn)入TIME_WAIT狀態(tài)呢?
有沒有什么情況使主動(dòng)關(guān)閉的socket直接進(jìn)入CLOSED狀態(tài)呢?
主動(dòng)關(guān)閉的一方在發(fā)送最后一個(gè) ack 后
就會(huì)進(jìn)入 TIME_WAIT 狀態(tài) 停留2MSL(max segment lifetime)時(shí)間
這個(gè)是TCP/IP必不可少的,也就是“解決”不了的。
也就是TCP/IP設(shè)計(jì)者本來是這么設(shè)計(jì)的
主要有兩個(gè)原因
1。防止上一次連接中的包,迷路后重新出現(xiàn),影響新連接
(經(jīng)過2MSL,上一次連接中所有的重復(fù)包都會(huì)消失)
2。可靠的關(guān)閉TCP連接
在主動(dòng)關(guān)閉方發(fā)送的最后一個(gè) ack(fin) ,有可能丟失,這時(shí)被動(dòng)方會(huì)重新發(fā)
fin, 如果這時(shí)主動(dòng)方處于 CLOSED 狀態(tài) ,就會(huì)響應(yīng) rst 而不是 ack。所以
主動(dòng)方要處于 TIME_WAIT 狀態(tài),而不能是 CLOSED 。
TIME_WAIT 并不會(huì)占用很大資源的,除非受到攻擊。
還有,如果一方 send 或 recv 超時(shí),就會(huì)直接進(jìn)入 CLOSED 狀態(tài)
sleep() 和 wait() 有什么區(qū)別?
sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。在sleep 時(shí)間間隔期滿后,線程不一定立即恢復(fù)執(zhí)行。這是因?yàn)樵谀莻€(gè)時(shí)刻,其它線程可能正在運(yùn)行而且沒有被調(diào)度為放棄執(zhí)行,除非(a)“醒來”的線程具有更高的優(yōu)先級(jí),(b)正在運(yùn)行的線程因?yàn)槠渌蚨枞?br />
wait是Object類的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,釋放當(dāng)前線程鎖定的任何對(duì)象。進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。
sleep()方法是本地方法,屬于Thread類,它有兩種定義:
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos) throws InterruptedException {
//other code
}
其中的參數(shù)millis代表毫秒數(shù)(千分之一秒),nanos代表納秒數(shù)(十億分之一秒)。這兩個(gè)方法都可以讓調(diào)用它的線程沉睡(停止運(yùn)行)指定的時(shí)間,到了這個(gè)時(shí)間,線程就會(huì)自動(dòng)醒來,變?yōu)榭蛇\(yùn)行狀態(tài)(RUNNABLE),但這并不表示它馬上就會(huì)被運(yùn)行,因?yàn)榫€程調(diào)度機(jī)制恢復(fù)線程的運(yùn)行也需要時(shí)間。調(diào)用sleep()方法并不會(huì)讓線程釋放它所持有的同步鎖;而且在這期間它也不會(huì)阻礙其它線程的運(yùn)行。上面的2個(gè)方法都聲明拋出一個(gè) InterruptedException類型的異常,這是因?yàn)榫€程在sleep()期間,有可能被持有它的引用的其它線程調(diào)用它的 interrupt()方法而中斷。中斷一個(gè)線程會(huì)導(dǎo)致一個(gè)InterruptedException異常的產(chǎn)生,如果你的程序不捕獲這個(gè)異常,線程就會(huì)異常終止,進(jìn)入TERMINATED狀態(tài),如果你的程序捕獲了這個(gè)異常,那么程序就會(huì)繼續(xù)執(zhí)行catch語句塊(可能還有finally語句塊)以及以后的代碼。
為了更好地理解interrupt()效果,我們來看一下下面這個(gè)例子:
public class InterruptTest {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
try {
System.out.println("我被執(zhí)行了-在sleep()方法前");
// 停止運(yùn)行10分鐘
Thread.sleep(1000 * 60 * 60 * 10);
System.out.println("我被執(zhí)行了-在sleep()方法后");
} catch (InterruptedException e) {
System.out.println("我被執(zhí)行了-在catch語句塊中");
}
System.out.println("我被執(zhí)行了-在try{}語句塊后");
}
};
// 啟動(dòng)線程
t.start();
// 在sleep()結(jié)束前中斷它
t.interrupt();
}
}
運(yùn)行結(jié)果:
我被執(zhí)行了-在sleep()方法前
我被執(zhí)行了-在catch語句塊中
我被執(zhí)行了-在try{}語句塊后
wait()方法也是本地方法,屬于Object類,有三個(gè)定義:
public final void wait() throws InterruptedException {
//do something
}
連接數(shù)過多會(huì)出現(xiàn):
root@darkstar:~# mysql
ERROR 1040 (00000): Too many connections
你只有選擇:
mysqladmin 執(zhí)行kill 進(jìn)程:
./mysqladmin -uroot -p processlist
./mysqladmin -uroot -p kill idnum
假如只有一個(gè)哥們A進(jìn)入mysql,后買的人BCD由于已經(jīng)連接吃緊咋辦?
方法如下:
1.
show processlist \G;
粘貼下來后放入文本:mysqlkillid.txt
cat mysqlkillid.txt |grep Id: |awk '{print "kill "$2";"}'
kill 180414;
kill 180433;
kill 180438;
kill 180446;
kill 180454;
kill 180455;
kill 180456;
kill 180457;
kill 180458;
kill 180460;
kill 180461;
kill 180462;
然后粘貼到mysql里面去殺死的同時(shí)讓其他同事連接mysql,可能某個(gè)時(shí)候就可以進(jìn)入了。
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:
http://blog.csdn.net/yakihappy/archive/2009/03/11/3979914.aspx
回憶未來,向東,沒時(shí)間整理:)
最后編輯: root 編輯于2010/03/17 15:40