关于pubsubhubbub和Google Reader

上一篇文章中,我描述了自己如何重制了一个Danbooru的feed。然而,经过一夜的睡眠,我「惊喜」地发现Google Reader在睡前到醒后的7个多小时里面都没有抓取过我订阅了的这个feed——也就是说,就算重制的feed包含10000条最近更新,只要GR不主动抓取,那这些更新也还是没有意义。

绝望之下,觉得归根到底还是弄清楚pubsubhubbub(以下简称PuSH)协议的原理。试着搜索有关GR和PuSH的文章,发现@keakon曾经发表过『PubSubHubbub不通知Google Reader的原因』『实现PubSubHubbub订阅』和『使用PubSubHubbub』三篇文章。拜读之后,明白了什么叫publisher和subscriber,也得知GR可能会自动忽略订阅数少的feed的PuSH,于是先写了一个sub,然后拿菜包工作室来当小白鼠(不好意思啦@tc201158),由于这个博客刚开张,只有我一个人在GR订阅了(订阅数为1),在装了PuSH插件并在hub上进行subscribe之后果然还是无法实现PuSH,可是我用另外一个GR帐号订阅其feed(订阅数为2)之后,PuSH就能正常工作了。

大喜,以为终于找到了原因,于是对重制的feed也如此这般地弄,结果却失败了…无奈之下,我又试着对danbooru的原feed重新在hub上subscribe,发现原feed实现了PuSH的同时,重制的feed也实现了PuSH!难道因为重制的feed中提供的id、url等信息仍然是原feed的信息,所以只有在收到原feed更新的ping请求后,hub才会通知GR抓取重制的feed?

不过既然原feed能够实现PuSH,那重制的feed就没什么意义了;只需要实现在GAE上利用cron定期检查原feed是否有更新,有的话就ping一下hub就可以了。于是又浪费了一整天的人参来实现了这个功能…

