Windows XP 设置开机自动登录

September 16, 2007 4:03 pm GMT-0700 | In Tech | 1 Comment | hide

每次要用都忘,记一下:control userpasswords2

Tags: ,

运动是相对的

September 8, 2007 11:13 pm GMT-0700 | In Study | No Comments | hide

用原子干涉仪(Atom Interferometer)测量引力常数的方法其实上个世纪就已经提出来了,不过实验是有人在 2002 年的时候才做出来的,因为种种原因,实验结果只在那个人的博士论文上发表过,最近才在 Science 上发出来(DOI: 10.1126/science.1135459)。

实验的基本原理就是把质量源(那个实验用的是铅块)从一个位置移动到另一个位置,看原子干涉仪感受到的引力有什么变化。数据分析需要建一个模型,计算质量源在不同位置对原子德布罗意波的影响。类似的原理也可以用来测量隧道啊、金矿啊之类的,只要把用来测量的原子干涉仪从金矿这头移动到那一头就可以了。 不过不同的是,因为这里移动的是干涉仪,而不是质量源,所以整个模型都需要重建了。

前几天和人说起这个,其实完全可以把干涉仪当作静止的,认为地球整个儿动了,老的模型改一改质量源就可以继续用了……(当然算出来的结果也是对的)

Tags: ,

rsyncrypto: rsync + encryption

September 7, 2007 1:04 am GMT-0700 | In Tech | Comments Off on rsyncrypto: rsync + encryption | hide

rsyncrypto is basically rsync plus encryption. It’s not feature-complete I guess, but it works for me. Ubuntu source has binary package but compiling isn’t hard at all. Alright, so obviously man page has most of what you need, here I’ll write simple outlines.

Suppose your data source folder is ~/src, sync destination is ~/dst (this could be a mounted nfs or smb share), and rsyncrypto working directory is ~/rr.

A. Encryption

First of all, create backup keys:

openssl req -nodes -newkey rsa:1536 -x509 \
  -keyout ~/rr/backup.key -out ~/rr/backup.crt

Then the actual sync command is:

rsyncrypto --ne-nesting=2 --trim=3 -n ~/rr/map \
  -cvr ~/src/ ~/dst/ ~/rr/keys ~/rr/backup.crt

This command will encrypt filename and folder structure. So obviously folder modification time will not be preserved, and empty folder will be lost. Parameter --trim depends on your folder location. --ne-nesting depends on the number of files you will have in the future. In general, you may want less than 1024 files per folder, so you need 1024*16^n > total number of files, --ne-nesting=2 is enough for 200,000 files. After this encrypted sync, and suppose you lose everything except files in the ~/dst/, then you’ll need backup.key to cold decrypt all files. So be sure to keep backup.key at another place, preferably at another physical location. You can put the above command into crontab if -v is removed. Also, syncing files without ownership might result in errors, and it may be hard to debug because rsyncrypto does not have very friendly error messages – in which case you may try to fix the file permission problem, or you may run the command by root.

If you want a parameter similar to --delete in rsync, the corresponding parameter in rsyncrypto is --delete-keys. The parameter --delete alone in rsyncrypto does not remove filename mapping in ~/rr/map.

B. Decryption

Suppose you want to cold decrypt to folder ~/rec/. First you need to decrypt filename mapping:

rsyncrypto -d ~/dst/filemap ~/rec/filemap \
  ~/rec/filemap-keys ~/rr/backup.key

The above command generates ~/rec/filemap, so then you can decrypt all files:

rsyncrypto --trim=3 -n ~/rec/filemap \
  -vrd ~/dst ~/rec/files ~/rec/keys ~/rr/backup.key

Tags: , , , ,

备份的重要性

September 4, 2007 11:11 pm GMT-0700 | In Tech | 4 Comments | hide

Google 年初出了一篇论文,Failure Trends in a Large Disk Drive Population,讲了硬盘故障的趋势和各类因素对之的影响。相信大家或多或少都听说过周围的人硬盘破掉哭天哭地的事情,甚至可能发生在自己身上。我前几天算了一下,我自己在过去的七年里用过大概 20 个硬盘,其中挂掉了三个硬盘。不知道是个人感觉还是确有其事,硬盘的平均寿命可能确实已经不如二十世纪了。

