March 18, 2010 by Chan Cham Chung
最近为那个公司很重视的项目搭建 lvs ,在这里 log 一下吧。
利用red hat 提供的 piranha ,简单快捷。
我选择的是 centos 5.4 ,安装 piranha ,很简单
yum install piranha
此时,它还需要你安装 ipvsadm , php , php-cli , php-common , httpd ,piranha 是一个 web 管理的工具,没办法,虽然我不用web 界面,但这些在yum 下还是必须装上的。
装完以后,/etc/sysconfig/ha/lvs.cf 还是空的,我去抄一份过来。
serial_no = 1
primary = 60.12.227.1
service = lvs
backup_active = 1
backup = 60.12.227.2
heartbeat = 1
heartbeat_port = 10001
keepalive = 6
deadtime = 18
network = direct
debug_level = NONE
virtual vs[1] {
active = 1
address = 60.12.227.200 eth0:200
vip_nmask = 255.255.255.0
port = 80
send = "GET / HTTP/1.0\r\n\r\n"
expect = "HTTP"
use_regex = 0
load_monitor = none
scheduler = wlc
protocol = tcp
timeout = 6
reentry = 15
quiesce_server = 0
server rs[1] {
address = 192.168.0.1
active = 1
weight = 2
}
server rs[2] {
address = 192.168.0.2
active = 1
weight = 2
}
}
到此,lvs 的 director 端,算是安装完成了。
有人会问了,为什么我没有修改 /proc/sys/net/ipv4/ip_forward 为1 。其实,这里我也还不是很懂,理论上,转发是必须设为1 的,但我发现,貌似不设,也可以正常工作,难道是 piranha 的关系??
然后就是配置 real server 端了。
我又抄一个shell 过来
#!/bin/sh
VIP=60.12.227.200
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
由于我的director 端配置的是 dr 模式,所以必须关闭arp 响应。
执行一下这个shell,real server 端也算是完成了。
启动 director 端:
# /etc/init.d/pulse start
Starting pulse: [ OK ]
查看服务状态:
# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 60.12.227.200:80 wlc
-> 192.168.0.1:80 Route 2 326 172
-> 192.168.0.2:80 Route 2 326 192
搭建完成了,算是比较快速的了,呵呵。还有一点知识点的,下回再说吧。
Tags: linux, lvs
Categories: technology •
No Comments »
March 7, 2010 by Chan Cham Chung
ssh 是SA 的一大利器,登录服务器、翻墙。。。ssh 通常都配合着 ssh-agent 来使用,ssh-agent 是个管理 private key 的 passphrase 的工具,启动 ssh-agent 后,执行一次 ssh-add ,此时需要输入一次 private key 的 passphrase ,输入正确后,passphrase 就归 ssh-agent 管理,往后的 ssh 操作,就不需要询问 passphrase 了。这里需要注意,ssh 必须开启了forwardagent ,一劳永逸的方法,就是在 /etc/ssh/ssh_config 中把#ForwardAgent no 去掉注释,并改为 ForwardAgent yes。
重点说说它的安全隐患。
ssh-agent 工作过程中会创建一个 socket 文件在 /tmp 目录里,如 /tmp/ssh-jlhtX14952/agent.14952 。我们需要使用 ssh-agent 时,运行一下 ssh-add ,把 private key 加入到 ssh-agent 中管理,此时,是需要输入一次 passphrase 的,当输入正确了以后,往后都不需要输入 passphrase 了。任何用户,只要连接上这个socket ,就可以使用已经加入到ssh-agent 管理的 private key 了,而且不需要输入 passphrase 。所以,这个 socket 的权限是 600 ,如:
srw——- 1 raymond raymond 0 May 1 2009 /tmp/ssh-jlhtX14952/agent.14952
但是。。。我们的 root ,是可以随意访问的。。。
这里演示一次!
1,用root 连接socket,这里很简单,就执行一句话
# SSH_AUTH_SOCK=/tmp/ssh-jlhtX14952/agent.14952; export SSH_AUTH_SOCK;
2, 查看此 socket 是否已经加入了 private key
# ssh-add -l
1024 fa:2d:87:1a:c5:a6:9d:7c:67:eb:51:a3:6a:7b:49:34 /home/raymond/.ssh/identity (RSA)
看,raymond 的 key 已经加入进去了
3,尝试登录raymond 的服务器,以root 的身份,但使用 raymond 的 key
# ssh raymond@220.181.xxx.xxx
Last login: Sat Mar 6 04:41:55 2010 from 220.181.xxx.xxx
[raymond@VM ~]$ whoami
raymond
看,此时,已经是以raymond 的身份登录的服务器了
Tags: linux, ssh
Categories: technology •
1 Comment »
February 26, 2010 by Chan Cham Chung
看了几篇文章,对linux的进程的内存占用,又有了一点认识,记录一下。
首先 ps 看一下我的系统跑着哪些process
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
...
czbug 1980 0.0 1.7 180472 34416 ? Sl Feb25 0:01 /usr/bin/yakuake
...
我拿 yakuake 这个小程序作例子。
其中,关于内存的是 VSZ 和 RSS 这两个
man ps 看看它们的含义:
rss RSS resident set size, the non-swapped physical memory that a task has used (in kiloBytes). (alias rssize, rsz).
vsz VSZ virtual memory size of the process in KiB (1024-byte units). Device mappings are currently excluded; this is subject to change. (alias vsize).
简单一点说,RSS 就是这个process 实际占用的物理内存,VSZ 就是process 的虚拟内存,就是process 现在没有使用但未来可能会分配的内存大小。
其实这里的ps 出来的结果,是有点不正确的,如果把所有程序的 RSS 加起来,恐怕比你的实际内存还要大呢。为什么呢??因为 ps 的结果,RSS 那部分,是包括共享内存的。这里我用 pmap 来看看。
$ pmap -d 1980
1980: /usr/bin/yakuake
Address Kbytes Mode Offset Device Mapping
00110000 2524 r-x-- 0000000000000000 008:00002 libkio.so.5.3.0
00387000 4 ----- 0000000000277000 008:00002 libkio.so.5.3.0
00388000 32 r---- 0000000000277000 008:00002 libkio.so.5.3.0
00390000 16 rw--- 000000000027f000 008:00002 libkio.so.5.3.0
00394000 444 r-x-- 0000000000000000 008:00002 libQtDBus.so.4.5.2
00403000 4 ----- 000000000006f000 008:00002 libQtDBus.so.4.5.2
00404000 4 r---- 000000000006f000 008:00002 libQtDBus.so.4.5.2
00405000 4 rw--- 0000000000070000 008:00002 libQtDBus.so.4.5.2
00407000 228 r-x-- 0000000000000000 008:00002 libkparts.so.4.3.0
00440000 8 r---- 0000000000039000 008:00002 libkparts.so.4.3.0
00442000 4 rw--- 000000000003b000 008:00002 libkparts.so.4.3.0
00443000 3552 r-x-- 0000000000000000 008:00002 libkdeui.so.5.3.0
007bb000 76 r---- 0000000000377000 008:00002 libkdeui.so.5.3.0
007ce000 24 rw--- 000000000038a000 008:00002 libkdeui.so.5.3.0
007d4000 4 rw--- 0000000000000000 000:00000 [ anon ]
....
mapped: 180472K writeable/private: 19208K shared: 20544K
我略去了一部分输出,都是差不多的,重点在最后那行输出。
linux 会把一些shared libraries 载入到内存中,在pmap 的输出中,这些shared libraries 的名字通常是 lib*.so 。如 libX11.so.6.2.0 。这个 libX11.so.6.2.0 会被很多process load 到自己的运行环境中,同时,ps 输出的RSS 结果中,每个process 都包含了这个libX11.so.6.2.0 ,而事实上它只被load 了一次,如果单纯把ps 的结果相加,这样就重复计算了。
而 pmap 的输出中,writeable/private: 19208K ,这个就是yakuake 这个程序真正占用的物理内存,不包含shared libraries 。在这里,它只有19208K,而ps 的RSS 是34416K。
————————————————————–
我在看这方面的资料时,还看到一些关于virtual memory 的,再记录下。
以下两个命令均可查看 vmsize 。
$ cat /proc/<pid>/stat | awk '{print $23 / 1024}'
$ cat /proc/<pid>/status | grep -i vmsize
一般来说,得出来的值,是和 ps 的 VSZ 是一样的,但有一种情况例外,就是查看X server 的时候。
举个例:
$ ps aux|grep /usr/bin/X|grep -v grep | awk '{print $2}' # 得出X server 的 pid ...
1076
$ cat /proc/1076/stat | awk '{print $23 / 1024}'
139012
$ cat /proc/1076/status | grep -i vmsize
VmSize: 106516 kB
而 ps 的 VSZ 为 106516 ,与后者是一致的。
据说是因为
VmSize = memory + memory-mapped hardware (e.g. video card memory).
这句话我不是很理解。。。就不作解释了。。。
对OS 的理解还很肤浅,还需努力啊。。。
Tags: linux
Categories: technology •
1 Comment »
February 11, 2010 by Chan Cham Chung
今天维护一个集群系统时,被人报障说集群的机器时间不对。。。我去看了一下,crontab 里有对时的命令啊。再手动执行一下,才发现,原来被我设的防火墙给墙住了。。。机器只允许特定的外网ip访问,内网无限制。。。所以ntpdate 外面一些对时服务器的时候,根本不会收到返回了。
话说这个防火墙,也是其它部门的同事建议我设的,本部门的程序员对安全这些事情好不上心的,专心于系统功能的开发,甚至连我多次建议的系统管理经验也不采纳。算了,none of my business 。
而他们说这个系统对时,很急,要不集群间的机器heartbeat 时间不对,就会以为对方挂了的了。
那我就马上在另一台对外网无限制的机器上搭一个ntpd ,就作为一个对时服务器的代理吧。
安装ntpd,这个很简单,那台机器是 centos 5,那就用yum。
装好还不能用呢,最快速度使用上的话,那就只修改一行配置,因为默认是只允许本地对时而已,我们必须加上内网都可以对时
把下面这行,取消注释,并加上自己网段的相关信息即可
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
如:
restrict 10.100.20.0 mask 255.255.255.0 nomodify notrap
然后重启ntp
重启成功后,如果你立刻想对时的话,是会报错的,如:
#ntpdate 10.100.20.59 # 就是我刚配的ntpd server
11 Feb 00:37:36 ntpdate[22276]: no server suitable for synchronization found
这种错误,应该是没有ntpd server 才会报的啊,究竟为什么呢??
原来,如果ntpd server 没有进行过对时的话,也是会报这个错的。。。很汗,为什么不写得明白一点呢??
好了,既然知道原因,只需要等待数分钟,让我的ntpd server 10.100.20.59 自己去对了一次时后,我们再操作,就会成功的了。
# ntpdate 10.100.20.59
11 Feb 00:41:30 ntpdate[22323]: adjust time server 10.100.20.59 offset -0.005792 sec
Tags: linux
Categories: technology •
No Comments »
February 11, 2010 by Chan Cham Chung
今天svn up的时候,发现一个报错:
#svn up
svn: Valid UTF-8 data
(hex:)
followed by invalid UTF-8 sequence
(hex: a1 b0)
突然爆出的错误。。。google 了一下,这个比较靠谱
http://ryanerwin.com/2007/04/09/valid-utf-8-data-hex-followed-by-invalid-utf-8-sequence/
大意是说,你的svn工作目录,有了一个不能由当前系统的字符集识别的文件。
解决方式是:删了这些文件。
ok,那我去删咯,确实有一个目录下,有一个?????????????? 的文件,gbk 编码的文件。。。
怎么出现的呢??不会是被某位大哥黑进来的吧,哈哈。
不追查了,就当是跑脚本失败生成的。删去,问题解决了!
Tags: linux
Categories: technology •
No Comments »
February 10, 2010 by Chan Cham Chung
见配置,摘自nginx.conf 里的server 段:
server {
listen 80;
server_name abc.163.com ;
location / {
proxy_pass http://ent.163.com/ ;
}
location /star/ {
proxy_pass http://ent.163.com ;
}
}
里面有两个location,我先说第一个,/ 。其实这里有两种写法,分别是:
location / {
proxy_pass http://ent.163.com/ ;
}
location / {
proxy_pass http://ent.163.com ;
}
出来的效果都一样的。
第二个location,/star/。同样两种写法都有,都出来的结果,就不一样了。
location /star/ {
proxy_pass http://ent.163.com ;
}
当访问 http://abc.163.com/star/ 的时候,nginx 会代理访问到 http://ent.163.com/star/ ,并返回给我们。
location /star/ {
proxy_pass http://ent.163.com/ ;
}
当访问 http://abc.163.com/star/ 的时候,nginx 会代理访问到 http://ent.163.com/ ,并返回给我们。
这两段配置,分别在于, proxy_pass http://ent.163.com/ ; 这个”/”,令到出来的结果完全不同。
前者,相当于告诉nginx,我这个location,是代理访问到http://ent.163.com 这个server的,我的location是什么,nginx 就把location 加在proxy_pass 的 server 后面,这里是/star/,所以就相当于 http://ent.163.com/star/。如果是location /blog/ ,就是代理访问到 http://ent.163.com/blog/。
后者,相当于告诉nginx,我这个location,是代理访问到http://ent.163.com/的,http://abc.163.com/star/ == http://ent.163.com/ ,可以这样理解。改变location,并不能改变返回的内容,返回的内容始终是http://ent.163.com/ 。 如果是location /blog/ ,那就是 http://abc.163.com/blog/ == http://ent.163.com/ 。
这样,也可以解释了上面那个location / 的例子,/ 嘛,加在server 的后面,仍然是 / ,所以,两种写法出来的结果是一样的。
PS: 如果是 location ~* ^/start/(.*)\.html 这种正则的location,是不能写”/”上去的,nginx -t 也会报错的了。因为,路径都需要正则匹配了嘛,并不是一个相对固定的locatin了,必然要代理到一个server。
Tags: linux, nginx
Categories: technology •
No Comments »
February 9, 2010 by Chan Cham Chung
一个项目是apache+resin的架构,有一条 rewrite 规则是这样的:
RewriteRule ^/flashinfo/vinfo/([a-z0-9A-Z_]+).xml$ /video/videolist.htm?sid=$1 [PT,L]
其中,\.htm 交给resin处理
<LocationMatch (.*)\.htm>
SetHandler caucho-request
</LocationMatch>
理论上,访问 /flashinfo/vinfo/V5OJEFN7C.xml 文件,是会代理访问到 /video/videolist.htm?sid=V5OJEFN7C 的。
但事实上,却403了,如下:
$curl -I -H host:so.v.test.com http://127.0.0.1/flashinfo/vinfo/V5OJEFN7C.xml
HTTP/1.1 403 Forbidden
Date: Tue, 09 Feb 2010 07:29:30 GMT
Server: Apache/2.2.11 (Unix) Resin/3.0.26
Content-Type: text/html; charset=iso-8859-1
让我看看rewrite后的访问是否正常:
$curl -I -H host:so.v.test.com http://127.0.0.1/video/videolist.htm?sid=V5OJEFN7C
HTTP/1.1 200 OK
Date: Tue, 09 Feb 2010 07:33:23 GMT
Server: Apache/2.2.11 (Unix) Resin/3.0.26
Cache-Control: max-age=600
Expires: Tue, 09 Feb 2010 07:43:23 GMT
Content-Type: text/html
究竟什么原因呢??我看了一下,应该是这样的:
原因在于,在DocumentRoot下,有一个错误的软链video.
$ls -alh| grep video
lrwxrwxrwx 1 root root 29 02-09 15:29 video -> /data/videopage
而/data/videopage这个目录是不存在的,所以video是一个错误的软链,rewrite 后的地址是 /video/videolist.htm?sid=$1 ,这样就爆403了。
真奇怪,其实apache 根本不用管我有没有video 这个目录的,因为都是转发到resin 去处理的了。既然想不通,就先记下。。。
我还做了两个测试:
1,让 video 成为一个正确的软链,curl 测试结果,200 。
2,把 video 删去,不存在这个软链,curl 测试结果,200。
————————————
结论:apache rewrite 后的地址,如 /data/dopost.jsp?sid=$1 这种,如果data 是一个错误的软链,尽管动态程序/data/dopost.jsp?sid=$1是正确的,apache 的 rewrite 都会不成功,返回 403 。如果 data 是一个正确的软链或者压根不存在,apache 正确地rewrite 。
Tags: apache, linux
Categories: technology •
No Comments »
February 9, 2010 by Chan Cham Chung
测试环境:
192.168.1.1 (squid) , 192.168.1.2 (nginx proxy) , 192.168.1.3 (nginx web)
squid 作为最外层的代理;nginx proxy 作为第二层代理,通过upstream访问后台;nginx web 真正的数据后台web server。
测试开始:
$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
HTTP/1.0 200 OK
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:11:48 GMT
Content-Type: text/html; charset=GBK
Expires: Mon, 08 Feb 2010 18:12:58 GMT
Cache-Control: max-age=70
X-Cache: MISS from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 192.168.1.3.nginx, 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close
此时, user -> squid -> nginx proxy -> nginx web
此时,这个页面已经被缓存住,往后的访问都是TCP_MEM_HIT的了。等到页面过期后,我把nginx web 后台弄挂,我在这里是直接把nginx proxy的upstream给改了,改为 192.168.1.4。此时,访问nginx proxy
$curl -I -H host:blog.lazybug.me http://192.168.1.2/test.html
HTTP/1.1 502 Bad Gateway
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:28:06 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive
因为根本没有192.168.1.4这个ip,肯定bad gateway了。
但此时访问squid
$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
HTTP/1.0 200 OK
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:11:48 GMT
Content-Type: text/html; charset=GBK
Expires: Mon, 08 Feb 2010 18:12:58 GMT
Cache-Control: max-age=70
Age: 1004
Content-Length: 0
X-Cache: HIT from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 192.168.51.3.nginx, 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close
squid 仍然返回200,不过并不是立刻返回,而是经过了几秒才返回,因为此时squid认为请求页面过期,正在尝试去后端取新数据,但此时,后端返回一个502 bad gateway,那它的工作机制就是,返回旧的缓存数据给用户。
看一下squid的access.log,写着TCP_REFRESH_FAIL_HIT。查一下手册,如下:
An expired copy of the requested object was in the cache. Squid attempted to make an If-Modified-Since request, but it failed. The old (stale) object was delivered to the client.
如果 squid 没有缓存到页面,而出现502,squid 会不会返回200呢??测试下
清缓存:
squidclient -p 80 -m purge http://blog.lazybug.me/test.html
然后再次访问:
$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
HTTP/1.0 502 Bad Gateway
Server: nginx/0.8.32
Date: Tue, 09 Feb 2010 18:17:13 GMT
Content-Type: text/html
Content-Length: 173
X-Cache: MISS from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close
呵呵,不出所料。
———————————————————————
结论:squid 作为前端代理,而后端502的话,如果squid已经缓存住的页面,那squid就返回用户旧的数据,如果squid没有缓存住的话,很遗憾,还是会502的。
Tags: linux, squid
Categories: technology •
No Comments »
January 28, 2010 by Chan Cham Chung
squid 不能缓存cache-control在65秒以下的页面,详见ayou同学的这篇文章:http://sudone.com/linux/squid_cache_65s.html
根据文章所说,如果想实现65秒以下的缓存呢,用last-modified头吧。
今天遇到了一个比较郁闷的事,就是架设在squid后的一台nginx,随意访问一个静态页面,死活不出last-modified头。也没作什么特殊的配置,我自己新装一个nginx,测试之。
$curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:11 GMT
Content-Type: text/html
Content-Length: 151
Last-Modified: Thu, 28 Jan 2010 03:07:20 GMT
Connection: keep-alive
Accept-Ranges: bytes
很正常嘛,不作任何配置时默认是会有last-modified的。
后来还是经ayou同学的提醒,因为使用了ssi。。。
使用了ssi,nginx 就假设你这个页面动态的,谁知道你include的页面上次修改时间啊,当然也就不给你返回last-modified头了。
另外,使用nginx的 http_sub_module时,也不会出这个头的。在测试机上试试,加了个ssi on
$curl -I http://127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:32 GMT
Content-Type: text/html
Connection: keep-alive
果然是ssi。。。
mark 一下,以前就试过了,今天竟然忘了!!
Tags: linux, nginx
Categories: technology •
4 Comments »
January 24, 2010 by Chan Cham Chung

封面写着linus大神倾力推荐。
扫了一下目录,觉得还OK,都是些比较基础的内容,不错不错,查漏补缺一下,巩固一下基础。
定一下计划,牛年内把这本书看完!!
Tags: book, linux
Categories: technology •
No Comments »