Login

新增缓存机制 - HTTP Caching

2008-06-18 23:04:52 by kommit

上次提到的 theme 机制带来的性能下降,这两天我折腾了一下,期待有所改善:

在处理 theme 相关的文件(css/image)的请求的时候,在 Response-Header 中加上这几项:

Last-Modified: Wed, 18 Jun 2008 14:22:27 GMT
Cache-Control: max-age=600
Expires: Wed, 18 Jun 2008 14:48:39 GMT
Date: Wed, 18 Jun 2008 14:38:39 GMT

其中 Last-Modified 后面的日期是上次更新 config 的时间,Date 后面是当前时间,Expires 后面是当前时间 + 10分钟,10分钟就是 Cache-Control 后面的 max-age,单位是秒。因为看到 GAE 对 static 文件的 Cache 时间也是10分钟,所以我使用了这个数字。

Last-Modified

如果客户端收到的 Response 中包含 Last-Modified,那么下次 request 的时候就会在 Request Header 中包含 If-Modified-Since 字段,值就是上次服务器发送的 Last-Modified,服务器端会判断上次的 config 时间是否比 If-Modified-Since 晚。如果自上次 request 之后又更新了 config,那么服务器就会返回完整的内容;如果期间没有更新 config,那么服务器就没必要返回完整的内容,只需要向客户端发送一个 304 Not Modified 状态码就可以了。

Cache-Control、Date 和 Expires

这几个参数的组合,表示告诉浏览器:这个文件在多长时间之内不会更改,在这个时间内不需要再 request,保守起见,我设置了10分钟。

浏览器行为

如果只是在网站的链接之间 click click click,那么浏览器会完全遵守上述行为。这样可以尽可能地减少请求次数,以及 response 的数据量。

如果在某个页面点击了浏览器的刷新按钮或者按 F5,浏览器会忽略 Expires 时间,把该页面需要的所有的文件都重新请求一遍。

如果按住 Ctrl 再刷新或者 Ctrl-F5 (俗称强制刷新),浏览器将不会发送 Last-Modified Header,将所有需要的文件请求一遍,服务器会返回文件的完整内容,而不是仅仅一个 304 Not Modified 状态码。

后记

经初步观察,现在浏览器不会每次都彪呼呼地去请求一大堆 css、jpg、gif 文件了,浏览器也不会每次都脑残地返回完整内容了,看来是有效了。

之前没怎么研究过 HTTP 协议,上面这些都是这两天通过抓包分析得出来的结论,然后参考了一下 django 的代码。不知道有没有不对的地方,欢迎大家指正。。。

另外有朋友建议我使用 MemCache API 来减少服务器端的计算量,这个我确实正在考虑。而且理论上确实可以提高效率。

在 GAE 提供的有限的资源上折腾,真是一件有意思的事情。

Tags: caching, performance, plog, http, dev

小小地研究了一把 XML-RPC

2008-05-06 16:14:32 by kommit