硬盘挂掉到底是个什么样的概率呢?按照现在一般厂家宣传的来看,我们就假设硬盘的平均寿命是 3 年。这个硬盘挂掉就跟重原子衰变一个规律,是指数规律,也就是说,时间 t 之后硬盘还没有挂掉的概率是 exp(-t/T),这里 T = 3 年。我们常常听人说,做事情要万无一失,这个意思是说出错的概率要小于 0.01%,现在我们宽容一点,硬盘数据也不是人命关天的事情,我们就说出错的概率小于 1% 就够满足了,那么这样的情况 t 是多少呢?t = -T * ln(0.99) = 11 天。也就是说,硬盘用了超过 11 天,就有大于 1% 的概率挂掉了。从这个计算我们可以看到,用硬盘指望硬盘不挂掉其实是很拼人品的。

有人说,既然硬盘会挂掉,那么我就建一个 raid 硬盘阵列就可以了,备份还是没什么必要的。raid1 可能是最常用的,高级一点可以用 raid5。自然,这是最基本的一个做法,即使一个硬盘挂掉也可以很快恢复数据。不过在硬盘物理层上还有文件系统,文件系统挂掉并不少见,而这种情况下 raid 的冗余数据是完全帮不上忙的。土人我亲眼见过 raid1 上 ntfs 文件系统崩溃,也见过 raid5 上 ext3 文件系统崩溃,从此大彻大悟再也不相信有了 raid 冗余模式就可以高枕无忧的屁话。

另外,在没有版本管理系统的情况下,有的时候写东西写错或者误操作往往会希望看看昨天这个文件是什么样子,这又是需要备份了。好了废话这么多,总之备份是放之四海而皆准的解决方案。如何备份?很多人不备份的原因就是太麻烦,首先,人最在乎的数据往往是每天都在变化的;其次,备份往往需要人去参与,比如刻盘;还有,如果没有好的软件,备份大量文件必然要耗费大量的机器时间。如果每天备份都要这么大张旗鼓,自然没人愿意备份了,所以实用的日常备份必定是自动进行的,而且需要程序快速准确判断出原始数据和备份的差异,只复制有差异的部分。

有了自动备份,那么多长时间备份一次?这个完全看具体情况。比如与盈利挂钩的办公环境,每天备份数据的要求并不过分。另外,备几份?有人说要多备几份,每次备份删除一份最早的;也有人备三份不同频率的,分别是每天、每周、每月备份。我这里只是把看到的罗列一下供参考。一般的数据备一份足够。

然后一点是,往哪里备份?一般来说往另一个硬盘备份就可以了,可以是自己这个机器,也可以是另一个机器通过网络备份。不过会不会备份和原始数据同时挂掉呢?有可能的,比方,火灾,或者雷电袭击了输电系统。如果有这种顾虑,一般推荐是进行异地备份,通过网络或者别的手段把数据同步到另一个物理位置的机器上。很多年前 Stanford 发生过一起火灾,把 Career Development Center 一个楼全烧没了,所有的学生求职数据库连同备份都烧没了。很认真地说一句,如果有特别重要的数据,应该考虑异地备份,最简单的方法可以是,每年刻一些盘放到别的地方去,也花不了多少时间。

废话了很多,貌似没有涉及备份的具体技术问题,留着且听下回分解吧。

ps,其实硬盘挂掉不是按指数规律来的,Google 那篇论文也提到这点,前面那个计算其实是忽悠人的…… 不过 11 天这个结果的数量级还是正确的。

Tags:

漫谈打洞

September 2, 2007 1:39 am GMT-0700 | In Tech | 6 Comments | hide

网络总是有缺陷的,一种常见的情形是,Alice 想向 Bob 建立 TCP 连接,但是因为种种原因不能直接建立连接。如果有一台机器和两边都没有连接障碍,那么就有可能通过这台机器帮助从 A 向 B 建立连接。一般把这个工作叫做建隧道,或者搭桥,不过好像也有人叫打洞,我觉得打洞这个名字听起来好玩一些,所以标题里就叫打洞吧。

A. 直接端口映射

先从最土鳖的说起。最简单的洞是在某台机器 C 上开一个 daemon 监听一个特定端口,然后把 A 发过来的数据都原封不动的转发给 B,这里假设 C 到 A 和 B 的通信都是毫无阻碍的。网上流传了两个版本的 datapipe.c 1 2。后者是前者的徒弟,当然也比新。不过后者带了 idle timeout 5 分钟,很容易改掉。另外一个简洁的程序是 rinetd。总之这些程序大同小异,对于最简单的应用足够了。究其本质,其实它就是把来去网络包的 src 和 dst 改了。所以上面这类 daemon 的工作可以用两条 iptables 规则搞定(nat 表):

