88250

Java

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  82 随笔 :: 0 文章 :: 5 评论 :: 0 Trackbacks

2010年12月3日 #



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-134.html
posted @ 2011-01-26 00:32 88250 阅读(253) | 评论 (0)编辑 收藏

上周硅谷非常热闹,重大消息频繁出现,其中包括了乔布斯因病休假,苹果的恐怖财报等等。对于我们所关心的移动业界跟互联网来说,Google 换帅是另外一个重量级消息。

Quora 上有一个讨论串,题目是“Larry Page 上任之后,Google 的重点应该是什么?”,讨论相当活跃。我也在这里凑个热闹,谈一谈在我看来,Larry Page 应该如何去改变 Google。

download (4).png

1:关注核心业务,也就是搜索

Google 前段时间在搜索结果上算是饱受攻击,由于与日俱增的垃圾内容,搜索结果的污染状况越发严重。Stack Overflow 的创始人之一 Jeff Atwood 在一篇文章里这样评价 Google 现在的搜索结果:

Google ,这个曾经的必备工具,某种程度上已经失去了它的优势地位。垃圾内容制造者、以点击率为终极目标的内容聚合站点正在走向胜利。

在 这一点上来说,ifanr 感同身受。作为内容提供者,我们是创造价值的人,是在给互联网不断添砖加瓦的一方。而之前在 Google 里搜索我们的原创文章,出现在结果最顶端的却往往是是通过拷贝+粘贴、有时候还不注明出处进行转载的内容聚合站点。它们用毫无成本的方式夺取着应该属于原 作者的访问量。

好在 Google 似乎已经认识到了这一点。之前搜索质量组的 Matt Cutts 表示他 们已经意识到了垃圾内容的增多,以及劣质内容聚合站点引发的不满,并且会很快进行处理。从我今早的实验来看,似乎 Google 已经采取了措施,最近 ifanr 的原创文章都出现在首页头条。从根子上(点击量带来的经济利益)驱逐劣质内容聚合站点,对现代互联网来说,确实是件好事

搜索,是 Google 的立身之本,从上周发布的财报来看,Google 收入的主要增长点仍然是在网站本身的业务。不断改进搜索,添加新的搜索方式,才能保持和增强 Google 在这个领域的领导地位。后院不起火,才有在其他领域发展的资本。

2323.jpg

这一条,是 Larry Page 上任以后最需要关注的。未来十年的搜索是什么样子?如何提高内容关联性,改进使用体验?怎么样通过创新,把 Bing 等竞争对手远远甩开,对 Google 来说,至关重要。

2:在社交网络方面另辟蹊径

Google 在社交网络方面的试探,到目前为止都是悲剧,坦率地说,我个人认为Google 已经错过了第一班社交网络的列车。

RIP-Google-Wave-Dead.jpg

作为新生事物的社交网络,从一开始负载的是用户虚拟交流的需求。

目 前的胜利者里面,Facebook 满足了人们交流的愿望,利用网络,表现了某种程度上真实的人与人关系,而大量互动元素的引入,则是模拟了现实生活的部分人际往来,从根底上来说,没有理念 上的创新,然而它仍然足够伟大,Facebook 把现实生活成功投影到了虚拟世界,是真正意义上的创造者。

另一个赢家是 Twitter,它满足的,是人们表达自己的愿望。通过简短的 140 个字,人与人之间形成了一种奇妙的交流关系,普通人也可以第一时间见证重大事件。可以说,Twitter 与智能手机的结合,创造了一种新媒体。表达自己,记录周边,关注别人,是 Twitter 类社交网络的根本。无论是变种的 foursquare,还是 Quora,从理念上看,都是这样的东西。

Google 之前的尝试呢? Wave 那个体验一塌糊涂的东西不去说它,出生太早了;Buzz 则是无限制版本的 Twitter:Google 试图利用现成的庞大用户群,但没有实质性创新,再加上拙劣的整合方式,这个产品的前景乐观不到哪儿去。

社交网络走到现在,实际上已经到了一个重要的关口,即:虚拟的内容如何与现实社会结合起来,怎样把线上关系与实体经济整合,创造出一个崭新的商业模式。在我看来,这才是第二代社交网络,也即成熟版本的社交网络。这个方向是未来两年的热点,也是 Google 下一步可以突围的角度。

Google 的最大优势是什么?大家应该都非常清楚,其一是庞大的用户群,其二就是信息了。Google 相对于 Twittter、fousquare 等来说,先天就有信息方面的优势。而 Google 在建设社交网络的时候,却完全忽略了这个优势,捆着手脚去从头开始跟已经成熟的对手竞争,怎么可能胜利?

举个最简单的例子,Google Maps 信息丰富,我经常用它来寻找晚餐地点,最大的好处之一就是可以看到多个网站的用户评价,看看截图:

Untitled-1.jpg

看 到了吧,有 Buzz 选项,然而搞笑的事来了。我可以看到其他网站的评价,可以在 Buzz 上分享这个地点,然后呢?没了。我完全看不到 Buzz 关于这个餐馆的讨论,看不到我分享以后朋友的看法——一点也没有。实体经济方面的内容本身就是 Google 的长项,然而在它的任何产品里面,都没有把这个长处跟自己的社交网络更紧密得结合起来。

放着庞大的现实数据不用,几个产品之间几乎没有交流,捧着金饭碗要饭,这就是 Google 的社交网络。跟现实社会结合的社交网络,将是 Google 在这一领域的最后一个机会。

3:细节,细节,还是细节

有一句老话,细节决定成败,然而 Google 现在的很多做法,却表现了一种对细节的漠视,极大影响了产品的使用体验。还是要以 Android 为例(这玩意简直就是反面教材):

就从简单的设置界面说起。Android 平铺直叙的设置界面,完全没有突出重点(我甚至怀疑这帮人安排顺序的时候是不是拍脑门做出的决定。),跟右边的 iOS 比,孰优孰劣,一目了然。

Untitled-2.jpg

还有应用市场,每次谈到 Android 的应用市场,我都有爆粗口的冲动。缓慢的速度、时常丢失的已下载应用列表、迟迟没有解决的应用无法下载问题……这是整个产业的核心之一,Google 就准备这么糊弄下去?

Android 不讲究的地方何止这些,工程师文化并不代表着可以不拘小节,Google 的目光,应该多放些在细节上。移动设备,用户体验至关重要。

4: 继续拥抱云,下注新能源产业

在这个卖杂货的、搞 B2C 的、做软件的都在搞云应用平台的当口,互联网界巨头,拥抱云的先驱之一,可能拥有着世界上最好硬件以及网络设施的 Google,当然也拥有自家的 App Engine。

download (3).png

云 计算平台对于中小企业、个人的意义,无论如何赞扬也不会过分,它直接引领了当前的互联网创业潮。低廉的平台成本,按需付费的方式,Amazon EC2 吸引了大量的个人开发者,Google 的 App Engine 当然不错,但我要说,还是不够灵活,如果能提供更多语言支持,就再好不过了。

新能源很好理解,随着碳交易市场的兴起,碳排放量眼看就要变成金融市场上的一个新产品。在这个趋势影响下,每个企业都应该考虑下自己的能源来源,为将来更加严格的排放调控措施做好准备,规避可能的经济风险。

data-center.jpg

降低所消耗能源的碳排放,对于 Google 这种能源消耗大户来说,是经济跟政治上都很正确的方向,而且同样有大量的利益存在。新能源产业,应该成为 Google 下一步的重点投入方向。

5:提高决策速度与质量,减少内部沟通环节

大 家都知道 Google 著名的 20% 规则:员工可以把 20% 的上班时间放在其他项目上。Google 的员工无疑是优秀的,这些业余时间做出的项目也应该有很多不错的点子,然而,从中孵化的成果却并不多。其中的部分原因,恐怕与 Google 的内部引导以及沟通机制存在很大的关系。由于缺乏引导,员工的项目往往与 Google 本身没什么联系,而因为沟通问题,好的项目不一定能够获得公司的帮助。

Google 的前员工遍布整个互联网业界,大量创新却往往出现在他们离开 Google 以后。应该如何去引发员工的创造力、提高内部效率跟执行力度,Larry Page 需要仔细考虑,以便调整内部架构来适应这个变化迅速的世界。三星这个反应快到根本不像大公司的大公司在全世界攻城掠地,诺基亚反应稍微迟缓一点就束手束 脚,Google,你要快一点,再快一点,才能跟 Facebook 以及数以千计的创业企业进行竞争。

转自:http://www.oschina.net/news/14996/larry-page-google-five-things-todo



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/larry-page-google-five-things-todo.html
posted @ 2011-01-25 09:21 88250 阅读(266) | 评论 (0)编辑 收藏

没有人能说清哪种缓存算法优于其他的缓存算法。(以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下)

Least Frequently Used(LFU):

大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率。我会把最不常用的缓存对象踢走。

Least Recently User(LRU):

我是LRU缓存算法,我把最近最少使用的缓存对象给踢走。

我总是需要去了解在什么时候,用了哪个缓存对象。如果有人想要了解我为什么总能把最近最少使用的对象踢掉,是非常困难的。

浏览器就是使用了我(LRU)作为缓存算法。新的对象会被放在缓存的顶部,当缓存达到了容量极限,我会把底部的对象踢走,而技巧就是:我会把最新被访问的缓存对象,放到缓存池的顶部。

所以,经常被读取的缓存对象就会一直呆在缓存池中。有两种方法可以实现我,array 或者是 linked list。

我的速度很快,我也可以被数据访问模式适配。我有一个大家庭,他们都可以完善我,甚至做的比我更好(我确实有时会嫉妒,但是没关系)。我家庭的一些成员包括LRU2 和 2Q,他们就是为了完善 LRU 而存在的。

Least Recently Used 2(LRU2):

我是 Least Recently Used 2,有人叫我最近最少使用twice,我更喜欢这个叫法。我会把被两次访问过的对象放入缓存池,当缓存池满了之后,我会把有两次最少使用的缓存对象踢走。 因为需要跟踪对象2次,访问负载就会随着缓存池的增加而增加。如果把我用在大容量的缓存池中,就会有问题。另外,我还需要跟踪那么不在缓存的对象,因为他 们还没有被第二次读取。我比LRU好,而且是 adoptive to access 模式 。

Two Queues(2Q):

我是 Two Queues;我把被访问的数据放到LRU的缓存中,如果这个对象再一次被访问,我就把他转移到第二个、更大的LRU缓存。

我踢走缓存对象是为了保持第一个缓存池是第二个缓存池的1/3。当缓存的访问负载是固定的时候,把 LRU 换成 LRU2,就比增加缓存的容量更好。这种机制使得我比 LRU2 更好,我也是 LRU 家族中的一员,而且是 adoptive to access 模式 。

Adaptive Replacement Cache(ARC):

我是 ARC,有人说我是介于 LRU 和 LFU 之间,为了提高效果,我是由2个 LRU 组成,第一个,也就是 L1,包含的条目是最近只被使用过一次的,而第二个 LRU,也就是 L2,包含的是最近被使用过两次的条目。因此, L1 放的是新的对象,而 L2 放的是常用的对象。所以,别人才会认为我是介于 LRU 和 LFU 之间的,不过没关系,我不介意。

我被认为是性能最好的缓存算法之一,能够自调,并且是低负载的。我也保存着历史对象,这样,我就可以记住那些被移除的对象,同时,也让我可以看到被移除的对象是否可以留下,取而代之的是踢走别的对象。我的记忆力很差,但是我很快,适用性也强。

Most Recently Used(MRU):

我是 MRU,和 LRU 是对应的。我会移除最近最多被使用的对象,你一定会问我为什么。好吧,让我告诉你,当一次访问过来的时候,有些事情是无法预测的,并且在缓存系统中找出最少最近使用的对象是一项时间复杂度非常高的运算,这就是为什么我是最好的选择。

我是数据库内存缓存中是多么的常见!每当一次缓存记录的使用,我会把它放到栈的顶端。当栈满了的时候,你猜怎么着?我会把栈顶的对象给换成新进来的对象!

First in First out(FIFO):

我是先进先出,我是一个低负载的算法,并且对缓存对象的管理要求不高。我通过一个队列去跟踪所有的缓存对象,最近最常用的缓存对象放在后面,而更早的缓存对象放在前面,当缓存容量满时,排在前面的缓存对象会被踢走,然后把新的缓存对象加进去。我很快,但是我并不适用。

Second Chance:

