存档

作者存档

如何关闭time_wait连接

2008年3月1日

结合netstat和awk命令来统计网络连接数
From: http://hi.baidu.com/thinkinginlamp/blog/item/afbcab64b1ad81f3f6365453.html

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

会得到类似下面的结果,具体数字会有所不同:

LAST_ACK 1
SYN_RECV 14
ESTABLISHED 79
FIN_WAIT1 28
FIN_WAIT2 3
CLOSING 5
TIME_WAIT 1669

状态:描述
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

下面解释一下为啥要这样写:

一个简单的管道符连接了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

你实际执行这条命令的时候,可能会得到成千上万条类似上面的记录,不过我们就拿其中的一条就足够了。

------------------------------------------------------------------

再来看看awk:

/^tcp/
滤出tcp开头的记录,屏蔽udp, socket等无关记录。

state[]
相当于定义了一个名叫state的数组

NF
表示记录的字段数,如上所示的记录,NF等于6

$NF
表示某个字段的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是TIME_WAIT

state[$NF]
表示数组元素的值,如上所示的记录,就是state[TIME_WAIT]状态的连接数

++state[$NF]
表示把某个数加一,如上所示的记录,就是把state[TIME_WAIT]状态的连接数加一

END
表示在最后阶段要执行的命令

for(key in state)
遍历数组

print key,"\t",state[key]
打印数组的键和值,中间用\t制表符分割,美化一下。

如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
vim /etc/sysctl.conf
编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

下面附上TIME_WAIT状态的意义:

客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口
状态为TIME_WAIT

是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?
有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?

主动关闭的一方在发送最后一个 ack 后
就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。

也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

TIME_WAIT 并不会占用很大资源的,除非受到攻击。

还有,如果一方 send 或 recv 超时,就会直接进入 CLOSED 状态

继续阅读:
查看Apache并发请求数及其TCP连接状态
Linux 反 DDOS的几个设置

Linux&Webserver , , ,

三十四位网络知名动漫设计师联合制作贺岁动画

2008年1月27日
载入中……

Video&Audio , ,

Js控制输入字符数限制

2008年1月23日

From: http://www.phpcake.cn/archives/26/

WebDesign

ZendFramework 使用数据表前缀

2008年1月17日

目录结构
zend framework dirs

在 config.ini 定义 prefix
[general]
adapter = PDO_MYSQL
host = localhost
username = root
password = 123456
dbname = test
charset = utf8
prefix = pf_ //表前缀

index.php 中将 prefix 注册
// 读取数据库配置
$dbconfig = new Zend_Config_Ini('../config/config.ini', 'general');
// 配置数据库
$database = Zend_Db::factory($dbconfig->adapter,$dbconfig->toArray());
// 设置数据库编码
$database->query("set names {$dbconfig->charset};");
Zend_Db_Table::setDefaultAdapter($database);
Zend_Registry::set('database',$database);
// 数据表前缀
Zend_Registry::set('dbprefix',$dbconfig->prefix);

在 library/Custom 目录下新建文件 Db.php 继承 Zend_Db_Table 类
class Custom_Db extends Zend_Db_Table
{
public function __construct()
{
$dbprefix = Zend_Registry::get('dbprefix');
$this->_name = $dbprefix.$this->_name;
parent::__construct();
}
}

最后在 model 中继承 Custom_Db 即可
class User extends Custom_Db
{
protected $_name = 'users'; //在Custom_Db中会自动加上表名的前缀
protected $_primary = 'userid'; //主键
}

Program&Database , ,

ZEND studio 编辑器字体美化方法

2008年1月14日

我这里用的是 ZendStudio 5.5.0
找到这个目录 "Zend\ZendStudio-5.5.0\jre\lib"
除 fontconfig.properties.src 文件保留外,删除所有以 fontconfig. 开头的文件
将 fontconfig.properties.src 文件改名为 fontconfig.properties, 然后打开编辑
把以下的值

dialoginput.plain.alphabetic
dialoginput.bold.alphabetic
dialoginput.italic.alphabetic
dialoginput.bolditalic.alphabetic

改成你要设置的字体名称

这里我设置的是

dialoginput.plain.alphabetic=Lucida Sans Typewriter
dialoginput.plain.chinese-ms950=MsYahei

dialoginput.bold.alphabetic=Lucida Sans Typewriter Bold
dialoginput.bold.chinese-ms950=MsYahei Bold

dialoginput.italic.alphabetic=Lucida Sans Typewriter
dialoginput.italic.chinese-ms950=MsYahei

dialoginput.bolditalic.alphabetic=Lucida Sans Typewriter Bold
dialoginput.bolditalic.chinese-ms950=MsYahei Bold

其中 dialoginput.xxxx.chinese-ms950 是中文所用字体

然后再文件末尾添加定义上面设置的字体名称

filename.MsYahei=MSYH.TTF
filename.MsYahei_Bold=MSYHBD.TTF

filename.Lucida_Sans_Typewriter=LucidaTypewriterRegular.ttf
filename.Lucida_Sans_Typewriter_Bold=LucidaTypewriterBold.ttf

其中如 filename.MsYahei 中的 MsYahei 就是上面 dialoginput.xxxx.chinese-ms950 所使用的中文名称, 这里空格要改成 "_", 后面的 MSYH.TTF 是你系统中安装的字体文件的名称, 打开系统字体文件夹(如c:\windows\fonts), 以详细方式查看, 文件名一列即是

打开 zend studio, 指定编辑器的字体为 "dialoginput",然后重启编辑器即可看到效果

UsefulTips , , ,

为wordpress添加coolcode插件的quicktag

2008年1月13日

修改 wp-includes/js/quicktags.js 文件

1. 找到

edButtons[edButtons.length] =
new edButton('ed_code'
,'code'
,''
,'
'
,'c'
);

在后面添加
[coolcode lang="javascript"]
edButtons[edButtons.length] =
new edButton('ed_coolcode'
,'coolcode'
,"
,''
,'x'
);[/coolcode]

2. 找到

else if (button.id == 'ed_link') {
document.write('
');
}

在后面添加

else if (button.id == 'ed_coolcode') {
document.write('
');
}

3. 在文件末尾添加

function edInsertCoolcode(myField, i, defaultLang, defaultLine) {
if (!defaultLang) {
defaultLang = 'php';
}
if (!defaultLine) {
defaultLine = 'off';
}
if (!edCheckOpenTags(i)) {
var codeLang = prompt('输入需要加亮的程序语言', defaultLang);
var codeLine = prompt('是否显示行号(on, off)', defaultLine);
edButtons[i].tagStart = '<' + 'coolcode';
if (codeLang) {
edButtons[i].tagStart = edButtons[i].tagStart + ' lang="'
+ codeLang + '"'
}
if (codeLine) {
edButtons[i].tagStart = edButtons[i].tagStart + ' linenum="'
+ codeLine + '"';
}
edButtons[i].tagStart = edButtons[i].tagStart + '>';
edInsertTag(myField, i);
}
else {
edInsertTag(myField, i);
}
}

Program&Database , , ,