-A PREROUTING -p tcp -m tcp --dport 9998 -j DNAT --to-destination Bob:9999
-A POSTROUTING -d Bob -p tcp -m tcp --dport 9999 -j SNAT --to-source C

这样就把发给 C:9998 的数据转发给 B:9999 了。当然了,iptables 需要 root 权限,所以比 daemon 权限要求高一些。另外一点是,如果 C 是 B 的网关,那么第二条 iptables 规则是不需要的,这时候第一条规则就相当于路由器配置常见的端口映射。

B. ssh 端口映射

稍微高级一点,可以用 ssh 端口映射。最简单的例子来说,比如 B 在内网所以 A 没办法向 B 建立连接,但是 B 的内网中有一台 D 可以操作并向外网的 A 建立连接。如果 A 这里有 sshd server,就可以从 D 用 ssh -R 来反向建立通道:

ssh -R 8888:Bob:8889 Alice

这样在 A 上连 localhost:8888 的时候,ssh 通道会自动把网络包发回 B 机器的 8889 端口。这里如果能操作 B,那么从 B 直接 ssh A 也可以,就不需要 D 了。在没有网关权限的情况下,这个方法是从外网连内网机器的最基本的方法。

ssh 的 -L 和 -R 两个参数神通广大,灵活运用可以打各种洞。比如假设 A B C 都是互联网上的机器,但是 A B 通讯不畅,想通过 C 中转。可能的方法有:从 C 往 A ssh -R,从 C 往 B ssh -L,从 A 往 C ssh -L,从 B 往 C ssh -R。有一个要注意的问题是 -L -R 参数开的端口往往只监听 localhost,绑定到外网 IP 可能被禁止,这时候可以再建一个本地的洞从 0.0.0.0:某个端口打通到那个本地洞。这些不同的方法本质一样,但是受各类网关和权限限制,或者 QoS 的影响,或者安全性的考虑,往往某个方法优于别的方法,所以可以根据实际情况选择。

比较新的 ssh 开始带 -D 参数,可以将 ssh 通道当作 socks4 代理使用。这个尤其适合连 B 上的 ftp。从 A 通过另一台机器 C 连 B 的 ftp 碰到的问题是数据连接端口是动态的,无论 PORT 还是 PASV 模式都需要特殊配置。比较简单的方法是:A 往 C ssh -D 8899 端口,然后配置 A 本地 ftp 软件使用 socks4 代理:localhost:8899,这样 ftp 软件就可以正常工作了。这个方法也可以用于浏览有 IP 限制的网段。比如从国外无法浏览中国教育网里面的网页,如果可以用 ssh -D 挂上一台能直连教育网的机器,那么配置浏览器使用这个 ssh 通道的 socks4 代理就可以了。另外比如你想下 bt 但是又想避开米国的耳目,或者你对某段网路的安全不放心,也可以用这个办法来方便的加密传输数据,因为 ssh 通道内传送的数据是加密的。

C. openvpn 大法

最后出场的就是 openvpn 了。 ssh 端口映射一般不需要 root 权限,但是 openvpn 需要,当然 openvpn 也会灵活得多。针对 A 无法直接连 B 的问题,最简单的 openvpn 解法是从 B 连上 A 的 openvpn server,这样就可以从 A 直接向 B 的 openvpn ip 连接了。这个方法和 ssh 端口映射比似乎没有什么优势,不过我碰到过土鳖破网关,openvpn 自动重连可以保证可靠的连接,虽然要折腾出可靠的 ssh 也不是不可能的。

openvpn 虚拟出一个网卡, 在网络配置上要灵活得多。一个常见的应用是将外网机器接入内网子网。假设 C 和 B 在一个子网 192.168.1.0/24,C 有外网 IP(不一定要是 B 的网关)。这时候在 C 上架 openvpn server,配置 openvpn.conf:

push "route 192.168.1.0 255.255.255.0"

如果 C 不是这个子网的网关,还需要在 iptables 配置 SNAT(nat 表):

-A POSTROUTING -s 10.38.0.0/255.255.255.0 -d 192.168.1.0/255.255.255.0 -j SNAT --to-source C