大家好,我是 second chance,我是通过FIFO修改而来的,被大家叫做 second chance 缓存算法,我比 FIFO 好的地方是我改善了 FIFO 的成本。我是 FIFO 一样也是在观察队列的前端,但是很FIFO的立刻踢出不同,我会检查即将要被踢出的对象有没有之前被使用过的标志(1一个bit表示),没有没有被使用 过,我就把他踢出;否则,我会把这个标志位清除,然后把这个缓存对象当做新增缓存对象加入队列。你可以想象就这就像一个环队列。当我再一次在队头碰到这个 对象时,由于他已经没有这个标志位了,所以我立刻就把他踢开了。我在速度上比FIFO快。

CLock

我是Clock,一个更好的FIFO,也比 second chance更好。因为我不会像second chance那样把有标志的缓存对象放到队列的尾部,但是也可以达到second chance的效果。

我持有一个装有缓存对象的环形列表,头指针指向列表中最老的缓存对象。当缓存miss发生并且没有新的缓存空间时,我会问问指针指向的缓存对象的标 志位去决定我应该怎么做。如果标志是0,我会直接用新的缓存对象替代这个缓存对象;如果标志位是1,我会把头指针递增,然后重复这个过程,知道新的缓存对 象能够被放入。我比second chance更快。

Simple time-based:

我是 simple time-based 缓存算法,我通过绝对的时间周期去失效那些缓存对象。对于新增的对象,我会保存特定的时间。我很快,但是我并不适用。

Extended time-based expiration:

我是 extended time-based expiration 缓存算法,我是通过相对时间去失效缓存对象的;对于新增的缓存对象,我会保存特定的时间,比如是每5分钟,每天的12点。

Sliding time-based expiration:

我是 sliding time-based expiration,与前面不同的是,被我管理的缓存对象的生命起点是在这个缓存的最后被访问时间算起的。我很快,但是我也不太适用。

好了!听了那么多缓存算法的自我介绍,其他的缓存算法还考虑到了下面几点:

  • 成本。如果缓存对象有不同的成本,应该把那些难以获得的对象保存下来。
  • 容量。如果缓存对象有不同的大小,应该把那些大的缓存对象清除,这样就可以让更多的小缓存对象进来了。
  • 时间。一些缓存还保存着缓存的过期时间。电脑会失效他们,因为他们已经过期了。

根据缓存对象的大小而不管其他的缓存算法可能是有必要的。

原文:http://www.zavakid.com/27



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/general-cache-algorithms.html
posted @ 2011-01-21 14:13 88250 阅读(2756) | 评论 (0)编辑 收藏



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-133.html
posted @ 2011-01-20 00:19 88250 阅读(217) | 评论 (0)编辑 收藏

提交 B3log Solo(运行在 GAE/J 上的博客程序) 代码后发现 Google Code 版本控制系统会将提交日志同步发布到 Google Buzz 中:

code-buzz.png

但在 Buzz connected sites 里并没有看到与 Google Code 关联:

buzz-connected.png

 

现在一提交代码就 Buzz,还是比较无奈的....



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/code-buzz.html
posted @ 2011-01-14 10:04 88250 阅读(205) | 评论 (0)编辑 收藏



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-132.html
posted @ 2011-01-11 22:09 88250 阅读(239) | 评论 (0)编辑 收藏

有时我们需要随机地获取数据记录(实体),比如博客程序中的“随机文章”的实现。

目前 GAE 并没有 API 可以直接获取随机实体,要实现这样的需求我们只能自己想办法了 :-)

在 stackoverflow 上也有人提过该问题,总结如下:

  • Generate and store a random number on your entities as you create them, then pick a random number and look (via a query) for the closet record(s) to it.
  • Implement some mechanism to ensure your entity ids are "densely" populated, then fetch within the known range using keys.
  • Periodically generate random lists of the entities and return entities from those lists. This may take the form of a stack that entities are popped off of, or as actual lists that are returned.

目前 B3log Solo 在处理“随机阅读”上采用的是方法一,即在每个文章实体上添加一个属性保存 0-1 的随机浮点数。

在获取随机文章时生成一个 0-1 的随机数(mid)作为查询条件,以此查询条件作为边界(0 <= mid <=1)来过滤实体保存的随机值属性。

这个方法基本可以达到随机的效果了,为了让随机的效果更动态一点,我们可以考虑经常更新文章实体中的随机浮点值:

  • 访问文章时(即在更新文章浏览次数时一并更新该文章的随机浮点值)
  • 后台定时任务(获取一定数量的随机文章然后更新它们的随机浮点值)
  • 用户做文章更新时

加上以上处理后,随机的效果比较好了 :-)



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/get-gae-random-entities.html
posted @ 2011-01-10 21:16 88250 阅读(222) | 评论 (0)编辑 收藏

作者 荣浩 发布于 2010年12月28日 上午12时0分

jBPM来说,今年最大的事件莫过于jBPM的创建者Tom Baeyens离开JBoss了。Tom Baeyens离开的具体原因尚不清楚,但他的离开产生了两个结果:一是jBPM的下一个版本jBPM5完全放弃了jBPM4的基础代码,基于Drools Flow重头来过;二是Tom Baeyens加入Alfresco后很快推出了新的基于jBPM4的开源工作流系统Activiti。 由此不难推测Tom Baeyens离开的部分原因:JBoss内部对jBPM未来版本的架构实现产生了严重的意见分歧。更加巧合的是12月1日Activiti5刚发布,紧 接着12月2日jBPM5就发布了第一个候选发布版本,jBPM与Activiti之间的微妙关系可见一般。

在这篇文章里,我们将一起回顾jBPM从jBPM3到jBPM5以及Activiti5的发展历程,我们可以清晰的看见jBPM(包括 Activiti)设计所遵循的一致原则:强调流程服务的可嵌入性和可扩展性。同时,从各个版本之间的变化我们也能看见产品设计思路的变化:更加强调面向 业务人员,增加BPMS(业务流程管理系统)特性。

在回顾之前,我们首先讨论一下BPMS应该嵌入还是独立部署的问题,因为不管是jBPM还是Activiti,都强调了流程服务的可嵌入性。此外,我们还需要讨论一下什么是BPMS的特性,它们所解决的问题是什么。

一、嵌入式还是独立部署?

不管是jBPM还是Activiti,都强调了流程服务的可嵌入性。Tom Baeyens在其个人博客里称作为独立部署的BPMS已死,原因有两个:一是独立部署的BPMS需要很高的安装使用成本,需要独立部署、需要用户支出大 量的培训成本和维护成本;二是独立部署的BPMS与外部系统的交互方式是分布式,这使得很多问题变得复杂,例如分布式事务。Tom Baeyens代表了相当一部分人特别是开发人员的观点。

Tom Baeyens没有完全理解BPMS。什么是BPMS?BPMS最重要的目标就是需要打破各个应用系统(CRM、ECM、ERP、SCM)之间的界线,将 分散在这些系统中的流程集中管理,这是BPMS的实质。一如流程再造,打破各个部门之间的壁垒,减少浪费,建立流程驱动性的组织。如下图1所示:

图 1:BPMS打破应用系统之间的界线

BPMS所要解决的问题要求其必然是独立部署的。Tom Baeyens错误的根本原因在于其将BPMS与工作流系统的定义混为了一谈,他如此定义BPMS:BPMS旨在简化对组织核心流程进行支撑的软件创建。 也就是BPMS面向的是软件开发人员,旨在简化他们的开发,降低他们使用流程的门槛。而这正是工作流系统需要解决的问题。

BPMS面向企业用户,工作流面向开发社区和系统集成商。

二、BPMS特性

jBPM4、jBPM5和Activiti5都增加了其BPMS特性,那些特性能够称为BPMS特性呢?我们先看一看BPMS需要解决的问题,为解决这些问题所增加的特性就是BPMS特性。

  1. 如何设计流程,在组织中高效地对设计出的流程进行沟通,取得共识?

    • 提供跨越组织的流程标准标记符号与术语(BPMN已经成为标准)
    • 流程及相关文档的可视化(流程/内容存储仓库)
    • 提供在组织结构内进行不同层次之间的流程导航(流程存储仓库支持组织模型)
    • 流程定义在各个层次/部门间的一致性,避免业务人员的流程建模转换到IT系统时受到损耗(流程引擎支持基于图的建模,支持扩展)
  2. 如何更好地执行流程?

    • 业务活动的实时监控,预警与控制(BAM)
    • 流程执行的仿真
    • 流程执行的统计分析与反馈(报表)
  3. 如何更好地管理流程?
    • 打破各个应用系统之间的界线,统一管理所有流程(EAI,与ESB的集成)
    • 对业务人员友好的建模工具
  4. 如何在执行流程过程中遵循业内最佳实践和规则?
    • 面向流程的知识管理
    • 规则引擎

三、完整的工作流实现jBPM3

jBPM3的最新版本是3.2.7,其包括了以下组件:基于Eclipse的流程设计器、用于监控案例(流程实例)和处理任务的Web控制台以及jPDL核心库。如下图2所示:

图 2:jBPM3组件

  1. 基于Eclipse的流程设计器

    提供给开发人员绘制jPDL流程图,因为该设计器基于Eclipse,所以生成的流程文件可以与开发代码一起组织管理,非常容易进行单元测试。实现了工作流管理系统参考模型里的接口1。

  2. Web管理控制台

    主要有两个功能:一是作为工作流客户端应用接口,给用户提供一种手段,以处理案例运行过程中需要人工处理的任务;二是对案例的状态进行监控与管理。实现了工作流管理系统参考模型里的接口2和5。

  3. jPDL核心库

    jPDL核心库是一个单独的JAR包,可以嵌入到目标应用中执行,它包括了:

    • 流程仓库:解析jPDL流程定义文件并存储读取;
    • 流程引擎:对流程定义进行初始化和调度执行,节点的运行期行为与jPDL里定义的节点类型一一绑定;
    • 任务管理:生成任务节点所对应的工作项,管理工作项的生命周期(初始化、分配执行者、执行、挂起、结束、终止);
    • 事件管理:发布案例和任务的开始、结束事件,通过监听者模式调用相应的事件处理器;
    • 异步执行机制:通过线程实现了Job Executor,进行异步工作的处理,这些工作包括了时间处理、异步动作。
    • 身份组件模型:实现了一套简单的身份组件模型,包括了组、用户和权限。

    通过调用自定义Java代码实现了对外部应用的调用,从而实现工作流管理系统参考模型里的接口3。

  4. jBPM3是一个轻量级的嵌入式工作流系统。它在Java社区的成功得益于两个方面:一是嵌入式,这降低了使用工作流的门槛;二是对开发人 员友好,这表现在易读的jPDL、流程的可测试性(Eclipse插件)以及节点行为的可扩展性,我们可以非常容易的在流程运行中加入自己定制的行为(通 过事件处理器和Action)。jBPM3面向开发人员,它解决的问题是流程的自动化,它的影响力集中在Java开发社区,是一个完整的工作流系统实现。

四、向BPMS努力的jBPM4

与jBPM3相比,jBPM4最大的变化是引入了流程虚拟机(PVM),同时增加了BPMS的特性。jBPM4不再满足于工作流系统的定位,开始向BPMS努力。

  1. 为什么引入流程虚拟机

    尽管jBPM3在Java社区取得了很大的成功,但是有一件事始终被人们诟病,那就是它不支持流程语言规范,从最开始的XPDL、BPEL 到后来的BPMN,它采用了自定义的jPDL。在jBPM3中,节点的运行期行为与jPDL里定义的节点类型是一一绑定的,这造成了流程引擎与特定流程语 言的绑定,要支持其他的流程语言变得困难。于是在jBPM4中,jBPM提出了流程虚拟机的概念,即流程引擎与流程语言解耦,通过一套通用的流程模型并配 以可定制的节点运行期行为实现了对多流程语言的支持。

    流程虚拟机带来的好处是多方面的:第一也是最重要的是jBPM4支持了BPMN。

    第二是实现了基于流程组件的流程引擎,流程图(语言)与实现解耦,我们使用通用编程语言实现节点运行期行为,称之为流程组件,通过将流程图 与流程组件挂接,避免了图的损耗。在这一点上,Tom Baeyens对BPMN到BPEL的转换提出了一针见血的批评:BPMN和jPDL以及XPDL都是基于图的,而BPEL是基于块的,这造成了当将业务 人员使用BPMN所建立的流程模型向BPEL执行模型进行转换时,出现许多的不匹配,最初的流程模型会扭曲变形。而扭曲的后果就是业务人员与开发人员之间 的协作困难,这影响了流程从业务到技术的实现。

    第三个好处是我们可以定义领域特定语言(DSL),在特定的应用里,采用DSL约定并隐藏了大部分的技术细节可能做到业务人员对执行流程的直接修改,例如企业文档管理里的审批流程。

  2. BPMS特性的加入

    这表现在以下三个方面:第一是支持了BPMN,BPMN已经成为业务人员的流程建模标准;第二是引入了Signavio作为面向业务人员的Web建模器;第三是在已有的Web管理控制台加入了对案例和任务的统计功能。jBPM4的组件如下图3所示:

    图3:jBPM4组件

    和jBPM3一样,jBPM4依然是轻量级的、可嵌入的工作流系统。相比jBPM3,它将业务人员作为最终用户之一,增加了部分BPMS特性,同时PVM的引入使得它的可扩展性得到了极大的增强,我们甚至可以定义自己的DSL。

    在BPMS特性里我们提到了应该避免业务人员的流程建模转换到IT系统时受到损耗,最理想的情况是业务人员与开发人员共用一个流程模型,业 务人员能够直接对流程进行调整(在特定应用中,通过DSL是可以做到的);其次是通过BPMS将业务人员的模型与实际执行的技术模型关联起来(很多商业产 品已经做到了这一点,在Activiti5中我们也会看到这一点),业务人员、开发人员以及运营团队之间能够做到很好的协调;最差是业务人员与开发人员各 自为政,独立维护各自的流程模型,并且模型之间存在极大的不匹配,此时流程的迅速变化基本上是奢望。

