CrabDB 能在许多场景下能取代现有数据库的索引,解决传统数据库『索引建少了查询慢,索引建多了占空间太大会把数据挤出内存』的问题。
它的官方主页在 http://crabdb.org/。相关的文档和使用场景介绍将在不久后放出。
CrabDB 能在许多场景下能取代现有数据库的索引,解决传统数据库『索引建少了查询慢,索引建多了占空间太大会把数据挤出内存』的问题。
它的官方主页在 http://crabdb.org/。相关的文档和使用场景介绍将在不久后放出。
目前很多网站都在使用 memcached 作为后端的缓存系统,能将一些经常查询的数据放到缓存里,以减少数据库的压力。memcached 的服务器与客户端通讯使用的协议叫做『memcache 协议』,包含有两种方式:文本和二进制。这里的文本协议采用换行符作为命令的结束,例如:
客户端发送
get key\r\n
服务器返回
VALUE key 0 5\r\n
1234\r\n
END\r\n
大多数的客户端并没有对 key 做转义或过滤,使得客户端能够将回车符("\r\n")作为 key 的一部分发送给服务器,导致服务器将这些回车符被作为协议本身来解析。例如 key 为 "foo\r\nset bar 0 600 4\r\ntest\r\n",会变成这样:
客户端发送
get foo\r\n
set bar 0 600 4\r\n
test\r\n
服务器返回
END\r\n
STORED\r\n
这样就使 key 里的一部分被解析成了另一条 set 命令,给『bar』这个 key 里写入了 『test』。
当某个网站使用 memcached 作为缓存系统时,如果直接将用户输入的内容(例如 URL 上的参数或表单提交的值)作为 key 传给 memcached,会由于上述的原因,用户能够给 memcached 写入任意缓存内容或清空所有缓存(使用 flush_all 命令)。解决方法有以下两种:
一些 VPS 服务商(如 Linode)可以允许运行自己编译的内核。这样就可以在编译内核时去掉不必要的功能,节约宝贵的系统资源。
首先在服务器按照常规方式来编译内核。在配置内核前,可以从正在运行的 Linux 中提取配置文件作为模板(从 /proc/config.gz 解压)。编译完成后用 make install 安装内核,例如 Linux 3.0.4 版本会安装到 /boot/vmlinuz-3.0.4。
然后写一份 grub 配置文件保存到 /boot/grub/menu.lst (不用安装 grub):
default 0 timeout 5 title Linux root (hd0) kernel /boot/vmlinuz-3.0.4 root=/dev/xvda console=hvc0 ro devtmpfs.mount=1
进入 Linode 的管理后台,在 Linode Configuration Profile 的 Kernel 里选择 pv-grub-x86_32 或 pv-grub-x86_64,重启即可进入新内核。
去年我们北航举办了第 32 届 ACM-ICPC 北京赛区比赛。这次比赛的系统搭建都是由我们学生完成的,最终还是成功地举办了这次比赛。
我们购买了 90 多台新计算机。比赛需要安装同样的软件环境,包括 Windows XP,Ubuntu 7.10,以及各种编程软件。考虑到这些计算机都为品牌机,硬件已经安装好,因此采用了网络克隆的方式来安装。先手动安装配置好一台计算机,然后用某个很常用的硬盘复制软件(都知道是什么吧)的企业版(盗版),其它计算机用 PXE 网络启动后开始接受组播。组播时最好断开交换机与其他网络的连接,否则会由于交换机要保证整个广播域都能收到数据而非常慢。但这个软件不能正确复制 GRUB,导致无法启动系统,就又做了个修复 GRUB 的启动盘(GRUB4DOS 可以直接作为 PXE 启动镜像),用 PXE 网络启动后自动修复。
这样,只花了很短的时间就把这么多台计算机的软件都安装好了,而且志愿者们只需做一些按回车等简单的操作。
为了在服务器上将 IP 地址和座位号对应起来,必须为每台计算机手动设置 IP 地址。为了节约时间,防止不小心设错,我写了个小程序用于设置 IP 等信息,只需在运行里输入网址下载设置程序并输入座位号。Windows 中的 Server 服务是禁用的,即使计算机名重复也没关系。最后用个 for 脚本轮流 ping 所有的计算机,如有不通的再单独检查。
比赛要防止作弊,需要有一定的安全措施。我们在 Windows 下安装了 WIPFW 防火墙,配置为只允许与服务器通信。Linux 下则用内置的 iptables 防火墙。同时,为了防止插入 USB 存储设备,我们还把 Windows 下的 USBSTOR 驱动设为禁用,Linux 下禁止用户挂载设备。
虽然很少有人敢在现场赛作弊,但也不要让别人认为很容易作弊。比如说 2007 年某赛区在比赛时竟然还能上网,会让人对比赛的公平性产生怀疑。
在 ACM-ICPC 现场赛需要部署打印服务,让选手随时打印程序或数据。以前的几届有些赛区是这样解决的:在每台计算机中放入一个打印脚本,这个脚本取得计算机名或 IP 地址后加在要打印的文件前面一起调用 lpr 命令送到服务器打印。这样会有个很严重的问题:用户可以把这个脚本复制一份出来,修改脚本中的的队伍号,然后就可以光明正大地把自己的程序送到同伙队伍那里去了。
所以,必须要在服务器端判断打印者的座位编号,于是就用了基于 Web 的打印。在服务器端写了个 PHP 脚本,按照请求者的 IP 地址计算出座位号(这样不会从客户端伪造),然后发送给一个文本转 PostScript 的程序(忘了叫什么了)。我们修改过这个程序使之能指定纸张的标题。选手将网页打开,把要打印的文本复制进去提交即可。
整体情况是这样:2 台 Windows 计算机插着 5 台打印机,并共享,服务器上用 CUPS 添加好这 5 台打印机,接收到任务后按照 IP 地址计算出队伍编号,发送到这一列座位对应的打印机上。
PC^2 直接下载解压后即可使用。我们生成随机密码并发放给选手,允许选手自行重启计算机。在比赛时不但要随时备份,而且还要随时备份!
PC^2 中本来有个气球管理器,但是不太好用,就用了最原始的纸和笔来管理。先打印一张纸上的记分板,标记每个队的做题情况,当有裁判判出一道正确的题后,就在这张纸上标记一下,然后写一张小纸条给发气球的志愿者。
证书有统一的样式,由于彩色打印机的打印速度很慢,就先把彩色部分提前打印好,比完赛之后再把这些纸塞入黑白激光打印机打印队伍名和排名。
我们喝了很多三 Y 牛奶。还好是三 Y,不是三 L。
1. 字体显示成方块
现在 Wine 的所有版本 (到 1.1.0) 在某些软件中显示中文时会出现方框,因为这些软件选择使用了 Tahoma 等英文字体,而这些字体中没有中文字符。目前在网上看到的一些补丁,都是强行把所有文字都用中文字体来显示,看上去好像好了,但这样就没法使用其它的字体。而在 Windows 中,选择了 Tahoma 等英文字体之后,显示中文会自动用其它字体替代。
这个补丁真正解决了此问题,如果当前字体中找不到需要显示的字符,会自动从其它字体中寻找并显示。 (在注册表里面设置一下 FontLink 就行了。)
2. 中文断行
当用 DrawText() 输出一大段中文文本时,Wine 的断行算法只允许从空格处断行。应该是所有 CJK 字符中间都能断行。
用这个补丁解决。
3. SCIM 造成的兼容性问题
SCIM 会吃掉 X11 的 KeyRelease 事件,导致按了 Ctrl 之后弹不起来。
这是 SCIM 的 bug,可能在 Wine 中也能 workaround 一下。
4. 输入法输入一个长句子之后无法显示
此时控制台下有两句错误提示,
err:keyboard:X11DRV_KeyEvent Buffer Overflow need n*3!
err:keyboard:X11DRV_ToUnicodeEx Buffer Overflow need n*3!
n 是输入的中文字数。
解决方法是修改源代码中 buffer 的大小,或者用动态内存。以前有人提交过补丁。
trac 是用于软件项目的 wiki 和问题跟踪系统,同时还是 Subversion 的前端。这篇文件介绍如何在 lighttpd 上搭建 trac。
在 Debian / Ubuntu 上安装 lighttpd trac subversion apache2-utils 这几个软件包就行了。安装 apache2-utils 是为了使用里面的 htpasswd 工具。其它的发行版应该类似。
sudo apt-get install lighttpd trac subversion apache2-utils
首先启用 rewrite 和 auth 模块,然后用使用此配置文件:
alias.url = (
"/trac/chrome/common/" => "/usr/share/trac/htdocs/",
)
$HTTP["url"] =~ "^/trac/chrome/" {
# no fastcgi
} # end of $HTTP["url"] =~ "^/trac/chrome/"
else $HTTP["url"] =~ "^/trac" {
fastcgi.server = (
"/" => (
(
"bin-path" => "/usr/share/trac/cgi-bin/trac.fcgi",
"socket" => "/tmp/trac.sock",
"check-local" => "disable",
"disable-time" => 1,
"min-procs" => 1,
"max-procs" => 1,
"bin-environment" => (
"TRAC_ENV_PARENT_DIR" => "/var/lib/trac/",
),
),
),
)
} # end of $HTTP["url"] =~ "^/trac"
重启 lighttpd 后,打开浏览器看一下 http://…./trac 是否能用。
以下假设项目名称为 project01。
sudo mkdir /var/svn sudo svnadmin create /var/svn/project01 sudo chown -R www-data:www-data /var/svn/project01 sudo chmod -R g+ws /var/svn/project01
即在 /var/svn/project01 建立了一个 Subversion 仓库。
sudo mkdir -p /var/lib/trac sudo trac-admin /var/lib/trac/project01 initenv
刚才这一步会出来个向导,按提示输入 Subversion 的路径。接下来修改权限:
sudo chown -R www-data:www-data /var/lib/trac sudo chmod -R g+ws /var/lib
trac 需要使用 HTTP 来验证用户,通过 lighttpd 的 auth 模块可以实现。
auth.backend = "htpasswd"
$HTTP["url"] =~ "^/trac/project01/" {
auth.backend.htpasswd.userfile = "/var/lib/trac/project01/htpasswd.htaccess"
}
auth.require = (
"/trac/project01/login" => (
"method" => "basic",
"realm" => "Your Project Name Here",
"require" => "valid-user"
)
)
然后用 htpasswd 创建用户,第一次要用 -c 参数新建密码表。下面添加叫 user01 的用户:
htpasswd -c /var/lib/trac/project01/htpasswd.htaccess user01
并输入密码。然后配置该用户在 trac 中的权限,例如把 user01 增加管理员权限:
sudo trac-admin /var/lib/trac/project01 permission user01 add TRAC_ADMIN
浏览器进入 http://…./trac/project01,开始使用上面的功能。
客户端用 svn 或 TortoiseSVN 提交代码后,在 trac 上应该能看到版本比较。
管理过 Web 服务器的都知道,如果不小心在服务器上放上了一个热门的电影,并且用迅雷下载了它,马上就会有成千上万的人来连接,占用服务器的大量带宽和系统资源,并将有机会造成网络堵塞,房子起火,卫星失控等各种问题。
lighttpd 里面有一个模块叫 mod-trigger-b4-dl,主要功能是使用户必须访问某些文件后才能访问另外某些文件。太好了,它正好可以用来防止盗链,即用户如果没有看我的网页就直接试图下载里面的文件,很有可能是通过迅雷或其它软件盗链的方式下载的。
首先安装并启用 lighttpd 的 mod-trigger-b4-dl 模块,Ubuntu 源里已有:
sudo apt-get install lighttpd-mod-trigger-b4-dl sudo lighty-enable-mod trigger-b4-dl
然后配置之,修改 /etc/lighttpd/conf-available/10-trigger-b4-dl.conf,这是一个例子:
trigger-before-download.gdbm-filename = "/var/www/data/trigger.db" trigger-before-download.trigger-url = "/$|.php$" trigger-before-download.download-url = ".exe$|.rar$|.zip$|.iso$|.mkv$|.avi$" trigger-before-download.deny-url = "/deny.htm" trigger-before-download.trigger-timeout = 600
这段的意思是说,在你访问了 *.php 的页面之后的600秒以内才能下载 *.exe *.rar *.zip 等等文件,否则跳转到 /deny.htm。如果还需要防止其它扩展名,可在 trigger-before-download.download-url 加上,格式为正则表达式。如果服务器上的下载文件都放在某一个目录中,比如叫 download,就写上 /download/ 就行了。trigger-before-download.deny-url 这里是需要跳转到的地址,提示正常用户重新进入页面再下载。
实际效果呢,上个月共拒绝了 52442 次请求。迅雷会伪造一切能伪造的信息,包括 user agent,referer,cookie 等。以前 Apache 和 IIS 都有人做过一些商业的防盗链模块,通过检查 referer、随机生成 cookie 等方式,对现在的迅雷已经失效了,而且还会影响用户体验。而 lighttpd 里自带的这个模块就能很好地解决这个问题。
lighttpd 还有一个模块叫 mod_secdownload,但是它需要使用 PHP 等脚本来生成 URL,对需要用户登录才能下载的网站也是一个选择。我这里需要固定 URL 的时候就暂时用不着了。
北航教务系统又要我们评价老师了,不评价就不能查课表,不能查考试,几乎教务系统的有用的功能都不能用。而且评价很麻烦,每个老师有一大堆选项。
把这个自动评价链接拖动到 Firefox 的书签工具栏上,进入教务系统的评价页面,点击一下自动填好评价表。2008年6月根据教务系统变动情况修改。
别的学校如果用正方现代教学管理信息系统应该都可以使用。
去年买了一块无线路由器的板子,并在里面刷了linux,移植了实达瑞捷的客户端,实现了一号多人同时上网。下面简单介绍一下整个过程。
首先刷系统,现在有很多对基于mips处理器的linux发行版,如ddwrt(dd-wrt),openwrt,hyperwrt,tomato等。这里刷的是openwrt,体积小,而且启动脚本看上去比较清晰。
然后移植客户端。前几年某校的一些学生把实达瑞捷的客户端分析出来,并写了一些客户端,如mento,mystar等。mystar是在linux中运行的,这里就用它了。从openwrt网站下到一套交叉编译器(linux-x86 ==> linux-mipsel),编译mystar。网上找到的mystar用了libpcap和libnet库,但libnet的函数接口有变化,要先把libnet的那部分修改掉。最后编译成一个可执行文件,在路由器里面装libpcap,(openwrt里面竟然也有软件包管理系统,等上了网就可以自动下软件安装了),也把编译好的mystar放进去,再运行。
遇到的问题:
网络中如果有人用迅雷、bt等软件后,服务器在检测到大量连接会把网络断开,因此要避免这种情况。迅雷的协议总是变,不好封。干脆一狠心把UDP上的非DNS和DHCP全封了算了,并限制每秒钟最多发起3个新连接。
有了iptables,将以下规则加入/etc/firewall.user。
iptables -t nat -I PREROUTING -p udp -j DROP iptables -t nat -I PREROUTING -p udp --dport 53 -j ACCEPT iptables -t nat -I PREROUTING -p udp --sport 53 -j ACCEPT iptables -t nat -I PREROUTING -p udp --sport 67 --dport 68 -j ACCEPT iptables -t nat -I PREROUTING -p udp --sport 68 --dport 67 -j ACCEPT iptables -t nat -I NEW -j DROP for i in `seq 255 -1 2`; do iptables -t nat -I NEW -s 192.168.200.$i -m limit --limit 3/sec --limit-burst 10 -j RETURN done
这些规则都加在PREROUTING中,是在内核建立记录之前就进行拦截。最后一行可按实际情况修改。
再配置内核的网络参数,修改/etc/sysctl.conf,加上以下参数:
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=600 net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent=5 net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv=5 net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=5 net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=10 net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=10 net.ipv4.netfilter.ip_conntrack_udp_timeout=5 net.ipv4.netfilter.ip_conntrack_udp_timeout_stream=10
注意,如果你想允许UDP的应用,最后一行的10应改成600。