这里 10.38.0.0/24 是 openvpn 的网段。这样配置之后,A 连上 C 的 openvpn 之后 A 去 192.168.1.0/24 的网络包就自动走 openvpn,几乎所有需要使用这个内网的程序都不需要任何配置就可以直接使用,连接 B 自然也没有问题。

现在绝一点,还是上面的情况,假设 B 这个子网里面没有机器有外网 IP,B 的网关没有权限,而且 A 在另一个子网,A 的网关也动不了手脚,那么怎么让 A 能够进入 B 这里的内网呢?这时候可以找外网一台自由的机器 D,让 A B 都连上 D 的 openvpn server,这样就可以利用 openvpn 客户端之间的通讯了。具体配置在 D 的 openvpn server 上有,配置 openvpn.conf:

client-config-dir ccd
route 192.168.1.0 255.255.255.0
client-to-client

配置 ccd/B:

iroute 192.168.1.0 255.255.255.0

配置 ccd/A:

push "route 192.168.1.0 255.255.255.0"

B 上面需要配置 SNAT:

-A POSTROUTING -s 10.38.0.0/255.255.255.0 -d 192.168.1.0/255.255.255.0 -j SNAT --to-source B

这样就可以了,A 连上 openvpn 以后应该会显示 192.168.1.0/24 路由走 openvpn 网卡。

可以看到,openvpn 配置了底层的路由表,所以大多数应用程序都不需要设置就可以直接使用这个洞了,这对于一些没有设置 socks 代理功能的软件尤其有用。更高级的应用还可以做 taprd,直接在外网去拿内网的 DHCP 地址等等。这些配置都是高科技武器,不一一叙述,不过我个人的体会是只有你想不到,没有你做不到。

D. 杂问题

  • openvpn 用 tcp 还是 udp,参见这个链接。我实测在高速可靠网路上,两者似乎没有区别。不过还是推荐 udp。
  • 性能。大多数打洞的方法是会损失性能的,包括网络速度和 CPU 的负荷。破机器或者嵌入式机器需要注意一下 CPU 负荷是不是性能瓶颈。网络速度一般会达不到满带宽,就 openvpn 来说,一般至少会损失 20% 的网络速度,去掉加密,加大压缩可能会有帮助。tunnel over ssh 属于 tcp over tcp,在不可靠网络上速度尤其会受到影响。不过带加密的洞在 tcp checksum 的基础上还有一层验证,数据可靠性很高。我曾经在极不稳定的网路上用 ftp over ssh 传过快 1 TB 的数据,一个 bit 也没有传错。
  • 不修改 src 的端口映射。打洞一般碰到的一个问题是,在目标机器 B 上看,连接是从中间机器 C 来的了,无法知道最初的连接来自哪里,这个问题在某些情况下是很不爽的。那么为什么 C 需要修改网络包的 src 呢? 这是由于一般来说路由表是根据网络包 dst 地址来配置的,所以如果 C 不修改网络包 src 地址,B 回应 A 的网络包就未必会经过 C 了。解决办法很自然:要么把 C 设置成 B 的网关,要么在 B 以及所有 B 和 C 之间的路由器上设置策略路由(policy-routing,根据 src 而不是 dst 选择路由)。在只有 B 有配置权限的情况下,可以用 openvpn 把 B 和 C 打通,保证 B 可以不通过路由器直接把网络包发送给 C。

其实很多打洞原理和方法说明白了也没什么奥妙,不过本文部分内容鄙人还是从康神czz 这里学到的,致敬!

Tags: , , , , ,

TeraStation Pro II 使用手记

August 30, 2007 11:06 pm GMT-0700 | In Tech | 1 Comment | hide

English Translation: A quick summary

  • to get root privilege: compile acp_commander.java and run
    java acp_commander -o -t TeraStation_ip

    You may need to temporarily disable firewall on the machine that executes this command. You can then telnet in with empty root password, and set a password. Start sshd to have secure connection. Because it’s so easy to hack TeraStation, I think it can only be used in trustworthy local network.

  • Every time you restart TeraStation, you have to use acp_commander to start sshd, but root password is preserved.
    java acp_commander -c 'sshd' -t TeraStation_ip
  • To have special characters in the windows sharing password, just run passwd and smbpasswd under shell.
  • TeraStation supports rsync but rsync is only intended to be used between TeraStations. You could change /etc/rsyncd.conf to configure rsyncd server. Also, you can setup crontab job to rsync from TeraStation main disk to a USB disk plugged into TeraStation. This is obviously the best local backup method.