五、鸠占鹊巢的Drools Flow与jBPM5

目前jBPM5刚刚发布了第一个候选发布版本,jBPM5基本上完全抛弃了jBPM4的代码,所有代码全部来自原先的Drools Flow。Drools Flow最初被用来解决规则执行顺序的问题。其实从Drools Flow开始支持BPMN时起,我们已经预感到它与jBPM的竞争关系。

jBPM5依旧定位为轻量级的可嵌入的工作流系统。在jBPM5的特性里,有这么两条引人关注:一是引入了Guvnor作为流程仓库,这解决了流程 的可视化问题,流程定义作为资源被管理,我们可以对流程定义进行可视化管理以及全文检索(Guvnor使用了Jackrabbit作为了其存储实现,但我 们的经验表明Jackrabbit在大数据量情况下性能存在严重问题);第二是规则引擎(Drools Expert)、事件处理引擎(Drools Fusion)与流程引擎的合三为一,这是jBPM5最让人期待的地方。jBPM5的组件如下图4所示:

图 4:jBPM5组件

规则引擎在流程中的应用已经非常广泛了,我们这里说说事件处理引擎。

事件处理引擎是业务活动监控(BAM)的基础,BAM的功能及执行过程,如下:

  • 捕获:BAM捕获各种事件(通过消息监听器、适配器、代理等)。这些事件来自应用、系统软件、外部交易伙伴。消息是BAM的核心——它们反应底层业务流程的状况。
  • 过滤:BAM过滤掉没有直接后果的事件,在很多情况下由支持事件流处理(Event Stream Processing,简称ESP)或复杂事件处理(Complex Event Processing,简称CEP)引擎来进行过滤。
  • 分析:BAM根据分析模型和规则将相关事件联系起来。
  • 警告:BAM向用户提出警告,以便用户在必要时进行控制。

如上所示,BAM的执行过程包含四个步骤,而前三个步骤都是对事件进行相关的处理(捕获事件、过滤事件、分析事件、关联事件),因此在大多数BAM的技术实现方案中,都基于CEP和ESP的引擎来实现BAM的功能。

与jBPM4相比,jBPM5对PVM的放弃也带来了几个不小的问题:第一是对开发人员来说只支持BPMN,不再支持jPDL(当然提供了迁移工 具);第二是流程执行的可扩展性回到了jBPM3的年代,仅仅支持自定义动作(相当于jBPM3里的Action)。此外,Web建模器由 Signavio替换为了Oryx Designer。

总而言之,jBPM5通过引入流程仓库和BAM继续向BPMS迈进(目前的进展是与流程仓库的集成还未完成,BAM基于日志进行分析),同时,由于不再支持PVM和jPDL,带来了流程扩展性的降低和社区开发人员的未来流失。

六、Activiti5的反击

Activiti5是Tom Baeyens加入Alfresco后推出的新的基于jBPM4的开源工作流系统,1号刚刚发布第一个版本。Activiti的开发团队相比与jBPM强 大了许多,有23位核心开发者。当然这也是由于activiti规划的功能所致:包括核心引擎、Web的流程建模器、协作工具Activiti Cycle、Activiti Probe、Activiti Explorer、与Spring的集成、与Mule的集成等。

图 5:Activiti5的组件

如上图所示,Activiti5由三种类型的组件组成,分别是:专用工具(Dedicated Tools)、内容存储工具(Stored Content)和协作工具(Collaboration Tool)。

专用工具包括以下:

  • Alfresco—Alfresco公司的企业级内容管理产品
  • Alfresco 是一个开源的、企业级的内容管理系统,功能包括:文档管理、协作、记录管理、知识库管理、Web内容管理等功能。Alfresco与Activiti的深 入集成实现了流程及相关文档的可视化。更重要的是Alfresco支持组织模型,能够提供在组织结构内进行不同层次之间的流程导航。

  • Activiti Modeler—建模器
  • 基于开源Signavio Web流程编辑器的一个定制版本,提供了对BPMN2.0图形化规范的支持,建模后的流程以文件格式进行存储。

  • Activiti Designer—Eclipse插件形式的建模器
  • Activiti probe—管理及监控组件
  • 对流程引擎运行期实例提供管理及监控的Web控制台。包含部署的管理、流程定义的管理、数据库表的检视、日志查看、事务的平均执行时间、失败多次的工作等功能。

  • Activiti Explorer—任务管理组件
  • 提供任务管理功能和对案例、任务基于历史数据的统计分析(报表)功能。Web应用程序。

内容存储工具:包括了文档仓库、模型仓库、SVN仓库、MVN仓库和Activiti引擎。其中文档仓库、SVN仓库和MVN仓库三个组件为协作工具(Activiti Cycle)提供底层的支撑。Activiti引擎则是以前的PVM。

协作工具:与jBPM4相比,Activiti5最令人瞩目的特性就在于它的协作工具组件。

Activiti Cycle完全是一种新类型的BPM组件。它是一个用来促进业务人员、开发人员和IT运营人员协作的Web应用程序。 在现实的场景中,业务文档有业务人员所持有,而软件程序由开发团队所管理,被部署的软件应用则被IT管理人员所管理。三者之间不能很好的协作。我们可以想 象这样一个场景,业务经理用文档来维护需求和visio格式的流程图,开发人员管理可执行的流程和大量的Java源文件而IT维护人员则管理部署在 Tomcat中的.war文件和存储在Activiti数据库中的流程。

图 6:Activiti cycle协作组件逻辑示意图

Activiti Cycle通过BusinessLink将与流程相关的业务人员、开发团队与IT维护人员关联起来,实现他们之间的协作。

总而言之,与jBPM4相比,Activiti5目前最重要的增强就是实现了流程的可视化以及创新的Activiti Cycle协作组件,此外,通过与Mule的集成加强了其集成能力。其对PVM的保留使其继承了jBPM4强大的可扩展能力,对jBPM的老用户来说,这是向其迁移的重要理由。

七、总结

jBPM3是一个完整的工作流系统实现,面向开发人员,目的在于简化对组织核心流程进行支撑的软件创建,不支持标准。

jBPM4引入PVM,使其拥有更强大的扩展性,同时增加BPMS特性,这些特性包括了对BPMN的支持、面向业务人员的Web建模器和简单统计分析功能的加入。

jBPM5基于原先的Drools Flow,支持BPMN,通过与Drools的合并支持BAM,通过内容仓库增加对流程可视化的支持。由于放弃了jBPM4的PVM,引擎的可扩展性受到损害,并且不再支持jPDL。

Activiti5基于jBPM4,与Alfresco的集成增加了其流程可视化与管理能力,同时通过创新的Activiti Cycle协作组件支持流程相关人员之间的协调,最后,它加强了集成能力。

对于工作流应用或者jBPM3、jBPM4的老用户,建议转向Activiti5。

关于作者

荣浩,ThoughtWorks咨询师,关注敏捷和企业流程改进过程,目前正与辛鹏合著《Head First Process-深入浅出IT流程》一书。博客地址http://ronghao.javaeye.com

转自:http://www.infoq.com/cn/articles/rh-jbpm5-activiti5



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/rh-jbpm5-activiti5.html
posted @ 2011-01-05 13:55 88250 阅读(8567) | 评论 (4)编辑 收藏

有很多理由都能说明为什么我们应该写出清晰、可读性好的程序。最重要的一点,程序你只写一次,但以后会无数次的阅读。当你第二天回头来看你的代码 时,你就要开始阅读它了。当你把代码拿给其他人看时,他必须阅读你的代码。因此,在编写时多花一点时间,你会在阅读它时节省大量的时间。

让我们看一些基本的编程技巧:

 

  1. 尽量保持方法简短
  2. 永远永远不要把同一个变量用于多个不同的目的
  3. 使用自描述的变量名和方法名
  4. 尽可能的把变量定义在靠近使用它的地方
  5. 拒绝神秘数字
  6. 友好的对待你的语言
  7. 不要逆常规而行
  8. 警惕过早优化
  9. 积极重构测试过的程序
  10. 不要过度沉迷于技巧
  11. 通过习例学习新知

现在,让我们把每个小点展开来详细讲一下。

1. 尽量保持方法简短

尽管很多人都遵循这个规则,但它仍然非常的重要。你写的方法要始终能在一个屏幕里放得下。如果你需要去滚动屏幕,这会分散你的注意力,而且你看不到 整个的上下文。最佳长度是5-20行,这根据你的情况而定。当然,getters/setters 通常是一行代码的方法,但与其说它们是真正的方法,不如说它们只是存取工具。

2. 永远永远不要把同一个变量用于多个不同的目的

一个变量应该始终只为一个目的服务。通过使变量常量化(C++里的const, Java里的final),使得编译器能够优化编译,而且使你的代码醒目表达这个变量是不能改变的,你的程序的可读性会变得更好。

3. 使用自描述的变量名和方法名

你的代码应该,对于任何人来说,只要看一眼就能知道是干嘛的。尽量不要用简写方式,除非有特殊的习惯,就像下面的:

 src - source
pos - position
prev - previous

如果你认为描述性的名称并不是那么有价值,请对比一下n, ns, nsisdnumTeamMembers, seatCount, numSeatsInStadium

4. 尽可能的把变量定义在靠近使用它的地方

盖房子时,你可不希望把锤子放到别人的院子里。你希望把它们放的离手头越近越好。定义变量也是同样的道理。

int foo = 3;
int bar = 5;
// 一大段使用“bar”的代码,
// 但没用到“foo”
// ...

baz(foo);

这段代码可以简单的重构成

int bar = 5;
// 一大段使用“bar”的代码,
// 但没用到“foo”
// ...

int foo = 3;
baz(foo);

当你把变量的声明和第一次用到它的地方间隔太远时(距离超过一个屏幕),这确实会成为一个问题。记住上下文关系会变得困难,你需要滚动屏幕去找哪来的这个变量。

5. 拒绝神秘数字

当你要把什么东西跟一个常量值做比较时,记得把这个值定义成常量。没有什么会比去猜测你的同事写的这样的代码更让人头疼的事了:

il < 4384

换个形式感觉如何?

inputLength < MAX_INPUT_LENGTH

6. 友好的对待你的语言

学习新语言是一种很有乐趣的事情,你能学到一种新的完成任务的途径。当一个对一种语言已经很专业的人去学习另一种语言时,会出现一种很大的负面效应。比如说你是一个Java开发者,试图去学习Ruby。你应该学会用Ruby的方式解决问题,而不是沿用Java的解决问题的思想。

当你需要重复5遍”Hello world!“时,在Java里,你可能会这样做:

for (int i = 0; i < 5; i++) {
System.out.println("Hello world!");
}

在Ruby里,你也许会禁不住这样写:

for i in (0..5)
puts "Hello world!"
end

这样看起来没问题,但有一个更好的方式:

5.times { puts "Hello world!" }

7. 不要逆常规而行

每种语言都有自己不同的习俗约定。一般来说,人们听的最多的是Java的编码规范。让我们看看其中的一些习俗规范:

  • 方法名应该小写字母开头,其后用字母大写的单词连接(veryLongVariableName)
  • 类名应该都使用首字母大写的单词连接而成
  • 常量名应该全部大写,用下划线连接(MY_CONSTANT)
  • 左大括号应该跟 if 语句在同一行

只有在有必要的理由时才去打破这些常规,不要轻易的因为你不高兴就违反它。如果你只是在团队里改变一些这样的习惯,那也没问题,但当把你代码拿出来和其他的没有这些思想准备的程序员共享时,问题就会来了。

8. 警惕过早优化

过早优化是所有问题的根源,至少电视上是这么说的 … 你第一应该关心的事情是写出易于理解的代码。起初写的程序不要求快。除非你的程序很慢,否则谈优化都是为时太早。如果你想优化什么东西,你首先需要知道问题出在哪。这就是我们需要profilers这个工具的原因。

