from : http://www.justwinit.cn/post/2734/

[不指定 2010/02/27 17:40 | by root ]
當(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