小日本作了一堆 TeraStation 文件服务器(民间 wiki民间论坛),卖得还不错。这玩意没什么特别的高科技成分,嵌入式 linux,加一堆软 raid。唯一比较赞的是机箱工艺比较好,体积也比较小。对于一般的应用,默认启动起来的 TeraStation 已经足够能用,但是没有 root 权限总是一件很不愉快的事情。下面简略记一下我对我们买的 TeraStation Pro II 的一些 hack。

默认的 TeraStation 对外只开了 web 管理界面和 smb 文件共享。但是它留了一个洞,可能是为了升级 firmware 方便。有人琢磨出来利用这个洞获得 root 权限,google acp_commander 就可以找到详细说明。acp_commander.java 源代码在 这里 备份一下。acp_commander 可以给 TeraStation 发送命令。执行

java acp_commander -o -t TeraStation_ip

清空 root 密码并启动 telnetd,然后 telnet 进去使用空密码登录 root 并设置密码。然后启动 sshd 就可以登录 ssh shell 了。一个要注意的问题是 acp_commander 需要接收 UDP 包,所以执行命令的这台机器需要临时关掉防火墙。

TeraStation 每次重启动会 reset 一些设置,所以需要重新用 acp_commander 来启动 sshd。注意 root 密码是不会被 reset 的,所以以后每次只要启动 sshd 即可,不需要清空 root 密码,也不需要再启动 telnetd 了。

java acp_commander -c 'sshd' -t TeraStation_ip

当然最彻底的方法是换掉 TeraStation 的 firmware,人民群众也已经创造了稳定的内核。不过我比较懒,所以还是用老的 firmware,反正我需要的功能都已经有了。另外,因为这个默认的 TeraStation fireware 这么容易被黑掉,所以建议只在可信赖的内网使用小日本的这个玩意儿。

TeraStation 的 web 界面相当的土鳖,不支持含有特殊字符的密码。大概看了一下貌似是因为 cgi 程序懒得处理这些特殊字符所以干脆禁止掉。当然,有了 shell 之后只要在 shell 下执行 passwd 和 smbpasswd 修改即可。ps 发现脚本到处都有日文注释,看来小日本写程序和有些中国人一样,也喜欢用母语注释。

TeraStation 本身支持 rsync 协议但是只是为了 TeraStation 之间备份用。有了 shell 之后可以修改 /etc/rsyncd.conf 来配置 rsync 服务器。当然也可以用 rsync over ssh,但是 TeraStation 的处理器不够强劲,高速解码 ssl 还是会影响一些性能。另外,从 raid 主盘往接在 TeraStation 上的 USB 盘备份可以在 crontab 设置 rsync,这应该是本地备份 TeraStation 最高效的方法。

Tags: , , ,

Squid 优化补遗

August 30, 2007 6:40 pm GMT-0700 | In Tech | No Comments | hide

Squid 优化补遗

by wuxinan[at]wuxinan[dot]net , 转载请保留。

康神早年写过一个 Squid 高级优化指南 系列,可惜似乎没有完全写完。当时协助康神调整优化某站,康神就是寥寥数笔,搞定了大配置方向和几个重要优化,留下我等小屁孩跟在康神后头做了一些细枝末节的工作。大师就是大师,做事情如此,写文章亦是如此。既然如此,那我就当做点技术笔记,补充一些细节问题。如果你没有看过康神的系列文章,那么最好先拜读一下康神的系列:

还有一篇不属于这个系列但是涉及到 cacti 监视 squid 的,也是好文章:

下面是我献丑的补遗。

A. 数据反馈