在没有知道问题在哪的情况下试图对程序进行优化,其结果必然是把程序能坏,至少你的代码会丧失可读性。如果你觉得有些地方很慢,不要盲目的重写代码,你应先找到慢的证据

不要傻乎乎的去解决根本不存在的问题。

9. 积极重构测试过的程序

没有任何东西会是完美的。即使你感觉你真正写出了一段完美的代码,几个月后回头再看看,你可能会惊讶道”怎么会这样傻?“

改进程序的一个好方法就是重构,但要等程序测试通过之后。你首先要确保程序是好的可运行的,你可以通过自动化测试或手工测试完成这个工作。

之初,你需要的是程序可用。不要期望在第一次就写出完美的程序,你只需要把它写出来,可用。然后重构它,使之完美。对于你们当中知道测试驱动开发 (TDD)的人来说,对这个会很熟悉。这里的关键就在于你要习惯于重构这种事情。如果你使用的是像IntelliJ IDEA这样强大的集成开发工具的话,重构的工作会变得简单的多。

重构之后,你也许会弄出一些Bug,导致某些功能出问题。这就是为什么说写自动化测试的原因。不论何时重构后,只要运行一下所有的测试用例,你就能准确的知道什么地方出了问题。

10. 不要过度沉迷于技巧

当我第一次读到有关设计模式的知识时,我觉得我找到了圣杯。这些精心设计的思想作用显著,它能使你的设计易于理解,因为你可以简单的说”我使用的是 ‘观察器模式’“,而不用从头到尾的解释一遍。那么,有问题吗?一切看起来都这么自然、简单,你开始不论在哪都使用设计模式。为什么不把这个类做成 singleton呢?干嘛不去再创建一些工厂类呢?

于是一个80行就能写完的脚本,你最终使用了10个类,15个接口,外加一大堆范式和标记符。97%的代码不做任何事情。设计模式是一种十分有用的用来简化你的设计的工具,但这不意味着你该在所有能用到的地方都用它。你应该用它们,但不能滥用。

11. 通过习例学习新知

编程是一种学习新知的过程。当你学到了新的程序库或新语言,你可能会迫不及待的丢掉旧的代码,用你新学到的东西重新写一遍。有很多的理由都能说明你不该这么做。

往现有的应用里增加新的类库或框架同属于这种情况。就说你写了一个Javascript的web应用,期间,你发现了jQuery。现在你突然急切的想丢到你的Javascript程序,重新用jQuery写,尽管你还从来没用过它。

最好的方式是你先用jQuery写一些简单的例子,通过这种方式把你在应用里将要用到的知识都学会。需要AJAX?在你的项目之外做一些小例子,当完全弄懂了后,丢掉例子,应用到你的产品里。

如果你非常关注编程技术,我强烈的推荐你阅读Steve McConnell写的 《代码大全》 一书。它会永远的改变你对编程的认识。:)

 

[英文出处]:11 tips for better code

[译文来源]:外刊IT评论



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/11-tips-for-better-code.html
posted @ 2011-01-05 09:08 88250 阅读(322) | 评论 (0)编辑 收藏



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-131.html
posted @ 2011-01-04 10:14 88250 阅读(217) | 评论 (0)编辑 收藏

“我说我是警察,也是执法 人员,应该文明执法,但还是被打断腿!”昨天,躺在病床上,昆明市 公安局民警张俊(化名)说起事发当天的情形时,依然有些愤怒!当天他接到母亲的电话,说辖区城管要强行拆除小区内的违章建筑,让他回家收拾东西。不料,张 俊刚到门口表明自己身份时,却遭到拆迁执法人员的围殴。据小区目击者称,张俊被殴打时,对方扬言“打的就是警察!”。

“我还以为身上有警械,就能够证明自己身份。”昨天下午,在解放军昆明总医院骨科住院部,记者见到了被打伤的张俊,他向记者讲述了事发经过。

“我是警察,也是执法人员。”张俊说,为了阻止自己被继续殴打,他一边表明自己的身份,一边准备从身上掏证件。慌忙中,张俊只摸到了自己随身携带的一根伸缩警棍,这一摸不要紧,更是遭了对方一顿暴打。

当 时现场执法人员叫张俊放下警棍,然后将他的警棍拿走。张俊说,第一次被打之后,自己的鼻子和嘴角已经被打出血了。但噩运还没有结束,之后,他被4名城管反 绑着双手押到邻居家的门前。他再次向执法人员提出要回家收拾东西,但没有人理他。听到他的反复要求后,一名执法人员转头对他说:“你拿警棍打我,怎么可能 让你上去。”张俊表示,他拿出警棍根本没有打到人。“我是市公安局的,也是执法者,执法要文明。”张俊说完时就听到对方一句狂喷:“你敢用手指头指我,兄 弟们,拿下。”

张俊说,他只感觉周围的20多名城管全部围了上来,用警棍和铁棍将他打倒在地,还有人上前用脚踩他。当时他感觉自己的右腿很疼,他大声恳求:“求求你们别打了,我的腿断了。”随后,他被打晕在地。

现 场很多小区业主都目睹了张俊被殴打的过程,“总共被打了两次。”张俊的邻居老邢说。同样目睹事情经过的程先生也说,张俊大概被殴打了10多分钟,他远远看 着张俊满脸都是血,倒在地上。他听到在场的一位执法人员对着几乎快晕厥过去的张俊喊道:“装死。”张俊的好友陈小姐说,现场就有执法人员带去的救护车,但 没有对他进行救治。

而对此,当时执法拆除违章建筑的昆明市综合行政执法局盘龙分局负责人称,是张俊先挥舞警棍导致冲突发生。

据知情人称,事件发生之后,已经有一名参与冲突的执法队长被拘留,但此说法未得到有关部门的证实。

转自:http://news.qq.com/a/20110103/000492.htm?qq=0&ADUIN=845765&ADSESSION=1294033435&ADTAG=CLIENT.QQ.3187_.0



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2011/01/03/1294035696457.html
posted @ 2011-01-03 14:22 88250 阅读(162) | 评论 (0)编辑 收藏

过去与今天
词 \ 黄家驹. 曲 \ 黄家驹. 主唱 \ 黄家驹.

夜雨街中里宁与静
雾色灯影照我身
在我的心里常会问
幻变的都市四周
可知我已放弃旧日的理想
知否我也有个梦 要我醉倒
就像 就像 就像
像那方的星光闪动 眼也会发光
仰望浮云常变不定 暗里叹一声
冲出他朝崎岖道上 哪怕会退倒
试问谁人曾会考虑 过去与今天
踏破这黑暗宁与静
谁会管失意冷风
幻变的都市谁问过
让暖风紧靠我身



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/31/1293811895091.html
posted @ 2011-01-01 00:12 88250 阅读(143) | 评论 (0)编辑 收藏

EverBox LogoEverBox 是一款由盛大创新院推出的网盘产品,提供数据存储和同步服务。EverBox 提供了 10GB 超大免费存储空间,支持文件同步、文件分享、在线浏览照片、在线听音乐等功能,并支持数据同步客户端。需要邀请的朋友可以改我留言 :-)

 

主要功能:

支持数据同步客户端:安装 EverBox后,您所需的文件都将自动同步到设备上,可以随时、随地的使用手边的任意一款设备访问文件了。目前提供了 Windows 客户端程序,支持 Windows XP,Windows Vista 和 Windows 7。在以后的版本中,EverBox 将会陆续推出其他客户端程序,如: Android,iPhone,iPad,Mac,Linux 等。

容灾备份服务:EverBox 会自动的、实时的备份文件数据到 EverBox 安全服务器,因此,当您本地的设备坏损或丢失时,不必担心由于数据丢失造成的损失,恢复数据易如反掌!

在线音乐播放:EverBox 支持在线音乐播放功能,几乎支持所有常用的音频格式,使用简单、便捷,无需操作即可连续播放 EverBox 当前目录中的歌曲,很适于一边使用电脑一边听歌时使用。

在线浏览图片:EverBox 支持在线浏览图片功能,几乎支持所有常用的图片格式,操作简单、便捷,并支持自动播放 EverBox 当前目录中的图片文件。

EverBox 功能特性

  1. 10GB 超大免费空间

    成功注册 EverBox 即可获得 2GB 免费空间,完成指定任务可升级空间到 10GB!EverBox 在随后的版本中将会有更多的奖励措施,赠送活跃用户更多空间,敬请期待!

  2. 支持数据同步客户端

    您是不是经常遇到以下的情况?“我喜欢在外出时用 iPhone 听歌,但是我需要从 PC 下载歌曲再用数据线将 MP3 导到 iPhone”;“我经常出差,但是程序和文件都在笨重的 PC 上,而我只带着笔记本”;“我到 XX 会议做演讲,但是保存 PPT 的 U 盘坏掉了”。

    现在有了 EverBox,这些问题将迎刃而解!只需安装 EverBox,您所需的文件都将自动同步到设备上,您就可以随时、随地的使用手边的任意一款设备访问文件了。当然,使用浏览器一样可以访问到您需要的文件。

  3. 容灾备份服务

    硬盘损坏?数据无法访问?笔记本电脑被盗?完了,重要的数据丢失了!

    不用担心,有了 EverBox,这一切都不会再是问题。EverBox 会自动的、实时的备份文件数据到 EverBox 安全服务器,因此,当您本地的设备坏损或丢失时,不必担心由于数据丢失造成的损失,恢复数据易如反掌!

  4. 在线音乐播放

    EverBox 支持在线音乐播放功能,几乎支持所有常用的音频格式,使用简单、便捷,无需操作即可连续播放 EverBox 当前目录中的歌曲,很适于一边使用电脑一边听歌时使用。

  5. 在线浏览图片

    EverBox 支持在线浏览图片功能,几乎支持所有常用的图片格式,操作简单、便捷,并支持自动播放 EverBox 当前目录中的图片文件。

     



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/everbox-invite.html
posted @ 2010-12-31 10:09 88250 阅读(198) | 评论 (0)编辑 收藏

B3log LogoGAE 博客 —— B3LOG Solo 0.2.5 Beta1 发布了。

该版本除了修复 Bugs,还增加了草稿夹、多人写作、改进了缓存,以及加入了新皮肤 community。

借此机会,祝大家圣诞节愉快,一切平安 :-)

新特性

  • 多人写作
  • 链接排序
  • 新皮肤——community(多人写作皮肤)

Bug 修复

  • 缓存多实例不一致
  • 文章访问次数统计失效
  • IE8 下 Feed 不能显示

改进

  • 存储对象缓存
  • 自定义页面排序方式
  • 改进了页面缓存

具体改动看这里

升级

如果您是 0.2.1 的用户,那么请在部署完 0.2.5 Beta1 后登录后台,访问 http://${application-id}.appspot.com/upgrade/v021-v025.do 进行升级。

项目

如果在使用、测试中发现任何问题,如果您有任何意见或建议,请告知我们 :-)

发布计划

  • 2011 年 1 月 21 日发布 0.2.5 Beta2
  • 2011 年 2 月 14 日发布 0.2.5

作者博客

发布历史

  1. GAE 博客——B3log Solo 0.2.1 发布了!
  2. GAE 博客——B3log Solo 0.2.0 发布了!
  3. GAE 博客——B3log Solo 0.1.1 发布了!
  4. B3log Solo 0.1.0 发布了!
  5. B3log Solo 0.1.0-preview2 发布了!
  6. Solo 0.1.0-Preview1 发布了


本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/b3log-solo-release-025-beta1.html
posted @ 2010-12-24 21:31 88250 阅读(142) | 评论 (0)编辑 收藏



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-130.html
posted @ 2010-12-23 15:36 88250 阅读(183) | 评论 (0)编辑 收藏

GAEAmazon WS

最近一个潜在客户要求我们比较一下 Amazon EC2 和 Google App Engine,正好我们刚刚在 EC2 和 Google App Engine 上完成了两个相对来说规模较大的项目,因此有必要做一下总结。

我打算从三个角度来对比这两大云计算平台:技术,业务和未来发展趋势,本文是技术方面的对比,ok,准备好咖啡,我们开始吧!

 

如果按平台类型来分,大家可能已经知道Google App Engine属于PaaS(平台即服务),而Amazon EC2属于IaaS(基础设施即服务),Amazon EC2给你一个安装了操作系统的“盒子”,你可以自己安装应用程序,也可以使用AMI(Amazon Machine Image),如果你想构建一个高度复杂的定制应用,Amazon EC2是不二之选,它允许你控制环境参数,底层操作系统,存储和网络需求,从技术上讲,它属于很底层的服务,你可以调整你需要的大部分东西。

