马克聚的那点事儿
不晓得从什么时候开始,生活中开始充斥各种社交网络,知识的获取也比任何时候更方便。很多网站都有收藏的功能,对我来说,Google reader里订阅了一些feed,看到不错的文章,就习惯在上面加星;新浪微博里,我也会收藏一些不错的微博;我也常用收藏夹来保存一些不错的网站。
但是呢?相信很多人和我一样,把看到不错的东西收藏一下,就再也没碰过,比如在新浪微博上,经常看到同学转发微博,上面写着“mark”,下面会有人说,别马克了,你会看吗?不光不看,而且以后遇到类似的问题,会觉得在哪里看过,但是却又想不起来,于是只能再去google或者百度了,这真是时间和效率的双重浪费。
所以,我花了一个多月的时间在GAE上做了个小应用——马克聚,地址在:http://www.makeju.com,就是马克聚的拼音。登录需要使用Google账户。目前,马克聚实现了新浪微博收藏和Google Reader加星两处的马克来源,将来会支持更多。
从个人角度,我希望用马克聚能做到这些事情:
- 分类:能够把mark的内容分门别类。
- 加标签:以后可以通过标签寻找马克。
- 打分:给内容评上重要程度,以后可以按重要的程度排序。
- 提醒:提醒一个时间看,不要忘了。
- 搜索:能够在所有马克的内容里寻找,遇到过的问题不用再问搜索引擎了。
当然,这些只是基本的,而目前的马克聚也只是最初的版本。它看起来和Google Reader很像,那是因为作为一个码农,对界面和用户体验部分不那么得心应手。不过,接下来,我想对马克聚有以下改造:
- 从两栏的结构改成三栏,每一栏可以滚动,因为现在两栏的左边部分是fixed的,所以我只能通过限制添加分类的方式来避免高度过高;而且我希望能够展示多层级的分类。
- 增加马克内容的备注功能,在阅读马克的内容的时候,可以对内容注释。
- 国际化,支持英文的界面。
在我的计划里,我打算做一个Chrome插件和Android客户端,用Chrome插件可以把收藏夹的内容导入,而Android客户端显而易见,可以在手机上阅读马克的内容,还有就是收到阅读的提醒。
由于实验室的事情比较多,业余的时间有限,所以,我只能在有限的事情里来慢慢实现以上计划。
各位同学,如果你对马克聚有任何意见,或者有什么经常使用的马克的来源,别忘了告诉我,在文章的评论,博客留言板,或者马克聚的意见反馈,都可以。
最后,感谢舍友对马克聚所做的测试。
使用GAE的一些感受
最近个人的一个小项目部署在GAE上,项目写了也有一个多月,所以这篇文章就主要说说这一个多月来使用GAE的一些感受,也算是给想选择使用GAE的同学一些建议把。
其实GAE一点都不是什么新奇的东西,推出也有好几年了,不过由于众所周知的原因,国内访问不是很顺畅,appspot.com更是断得彻底,所以很多程序猿都不是很了解。其实,GAE就是云计算当中一个重要分支PaaS(平台即服务)的重要代表,你只需按照GAE提供的一系列API写好应用,upload上去,就可以访问了,服务器的事情都可以交给Google来处理,包括云的弹性和数据的存储等等。而Google方面也提供用户一些基础的配额,在这些配额之下,用户是无需任何花费的,不过如果应用如果需要更多的资源,那就需要付费了,好的地方是,你的应用瓶颈在哪里,你就可以只为那部分付费,这看起来确实节约了开销。
GAE访问不畅,国内类似的产品倒不少,比较知名的就是新浪的SAE和百度的BAE,这俩从名字上就明白了。SAE和GAE很类似,BAE看起来也差不多,不过,现在还在邀请使用的阶段,而我也没能拿到邀请码,所以哪位同学有多余的,可以分享给我一份,不胜感激:)
话休絮烦。使用下来的体会主要有以下几点:
使用GAE就意味着你的应用被限定在它的框架中,这是一把双刃剑。好处主要是方便,操作数据库可以使用datastore API而无需自己配置数据库;taskqueue也直接有API使用,异步的任务队列很轻松就搞定,而无需使用诸如Celery+RabbitMQ的解决方案;Channel API提供了类似客户端和服务器长连接的技术,它复用了GTalk的组件,会适配浏览器而选择使用WebSocket抑或是长轮询,你无需去了解它们的细节。这些当然只是例子,还有诸如cron job等等,它极大得简化了开发人员的工作,而不是让程序猿们花大量时间在配置上。
坏处也就是显而易见的了,由于大量使用GAE提供的接口,应用的可移植性就变得很差,如果一旦由于各种原因放弃使用GAE,整个程序面临着重写,当然将问题减少到最小的方法是使用适配器模式来做一层封装,不过还是有较大的工作量。
第二就是关于配额的的问题。其实在GAE部署应用了之后才能深刻体会到配额的数量真的不多,所以不可避免的做法就是在应用里处处精打细算,至少不能浪费。
首先是datastore的配额问题。在其免费配额中关于读操作有两项:“Datastore Read Operations”和:“Datastore Small Operations”,他们都有5万次/天的配额,不过千万别觉得Google慷慨,这个其实是很不经用的。不过相信很多人不明白什么是read和small,这里就先简单做个介绍。
对于datastore,每个要存储的model实体(相当于关系数据库中的行),都有个必有的key和可选的parent属性,通过它们就可以找到一个model实体,而parent是极其重要的,如果应用中用到了事务,不论是否跨model,只有拥有相同的祖先(ancestor)才可以完成一次事务。对于譬如一次查询操作,我们查询到了十个结果并返回这些model实体,那么我们就使用了11次read操作;更极端的是,如果查询的时候使用了offset,就是跳过了offset个结果,这些要是要算入到read操作中的,所以比如说取跳过50个的10个结果,这实际上就是61次read操作,所以开销是极大的。解决方法就是使用游标(cursor),每次查询的时候拿到上次查询的游标,从游标开始取10个,这样就还是11次操作。
那么什么是small操作呢,刚刚提到了model的key属性,我们通过key得到一个model实体,这就是1次small操作;还有就是count操作,比如说我们得到结果是100,那么就是1次的read操作+100次的small操作,因为计算数量不需要取到数据,只需要知道key就可以了。而我们查询结果的时候,可以只查询得到key,再通过key去得到model实体,这样就减少了read操作,但也相应增大了small操作。不过无论如何,都要记住游标是很重要的东西,它其实只是一个很长的字符串,所以在网页应用中,我们可以渲染到页面中,然后在之后的查询时,作为参数传递。
使用游标确实能减少配额,不过不能一劳永逸,那么怎么办呢?相信很多同学都想到了,当然是使用缓存(memcache)。因此可以说缓存在GAE中非常重要,因为缓存和配额没有关系,它的使用仅仅和内存的大小有关,所以几乎所有常用的数据都要放到缓存中,缓存的类型也可以包括model实体和页面等等的缓存。所以我们可以用工厂模式来操作数据库的增删查改,每个操作都和缓存结合起来。
关于配额还有一点就是Channel API,它的使用需要在用户访问时创建一个channel,而这个channel 2个小时就会失效。由于每天创建channel的个数为100,如果每次用户访问都需要创建channel,开销太大了,所以,我的做法还是将这个用户的channel缓存,并设置2个小时的失效时间。
好了,关于GAE使用的感受和心得,暂时就总结到这里。如果想到其他的,我会进行补充,以后也会对一些细节做一些分享。