康神教导我们:反馈是做一切事情的基础,优化也不例外。那么具体看一些什么反馈数据呢?很遗憾,这个问题没有固定的答案,基本上需要具体问题具体分析。具体来说,用 cacti 之类的看 squid snmp 数据是第一步。主要的数据有:

  • BHR (Byte Hit Rate)/RHR (Request Hit Rate),这两个分别表示有多少数据量/请求数是被 squid hit cache 的。要特别注意的是,squid hit cache 并不等于 squid 不往主服务器发请求。具体情况在 squid 2.5/2.6 里面参看 isTcpHit() 函数。举个例子,如果 RHR 显示 90%,那么可能有 20% 的请求 squid 还是往主服务器发送了请求询问它过期的 cache 内容是否有变化的,只不过主服务器的回应是没有变化。主服务器的判断一般需要一次数据库查询或者文件系统的 stat 调用。高负荷服务器到最后如果瓶颈在主服务器磁盘 I/O,这些貌似 HIT 的请求也会对主服务器造成一定量的冲击。单纯盲目追求高 BHR/RHR 是不可靠的。
  • Service Time,这个是各类请求的回应时间,但是这个时间受到外部网络速度的影响,所以也不一定代表真实的性能。另外,如果出现 Miss Service Time 比别的几个 Service Time 指标高出很多,表示去主服务器的请求耗时比较长,一般是代表瓶颈在主服务器那里,但这也不是绝对的。如果 squid 服务器磁盘 I/O 性能跟不上或者 CPU 不够强劲(squid 2 核心是可怜的单进程),那么也可能是 squid 本身的调度出了问题。
  • Storage,在特定情况下可以估算 squid 每天缓存多少东西,在配置缓存大小等问题的时候会有帮助。

总的来说,squid snmp 数据是需要根据具体情况分析的,而且 squid snmp 的数据也不多,有时候往往需要配合别的监控来综合分析问题,比方网络出入流量,服务器的各类性能分析,主服务器和 squid access log。有一次我在某站 squid 调整了一个参数,结果那天 squid 的反应奇好,BHR 更是上了前所未有的 98%。但是后来反复推敲发现这个参数并没有作用,结合各类 log 分析发现是因为那天 frjj 贴了新照片,而且被盗链,导致巨大比例的 frjj 照片的请求被 squid 有效的缓存,squid 网络出流量激增也支持这个结论。说了半天,中心意思是高负荷服务器的 squid 优化是一个长期而艰巨的任务,某些参数的优化需要几天的数据才能得出有意义的结论,所以需要有足够的耐心和针对实际情况的系统化的优化步骤。

B. 缓存策略

康神教导我们:一般来说,(缓存策略)如果后端不是配置很麻烦,建议还是在后端做,前端的配置修改大多数都是违背 http 协议的,如果出现问题,也比较难排查。HTTP 缓存协议比较权威的可以参考 RF2616 第十三章,特别是 13.2 和 13.3 节。具体实现可以参考比方 Firefox 代码 nsHttpResponseHead.cpp 的 ComputeCurrentAge() 和 ComputeFreshnessLifetime() 函数看看各类情况的处理方式。mod_expires 的配置就需要深刻理解这些基本概念,否则可能反而会增加请求数。如果没有特别的理由,静态文件的过期时间一般是设置为 access time 加上一定量的时间。这个一定量的时间由具体情况决定。比如网站建设初期,各类静态文件可能需要比较短的过期时间以方便网站更新;而一旦美工敲定图片,图片的过期时间可以大胆的设置为几个月。在配置完成以后如果没有很大的把握也可以实际浏览一下分析请求序列看是否浏览器端和 squid 服务器都做到了有效的缓存,特别注意 cache 相关的请求和回复头,包括 squid 提供的 X-Cache 头。

另外,虽然违反 HTTP 协议的 squid 配置一般都不推荐,但是具体到细节上,这也不是绝对的原则。下面举例说说必须违反 HTTP 协议的情况。

  • 使用 javascript 做镜像网站测速,一般实现方式是从各个镜像站下载一个图片看哪一个最快。最理想的情况是图片在浏览器端不要缓存(以便下次准确测速),但是这个请求又完全没必要打到主服务器上。那么可以在 squid 里针对这个图片 url 配置强制缓存 refresh_pattern reload-into-ims ignore-reload。当然这个例子很土鳖,只是举个例子。
  • reload_into_ims (这里说的是 squid 的配置参数,不是 refresh_pattern 里面的 option)。这个参数虽然违反 HTTP 协议但是对大部分网站来说是可以设置为 on 的,只要后端服务器对 If-Modified-Since 头的判断正确并且没有潜在安全问题即可。
  • 浏览器 F5 刷新和 javascript 的 location.reload() 刷新可能会重新请求所有的网页内嵌元素并且可能带 no-cache 请求头,一般来说 reload_into_ims 设置成 on 已经足够保证对主服务器不造成冲击,但是如果有必要可能还是需要在 squid 配置强制缓存。
  • 针对土鳖客户端的优化。比如早期的 fterm 预览图片会发送 Pragma: no-cache 的请求头,这势必导致所有 fterm 预览图片的请求如数全部打在后端服务器上,所以解决方法是 squid 这里做手脚针对这类 url 配置强制缓存。一个细节问题是如果不能缓存的图片(比方有察看权限限制的)和能缓存的图片的 url 结构完全一样,那么在 squid 强制缓存这类 url 的话又会有潜在的安全问题,这里涉及到后面会讲到的网站结构优化,针对这个问题需要修改网站的代码以明确区分这两类 url。还有另外一个例子是早期的 firefox 发送 XMLHttpRequest 请求也会发送 no-cache 的头,后来的版本改了。当年这一类 ajax 请求的 url 也是需要配置强制缓存的。
  • 最后一个问题是,如果在特殊情况下必须在后端服务器发送 Expires 头,并且同时又在 squid 中配置这类 url 的 refresh_pattern,那么需要特别小心。比如,如果 squid 强制缓存时间比 mod_expires 配置的过期时间长,那么可能造成 squid 发送已经过期的内容,导致浏览器本来可以有效缓存的内容却需要不断的向服务器检查更新。