Google App Engine给你一个完整的平台,包括完整的SDK(以及Eclipse插件)和服务,你可以构建和部署你自己的应用程序,但你不能很好地控制操作系统, 硬件和存储,诸如写文件系统,使用线程等操作都有限制,这样设计的目的是为了确保平台不会被某个应用程序绑架。

简单起来就是:

IaaS:原始硬件(处理器,网络和存储)

PaaS:操作系统,系统软件,开发框架和虚拟机。

下面从技术角度来比较一下这两个平台。

1、提供的服务

Google App Engine凭借丰富的服务击败Amazon EC2,Google App Engine提供的服务可以让开发人员快速进入开发状态。如 Blobstore,Images,Mail,Memcache,Multitenancy,Oauth,Task Queues,URL Fetch,Users,XMPP这些服务在Amazon EC2上是需要自己安装的,为了便于比较,假设你已经为Memcache,Mail和多租户搭建好了基础设施,看看在EC2上你用了多长时间安装,我敢打 赌你会超过一个小时,使用Google App Engine时,这些服务都是现成的,就象果盘中插好牙签的水果一样,你可以随时享用。

2、管理

Google App Engine再次胜出,因为一旦你的应用程序部署成功后,它几乎不需要管理,当你的应用程序负载变大时,你不需要向服务注入新的实例,Google App Engine可以自由扩大负载能力,新实例是实时剥离的。使用Amazon EC2时,你必须时刻跟踪通信流量(现在可以通过脚本自动跟踪了),新实例是在你的配置基础上剥离的,因此,如果我的峰值负载是2x+y,那么需要剥离2 个以上的应用程序服务器。

此外,使用Google App Engine升级应用程序服务器实例,安装新的负载均衡器时,没有管理开销,这一切都是自动执行的。

3、抽象水平

和上一条联系紧密的是抽象水平,Google App Engine抽象得比较好,你只需要关心你的应用程序和业务逻辑,不用担心底层基础设施的管理,正如Nick Johnson所说的那样,抽象水平应作为挑选云计算平台的一个基本原则,你需要做的是驾驶,不需要研究引擎盖以下的东西。在我看来,如果你的核心业务是 货物运输,那么你应该买一辆卡车,它能高效地把你的货物从A地运输到B地,相反,你不应该考虑如何购买零部件自己组装一辆卡车。

在软件开发领域,我们看到有Grails,RoR等框架,它们大受欢迎,是因为它们提供了高水平的抽象,如果你是一名泥瓦匠,它们就象是脚手架,你可以踩在它们上面干你的工作。

4、可靠性

从我个人的认识来讲,两者都很可靠,这一点从它们的用户数量就可以知道一二,用户可以时刻查看Google App Engine的状态,它是透明的,但从历史数据来看,Amazon EC2的正常运行时间比Google App Engine要好。

5、可移植性

从使用的底层操作系统和开发框架来看,Amazon EC2具有更好的可移植性,但也不要担心你会被Google App Engine给锁住,Google已经给出了迁移指南,指导你如何从转移出Google App Engine平台,当然包含你所有的数据在内。还有AppScale这样的程序可以帮助你将Google App Engine上的程序转移到Amazom EC2或其它云平台上,AppScale已经可以支持EC2,Eucalyptus,Xen和KVM。

6、存储

Google App Engine目前严重依赖于BigTable,开发人员需要从一个完全不同的角度来认识和学习它,特别是对于那些特熟悉关系数据库,被关系数据库理论束缚 的人更需要洗洗脑,它提供了一个JPA&JDO访问接口,但它不支持所有的JPA&JDO功能,特别是关系部分,Google最近也高调 宣布要让Google App Engine支持传统的SQL数据库。Amazon EC2已经支持SQL数据库,你可以使用Oracle,MySQL等你所熟悉的关系数据库。

7、应用程序维护和升级

对Google App Engine来说,应用程序维护和升级是件轻而易举的事,它为各种应用程序提供了一个详细的管理面板,包括日志查看器和数据查看器,一个程序可以有多个版 本,当新版本经过测试,可以用于生产环境时,你可以将其设为默认的版本,而Amazon EC2就麻烦多了,因为它属于IaaS类型,所有维护和升级相关的事情你必须亲力亲为。

8、开发限制

使用Google App Engine时,你必须受到平台的限制,如果你的查询处于僵死状态,很难将其杀掉,此外,Google App Engine没有线程,提供的SDK也是受限的,有些类和功能被列入黑名单,因此不能被使用,也不能写文件系统等等。

从表面上看这些限制是不可理喻的,但如果有朝一日你也要提供PaaS类型的平台时,你就能理解为什么Google要做这些限制了,这样才能确保运行 在平台上的应用程序不会违反平台的规则,否则平台就可能被应用程序绑架,从而变得不可使用,平台上的其它应用程序就会收到牵连。

即便有这些限制,90%的商业应用程序仍然可以在Google App Engine上正常运行,但对于那些要使用线程,或写文件系统的应用,最好还是选择Amazon EC2,因为它提供了所有底层访问和控制权。

9、语言支持

截至目前,Google App Engine支持Java和Python,但任何可以转换成字节码,可在JVM上执行的任何编程语言都可以在Google App Engine上运行,如果你喜欢其它编程语言,最好选择Amazon EC2,因为你可以在它的操作系统上面安装语言运行时环境,你拥有几乎完整的硬件和操作系统控制权,还有什么不能做的呢?在Amazon EC2上也托管了许多有趣的C#,.NET,ASP.NET MVC/Visual Studio项目,具有讽刺意味着的是,尽管还有Microsoft Azure,但许多以MS技术开发的项目却托管在Amazon EC2上。

概括地说,Amazon EC2是进入云计算的早期尝试者,它利用互联网标准和开放平台创建了一个非常灵活的云计算平台,Google则利用了它在大型数据库方面的研究成果和它内 部实现的一些技术创建了一个强大,但有更多限制的云计算环境。从核心技术来讲,Amazon EC2允许你扩展任何计算机实例到多个实例,因此你拥有每个虚拟盒子的完全控制权,Google App Engine从操作系统抽象而来,没有计算机实例的概念,如果你的Web应用程序不需要操作系统相关的功能,那么Google App Engine无疑是最好的选择,如果需要更好地控制你的系统环境,特别是操作系统相关的控制,那么最好选择Amazon EC2。

原文名:Comparing Google App Engine and Amazon EC2 on Technology 作者:Vikas Hazrati



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/ec2-vs-gae.html
posted @ 2010-12-22 15:21 88250 阅读(149) | 评论 (0)编辑 收藏

有人在Stack Overflow上发问,动手开发网站之前,需要知道哪些事情?

不出意料地,他得到了一大堆回答。

通常情况下,你需要把所有人的发言从头到尾读一遍。但是,Stack Overflow有一个很贴心的设计,它允许在问题下方开设一个wiki区,让所有人共同编辑一个最佳答案。于是,就有了下面这篇文章,一共总结出六个方面共计61条"网站开发须知"。

我发现,这种概述性的问题,最适合这种集合群智、头脑风暴式的回答方式了。这也是我第一次觉得,Stack Overflow做到了Wikipedia做不到的事。(难怪它最近挤进了全美前400大网站。)

在我的印象中,关于网站开发,这样全面的概述性文章非常少见,因此也就非常有用。大家不妨看看,61件事情中你做到了多少?

(更新:刚刚发现,一共应该是62条建议,我先前数错了,这个......太窘了。)

=============================

网站开发人员应该知道的61件事

原文网址:http://stackoverflow.com/questions/72394

译者:阮一峰

一、界面和用户体验(Interface and User Experience)

1.1

知道各大浏览器执行Web标准的情况,保证你的站点在主要浏览器上都能正常运行。你至少要测试以下引擎:Gecko(用于Firefox)、Webkit(用于SafariChrome和一些手机浏览器)、IE(你可以利用微软发布的Application Compatibility VPC Images进行测试)和Opera。同时,不同的操作系统,可能也会影响浏览器如何呈现你的网站。

1.2

除了浏览器,网站还有其他使用方式:手机、屏幕朗读器、搜索引擎等等。你应该知道在这些情况下,你的网站的运行状况。MobiForge提供了手机网站开发的一些相关知识。

1.3

知道如何在基本不影响用户使用的情况下升级网站。通常来说,你必须有版本控制系统(CVS、Subversion、Git等等)和数据备份机制(backup)。

1.4

不要让用户看到那些不友好的出错提示。

1.5

不要直接显示用户的Email地址,至少不要用纯文本显示。

1.6

为你的网站设置一些合理的使用限制,一旦超过门槛值,就自动停止服务。(这也与网站安全相关。)

1.7

知道如何实现网页的渐进式增强(progressive enhancement)。

1.8

用户发出POST请求后,总是将其重导向(redirect)至另外一个网页。

1.9

不要忘记网站的可访问性(accessibility,即残疾人如何使用网站)。对于美国网站来说,有时这是法定要求WAI-ARIA有一些这方面很好的参考资料。