研究这个的初衷是为了让 plog 能支持通过 Google Docs (http://docs.google.com) 写文章。那样的最直接好处就是有了一个 WYSIWYG 的编辑器,而且它都会帮你处理好 html 过滤的问题(后来发现我还需要再过滤一遍);另一个好处就是可以让 plog 支持桌面博客工具写文章,以提升我写作的动力 >o<

Google docs 支持三种 API: Blogger、MetaWeblog 和 Movable Type。A Core 说Movable Type 号称最有前途的 API,但是我没在网上找到太多的资料。。。。不过不管怎样,先看看 google docs 到底是怎么通过 API 和 blog 程序交流的。

往试验田 (http://joeseayam.appspot.com) 放了一个 dumper,用来记录 request 和 response 的数据,然后用 google docs 发文章,初步的实验结果如下:

三种 API 都是用的 xml-rpc 来和服务器通讯。

无论选择哪种 API,一开始都要调用 blogger.GetUsersBlogs,来获取该用户的 blog 列表,以及每个 blog 的基本信息(如 url、id、name)。于是我就造了个假的 response 返回给 google。

之后,如果选的 API 是MetaWeblog,那么会调用 metaWeblog.newPost;如果选的是 Blogger 或者 Movable Type,那么调用的是 blogger.newPost。
如果文章已经发过一次了,第二次 publish 调用的就是 metaWeblog.editPost 或者 blogger.editPost。
我不明白的是为什么 MT 和 blogger 要调用一样的 API,而且是 Blogger API 1.0,这个方法的问题就是没有 title 这个参数,也就是说我没法在 google doc 里面设置文章的标题。。。

但是 MetaWeblog 有另一个问题,不知道是不是 google doc 的 bug:
如果我想在文章中写一段有格式的 html 代码,比方说写一段文字<h1>Heading</h1>,然后格式成<h1>,那么 html 应该是这样:
<h1>&lt;h1&gt;heading&lt;h1&gt;</h1>
但是实际上发过去的 xml 中的内容却变成了这样:
&lt;h1&gt;&lt;h1&gt;heading&lt;h1&gt;&lt;/h1&gt;
然后一转义,成了这样:
<h1><h1>heading<h1></h1>
于是格式乱掉了。
但是 blogger 的 API 就没有这样的问题。。。真是难两全啊……回头看看 别的 blog 程序,比如 wordpress 是怎么处理的这两个问题。

另外,google docs 生成的 html 中,每个标签都会有一个 id 属性,我觉得在文章中出现这个是没什么必要的,所以我希望把它过滤掉。所幸的是,昨天在网上找到一个现成的 python html filter:
http://amisphere.com/contrib/python-html-filter/
感觉很好很强大,可以自定义允许的标签以及属性的白名单,还可以修复一些不规范的格式,以后编辑之后的 html 就可以用它来过滤了。

Tags: googledoc, xmlrpc, htmlfilter, dev, plog, api, atppp

五一在家里宅了3天

2008-05-03 18:39:49 by kommit

熬夜,睡觉,中午起床,玩游戏,写 plog 代码。。。

今天终于把 tag 功能搞定了,原本以为是一个比较简单的功能,但是做起来才发现我对 google app engine 提供的 datastore 功能理解太少了。

因为不支持 JOIN、DISTINCT、COUNT、GROUP 等功能,所以不能用常规的关系数据库的思维来设计数据存储方式。到最后还是参考了别人的一个例子,才想到用 StringListProperty 来存储若干 tags。

不过,随着功能的越来越多,页面布局和样式我也越来越搞不定了。我从小就没有艺术细胞,所以虽然我懂一点 css,却只能胡搞。。再次呼唤美工大牛们给俺一些指点,Orz...

Tags: life, plog, dev, appengine

完成了文章分页功能,以及两个 widget

2008-05-01 00:45:23 by kommit

另外还修复了一个时间显示的bug,现在发帖时间能正常显示北京时间了。

calendar widget 还没想好如何实现,而且现在看来也不是特别需要。

不过感觉现在增加的这几个东西还比较丑,而且还破坏了原来布局的美感……我辜负了 蓝 给我的耐心指导。。抱歉。。。

希望能有更多懂美工的朋友能给我提一些建议,小七将感激不尽 Orz

下一步任务应该是 分类 以及 tag 了吧,五一期间好好考虑考虑怎么做,嗯

(edit:) A Core 说,RSS 更重要

Tags: atppp, plog, dev

我们需要的不仅仅是纯文本

2008-04-30 15:30:21 by kommit

所以我希望能输入一些 rich text,比方说一二三级标题区别显示,比方说字体颜色,比方说超链接,比方说图片,比方说图片+超链接,比方说表格,比方说 script..哦,这个不要,有安全隐患。

但是我该选择用何种方式呢?
一开始打算实现一个简单的 WYSIWYG 编辑器。现在有不少现成的这种程序,但是我不打算拿别人的过来用(想想引入别人的一个体积超过 plog 代码若干倍的程序包,多不爽呀。。),但是如果自己实现的话,恐怕我一时半会捣鼓不出来一个像样的。

所以我后来又打算用一些 text-html 标签,参考了一些别的东西。

wordpress 用的是 html 标签,但是为了安全,过滤掉了一些东西,比方说 script。

wiki 标签,这个现在也比较流行了,但是翻了一下 wiki 标签的标准,发现 WikiCreole 似乎是用的比较多的, 也找到了一个 WikiCreole 的 Python 实现,但问题同样是体积比较大。

UBB 标签,这个在国内论坛上用的比较广泛,把常见的 html 标签改成了类似[IMG][/IMG]的这种形式,从而保证了用户只能输入安全的标签。 没有找到 python 的实现,自己实现一个估计也不难,但是问题是这种标签似乎没有官方标准,怕以后给 plog 开发对外接口的时候遇到麻烦。。。

又看了一下 Django 号称支持的几种 filter: Textile, Markdown 和 ReST。 第一个似乎不错,和 wiki 有点类似,而 Markdown 和 ReST 看起来功能有些简单,而且语法看起来也不那么清爽,估计会影响用户的情绪。

试了一下 Textile 的 python 实现,虽然体积也比较大,但是只有一个文件。
不过后来运行时遇到一个问题: google app engine 的开发工具在 Windows 下有个 bug: 某些 C modules 不能 import, unicodedata 模块就是其中一个,这就导致我没办法在自己的机器上运行 plog,只能部署到试验田去运行,影响了开发的情绪。。。

问题是我到底该用哪种方式呢?
我需要的是一种应用比较广泛,并且有一个比较明确的规范的 text-html 转换方案。初步打算继续模仿 wordpress,硬着头皮搞 html 标签过滤; 或许等 google 修复了 sdk 的 bug,用 Textile; 或者干脆用 wiki 标签算了。不过 rich text editing 还不是眼下的目标,尚有几个功能未完成,俺需要继续努力。。。。

Tags: plog, markup, dev