最后,有些后端服务器没办法配置 mod_expires。这可能是因为没有配置权限,也可能是因为后端服务器软件太土鳖,总之这样的情况下就必须用 squid 配置 refresh_pattern 了。

C. 网站代码及结构优化

康神教导我们:很多 squid 优化(的文章)只限于在 squid 参数和系统参数上面的调整。但是这个实在只是细枝末节的事情,只要不是太弱智的配置导致无法缓存,squid 的性能不会有太大差距。网站优化一般来说也是属于这种类型的优化,对于主服务器负荷瓶颈在磁盘 I/O,或者网络瓶颈是大量大图片文件的情况,优化网站 html 结构可能对性能提升没有半点作用。不过即便如此,有一个为 squid 考虑的网站结构,可以使得 squid 服务器的配置比较容易,也可以比较容易的实现多 squid 业务分拆,有的时候业务分拆并不是为了性能,而是为了更好的分析问题以便进一步优化网站。下面简要说说有可能提高性能的网站代码优化。

  • 减少页面大小。这个问题实在是到处都有好文章,我就不详细说了。常见技巧是分离 css/js 到单独文件减少动态主页面大小同时保证静态内容有效缓存;页面 layout 设计尽量使用 div+css;有大量冗余 html 元素的部分使用 javascript 来输出。最后这个页面 javascript 化可能需要考虑搜索引擎优化 (SEO) 的问题,总的来说需要在减少流量和 SEO 之间寻找一个好的平衡点,这个只有做网站的人自己最清楚。
  • 减少同一份数据的不同表现形式。大量使用 ajax 的站点有时候考虑 SEO 往往要重写一套给搜索引擎看的页面,这势必导致 squid 这里要存两套页面。但是如果功力足够还是可以做到大部分页面重用。举例来说,网站可能希望用户读文章不切换页面而使用 XMLHttpRequest 载入,这个就可以在 <a href 写上文章内容的页面以便搜索引擎扒站同时也允许用户在新窗口打开这个文章,而 onclick 事件则触发 XMLHttpRequest 载入页面并分析显示内容。只要代码写的足够漂亮,这里用一个文章页面就可以实现所有的功能。
  • 标准化 url。这个可以算前一条的补充。写网站如果不小心,可能同一个资源会有不同的 url。比方某篇文章,从主页进去的 url 是 article?bid=3&id=50,从搜索结果进去却是 article?id=50&bid=3。这样两个页面,不但影响外部搜索引擎排名(自己和自己打架),更会影响 squid 效率,因为 squid 需要单独存这两类页面。
  • 网站建设初期充分考虑到将来的 squid 优化。举例来说,很多网站都在页面带用户登录信息显示,这样的页面如果不使用 javascript 技巧就完全不可以在 squid 这里 cache。而实际上,如果这些动态内容可以在 javascript 里面通过 cookie 判断出来,那么完全可以用 javascript 来写。这方面的细节工作做得越好,就有越多的页面可以被 squid 安全的缓存。当然这方面的优化有时候也只有网站运行起来才能发现,维护网站的时候多分析 log,多观察,就可以发现这些细小的可以优化的地方,水滴石穿,大量小细节的优化也可以带来可观的性能提升。