二、安全性(Security

2.1

阅读《OWASP开发指南》,它提供了全面的网站安全指导。

2.2

了解SQL注入(SQL injection)及其预防方法。

2.3

永远不要信任用户提交的数据(cookie也是用户端提交的!)。

2.4

不要明文(plain-text)储存用户的密码,要hash处理后再储存。

2.5

不要对你的用户认证系统太自信,它可能很容易就被攻破,而你事先根本没意识到存在相关漏洞。

2.6

了解如何处理信用卡

2.7

在登录页面及其他处理敏感信息的页面,使用SSL/HTTPS

2.8

知道如何对付session劫持(session hijacking)。

2.9

避免"跨站点执行"(cross site scripting,XSS)。

2.10

避免"跨域伪造请求"(cross site request forgeries,XSRF)。

2.11

及时打上补丁,让你的系统始终跟上最新版本。

2.12

确认你的数据库连接信息的安全性。

2.13

跟踪攻击技术的最新发展,以及你使用的平台的最新安全漏洞。

2.14

阅读Google的《浏览器安全手册》(Browser Security Handbook)。

2.15

阅读《网络软件的黑客手册》(The Web Application Hackers Handbook)。

三、性能(Performance)

3.1

只要有可能,就使用缓存(caching)。正确理解和使用HTTP cachingHTML5离线储存

3.2

优化图片。不要把一个20KB的图片文件,作为重复出现的网页背景图案。

3.3

学习如何用gzip/deflate压缩内容(deflate方式更可取)。

3.4

将多个样式表文件或脚本文件,合为一个文件,这样可以减少浏览器的http请求数,以及减小gzip压缩后的文件总体积。

3.5

浏览Yahoo的Exceptional Performance网站,里面有大量提升前端性能的优秀建议,还有他们的YSlow工具。Google的page speed则是另一个用来分析网页性能的工具。两者都要求安装Firebug

3.6

如果你的网页用到大量的小体积图片(比如工具栏),就应该使用CSS Image Sprite,目的是减少http请求数。

3.7

大流量的网站应该考虑将网页对象分散在多个域名(split components across domains)。

3.8

静态内容(比如图片、CSS、JavaScript、以及其他cookie无关的网页内容)都应该放在一个不需要使用cookie的独立域名之上。因为域名之下如果有cookie,那么客户端向该域名发出的每次http请求,都会附上cookie内容。这里的一个好方法就是使用"内容分发网络"(Content Delivery Network,CDN)。

3.9

将浏览器完成网页渲染所需要的http请求数最小化。

3.10

使用Google的Closure Compiler压缩JavaScript文件,YUI Compressor亦可。

3.11

确保网站根目录下有favicon.ico文件,因为即使网页中根本不包括这个文件,浏览器也会自动发出对它的请求。所以如果这个文件不存在,就会产生大量的404错误,消耗光你的服务器的带宽。

四、搜索引擎优化(Search Engine Optimization,SEO)

4.1

使用"搜索引擎友好"的URL形式,比如example.com/pages/45-article-title,而不是example.com/index.php?page=45。

4.2

不要使用"点击这里"之类的超级链接,因为这样等于浪费了一个SEO机会,而且降低了"屏幕朗读器"(screen reader)的使用效果。

4.3

创建一个XML sitemap文件,它的缺省位置一般是/sitemap.xml(即放在网站根目录下)。

4.4

当你有多个URL指向同一个内容时,在网页代码中使用<link rel="canonical" ... />

4.5

使用Google的Webmaster Tools和Yahoo的Site Explorer

4.6

从一开始就使用Google Analytics(或者开源的访问量分析工具Piwik)。

4.7

知道robots.txt的作用,以及搜索引擎蜘蛛的工作原理。

4.8

将www.example.com的访问请求导向example.com(使用301 Moved Permanently重定向),或者采用相反的做法,目的是防止Google把它们当做两个网站,分开计算排名。

4.9

知道存在着恶意或行为不正当的网络蜘蛛。

4.10

如果你的网站有非文本的内容(比如视频、音频等等),你应该参考Google的sitemap扩展协议

五、技术(Technology)

5.1

理解HTTP协议,以及诸如GET、POST、sessions、cookies之类的概念,包括"无状态"(stateless)是什么意思。

5.2

确保你的XHTML/HTMLCSS符合W3C标准,使得它们能够通过检验。这可以使你的网页避免触发浏览器的古怪行为(quirk),而且使它在"屏幕朗读器"和手机上也能正常工作。

5.3

理解浏览器如何处理JavaScript脚本。

5.4

理解网页上的JavaScript文件、样式表文件和其他资源是如何装载及运行的,考虑它们对页面性能有何影响。在某些情况下,可能应该将脚本文件放置在网页的尾部

5.5

理解JavaScript沙箱(Javascript sandbox)的工作原理,尤其是如果你打算使用iframe。

5.6

知道JavaScript可能无法使用或被禁用,以及Ajax并不是一定会运行。记住,"不允许脚本运行"(NoScript)正在某些用户中变得流行,手机浏览器对脚本的支持千差万别,而Google索引网页时不运行大部分的脚本文件。

5.7

了解301重定向和302重定向之间的区别(这也是一个SEO相关问题)。

5.8

尽可能多得了解你的部署平台(deployment platform)。

5.9

考虑使用样式表重置(Reset Style Sheet)。

5.10

考虑使用JavaScript框架(比如jQueryMooToolsPrototype),它们可以使你不用考虑浏览器之间的差异。

六、解决bug

6.1

理解程序员20%的时间用于编码,80%的时间用于维护,根据这一点相应安排时间。

6.2

建立一个有效的错误报告机制。

6.3

建立某些途径或系统,让用户可以与你接触,向你提出建议和批评。

6.4

为将来的维护和客服人员撰写文档,解释清楚系统是怎么运行的。

6.5

经常备份!(并且确保这些备份是有效的。)除了备份机制,你还必须有一个恢复机制。

6.6

使用某种版本控制系统储存你的文件,比如SubversionGit

6.7

不要忘记做单元测试(Unit Testing),Selenium之类的框架会对你有用。

(完)

转自:http://www.ruanyifeng.com/blog/2010/11/61_things_every_web_developer_should_know.html



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/61_things_every_web_developer_should_know.html
posted @ 2010-12-21 17:05 88250 阅读(197) | 评论 (0)编辑 收藏

Memcached Banner
Martin Brown, 自由撰稿人, Freelance Developer

简介: 开源 memcached 工具是一个用来存储常用信息的缓存,有了它,您便无需从缓慢的资源,比如磁盘或数据库,加载(并处理)信息了。该工具可部署在专用的情况下,也可作为用完 现有环境内的多余内存的一种方法。尽管 memcached 十分简便,但有时它仍被不当使用,或被用在错误的环境类型中。在本文中,了解使用 memcached 的最佳时机。

简介

memcached 常被用来加速应用程序的处理,在这里,我们将着重于介绍将它部署于应用程序和环境中的最佳实践。这包括应该存储或不应存储哪些、如何处理数据的灵活分布以 及如何调节用来更新 memcached 和所存储数据的方法。我们还将介绍对高可用性的解决方案的支持,比如 IBM WebSphere® eXtreme Scale。

所有的应用程序,特别是很多 web 应用程序都需要优化它们访问客户机和将信息返回至客户机的速度。可是,通常,返回的都是相同的信息。从数据源(数据库或文件系统)加载数据十分低效,若是每次想要访问该信息时都运行相同的查询,就尤显低效。

虽然很多 web 服务器都可被配置成使用缓存发回信息,但那与大多数应用程序的动态特性无法相适。而这正是 memcached 的用武之地。它提供了一个通用的内存存储器,可保存任何东西,包括本地语言的对象,这就让您可以存储各种各样的信息并可以从诸多的应用程序和环境访问这些信息。


基础知识

memcached 是一个开源项目,旨在利用多个服务器内的多余 RAM 来充当一个可存放经常被访问信息的内存缓存。这里的关键是使用了术语缓存:memcached 为加载自他处的信息提供的是内存中的暂时存储。

比如,考虑这样一个典型的基于 web 的应用程序。即便是一个动态网站可能也会有一些组件或信息常量是贯穿页面整个生命周期的。在一个博客站点内,针对单个 blog post 的类别列表不大可能在页面查看间经常性地变更。每次都通过一个对数据库的查询加载此信息相对比较昂贵,特别是在数据没有更改的情况下,就更是如此。从图 1 可以看到一个博客站点内可被缓存的页面分区。


图 1. 一个典型的博客页面内的可缓存元素
此图显示了可缓存的 blog 元素及其布局:顶部是 Page Header,左边是当前的 Current post lists,右边是 About、Post History、External Links 和 Category list

将这种结构放在 blog 站点的其他元素,poster 信息、注释 — 设置 blog post 本身 — 进行推断,可以看出为了显示主页的内容很可能需要发生 10-20 次数据库查询和格式化。 每天对数百甚至数千的的页面查看重复此过程,那么您的服务器和应用程序执行的查询要远远多于为了显示页面内容所需执行的查询。

通过使用 memcached,可以将加载自数据库的格式化信息存储为一种可直接用在 Web 页面上的格式。并且由于信息是从 RAM 而不是通过数据库和其他处理从磁盘加载的,所以对信息的访问几乎是瞬时的。

再强调一下,memcached 是一个用来存储常用信息的缓存,有了它,您便无需从缓慢的资源,比如磁盘或数据库,加载并处理信息了。

对 memcached 的接口是通过网络连接提供的。这意味着您可以在多个客户机间共享单个的 memcached 服务器(或多个服务器,如本文稍后所示的)。这个网络接口非常迅速,并且为了改善性能,服务器会故意不支持身份验证或安全性通信。但这不应限制部署选项。 memcached 服务器应该存在于您网络的内部。网络接口的实用性以及可以部署多个 memcached 实例的简便性让您可以使用多个机器上的多余 RAM 来提高您缓存的整体大小。

memcached 的存储方法是一个简单的键/值对,类似于很多语言内的散列或关联数组。通过提供键和值来将信息存储到 memcached 内,通过按特定的键请求信息来恢复信息。

信息会无限期地保留在缓存内,除非发生如下的情况:

  1. 为缓存分配的内存耗尽 — 在这种情况下,memcached 使用 LRU(最近最少使用)方法从此缓存删除条目。最近未曾使用的条目会从此缓存中先删除,最旧的最先访问。
  2. 条目被明确删除 — 总是可以从此缓存内删除条目。
  3. 条目过期失效 — 各条目均有一个有效的期限以便针对此键存储的信息在过于陈旧时可从缓存中清除这些条目。

上述这些情况可以与您应用程序的逻辑综合使用以便确保缓存内的信息是最新的。有了这些基础知识后,让我们来看看在应用程序内如何能最好地利用 memcached。


何时使用 memcached

在使用 memcached 改进应用程序性能时,可以对一些关键的过程和步骤进行修改。

在加载信息时,典型的场景如图 2 所示。


图 2. 加载要显示的信息的典型顺序
此图显示了从加载数据到处理/格式化数据再到发送数据至客户机的流程

一般而言,这些步骤是:

  1. 执行一个或多个查询来从数据库加载信息
  2. 格式化适合于显示(或进一步处理)的信息
  3. 使用或显示格式化了的数据

在使用 memcached 时,为配合这个缓存,可对应用程序的逻辑进行稍许修改:

  • 尽量从缓存加载信息
  • 如果存在,使用信息的被缓存版本
  • 如果它不存在:
    1. 执行一个或多个查询来从数据库加载信息
    2. 格式化适合于显示或进一步处理的信息
    3. 将信息存储到缓存内
    4. 使用格式化了的数据

图 3 是对这些步骤的总结。


图 3. 在使用 memcached 时加载适合于显示的信息
此图显示了如果所请求的数据位于缓存内,它就会跳过所有处理步骤,节省了时间

数据加载成为了至多三个步骤的一个过程,从缓存加载数据或从数据库(视情况而定)加载数据并存储在缓存内。

当这个过程首次发生时,数据将正常地从数据库或其他数据源加载,然后再存储到 memcached 内。当下一次访问此信息时,它就会从 memcached 拉出,而不是从数据库加载,节省了时间和 CPU 循环。

问题的另一个方面是要确保如果更改了要存储在 memcached 内的信息,在更新后端信息的同时还要更新 memcached 的版本。这会让图 4 内所示的这个典型顺序发生稍许变化,如 图 5 所示。


图 4. 在一个典型的应用程序内更新或存储数据
此图显示了从更新数据到处理/格式化数据再到发送更新了的数据至客户机的流程

图 5 显示了使用 memcached 后发生了变化的流程。


图 5. 在使用 memcached 时更新或存储数据
此图显示了拓展了的流程:从更新数据到处理/格式化数据,再到将数据存储在 memcached 内,最后到发送更新了的数据至客户机

比如,仍以博客站点为例,在博客系统更新数据库内的类别列表时,更新应该遵循如下顺序:

  1. 更新数据库内的类别列表
  2. 格式化信息
  3. 将信息存储到 memcached 内
  4. 将信息返回至客户机

memcached 内的存储操作是原子的,所以信息的更新不会让客户机只获得部分数据;它们获得的或者是老版本,或者是新版本。

对于大多数应用程序,这两个操作是您惟一需要注意的。在访问他人使用的数据时,它会自动被添加到这个缓存内,而且如果对该数据进行了更改,此缓存内也会自动进行更新。


键、名称空间和值

memcached 另一个需要重点考虑的因素是如何组织和命名存储在缓存内的这些数据。从之前博客站点的例子中,不难看出需要使用一种一致的命名结构以便您能加载博客类别、历史和其他信息,然后再在加载信息(并更新缓存)时或者在更新数据(同样也要更新缓存)时使用。

使用的何种具体的命名系统特定于应用程序,但通常可以使用一种与现有应用程序类似的结构,并且这种结构很可能基于某种惟一识别符。当从数据库拉出信息或在整理信息集时,就会发生这种情况。

以 blog post 为例,可以在一个具有键 category-list 的项中存储类别列表。与此 post ID 对应的单个 post,比如 blogpost-29 相关的值都可以使用,而该项的注释则可以存储在 blogcomments-29 内,其中 29 就是这个 blog post 的 ID。这样一来, 您就可以将各种各样的信息存储在缓存内,使用不同的前缀来标识这些信息。

memcached 键/值存储的简便性(以及安全性的缺乏)意味着如果您想要在使用同一个 memcached 服务器的同时支持多个应用程序,那么就可以考虑使用其他格式的量词来标识数据属于某种特定的应用程序。比如,可以添加像 blogapp:blogpost-29 这样的应用程序前缀。这些键是没有格式的,所以可以使用任何字符串作为键的名称。

在存储值的方面,应该确保存储在缓存内的信息适合于您的应用程序。比如,对于这个博客系统,您可能想要存储被博客应用程序使用的对象以便格式化博客信息,而不是原始的 HTML。如果同一个基础结构用在应用程序内的多个地方,这一点更具实用性。

大多数语言的接口,包括 Java™、Perl、PHP 等,都能串行化语言对象以便存储在 memcached 内。这就让您可以存储并随后从内存存储恢复全部对象,而不是在您的应用程序内手动重构它们。 很多对象,或它们使用的结构,都基于某种散列或数组结构。对于跨语言的环境,比如在 JSP 环境和 JavaScript 环境间共享相同信息,可以使用一种架构中立的格式,比如 JavaScript Object Notation (JSON) 甚或 XML。


填充并使用 memcached

作为一种开源产品以及一种最初开发用来工作于现有开源环境内的产品,memcached 受大量环境和平台支持。与 memcached 服务器通信的接口有很多,并常常具有针对所有语言的多个实现。参见 参考资料 以获得常用的库和工具箱。

要列出所有受支持的接口和环境不太可能,但它们均支持 memcached 协议提供的基础 API。这些描述已经被简化并应用在不同语言的上下文内,在这些语言中,使用不同的值可指示错误。主要的函数有:

  • get(key) — 从存储了特定键的 memcached 获得信息。 如果键不存在,就返回错误。
  • set(key, value [, expiry]) — 使用缓存内的标识符键存储这个特定的值。如果键已经存在,那么它就会被更新。期满时间的单位为秒,并且如果值小于 30 天 (30*24*60*60),那么就用作相对时间,如果值大于 30 天,那么就用作绝对时间 (epoch)。
  • add(key, value [, expiry]) — 如果键不存在就将这个键添加到缓存内,如果键已经存在就返回错误。如果您想要显式地添加一个新键而又不会因它已经存在而更新它,那么这个函数将十分有用。
  • replace(key, value [, expiry]) — 更新此特定键的值,如果键不存在就返回一个错误。
  • delete(key [, time]) — 从缓存中删除此键/值对。如果您提供一个时间,那么添加具有此键的一个新值就会被阻塞这个特定的时期。超时让您可以确保此值总是可以重新读取自您的数据中心。
  • incr(key [, value]) — 为特定的键增 1 或特定的值。只适用于数值。
  • decr(key [, value]) — 为特定的键减 1 或特定的值,只适用于数值。
  • flush_all — 让缓存内的所有当前条目无效(或到期失效)。

比如,在 Perl 内,基本 set 操作可以如清单 1 所示的那样处理。


清单 1. Perl 内的基本 set 操作

				
use Cache::Memcached;

my $cache = new Cache::Memcached {
'servers' => [
'localhost:11211',
],
};

$cache->set('mykey', 'myvalue');

 

Ruby 内的相同的基本操作如清单 2 所示。


清单 2. Ruby 内的基本 set 操作

				
require 'memcache'
memc = MemCache::new '192.168.0.100:11211'

memc["mykey"] = "myvalue"

 

在两个例子中可以看到相同的基本结构:设置 memcached 服务器,然后分配或设置值。其他的接口也可用,包括适合于 Java 技术的那些接口,让您可以在 WebSphere 应用程序内使用 memcached。memcached 接口类允许将 Java 对象直接序列化到 memcached 以便于存储和加载复杂的结构。当在像 WebSphere 这样的环境内进行部署时,有两个事情非常重要:服务的弹性(在 memcached 不可用时如何做)以及如何提高缓存存储量来改进在使用多个应用程序服务器或在使用像 WebSphere eXtreme Scale 这样的环境时的性能。我们接下来就来看看这两个问题。


弹性和可用性

有关 memcached 最常见的一个问题是:“若缓存不可用了,会发生什么情况呢?”正如之前章节中明示的,缓存内的信息不应该成为信息的的惟一资源。必须要能够从其他位置加载存储在缓存内的数据。

虽然,无法从缓存访问信息将会减缓应用程序的性能,但它不应该阻止应用程序的运转。可能会发生这样几个场景:

  1. 如果 memcached 服务宕掉,应用程序应该回退到从原始数据源加载信息并对信息进行显示所需的格式化。此应用程序还应继续尝试在 memcached 内加载和存储信息。
  2. 一旦 memcached 服务器恢复可用,应用程序就应该自动尝试存储数据。没有必要强制重载已缓存了的数据,可以使用标准的访问来用信息加载和填充缓存。最终,缓存将会被最常用的数据重新填充。

再次重申,memcached 是信息的缓存但并非惟一的数据源。memcached 服务器不可用不应该是应用程序的终结,虽然这意味着在 memcached 服务器恢复正常之前性能会有所降低。实际上,memcached 服务器相对简单,并且虽然不是绝对无故障的,但它的简单性的结果就是它很少会出错。


分配缓存

memcached 服务器只是网络上针对一些键存储值的一个缓存。如果有多台机器,那么很自然地会想要在所有多余机器上设置一个 memcached 的实例来提供一个超大的联网 RAM 缓存存储。

有了这个想法后,还有一种想当然是需要使用某种分配或复制机制来在机器之间复制键/值对。这种方式的问题是如果这么做反而会减少可用的 RAM 缓存,而不是增加。如图 6 所示,可以看出这里有三个应用程序服务器,每个服务器都可以访问一个 memcached 实例。


图 6. 多重 memcached 实例的不正确使用
此图显示了 memcached 的三个独立的 1-GB 实例,支持三个应用程序服务器,各产出 1 GB 的缓存空间

尽管每个 memcached 实例都是 1 GB 的大小(产生 3 GB 的 RAM 缓存),但如果每个应用程序服务器只有其自己的缓存(或者在 memcached 之间存在着数据的复制),那么整个安装也仍只能有 1 GB 的缓存在每个实例间复制。

由于 memcached 通过一个网络接口提供信息,因此单个的客户机可以从它所能访问的任何一个 memcached 实例访问数据。如果数据没有跨每个实例被复制,那么最终在每个应用程序服务器上,就可以有 3 GB 的 RAM 缓存可用,如图 7 所示。


图 7. 多重 memcached 实例的正确使用
此图显示了三个交互的 1-GB memcached 实例,支持三个应用程序服务器,导致总体 3 GB 的共享缓存空间

这个方法的问题是选择哪个服务器来储存键/值对,以及当想要重新获得一个值时,如何决定要与哪个 memcached 服务器对话。问题的解决方案就是忽略复杂的东西,比如查找表,或是寄望 memcached 服务器来为您处理这个过程。而 memcached 客户机则必须要力求简单。

memcached 客户机不必决定此信息,它只需对在存储信息时指定的键使用一个简单的散列算法。当想要从一列 memcached 服务器存储或获取信息时,memcached 客户机就会用一个一致的散列算法从这个键获取一个数值。举个例子,键 mykey 被转换成数值 23875 。是保存还是获取信息无关紧要,这个键将总是被用作惟一标识符来从 memcached 服务器加载,因此在本例中,“mykey” 散列转化后对应的值总是 23875

如果有两个服务器,那么 memcached 客户机将对这个数值进行一个简单的运算(例如,系数)来决定它应将此值存储在第一个还是第二个配置了的 memcached 实例上。

当存储一个值时,客户机会从这个键确定出散列值以及它原来存储在哪个服务器上。当获取一个值时,客户机会从这个键确定出相同的散列值并会选择相同的服务器来获取信息。

如果在每个应用程序服务器上使用的是相同的服务器列表(并且顺序相同),那么当需要保存或检索同一个键时,每个应用程序服务器都将选择同一个 服务器。现在,在这个例子中,有 3GB 的 memcached 空间可以共享,而不是同一个 1 GB 的空间的复制,这就带来了更多的可用缓存,并很有可能会提高有多个用户情况下的应用程序的性能。

这个过程也有其复杂性(比如当一个服务器不可用时会怎样),更多信息,请参见相关文档(参见 参考资料)。


如何能不使用 memcached

尽管 memcached 很简单,但 memcached 实例有时候还是会被不正确地使用。

memcached 不是一个数据库

最常见的 memcached 误用就是把它用作一个数据存储,而不是一个缓存。memcached 的首要目的就是加快数据的响应时间,否则数据从其他数据源构建或恢复需要很长时间。一个典型的例子就是从一个数据库中恢复信息,特别是在信息显示给用户前 需要对信息进行格式化或处理的时候。Memcached 被设计用来将信息存储在内存中以避免每次在数据需要恢复时重复执行相同的任务。

切不可将 memcached 用作运行应用程序所需信息的惟一信息源;数据应总是可以从其他信息源获取。此外,要记住 memcached 只是一个键/值的存储。不能在数据上执行查询,或者对内容进行迭代来提取信息。应该使用它来存储数据块或对象以备批量使用。

不要缓存数据库行或文件

虽然可以使用 memcached 存储加载自数据库的数据行,但这实际上是查询缓存,并且大多数数据库都提供各自的查询缓存的机制。其他的对象,比如文件系统的图像或文件的情况与此相同。很多应用程序和 web 服务器针对此类工作已经有了一些很好的解决方案。

如果在加载和格式化后,使用它来存储全部信息块,就可以从 memcached 获得更多的实用工具和性能上的改善。仍以我们的博客站点为例,存储信息的最佳点是在将博客类别格式化为对象,甚至是在格式化成 HTML 后。博客页面的构造可通过从 memcached 加载各个组件(比如 blog post、category list、post history 等)并将完成的 HTML 写回至客户机实现。

memcached 并不安全

为了确保最佳性能,memcached 并未提供任何形式的安全性,没有身份验证,也没有加密。这意味着对 memcached 服务器的访问应该这么处理:一是通过将它们放到应用程序部署环境相同的私有侧,二是如果安全性是必须的,那么就使用 UNIX® socket 并只允许当前主机上的应用程序访问此 memcached 服务器。

这多少牺牲了一些灵活性和弹性,以及跨网络上的多台机器共享 RAM 缓存的能力,但这是在目前的情况下确保 memcached 数据安全性的惟一一种解决方案。


不要限制自己

除了不应该使用 memcached 实例的情况外,memcached 的灵活性不应忽视。由于 memcached 与应用程序处于相同的架构水平,所以很容易集成并连接到它。并且更改应用程序以便利用 memcached 也并不复杂。此外,由于 memcached 只是一个缓存,所以在出现问题时它不会停止应用程序的执行。如果使用正确的话,它所做的是减轻其余服务器基础设施的负载(减少对数据库和数据源的读操 作),这意味着无需更多的硬件就可以支持更多的客户机。

但请记住,它仅仅是个缓存!


结束语

在本文中,我们了解了 memcached 以及如何最佳地使用它。我们看到了信息如何存储、如何选择合理的键以及如何选择要存储的信息。我们还讨论了所有 memcached 用户都要遇到的一些关键的部署问题,包括多服务器的使用、当 memcached 实例消亡时该怎么做,以及(也许最为重要的)在哪些情况下不能使用 memcached。

作为一种开源的应用程序并且是目的简单而直白的应用程序,memcached 的功能和实用性均来自于这种简单性。通过为信息提供巨大的 RAM 存储空间、让它在网络上可用,然后再让它可通过各种不同的接口和语言访问到,memcached 可被集成到多种多样的安装和环境中。

 

参考资料

学习

获得产品和技术

讨论

关于作者

Martin Brown 成为专业作家已有七年多的时间了。他是题材广泛的众多书籍和文章的作者。他的专业技术涉及各种开发语言和平台 —— Perl、Python、Java™、JavaScript、Basic、Pascal、Modula-2、C、C++、Rebol、Gawk、 Shellscript、Windows、Solaris、Linux®、BeOS、Mac OS/X 等等,还涉及 Web 编程、系统管理和集成。Martin 是 Microsoft® 的主题专家(SME),并且是 ServerWatch.com、LinuxToday.com 和 IBM developerWorks 的定期投稿人,他还是 Computerworld、The Apple Blog 和其他站点的正式博客。您可以通过他的 Web 站点 : http://www.mcslp.com 与他联系。

转自:http://www.ibm.com/developerworks/cn/opensource/os-memcached



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/21/1292901251292.html
posted @ 2010-12-21 11:14 88250 阅读(462) | 评论 (0)编辑 收藏

“比心情更好的是你的选择!”这条挂在“天骄北麓”售楼部房顶上的广告词极其充满诱惑,与之形成鲜明反差的是上百准业主半月来的维权,比其心情更糟的是“天骄北麓”背后“那点房事”。12月18日,位于红云路上的“天骄北麓”在准业主们的不满和遭遇鸡粪洒门中迎来了开盘。

这 场被媒体和市民高度关注的房事,其实是一场赤裸裸的利益纷争,以及一个企业在市场经济下,面对市场风险如何做到诚实守信?对于准业主们来说,需要思考的是 在市场经济下,如何用法律来保障自己的权益。市场经济就是法治经济,道德、诚信这些没有落在纸上具有法律约束力的字眼,在利益面前显得苍白无力。

为防不测,防暴警察也来到现场

昨天上午,“天骄北麓”迎来开盘。由于上百准业主的不满和抗议,让这次开盘显得格外谨慎和受到外界广泛关注。数十警察赶到现场维持秩序,为了防止不测,防暴警察也来到现场。

中 午12点39分左右,准房主们把早已准备好的两箱鸡粪洒在了售楼部的门口。顿时,现场出现了一点骚乱,在旁边维持秩序的警察开始前去阻拦。就在这时,一矿 泉水瓶砸向售楼部大门,站在门口的一名保安拿着警棍朝着准业主们指了指,几个情绪激动的准业主向保安冲去,被维持秩序的警察拦下,在其他保安的劝说下,该 名保安走进了售楼部。

56岁的代阿姨,是这次“天骄北麓”团购房的一名准业主,交了20万元。维权15天以来,代阿姨有着不少的委屈和不满。为了换一套大一点的房子,代阿姨把原来的房子卖了,手里攥着60多万元,本想把这60多万投向“天骄北麓”,买大一点的房子,等待她的却是一场纷争。

“比心情更坏的是花言巧言设下的陷阱,一个没有出口、巷道林立的购房迷宫。”代阿姨说。

说起购买“天骄北麓”的房子,患有高血压的代阿姨苦不堪言,当她7月初从中介公司获知4800元一平方米就可以购买天骄北麓的房子时,义无反顾地交了1.7万元的转让金,并与这家中介公司签下合约。7月10日选房时,她交了20万元。

本以为可以圆一个住房梦的她,每天都在盼着房子开盘,日子就这么一天天过去,代阿姨也没感到有什么烦恼。

当12月1日获知她交了20万元参与团购的“天骄北麓”价格比当初和中介公司签下合约的房价高出一倍时,代阿姨蒙了。自12月4日起,代阿姨和上百团购者开始了维权。由于身体不好,上了年纪,每天的维权之路,代阿姨还是吃不消。

和代阿姨一样的购房者还有来自四川的周女士。周女士交了6万元的购房意向金,结果也陷入了这场纷争。欲哭无泪的周女士昨天上午后悔不已,当初不该草率地卖了房子来购买“天骄北麓”。在这起购房中,还有她的10多个老乡。

“开发商的一小步,维权者的一大步”

在这些准业主提供的协议中,记者没有看到一份真正的购房合同,听到和看到的只是团购、意向金,这些不明不白的词语,让人眼花缭乱。

在“天骄北麓”售楼部,一张由云南伦华房地产有限公司贴出的通告里称,对未选中房子的购房客户,公司愿意现金一次性补偿,以中国人民银行公布的现行两年定期存款率3.25%为计算标准。

对于此,准业主霍先生把其称为“开发商的一小步,维权者的一大步”。霍先生说,在各方压力和他们准业主的努力下,开发商愿意为返还意向金支付利息,来之不易。

代阿姨说,她交了20万元的意向金,可以得到6500多元的利息,对于她来说,这点利息已经对其没有多少用处,因为这几个月来,看着往上涨的房子,她付出去的更多,已经耽误了她买房。

中午12点51分,准业主们开始从售楼部撤离,环卫工人开始打扫门口的鸡粪。下午1点10分左右,“天骄北麓”恢复了暂时的安宁。挂在售楼部西边“所有关于生活的梦想从这一刻开启”的广告词,是否会因为一些准业主们的离开而开启更多准业主们生活的梦想呢?

背景

“天骄北麓”团购风波

2009年11月,由云南伦华房地产有限公司开发的“天骄北麓”项目开始认购,打出的广告上称项目房源最低售价3660元/平米,均价4300元/平米,并承诺如正式开盘时提价,团购房源价格不变,上万的团购者缴纳了2至30万元不等的意向金预订房源。

2010年12月1日,“天骄北麓”项目公布了每套房源价格,均价上调。开发商称所有房源按照公布价格出售,不想买房的,无息返还意向金。

当 准业主们获知这个消息后,犹如五雷轰顶,当初不是说好了3660元到4300元吗?怎么会有这么大的差距呢?一种不满的情绪开始在准业主中蔓延。12月1 日,因开盘价格远远高于已经交了认购金的购房者的心理底线,这些准业主们一气之下砸了售楼部的沙盘模型。12月4日、5日,准业主们聚集售楼部,用番茄鸡 蛋来招呼开发商,表达对开发商行为的不满。

记者秦聪俊(都市时报)

 

转自:http://news.qq.com/a/20101219/001080.htm?qq=0&ADUIN=84588990&ADSESSION=1292750641&ADTAG=CLIENT.QQ.3073_.0

 



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/19/1292773828916.html
posted @ 2010-12-19 23:50 88250 阅读(174) | 评论 (0)编辑 收藏

腾讯微博开放平台API开放啦,使用腾讯微博开放平台提供的API创建自己的应用,需要首先填写个人资料,通过联系邮箱验证,获取开发者资格,就能 创建自己的应用。腾讯微博开放平台,是基于腾讯微博系统,为广大开发者和用户提供的开放数据分享与传播平台。广大开发者和用户登录平台后,就可以使用平台 提供的开放API接口,创建应用从微博系统获取信息,或将新的信息传播到整个微博系统中,丰富多样的API接口和应用,加上你的智慧,将创造出无穷的应用和乐趣。

平台使用说明:

腾讯微博开放平台,是基于腾讯微博系统,为广大开发者和用户提供的开放数据分享与传播平台。广大开发者和用户登录平台后,就可以使用平台提供的开放 API接口,创建应用从微博系统获取信息,或将新的信息传播到整个微博系统中,丰富多样的API接口和应用,加上你的智慧,将创造出无穷的应用和乐趣!

平台介绍 — 在微博开放平台能获取到的资源及优势

应用开发说明 — 说明如何成为一个开发者并创建应用

应用审核流程 — 审核应用的来源字段能获得的好处,以及如何审核

开发者协议 — 在此查看腾讯微博开放平台开发者服务协议

如何开发微博应用?(马上成为开发者)

你只需要按照如下步骤操作:

第一步:填写你的开发者信息;

第二步:联系邮箱通过验证;(电子邮箱将作为我们联系你的重要方式,请提供常用邮箱地址)

第三步:填写要创建的应用信息。

就能马上获取到微博App Key和App Secret,调用微博API,进行应用开发。 查看详细说明

----

代表着中国最先进的互联网技术的腾讯终于走出了开放的第一步 :-)

