http://blog.csdn.net/dog250/article/details/6596046
http://blog.c114.net/html/02/157502-59605.html
http://blog.csdn.net/dog250/article/details/5302773
http://basiccoder.com/intro-linux-kernel-hash-rt-1.html
DevOps
http://blog.csdn.net/dog250/article/details/6596046
http://blog.c114.net/html/02/157502-59605.html
http://blog.csdn.net/dog250/article/details/5302773
http://basiccoder.com/intro-linux-kernel-hash-rt-1.html
问题:
1. 出现swap换入就意味着缺页吗?
2. 如何查看一个进程的换入换出?
3. 如何演示swap的换入换出?
解答:
1. 需要查一下
参考资料:
http://hi.baidu.com/shichaojiang/item/6fd7aa7950dd8235714423c2
这个写的还不错,一定要看一下
2. 查看进程的换入换出
查看100次,间隔为1s
sar -x pid 1 100
查看子进程的换入换出
sar -X pid 1 100
3. 需要思考一下
有这么一些服务器软件(如: tokyotyrant、memcached),他们提供长连接的功能,简单说,server端基本不会主动关闭连接的;非长连接的时候也会存在这种问题,只是长连接时会表现的更明显一下。如果客户端抽风(或者一些恶意的目的),打开连接后,并不关闭而直接离开,这样,就会在server端残留大量的连接,最直接的表象就是: netstat -anpt 时很慢。
具体原因未明,来个命令:
sar -n SOCK :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
11:00:01 AM totsck tcpsck udpsck rawsck ip-frag ... 12:20:01 PM 291 198 6 0 0 12:30:01 PM 275 182 6 0 0 12:40:01 PM 284 194 6 0 0 12:50:02 PM 285 192 6 0 0 01:00:01 PM 300 207 7 0 0 01:10:01 PM 299 207 6 0 0 01:30:03 PM 434614 374694 6 0 0 01:50:03 PM 871925 668143 6 0 0 02:00:01 PM 830446 639373 6 0 0 02:10:01 PM 442958 442852 7 0 0 02:20:01 PM 442929 442826 6 0 0 02:30:01 PM 442895 442792 6 0 0 02:40:01 PM 442888 442785 6 0 0 02:50:01 PM 442903 442797 6 0 0 03:00:01 PM 442889 442785 6 0 0 03:10:01 PM 442892 442787 6 0 0 03:20:01 PM 440122 440017 6 0 0 03:30:01 PM 439761 439659 7 0 0 03:40:01 PM 161380 161281 6 0 0 03:50:01 PM 216 118 6 0 0 04:00:01 PM 218 118 6 0 0 04:10:01 PM 222 124 6 0 0 |
我们发现在1:30 PM时,tcp连接数突然飙升到 40万, 没有做任何操作3:40 PM时,连接数就开始减少了。
1 2 3 |
# cat /var/log/messages | grep "port 6101" Nov 26 13:28:43 localhost kernel: [4771814.322915] possible SYN flooding on port 6101. Sending cookies. Nov 26 13:32:02 localhost kernel: [4772012.800915] possible SYN flooding on port 6101. Sending cookies. |
原因:
1 2 3 4 |
# /sbin/sysctl -a| grep keep net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_time = 7200 |
连接2小时没有操作,探活机制发现对方已经消失,于是,关闭了连接; 看了一下tokyotyrant 和 memcached的源码,都做了KEEPALIVE 的设置:
1 |
./ttutil.c: setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&optint, sizeof(optint)); |
1 |
./memcached.c: setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); |
只是都没有做平静时间的设置,于是就都参考系统的设置了。
1. 如果没有keepalive的机制,系统运行时间过长总会出现这样的问题的
关于keep-alive的一些参数设置,摘自: man tcp :
tcp_keepalive_intvl (integer; default: 75)
The number of seconds between TCP keep-alive probes.
如果探活时,对方没有反应则,间隔 tcp_keepalive_intvl 秒后重发探活数据包,避免因丢包产生的探活差错
tcp_keepalive_probes (integer; default: 9)
The maximum number of TCP keep-alive probes to send before giving up and killing the connection if no
response is obtained from the other end.
如果发送了 tcp_keepalive_probes 次探活数据包,对方都没有反应,则视为对方死掉,而不是探活1次失败就放弃
tcp_keepalive_time (integer; default: 7200)
The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes.
Keep-alives are only sent when the SO_KEEPALIVE socket option is enabled. The default value is 7200 sec-
onds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes
an interval of 75 seconds apart) when keep-alive is enabled.
Note that underlying connection tracking mechanisms and application timeouts may be much shorter.
从连接平静开始,间隔 tcp_keepalive_time 秒开始探活,避免对方异常退出
使用setsockopt(…) 函数来实现:
1 2 3 4 |
TCP_KEEPALIVE : set idle time in milliseconds TCP_KEEPIDLE : set idle time in seconds TCP_KEEPINTVL : set keep alive time interval TCP_KEEPCNT : set number of keep alive probes. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#define SERV_HOST_ADDR "192.168.1.40" #define SERV_HOST_PORT 8000 void receiver(void) { int socket_fd, ret; struct sockaddr_in serv_addr; int num_recv_bytes =0; int val=1; int keepalive_idle_time = 5000; /* number of milli seconds */ if ((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1) { return; // error } memset((char *)&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); serv_addr.sin_port = htons(SERV_TCP_PORT); /* set the idle time after which tcp keepalive probes should start */ if( setsockopt(socket_fd,IPPROTO_TCP,TCP_KEEPALIVE,(void*)&keepalive_idle_time,sizeof(keepalive_idle_time)) == -1) { printf("setsockopt TCP_KEEPALIVE failed\n"); return; } if( setsockopt(socket_fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&val,sizeof(val)) == -1) { printf("setsockopt SO_KEEPALIVE failed\n"); return; } if (connect(socket_fd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) <0) { ret = send(socket_fd,buffer,strlen(buffer),0); // Receive the same string, if idle then break // memset(rcv_buffer,0,sizeof(rcv_buffer)); while(1) { num_recv_bytes = recv(socket_fd,rcv_buffer,BUFFER_LENGTH,0); if(num_recv_bytes < 0) { printf("Receiver: failed exiting\n",buffer); return; } else if (num_recv_bytes == 0) { /* Connection is closed by the tcp keep alive timer upon timeout we will break out of the while loop and close the socket. */ printf("Connection IDLE Keep-Alive timer terminated connection\n"); break; } } // close the socket close(socket_fd); } } |
参考资料: http://ez.analog.com/docs/DOC-1862
display 和 position的用法:
学习一点儿css,应该系统地看一遍的,否则,用到的时候就比较浪费时间了;
曾经总在div的布局上花费时间,今天才发现是因为display属性没有看明白。h1,p,div等元素默认是display:block的,所以,两个div 挨着就总换行; span,a等元素默认display:inline 的,所以,两个span挨着就不会自动换行; 现在,了解了 display属性后,就可以方便地控制他们是否换行了。
通过:
<style> div {display:inline}<style> 就可以让div也不换行了
通过:
<style> span{display:block}<style> 也可以让span换行了
参考资料:
http://www.w3schools.com/css/css_display_visibility.asp
http://www.w3schools.com/css/css_positioning.asp
http://www.w3schools.com/css/css_float.asp
http://www.zhangxinxu.com/wordpress/?p=1565
IN http://www.w3schools.com/css/css_align.asp
When aligning elements like this, it is always a good idea to predefine margin and padding for the <body> element. This is to avoid visual differences in different browsers.
There is a problem with IE8 and earlier, when using the position property. If a container element (in our case <div>) has a specified width, and the !DOCTYPE declaration is missing, IE8 and earlier versions will add a 17px margin on the right side. This seems to be space reserved for a scrollbar. Always set the !DOCTYPE declaration when using the position property:
一周来忙个不停,基本都是围绕一个问题:
如果请求执行变慢,web server的进程数迅速飙高,然后就拒绝服务,并且报警,又由于个IDC之间有一些暧昧的关系,于是,一个地方的问题就会迅速导致所有的IDC告急,让人毛骨悚然。
请求执行慢主要有几个方面的问题:
1. 后端存储响应慢
2. 网络出现问题
3. 后端存储死掉
请求执行慢的问题曾经也多次遇到,但是都没有导致过拒绝服务,更没有出现过多个IDC连锁反应的,现在出现这些问题,应该和新环境的web server对进程数的限制太低有很大关系。
当然,系统的设计也存在一些问题。
我想,应该清醒和理智地看待这些天的问题:
1. 新环境存在的问题
2. 系统本身存在的问题
这些天,我遇到了这么多问题,我也深刻地意识到了访问外部资源需要多么的慎重。
另外,这些天的事情使我对监控的理解也有所改变,不是说错了什么,只是原来的理解不够全面和深刻,我需要进步。
我不可能什么都去学习,更不可能什么都能学好,要注意把握一个度的问题,以一个正确的心态来做好自己的事情;既能把工作做好,自己也能有所提高。
最简单快捷的方法,打开Terminal,使用openssl生成私钥和自签名的x509证书。
1 |
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650 |
按照命令行的提示输入内容就行了。
几个说明:
public_key.der是输出的自签名的x509证书,即我们要用的。
private_key.pem是输出的私钥,用来解密的,请妥善保管。
rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。
-days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。
事实上,这一行命令包含了好几个步骤(我研究下面这些步骤的原因是我手头已经由一个private_key.pem私钥了,想直接用这个来生成x509证书,也就是用到了下面的2-3)
1)创建私钥
1 |
openssl genrsa -out private_key.pem 1024 |
2)创建证书请求(按照提示输入信息)
1 |
openssl req -new -out cert.csr -key private_key.pem |
3)自签署根证书
1 |
openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650 |
摘自: http://blog.iamzsx.me/show.html?id=155002
参考资料:
http://blog.csdn.net/jinglijun/article/details/7770301
http://blog.csdn.net/jinglijun/article/details/7770411
PHP 使用证书加密、私钥解密:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php echo "Source: $source"; $fp=fopen("/path/to/certificate.crt","r"); $pub_key=fread($fp,8192); fclose($fp); openssl_get_publickey($pub_key); /* * NOTE: Here you use the $pub_key value (converted, I guess) */ openssl_public_encrypt($source,$crypttext,$pub_key); echo "String crypted: $crypttext"; $fp=fopen("/path/to/private.key","r"); $priv_key=fread($fp,8192); fclose($fp); // $passphrase is required if your key is encoded (suggested) $res = openssl_get_privatekey($priv_key,$passphrase); /* * NOTE: Here you use the returned resource value */ openssl_private_decrypt($crypttext,$newsource,$res); echo "String decrypt : $newsource"; |
PHP的mongo模块使用域名访问mongodb时,其连接池是用域名做key来记录长连接的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
... 'gm9004.mars.grid.sina.com.cn:9004....28953' => array ( 'in use' => 0, 'in pool' => 1, 'remaining' => -2, 'total' => -1, 'timeout' => 498, 'waiting' => 0, ), 'gm9002.mars.grid.sina.com.cn:9002....28953' => array ( 'in use' => 0, 'in pool' => 1, 'remaining' => -2, 'total' => -1, 'timeout' => 498, 'waiting' => 0, ), ... |
从认识mysql开始就开始受困于mysql的字符集问题,希望能花点时间搞清楚,下面是一个什么样的问题呢:
“汉字”在utf8的字符集中是6个字节的,然而,这里却是8个字节,怎么解释呢?而且,“汉字”在utf8字符集中的16进制编码应该是“e6 b1 89 e5 ad 97”
参考资料: http://mysql.rjweb.org/doc.php/charcoll
里面有如下一段描述,似乎可以解释上述的问题:
—————————–
“Double encoding” is a term I made up for the following situation. It is a case where “two wrongs make a right”.
⚈ Table defined utf8
⚈ INSERTer declared latin1 (used default instead of doing SET NAMES)
⚈ Data being INSERTed is actually utf8 already.
What happened:
⚈ A 2-byte letter (say, a grave-e) was correctly represented in utf8.
⚈ The INSERT statement handed the 2 bytes to MySQL, but implied the need for conversion
⚈ Each byte was converted to utf8
⚈ The table has 4 bytes.
When SELECTing, the reverse happens 4->2->1, and the user is oblivious of the bug. Looking CHAR_LENGTH will spot it. Strange orderings may happen.
—————————–
看来预期6个字节存储为8个字节还不算严重的,严重的是上面存储翻倍的情况,上面的引用翻译如下:
================
“Double encoding” 是我用来描述下述情况的一个术语,这是一种“错错得对”的情况。
⚈ 表定义为utf8
⚈ INSERT时声明的字符集为latin1(如果没有使用 set names,则默认就是latin1的)
⚈ 要插入的数据确实是utf8编码
发生了什么?
⚈ 一个utf8编码的2字节的字母
⚈ 插入语句写mysql时要对2字节做处理,但是因为字符集声明为latin1的,所以要做编码转换
⚈ 每个字节用2字节的utf8编码表示
⚈ 存储结果为4个字节
在SELECT 的时候,发生一个反向的转换 4->2->1,并且用户不知道这个’bug’,于是就出现了上面的问题
=================
PHP中curl模块的设置为post后,如果设置post内容为一个数组,则默认并不是使用 Content-Type: application/x-www-form-urlencoded 编码的, 如果post内容为 a=A&b=B… 的形式,则使用 Content-Type: application/x-www-form-urlencoded 编码,示例如下:
1 2 3 4 5 |
<?php $curl = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $arrQuery); |
这时候就不会添加Content-Type: application/x-www-form-urlencoded 头
1 2 3 4 5 |
<?php $curl = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arrQuery)); |
这时候就会添加 Content-Type: application/x-www-form-urlencoded 头
也不知道这样的实现是友好还是2
越来越多的网络软件在采用基于事件的网络编程了,需要详细了解一下事件网络编程的原理和机制。结合memcache、redis的源码了解一下
参考资料:
使用libevent的小例子: http://blog.csdn.net/robertkun/article/details/7885379
libevent示例2:http://blog.sina.com.cn/s/blog_0001988f0100l9ym.html
libevent的使用: http://www.cnblogs.com/cnspace/archive/2011/07/19/2110891.html