D. 一些杂问题

  • 同步 squid 和主服务器的时钟。从原理上说即使主服务器、squid 以及浏览器端的时钟都不同步,应该也不会造成缓存策略上的问题,但是为了防止诡异问题的发生,还是配置一下 squid 和主服务器的 ntpd 为好。ntp 是一个极轻量级的协议,现在网络上 ntpd server 也遍地都是,保证服务器时钟准确到 1 秒之内也可以保证别的一些程序的事务处理逻辑。
  • 密切注意搜索引擎的动向。有一些搜索引擎做的比较弱智,有的时候会突然发很多请求过来。搜索引擎扒站很容易扒到冷僻内容,所以即使请求量只是普通浏览用户请求量的零头,也可能会对主服务器造成冲击。大部分搜索引擎还是比较守规矩的,甚至有些搜索引擎公司还可以与他们接触配置扒站方案。不老实的搜索引擎可以通过 squid 或者主服务器 log 找出来,特别不老实的可能 iptables 都能发现。解决方法比如可以针对搜索引擎 user agent 判断,或者干脆 iptables 咔嚓掉。
  • Cache replacement policy,对大论坛站点,虽然 lru 算法占用 cpu 较低,但是 service time 可能会不如带 dynamic aging 的算法稳定。据观察,lru 算法在运行几天之后的早晨如果突然碰到大量新请求,新请求会很难进入 cache,或者进入了也很快被踢出,导致非常容易形成恶性正反馈拖垮后台服务器。但是假如每天清晨清 cache,并且保证磁盘 cache 的量稍大于每天能存下来的量,那么 lru 算法应该也不会比别的算法差(事实上什么算法都一样了)。当然这只是我的一家之言,一般来说这个问题还是需要根据 squid 服务器性能和网站具体情况多次反复试验选择最合适的算法。一般来说小规模和超大规模的站点优化这个参数可能不会有什么显著的性能提升,所以不建议耗费太多时间优化这个。
  • 一定时间清理 cache 并重启 squid。这个有可能只是 squid 2.5 并且是高负荷破机器上需要考虑的一个方案。某站曾经有段时间每天高峰期 Miss Service Time 都会飙升,但是主服务器却没有超负荷的现象,最后推测可能是 squid 自己调度的问题。后来每三天清理 cache 并重启 squid 似乎大大减少了这种现象。后据权威人士批复,这个可能是因为 squid cache replacement 算法过于古老,不适应高速更新的大型论坛所致。
  • 多域名宣传的服务器。如果网站允许有多个域名但是所有的域名都指向同一个网站,那么要注意 squid 不要配置成多域名模式,否则它会把每个域名的 cache 都分开处理,导致效率低下而且不能有效利用缓存存储空间。题外话,单个网站宣传多个域名也会影响搜索引擎排名等等,所以本质上也是不推荐这么做的。
  • maximum_object_size_in_memory,maximum_object_size 这两个参数的配置也是具体问题具体分析的。具体到某站上,常见的大文件就是附件了,由于附件最大允许大小是 5120 KB,所以 maximum_object_size 配置了 5123 KB 以保证即使最大的附件加上各 HTTP 头也能有效的被缓存。最早这个参数是配置成 5120 KB 的,然后曾经有一次发生 BHR 骤降的情况,后来分析发现是有人贴了 5120 KB RAR 分卷压缩的李宇春同学的视频,而且恰好又有无数玉米下载,大量这类请求因为超容所以都压到了主服务器上。另外 maximum_object_size_in_memory 的配置需要考虑网站具体情况和 squid 服务器的性能,这也需要实际试验出来。

最后废话一句,现在硬件降价很快,给机群升级扩容提升硬件性能往往比找个猪头优化 squid 配置更有效果,而且见效也快。所以在 squid 大配置没有问题的前提下,有钱的话应该首选硬件优化方案而不是软件细节优化。

康神教导我们,windtear 是 squid 之王,Lord of Squid,业务分拆是从他那里学来的,致敬。本文部分内容是间接从 windtear 那里学到的,一并致敬。

Tags: , , , , ,

月全食

August 28, 2007 1:00 pm GMT-0700 | In Life | 4 Comments | hide

本人一向贯彻土人就要土到家的原则,这次临时发现有月全食,就地取材拍了几张照片。没有三脚架,我就用袖珍三脚架和胶带把相机绑在椅背上;没有好相机,我就直接用老古董傻瓜相机,几乎都用自动模式拍的;另外,照片合成是用了两行 matlab… orz。(点图片看大图)

eclipse

Tags: ,

« 上一页下一页 »

This weblog is licensed under a Creative Commons License.
Powered by WordPress. Theme based on Pool by Borja Fernandez.