转自:http://www.oschina.net/news/13863/tencent-open-micro-blogging-api



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/tencent-open-micro-blogging-api.html
posted @ 2010-12-17 09:08 88250 阅读(197) | 评论 (0)编辑 收藏

好久没贴过代码了,心血来潮。

/*
 * Copyright (c) 2009, 2010, B3log Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.b3log.latke.servlet.filter;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * Abstract HTTP response GZIP filter.
 *
 * @author Liang Ding
 * @version 1.0.0.1, Dec 16, 2010
 */
public abstract class AbstractGZIPFilter implements Filter {

    /**
     * Logger.
     */
    private static final Logger LOGGER =
            Logger.getLogger(AbstractGZIPFilter.class.getName());

    @Override
    public void init(final FilterConfig cfg) throws ServletException {
    }

    /**
     * Wraps the http servlet response with GZIP if could.
     *
     * @param request the specified request
     * @param response the specified response
     * @param chain filter chain
     * @throws IOException io exception
     * @throws ServletException servlet exception
     */
    @Override
    public void doFilter(final ServletRequest request,
                         final ServletResponse response,
                         final FilterChain chain) throws IOException,
                                                         ServletException {
        final HttpServletRequest httpServletRequest =
                (HttpServletRequest) request;
        final String requestURI = httpServletRequest.getRequestURI();
        if (shouldSkip(requestURI)) {
            LOGGER.log(Level.FINEST, "Skip GZIP filter request[URI={0}]",
                       requestURI);
            chain.doFilter(request, response);

            return;
        }

        final String acceptEncoding =
                httpServletRequest.getHeader("Accept-Encoding");
        boolean supportGZIP = false;
        if (null != acceptEncoding
            && 0 <= acceptEncoding.indexOf("gzip")) {
            supportGZIP = true;
        }

        if (!supportGZIP) {
            LOGGER.info("Gzip NOT be supported");
            chain.doFilter(request, response);

            return;
        }

        final HttpServletResponse httpServletResponse =
                (HttpServletResponse) response;
        httpServletResponse.addHeader("Content-Encoding", "gzip");
        httpServletResponse.addHeader("Vary", "Accept-Encoding");
        chain.doFilter(request,
                       new GZIPServletResponseWrapper(httpServletResponse));
    }