至此,对Danbooru feed的PuSH改造完满完成。经验教训:

  1. 尽管有约定,但在feed中添加hub link并不是必须的,至少对于Google的hub(http://pubsubhubbub.appspot.com)是如此;
  2. 利用第一点,可以对任何一个feed实现PuSH改造。先写一个sub以便在Google的hub上对feed进行订阅(必须有订阅才能实现PuSH),然后写一个cron定期检查feed的更新并且ping hub即可;
  3. 开发GAE应用时,利用handlers和wsgi来架构整个应用,无论是应用结构还是debug都方便太多了,决定从此放弃像twitter2weiboviagtalk那样面向过程开发的方法…

题外话。今天是⑨月⑨日的⑨节,可是⑨的同人图一点都不给力啊…

梯云纵心法:有效利用GApp

按:梯云纵心法是种武当派轻功,这里用来表示用来翻过某种障碍的方法^_^

前几天重新折腾和部署在学园都市中生存的网络访问方案,才发现GAppProxy(以下简称gapp)升级到了2.0。新版的gapp曲线解决了1MB下载文件大小限制问题和SSL网站访问问题,使其可用性有了不少提高。我在这次调整的网络访问方案中充分运用了这一通道,加速了对一些国外网站(无论被封与否)的访问,现分享下心得。

如何快速、安全地访问gapp

目前GAE的ssl连接会被重置,但经本人测试,若将yourdomain.appspot.com指向某些google本家的ip地址的话,同样可以成功连接,关键在于,这些ip支持ssl加密连接(毕竟兲朝不太可能完全封杀google的ssl连接),这样的话,把这个ip当作ssl加密的“入口”,让梯云纵数据通过这个入口来传输,就可以做到神不知鬼不觉的梯云纵。

为了加快gapp的访问,需要选择一个速度较快的google ip。获得ip的方法很多,最简单的无过于google一下(囧),也可以通过opendns.com/cache查,然后在这些ip中选择些ping值较快的。不过,并非所有的ip都支持指向gae(其原因复杂,略去不说…),可以尝试下收集到的ip所在ip段的其它ip,这往往需要多次测试才能找到。

gapp的定位:不只是梯云纵的工具

不少人只是将gapp当成一个梯云纵的工具,其实gapp起初的定位是“帮助教育网访问国外网”,所以教育网可以通过这个方法来上国外网(前两天教育网封杀google失败,表明这个方法还是不容易失效的);此外,考虑到:我们访问google的速度+google访问国外网的速度(近乎于0)<我们访问国外网的速度,即使是普通的电信/联通网络,也可以通过这个方法来进行外网加速。

此外,曾经有段时间到处流传“能用SSL就尽量用SSL”的忠告。然而有了上述安全和性能均有保障的gapp通道后,我们完全可以考虑对一些普通的内容(例如静态文件和图片)用回非加密连接。举个例子,访问twitter,我可以用gapp和ssh代理两种方法。ssh速度较慢,但是安全性最高;gapp速度较快,但安全性稍低(主要是ssl连接通过gapp代理是不安全的,google有可能截获传输数据,但显然我们会信任google)。通过foxyproxy或自己写proxy pac的方法,让所有的非加密连接(如http://*twitter.com)走gapp通道,加密连接(https://*twitter.com)走ssh通道;*.twimg.com这个twitter的图片服务,虽然没有被墙,但是直连速度不太理想,也可以采取通过gapp通道访问的方法。通过这种方法,我上twitter官网的速度以及客户端利用twitter api的速度均得到很大改善。

总结

本文不是介绍如何使用gapp的文章(相关教程网上甚多),而是关于如何稍微发挥geek精神让梯云纵变得更加有效和安全的心得。作为一个http代理,gapp还无法取代ssh或vpn成为一个最有效的梯云纵工具,但其胜在支持ssl,并能混杂在通向google云端的海量数据中。虽然会担心一旦这种方法被推而广之,墙娘就不得不考虑全面封杀google ssl了;不过考虑到其原理和操作的复杂性,我想,能参照本文并有效利用的人大约不会多,所以还是将这个思路公布出来,以期能对大家有所帮助。

最后唠叨一句,记得一定要用ssl访问gapp。

在Google App Engine上架设反向代理

参考文献:

反向代理的作用大家可以Google下,上面的文章也有介绍。其实上面的文章已经介绍了如何架设,我只是稍微说得更明白一些。

准备工作
  1. 申请Google App Engine帐号(我很早之前就有了,不知道现在还能不能申请),并创建一个应用,例如myapps;
  2. 安装Python 2.5,这是GAE SDK推荐的,我用的是Python 2.6,看起来问题不大,传送门,安装好之后,需要在环境变量中的PATH加入Python的安装位置(如C:\python26);
  3. 安装GAE SDK,传送门
  4. 下载bs2grproxy,传送门
架设代理

解压缩bs2grproxy,有两个地方要修改:

  1. app.yaml中第一行改为application: myapps,其中myapps是你刚才新建的GAE应用的名称;
  2. bs2grpconfig.py中第15行的TARGET_HOST改为你要反向代理的目标地址,这里其实暂不修改也没关系,可以上传好后再改。

弄好之后就可以开始上传,经过尝试,比较保险的上传方法是(环境:Win7 x64,其它环境大同小异吧):

  1. 打开控制台,转到bs2grproxy所在的文件夹,例如解压在C:\yourdir\bs2grproxy,就转到C:\yourdir;
  2. 执行“appcfg.py update_indexes bs2grproxy/”,可能会提示输入GAE的邮箱帐号和密码,按照提示输入。这个命令是在GAE应用上创建索引(所谓的索引,我现在将它理解成GAE上的虚拟文件夹,细节可以不管),这一步理论上可以跳过,但是有很高的几率导致出错,建议还是不要跳过;
  3. 执行“appcfg.py update bs2grproxy/”,上传反向代理应用的本体。
  4. 架设完毕,尝试用myapps.appspot.com访问反向代理的网站。
配置反向代理

主要就是修改反向代理的地址,在应用首页上进入反向代理应用的沙盒,选左侧的Datastore Viewer,可以看到有且只有一条记录,点进去,拉到最下面,可以看到修改target_host的地方。

外:GAE的索引400错误的处理办法

当上传发生了索引的400错误(可以在上传时观察信息提示,如果发生错误会有error字样)时,直接覆盖上传是无法解决的,网上有人说删除index.yaml可以避免这个错误,经过摸索,我自己的解决办法如下(假设是上述的反向代理发生了错误):

  1. 将index.yaml改名,例如_index.yaml;
  2. 执行“appcfg.py vacuum_indexes bs2grproxy/”,由于没有了index.yaml,所有的索引都将被删除;
  3. 将index.yaml的名字改回来,重新用“appcfg.py update_indexes bs2grproxy/”上传索引。

如果不update_indexes,而是直接update应用的话,发生400错误的概率很高,所以先上传好索引会比较好。

了解了GAE的原理之后觉得还是很赞的,如果不是数据库有限制,我真想把actools放上去。