adoal 的blog

用 FastCGI 连接 Nginx 和 Zope

跟用 Apache 相比小有一点麻烦,需要配置一下。

location ~ /zope(/|$) {
    fastcgi_pass unix:/var/run/plone-site.sock;
    include /etc/nginx/fastcgi_params;

    set $fixed_content_length $content_length;
    if ( $fixed_content_length = "" ) {
        set $fixed_content_length "0";
    }

    set $path_info "/";
    if ( $document_uri ~ "^/zope(/.*)$" ) {
        set $path_info $1;
    }

    fastcgi_param CONTENT_LENGTH $fixed_content_length;
    fastcgi_param PATH_INFO $path_info;
    fastcgi_param SCRIPT_NAME /zope;
}

主要原因是, Zope 对 SCRIPT_NAMEPATH_INFO 两个参数的要求是以 Apache 方式为基准的, Nginx 的方式无法分辨出访问的对象标识。看了一下 CGI 标准,应该是 Nginx 的做法站不住脚,但好在可以通过配置来解决。另外, Zope 直接把 CONTENT_LENGTH 的值(字符串)丢给 aoti 而这个函数在字符串为空时会抛出异常, Zope 没考虑到这一点,所以也要修正一下。

顺便感慨,把这条技巧加到 Nginx Wiki 里的时候,看了一下历史变动,里面有相当多的中文 spam 广告被管理员删掉的记录,汗啊。

SSLVerifyClient 导致的上传文件失败问题

自某年某月某日起,某 Plone 服务出现一个严重问题,上载文件稍微大一点就会出错。当时懒得折腾,今天领导敦促,于是试图解决之。直觉告诉我问题不在 Zope 里,前端的 Apache 出问题的可能性比较大。看日志,果然如彼:

[Wed Dec 05 13:54:30 2007] [error] [client ##.##.##.##] request body exceeds maximum size for SSL buffer, referer: ...

[Wed Dec 05 13:54:30 2007] [error] [client ##.##.##.##] could not buffer message body to allow SSL renegotiation to proceed, referer: ...

骨骼了一下,发现 [ASF39154] 提到了这个问题,回答是:

This does not work on directory level with large files, because we currently do not buffer the request body on disk but only 128k at max in memory. Moving SSLVerifyClient require to virtual host level will make it work (see also PR12355)

好吧,虽然我用的是 SSLVerifyClient optional 不过原因是一样的,于是照做,把这个东西搬到 <VirtualHost> 上下文里,于是问题解决了。隐约回忆一下,似乎当初用 Plone 默认登录方式的时候是没这问题的。据传 Apache 这样设计是为了防止被 DoS 死,大汗!

不过这个 virtual host 里除了 Zope 还运行着其它东西,试验了一下在其它 <Location> 上下文里加入 SSLVerifyClient none 还是要做一次可选的验证,似乎不起作用,不解。先不管了,大不了另找个机子移过去。

[ASF39154]Problem with webdav over SSL with client certificate autentication <http://issues.apache.org/bugzilla/show_bug.cgi?id=39154>

clamav 0.90 不是很靠谱

运行时载入病毒库的过程疯狂占用 CPU 数分钟。由此带来的糟糕后果就是,系统启动时 clamd 需要过很长时间才能创建监听的 socket,于是 amavisd 在寻找 clamd 的 socket 时连接失败,然后 fallback 到使用 clamscan,然而不幸的是 clamscan 载入病毒库的过程是一样,于是整个系统的大部分 CPU 资源都被用于 clamscan 了,邮件被严重阻塞。

这个问题比较难以谷歌出答案。好不容易才在 clamav 邮件列表的一个边边角角找到讨论,说 0.91 版修正了。但是懒得自己编译。幸好 Debian 还有个 backports 用起来比较方便。唯一遗憾的就是 CERNET 里找个 backports 的 mirror 不是件容易事。

如何防止 VMware 被应用程序检测

网上转载的,不知道原始出处在哪里(诶,好像大家都习惯转载不留原始出处信息)。留个底,说不定哪天会用到呢。

某不靠谱银行(就不指名道姓了,大家心照不宣)的网银专业版检测到运行在虚拟机里就拒绝登录。有个办法是花钱买牠家的 USB Key,映射到虚拟机 guest 里。如果不想花钱,就只好用下面的方法欺骗一下。孟子说,君子可欺之以方。对某银行 IT 部这群偏执狂,更可以欺之而心安理得。

另外,期待其它虚拟机的反检测方案。嘿嘿。


如果你的电脑足够快,那么

  1. 首先你把你的 VMware 虚拟机里面的操作系统调到最快的状态(关闭不必要的程序、自动更新等)然后关闭虚拟机;
  2. 打开 VMware 虚拟机的配置文件,这是一个后缀为 vmx 的文本文件。在里面加入以下内容
isolation.tools.getPtrLocation.disable = "TRUE"
isolation.tools.setPtrLocation.disable = "TRUE"
isolation.tools.setVersion.disable = "TRUE"
isolation.tools.getVersion.disable = "TRUE"
monitor_control.disable_directexec = "TRUE"
monitor_control.disable_chksimd = "TRUE"
monitor_control.disable_ntreloc = "TRUE"
monitor_control.disable_selfmod = "TRUE"
monitor_control.disable_reloc = "TRUE"
monitor_control.disable_btinout = "TRUE"
monitor_control.disable_btmemspace = "TRUE"
monitor_control.disable_btpriv = "TRUE"
monitor_control.disable_btseg = "TRUE"

这些参数不一定都需要,不过最保险的是都加。可以提高模拟的真实性,不过速度也会慢很多。

对今天的某行网银专业版而言只需要加

isolation.tools.setVersion.disable = "TRUE"
isolation.tools.getVersion.disable = "TRUE"

这两个,不影响虚拟机速度。以后不行了再加其它项。

修改 vmx 文件完毕后应测试 VMware 是否能登录专业版。

先用 SetEnvIf 撑一下

这个 Drupal 站的服务器放在 reverse proxy 后面,统计里显示的 IP 都是服务器的,不爽。本来想把 6.0 里的代码移植过来,可是 5.0 里一大堆直接读取 REMOTE_ADDR 的,嫌烦。今天想到一个办法:在 Apache 的虚拟主机上下文里加一句:

SetEnvIf X-Forwarded-For (.*) REMOTE_ADDR=$1

搞定!不知道有什么潜在问题。先用用再说。改代码的方法慢慢来。

在 Drupal 中使用 reStructuredText

基于 Python 的 CMS 几乎都支持用 reStructuredText(reST) 来写内容,然后用 docutils 转成 HTML 输出。Drupal 是 PHP 写的,所以想在这上面用 reST 就不是那么显而易见了。抽空写了个 Drupal 的插件,叫DreST,调用外部程序来实现 reST 到 HTML 的转换。依赖于 docutils 0.3.9 或更高版本,因为需要调用 publish_parts 做转换。测试了一下,基本可用。

暂时先自用,过段时间整理一下,符合 Drupal 模块开发规范了之后就到 Drupal Modules 上申个开发者帐号放上去。

发布前需要修改的地方:

  • 写 README/LICENSE
  • 写运行时显示的 help 和 tips
  • 测试外部程序 drestconv.py 在不同 locale 下的兼容性

以后的增强计划:

  • 提供在系统里和 Drupal 里做配置的选项 可是需要什么选项呢?

  • 程序源代码语法加亮控制 有客户端和服务器端两种方案

    • 客户端方案,需要在 PHP 代码里替换生成的 <pre> 标签的属性,以便 dp.SyntaxHighlighter 之类的 JavaScript 语法加亮工具能识别出来
    • 服务器段方案,使用 Pygments 生成 <span> 标签控制颜色

    两种方法各有利弊

To QDII, or not to QDII

QDII 的产品线越来越丰富,银行系、基金系、信托系……虽然不如 A 股那么火爆,但在 A 股越走越高让人心慌的情况下,分散投资降低风险以及拓宽投资面享受全球市场收益的想法也着实让很多人对 QDII 产生了不小的兴趣。在 88 上也看到有些人配置了 QDII 的投资品种。

但我并不倾向于现在就配置 QDII 产品。我的看法是:投资国际市场,从资产配置的角度来看是非常必要的,在将来某个时候我一定会配一些投资国外的产品,然而没必要现在就做,没必要一看到 QDII 就跟上。原因很简单,很多人投资 QDII 的最主要目的是降低风险,那么,有什么比“未知”具有更大的风险呢?QDII 的历史很短,不论基金系还是银行系,几乎没有过往业绩可参考,而且冲出国门投资本身就是国内的机构投资者所不熟悉的,即使是有深厚外资背景的机构,譬如上投摩根,也需要经过实战检验才能说行不行啊。至于以拓宽投资渠道,享受全球市场收益为目的,也是同样的道理。

如果能接受 LaoK 关于买新基金是指腹为婚的说法,也就不难理解,现有的 QDII 其实也是娃娃亲哦。不妨再耐心等候,时间会给出结论的。更何况,将来会有越来越丰富的投资渠道,包括直接投资海外市场。又何必急于一时呢。

联机证券交易系统绝对是天才设计出来的

很多人都知道 Unix 系统在设计上有一个很酷的亮点:一切都是文件。普通文件、目录、设备节点、系统运行状态和控制、套接字、管道等等都可以用统一的文件 API 来访问。这个特性,称之为天才设计决不过分。

接触了一段时间股市之后发现,联机证券交易系统竟然也有类似的统一接口设计:联机交易的大部分功能都可以统一成跟买卖股票一样的操作。不同功能设计成不同的伪股票代码就可以了。譬如:

  • 这个星期一的建行打新股,只要交易系统在这个交易日开立一只代码 790939 的“建行申购”伪股票,交易者下单“买”这只伪股票即可。同样,配号也不需要单独设计,有个代码为 791939 的“建行配号”。客户端程序不需要为打新股功能做任何修改,只要服务器端加上相应的模块就可以,减轻了普通投资者升级本机安装的软件的负担,也减轻了客户端软件开发者的负担。
  • 股东大会投票,也可以用交易系统来操作。深交所股东大会网络投票平台网站上有个例子:如果万科有网络投票,交易系统会在当天挂牌一只伪股票,代码 360002(因为万科 A/B 的代码为 000002/200002),假设有三个议案,那么委托价格 3.01 元就表示第三个议案的第一项子议案;买入 1 股表示同意,2 股表示反对。由此可见,交易软件的客户端也没必要实现单独的股东在线投票系统,通过和股票买卖完全一样的操作就能实现。

这种操作方式是谁发明的不得而知。不过,像 Unix 下一切都是文件一样,一切都是股票代码,也是统一而强大的接口。当初设计这个接口的系统架构师,无疑是个天才!

软件开发需要什么样的美工

交互式软件的开发必然需要界面设计,尤其是,基于传统 GUI 和基于 Web 的软件系统,美工在其中起的作用非常大。通常,软件美工是做平面设计出身的,这是业内和业外的共识。大家也想当然地认为美工做的是美术设计工作,不需要懂软件本身用到的技术——另外,与此相伴的就是,对于程序员缺乏可用性观念和审美情趣,虽然痛心疾首,但同样习以为常。在程序员和美工之间通常难以存在高效的沟通。

相对好一点的情况是,开发团队运用科学的管理手段进行管理,如果人员数量能得到保证,项目管理人员、交互设计师可以作为程序员和美工之间的桥。但这也只是从工程管理的角度来看相对好一点而已。这种桥式接口毕竟只是桥,不是路。

从我自己这些年来跟一些美工合作过的经历来看,我认为沟通出现困难的根源在于,软件开发过程中需要的美工,决不能是纯粹的平面设计美工!因为他们的工作,不是设计海报、广告、宣传画,而是设计软件界面;不仅要考虑美观性和可用性,还要考虑是否“是”个软件界面,考虑其可实现性;软件美工,最后交出来的活,应该是交互设计师给出的软件界面上各元素独立的形象设计——可以由程序员不需要再做“副美工”的加工就能在程序中直接拿来构造出界面的资源,而不是给一张像海报一样的设计图,整个界面的效果图全在一张没有层的 JPEG 或 PNG 或其它格式的像素图中,要程序员再从里面抠出按钮、输入框等部件。

事实上传统的平面设计美工在设计和制作软件界面效果图的过程倒恰好跟程序员的需求有些对路。使用诸如 PhotoShop 之类的专业图像处理软件,必然涉及到层的操作。他们通常在不同的层里处理界面中不同部分,逐渐“组合”起来出现最后的效果。譬如整个窗体的背景图是一个层,非客户区(标题条、边框、缩放把手)是一个层,别的层里做好按钮、图标、输入框等效果,最后组合成一张图。其实,这些分立的部件(或者说 PSD 文件也可以,不过程序员通常还是不要拿到这个来自己搞为妙),对程序员来说比那张最终效果的 JPEG 更重要。

在正规的项目里,因为开发过程和团队都相对完备,所以美工可能会在经验丰富的组长管理之下把这些事情做好。然而我们(尤其指像我这种情况的非正式软件开发者)可能不具备组建一个完备团队的条件。于是就会遇到这样一种情况:美工辛辛苦苦熬了几个夜,终于做出了漂亮的界面设计图,兴高采烈地交给程序员,可怜的业余程序员傻了眼——图虽然好看,但还要做不少额外工作才能用在程序中,甚至根本没法用。基于窗体的程序还好一些,最郁闷的是网页。很多美工用 PhotoShop 设计网页效果,然后用内置的切割和导出工具直接输出成 HTML,这样看似不错,但实际很糟糕。页面被切成大大小小十几个 用 absolute 方式定位的 DIV,每个大小和位置几乎难以调整,动一下就会在别的位置出现糟糕的空白,还有一堆无用的细长条 DIV 纯粹就是切割的时候出现的占位块。纯静态的 HTML 还好一些,如果内容是动态填充的,可能哪里多几个字符就会破坏布局,或者把显示的内容裁剪掉一部分。如果是内容管理系统,页面区块可以用户控制的,那可就彻底乱套了。

因此,非常有必要细化出“软件界面美工”这样专门的角色,甚至有必要在高校艺术设计类专业里增设类似的课程。他们不需要了解一个 GUI 程序从启动到推出的窗口消息是怎么路由的,不需要知道网站后台如何生成页面传送给浏览器,但是,应当有一定的简单 GUI 程序开发经历,要手写过 HTML 页面,知道 CSS 是怎么用的,也就是说能够理解程序和艺术数据之间如何契合,程序展现界面时需要什么形式、什么组织结构、什么格式的美工作品。

当然,作为程序员这个想法还是有点自私的:让学艺术的人来理解和计算机代码相关的东西,似乎不太人性化。不过,软件界面毕竟不是纯粹的艺术品,软件美工也不可能是纯粹的艺术家,对吧?

越来越多 Windows 下的中文输入法支持 Unicode 了

今天在水木意外看到说搜狗拼音 3.0beta2 版支持 Unicode IME 模式。记得当初不少人提到过不选搜狗的理由包括这一点。现在终于支持了,或许可以装个试试看?

现在 Windows 下支持 Unicode 的中文输入法越来越多,在主流的拼音输入法中有:

  • 微软拼音 嗯,很早就支持了,不愧是微软自己的产品
  • 拼音加加 佳佳是个好同志,从 3.1 开始支持,在 4 系列里一开始不支持,俺在牠论坛里提过这事,后来就发现支持了
  • Google 拼音 不习惯叫牠的中文名字谷歌 :D 看来 Google 还是很有国际化意识的

大概就差紫光了吧。不知道刚发布内测版的那个 QQ 拼音如何。懒得下载试用,不过考虑到 TM 2008 开始支持 Unicode ,有理由认为比较乐观。

上面说的是拼音。据说五笔也不错,据我所知极点、小鸭都支持得很好,当然俺不用五笔所以不了解其它的情况如何。

从当年除了微软拼音和基于码表生成器模块之外很难找到支持 Unicode 的输入法,到现在各类 Unicode 输入法百花齐放,这是大大的好事啊。

同步内容