    /**
     * Determines whether the specified request URI should be skipped filter.
     *
     * 

* Note: This method SHOULD be invoked for all filters with pattern * "/*". *

* * @param requestURI the specified request URI * @return {@code true} if should be skipped, {@code false} otherwise */ public abstract boolean shouldSkip(final String requestURI); @Override public void destroy() { } /** * HTTP response wrapper for GZIP. * * @author Liang Ding * @version 1.0.0.0, Dec 16, 2010 */ private class GZIPServletResponseWrapper extends HttpServletResponseWrapper { /** * GZIP output stream. */ private GZIPOutputStream gzipStream; /** * Servlet output stream. */ private ServletOutputStream servletOutputStream; /** * Print writer. */ private PrintWriter printWriter; /** * Constructs an {@link GZIPServletResponseWrapper} object with the * specified http servlet response. * * @param httpServletResponse the specified http servlet response * @throws IOException io exception */ GZIPServletResponseWrapper(final HttpServletResponse httpServletResponse) throws IOException { super(httpServletResponse); } @Override public ServletOutputStream getOutputStream() throws IOException { if (null == servletOutputStream) { servletOutputStream = createOutputStream(); } return servletOutputStream; } @Override public PrintWriter getWriter() throws IOException { if (null == printWriter) { printWriter = new PrintWriter( new OutputStreamWriter(getOutputStream(), getCharacterEncoding())); } return printWriter; } /** * Creates output stream with GZIP delegation. * * @return servlet output stream * @throws IOException io exception */ private ServletOutputStream createOutputStream() throws IOException { final ServletResponse servletResponse = this.getResponse(); gzipStream = new GZIPOutputStream(servletResponse.getOutputStream()); return new ServletOutputStream() { @Override public void write(final int b) throws IOException { gzipStream.write(b); } @Override public void flush() throws IOException { gzipStream.flush(); } @Override public void close() throws IOException { gzipStream.close(); } /* * These two are not absolutely needed. They are here simply * because they were overriden by GZIPOutputStream. */ @Override public void write(final byte[] b) throws IOException { gzipStream.write(b); } @Override public void write(final byte[] b, final int off, final int len) throws IOException { gzipStream.write(b, off, len); } }; } } }



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/16/1292515963081.html
posted @ 2010-12-17 00:13 88250 阅读(585) | 评论 (0)编辑 收藏



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-129.html
posted @ 2010-12-14 22:59 88250 阅读(192) | 评论 (0)编辑 收藏

 



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/netbeans-chinese-newsletter-128.html
posted @ 2010-12-11 11:33 88250 阅读(233) | 评论 (0)编辑 收藏

WebSocket 协议是实现了浏览器与服务器全双工通信的 HTML5 新协议之一。传统浏览器只允许通过 HTTP 与网站互动,然而对于富 Web 应用 如聊天和游戏,HTTP 的效率不太高,因此HTML5 提供了socket API,只需一个握手动作就能在浏览器和服务器之间建立快速通道。

然而在 11 月 26 日,安全研究人员发表一篇研究报告(PDF),他们发现 WebSocket 和透明代理存在严重安全问题,他们演示了基于 Upgrade 和 CONNECT 的缓存中毒攻击,研究人员提议修改握手方式。在 Bugzilla 上,Firefox 开发者讨论了该问题,他们最后决定Firefox 4 将默认不启用 WebSockets,从 Firefox 4 beta 8 开始用户将需要修改设置才能启用 WebSockets。未来在解决安全问题后,Firefox 会选择默认启用。

转自:http://www.oschina.net/news/13668/disabling-websockets-for-firefox-4



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/10/1291942973503.html
posted @ 2010-12-10 09:03 88250 阅读(163) | 评论 (0)编辑 收藏

自从发布第一个版本来,大家给了很多建议,谢谢了 :-)

下个版本 0.2.5 将于明年 2 月 14 日发布,其中加入两个大的特性:

  • 多用户
    Solo 不再是单用户博客了。多人可以一起在一个博客里进行文章撰写,非常适合团队博客。另外,如果是情侣博客的话,哼哼....
  • 草稿夹
    想发布再发布吧!当然,发布了也可以再草稿化....

这个版本的改变比较大(数据存储、逻辑控制、视图),除了 Solo 上述两个大特性的加入,还有 Latke 框架上的增强:

  • 存储缓存
    本地测试可以提升单一实体按 Key 访问时速度 400 倍左右。当然,部署到 GAE 后可能没这么好的效果 - -~

(广告:Latke 是 GAE 上的一个应用框架,主要整合了 Guice、FreeMarker、Jabsorb,数据模型从视图到存储都以 JSON 贯穿

下个版本是 B3log Solo 的第一个正式版吧 :-)

P.S. 情侣博客?两个人也是多用户嘛,0.2.5 中将加入一款皮肤,非常适合情侣写作!谢谢 Lamb 这么给力!

 



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/08/1291818048978.html
posted @ 2010-12-08 22:21 88250 阅读(180) | 评论 (0)编辑 收藏

那大爷买西红柿来着的,挑了三个放到秤盘里,摊主秤了下说:“一斤半,三块七。”

大爷说:“我就做个汤,用不着那么多。”说完就去掉了个儿最大的那个西红柿。

摊主迅速又瞧一眼秤子,“一斤二两,三块。”

正当我看不过去想提醒大爷注意摊主的秤子时,大爷从容的掏出了七毛钱,拿起刚刚去掉的那个大的西红柿,扭头就走了……

摊主当场就风中凌乱了,我憋成内伤,把头扭向一边……

 

转自:http://www.douban.com/group/topic/16089209/



本文是使用 B3log Solo简约设计の艺术 进行同步发布的
原文地址:http://88250.b3log.org/articles/2010/12/03/1291338840521.html
posted @ 2010-12-03 09:14 88250 阅读(193) | 评论 (0)编辑 收藏