2008年11月17日星期一

告诉搜索引擎你的Sitemap更新了

当Sitemap随着网站的更新增加了内容,如何最快的让搜索引擎知道而不是坐等蜘蛛光临呢?当然最好的办法就是告诉搜索引擎你的Sitemap更新了,就等你放蜘蛛过来了!

如何告诉搜索引擎?用他们开放的Ping功能。

遗憾的是国内搜索引擎对Sitemap都不感兴趣,更别说Ping了,所以中文站可能效果有限。

下面几个地址是老乐搜集过来的,大家可以照此格式将其中Sitemap完整地址换成你自己的,Ping一下搜索引擎,告诉你的Sitemap更新。

Google:http://www.google.com/webmasters/sitemaps/ping?sitemap=XML文件完整地址

Yahoo:http://api.search.yahoo.com/SiteExplorerService/V1/updateNotification?appid=YahooDemo&url=XML文件完整地址

Live:http://webmaster.live.com/ping.aspx?siteMap=XML文件完整地址

Ask:http://submissions.ask.com/ping?sitemap=XML文件完整地址

Moreover:http://api.moreover.com/ping?u=XML文件完整地址

可惜,主流中文搜索引擎对Sitemap不感冒,支持Sitemap的搜索引擎市场份额又上不去。

2008年11月15日星期六

Using the robots meta tag

Recently, Danny Sullivan brought up good questions about how search engines handle meta tags. Here are some answers about how we handle these tags at Google.

Multiple content values
We recommend that you place all content values in one meta tag. This keeps the meta tags easy to read and reduces the chance for conflicts. For instance:

<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">

If the page contains multiple meta tags of the same type, we will aggregate the content values. For instance, we will interpret

<meta name="ROBOTS" content="NOINDEX">
<meta name="ROBOTS" content="NOFOLLOW">

The same way as:

<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">

If content values conflict, we will use the most restrictive. So, if the page has these meta tags:

<meta name="ROBOTS" content="NOINDEX">
<meta name="ROBOTS" content="INDEX">

We will obey the NOINDEX value.

Unnecessary content values
By default, Googlebot will index a page and follow links to it. So there's no need to tag pages with content values of INDEX or FOLLOW.

Directing a robots meta tag specifically at Googlebot
To provide instruction for all search engines, set the meta name to "ROBOTS". To provide instruction for only Googlebot, set the meta name to "GOOGLEBOT". If you want to provide different instructions for different search engines (for instance, if you want one search engine to index a page, but not another), it's best to use a specific meta tag for each search engine rather than use a generic robots meta tag combined with a specific one. You can find a list of bots at robotstxt.org.

Casing and spacing
Googlebot understands any combination of lowercase and uppercase. So each of these meta tags is interpreted in exactly the same way:

<meta name="ROBOTS" content="NOODP">
<meta name="robots" content="noodp">
<meta name="Robots" content="NoOdp">

If you have multiple content values, you must place a comma between them, but it doesn't matter if you also include spaces. So the following meta tags are interpreted the same way:

<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta name="ROBOTS" content="NOINDEX,NOFOLLOW">

If you use both a robots.txt file and robots meta tags
If the robots.txt and meta tag instructions for a page conflict, Googlebot follows the most restrictive. More specifically:
  • If you block a page with robots.txt, Googlebot will never crawl the page and will never read any meta tags on the page.
  • If you allow a page with robots.txt but block it from being indexed using a meta tag, Googlebot will access the page, read the meta tag, and subsequently not index it.
Valid meta robots content values
Googlebot interprets the following robots meta tag values:
  • NOINDEX - prevents the page from being included in the index.
  • NOFOLLOW - prevents Googlebot from following any links on the page. (Note that this is different from the link-level NOFOLLOW attribute, which prevents Googlebot from following an individual link.)
  • NOARCHIVE - prevents a cached copy of this page from being available in the search results.
  • NOSNIPPET - prevents a description from appearing below the page in the search results, as well as prevents caching of the page.
  • NOODP - blocks the Open Directory Project description of the page from being used in the description that appears below the page in the search results.
  • NONE - equivalent to "NOINDEX, NOFOLLOW".
A word about content value "NONE"
As defined by robotstxt.org, the following direction means NOINDEX, NOFOLLOW.

<meta name="ROBOTS" content="NONE">

However, some webmasters use this tag to indicate no robots restrictions and inadvertently block all search engines from their content.

2008年11月11日星期二

美国新当选总统奥巴马获胜演讲全文

以下是奥巴马(Barack Obama)为今晚在芝加哥演讲准备的讲稿:

如果还有人对美国是否凡事都有可能存疑,还有人怀疑美国奠基者的梦想在我们所处的时代是否依然鲜活,还有人质疑我们的民主制度的力量,那么今晚,这些问题都有了答案。

这是设在学校和教堂的投票站前排起的前所未见的长队给出的答案;是等了三四个小时的选民所给出的答案,其中许多人都是有生以来第一次投票,因为他们认定这一次肯定会不一样,认为自己的声音会是这次大选有别于以往之所在。

这是所有美国人民共同给出的答案--无论老少贫富,无论是民主党还是共和党,无论是黑人、白人、拉美裔、亚裔、原住民,是同性恋者还是异性恋者、残疾人还是健全人--我们从来不是“红州”和“蓝州”的对立阵营,我们是美利坚合众国这个整体,永远都是。

长久以来,很多人一再受到告诫,要对我们所能取得的成绩极尽讽刺、担忧和怀疑之能事,但这个答案让这些人伸出手来把握历史,再次让它朝向美好明天的希望延伸。

已经过去了这么长时间,但今晚,由于我们在今天、在这场大选中、在这个具有决定性的时刻所做的,美国已经迎来了变革。

我 刚刚接到了麦凯恩参议员极具风度的致电。他在这场大选中经过了长时间的努力奋斗,而他为自己所深爱的这个国家奋斗的时间更长、过程更艰辛。他为美国做出了 我们大多数人难以想像的牺牲,我们的生活也因这位勇敢无私的领袖所做出的贡献而变得更美好。我向他和佩林州长所取得的成绩表示祝贺,我也期待着与他们一起 在未来的岁月中为复兴这个国家的希望而共同努力。

我要感谢我在这次旅程中的伙伴--已当选美国副总统的拜登。他全心参与竞选活动,为普通民众代言,他们是他在斯克兰顿从小到大的伙伴,也是在他回特拉华的火车上遇到的男男女女。

如 果没有一个人的坚决支持,我今晚就不会站在这里,她是我过去16年来最好的朋友、是我们一家人的中坚和我一生的挚爱,更是我们国家的下一位第一夫人:米歇 尔•奥巴马(Michelle Obama)。萨莎(Sasha)和玛丽亚(Malia),我太爱你们两个了,你们已经得到了一条新的小狗,它将与我们一起入驻白宫。虽然我的外祖母已经 不在了,但我知道她与我的亲人肯定都在看着我,因为他们,我才能拥有今天的成就。今晚,我想念他们,我知道自己欠他们的无可计量。

我的竞选经理大卫•普劳夫(David Plouffe)、首席策略师大卫•艾克斯罗德(David Axelrod)以及政治史上最好的竞选团队--是你们成就了今天,我永远感激你们为实现今天的成就所做出的牺牲。

但最重要的是,我永远不会忘记这场胜利真正的归属--它属于你们。

我从来不是最有希望的候选人。一开始,我们没有太多资金,也没有得到太多人的支持。我们的竞选活动并非诞生于华盛顿的高门华第之内,而是始于得梅因、康科德、查尔斯顿这些地方的普通民众家中。

我 们的竞选活动能有今天的规模,是因为辛勤工作的人们从自己的微薄积蓄中拿出钱来,捐出一笔又一笔5美元、10美元、20美元。而竞选活动的声势越来越大则 是源自那些年轻人,他们拒绝接受认为他们这代人冷漠的荒诞说法;他们离开家、离开亲人,从事报酬微薄、极其辛苦的工作;同时也源自那些已经不算年轻的人 们,他们冒着严寒酷暑,敲开陌生人的家门进行竞选宣传;更源自数百万的美国民众,他们自动自发地组织起来,证明了在两百多年以后,民有、民治、民享的政府 并未从地球上消失。这是你们的胜利。



我知道你们的所做所为并不只是为了赢得大选,我也知道你们做这一切并不是为了 我。你们这样做是因为你们明白摆在面前的任务有多艰巨。因为即便我们今晚欢呼庆祝,我们也知道明天将面临我们一生之中最为艰巨的挑战--两场战争、一个面 临危险的星球,还有百年来最严重的金融危机。今晚站在此地,我们知道伊拉克的沙漠里和阿富汗的群山中还有勇敢的美国士兵醒来,甘冒生命危险保护着我们。会 有在孩子熟睡后仍难以入眠的父母,担心如何偿还按揭月供、付医药费或是存够钱送孩子上大学。我们亟待开发新能源、创造新的工作机会;我们需要修建新学校, 还要应对众多威胁、修复与许多国家的关系。

前方的道路会十分漫长艰辛。我们可能无法在一年甚至一届任期之内实现上述目标,但我从未像今晚这样满怀希望,相信我们会实现。我向你们承诺--我们作为一个整体将会达成目标。

我 们会遭遇挫折和不成功的开端。对于我作为总统所做的每项决定和政策,会有许多人持有异议,我们也知道政府并不能解决所有问题。但我会向你们坦陈我们所面临 的挑战。我会聆听你们的意见,尤其是在我们意见相左之时。最重要的是,我会请求你们参与重建这个国家,以美国221年来从未改变的唯一方式--一砖一瓦、 胼手胝足。

21个月前那个寒冬所开始的一切不应该在今天这个秋夜结束。今天的选举胜利并不是我们所寻求的改变--这只是我们进行改变的机会。而且如果我们仍然按照旧有方式行事,我们所寻求的改变不可能出现。没有你们,也不可能有这种改变。

因此,让我们发扬新的爱国精神,树立新的服务意识和责任感,让我们每个人下定决心全情投入、更加努力地工作,并彼此关爱。让我们铭记这场金融危机带来的教训:我们不可能在金融以外的领域备受煎熬的同时拥有繁荣兴旺的华尔街--在这个国家,我们患难与共。

让 我们抵制重走老路的诱惑,避免重新回到令美国政治长期深受毒害的党派纷争和由此引发的遗憾和不成熟表现。让我们牢记,正是伊利诺伊州的一名男子首次将共和 党的大旗扛到了白宫。共和党是建立在自强自立、个人自由以及全民团结的价值观上,这也是我们所有人都珍视的价值。虽然民主党今天晚上赢得了巨大的胜利,但 我们是以谦卑的态度和弥合阻碍我们进步的分歧的决心赢得这场胜利的。林肯在向远比我们眼下分歧更大的国家发表讲话时说,我们不是敌人,而是朋友……虽然激 情可能褪去,但是这不会割断我们感情上的联系。对于那些现在并不支持我的美国人,我想说,或许我没有赢得你们的选票,但是我听到了你们的声音,我需要你们 的帮助,而且我也将是你们的总统。

那些彻夜关注美国大选的海外人士,从国会到皇宫,以及在这个世界被遗忘的角落里挤在收音机旁的人 们,我们的经历虽然各有不同,但是我们的命运是相通的,新的美国领袖诞生了。那些想要颠覆这个世界的人们,我们必将击败你们。那些追求和平和安全的人们, 我们支持你们。那些所有怀疑美国能否继续照亮世界发展前景的人们,今天晚上我们再次证明,我们国家真正的力量并非来自我们武器的威力或财富的规模,而是来 自我们理想的持久力量:民主、自由、机会和不屈的希望。

这才是美国真正的精华--美国能够改变。我们的联邦会日臻完善。我们取得的成就为我们将来能够取得的以及必须取得的成就增添了希望。



这次大选创造了多项“第一”,也诞生了很多将世代流传的故事。但是今天晚上令我难忘的却是在亚特兰大投票的一名妇女:安•尼克松•库波尔(Ann Nixon Cooper)。她和其他数百万排队等待投票的选民没有什么差别,除了一点:她已是106岁的高龄。


她出生的那个时代奴隶制度刚刚结束;那时路上没有汽车,天上也没有飞机;当时像她这样的人由于两个原因不能投票--一是她是女性,另一个原因是她的肤色。

今天晚上,我想到了她在美国过去一百年间所经历的种种:心痛和希望;挣扎和进步;那些我们被告知我们办不到的世代,以及那些坚信美国信条──是的,我们能做到──的人们。

曾几何时,妇女没有发言权,她们的希望化作泡影,但是安•尼克松•库波尔活了下来,看到妇女们站了起来,看到她们大声发表自己的见解,看到她们去参加大选投票。是的,我们能做到。

当30年代的沙尘暴和大萧条引发人们的绝望之情时,她看到一个国家用罗斯福新政、新就业机会以及对新目标的共同追求战胜恐慌。是的,我们能做到。

当炸弹袭击了我们的海港、独裁专制威胁到全世界,她见证了美国一代人的伟大崛起,见证了一个民主国家被拯救。是的,我们能做到。

她看到蒙哥马利通了公共汽车、伯明翰接上了水管、塞尔马建了桥,一位来自亚特兰大的传教士告诉人们:我们能成功。是的,我们能做到。

人类登上月球、柏林墙倒下,世界因我们的科学和想像被连接在一起。今年,就在这次选举中,她用手指触碰屏幕投下自己的选票,因为在美国生活了106年之后,经历了最好的时光和最黑暗的时刻之后,她知道美国如何能够发生变革。是的,我们能做到。

美国,我们已经走过漫漫长路。我们已经历了很多。但是我们仍有很多事情要做。因此今夜,让我们自问--如果我们的孩子能够活到下个世纪;如果我们的女儿有幸活得和安一样长,他们将会看到怎样的改变?我们将会取得怎样的进步?

现 在是我们回答这个问题的机会。这是我们的时刻。这是我们的时代--让我们的人民重新就业,为我们的后代敞开机会的大门;恢复繁荣发展,推进和平事业;让 “美国梦”重新焕发光芒,再次证明这样一个基本的真理:我们是一家人;一息尚存,我们就有希望;当我们遇到嘲讽和怀疑,当有人说我们办不到的时候,我们要 以这个永恒的信条来回应他们:

是的,我们能做到。感谢你们。上帝保佑你们。愿上帝保佑美利坚合众国。

Barack Obama

2008年11月9日星期日

揭秘“重复内容处罚”

转载自谷歌中文网站管理员博客
发表者:Susan Moskwa, 网站管理员趋势研究员

原文:Demystifying the“duplicate content penalty”
发表于:2008 年 9 月 12 日星期五,上午 8: 30

重复内容始终是一个经常被谈论的话题。我们不断地发表关于这方面文章,人们也在不断地提出问题。特别是,我还听到有很多网站管理员担心自己受到了“重复内容处罚”。

在这里请允许我们把这个问题一次性跟大家讲清楚:根本不存在所谓的“重复内容处罚”。至少,也不是大多数人谈论时所认为的那样。

有一些处罚是和抄袭其他网站的内容有关的,比如完全抄袭并且发布其他网站的内容,或者在完全没有提供任何其他附加价值的情况下发布这些抄袭的内容。这些都是我们不提倡的做法,您可以在网站管理员指南里找到有关此问题的清晰的论述:

* 请不要创建含有大量重复内容的多个页面、子域或者域。
* 请避免使用那种“一个模子印出来”(cookie cutter)的方式创建网站,比如没有或者很少原创内容的联属计划。
* 如果您的网站参与联属计划,请确保您的网站可提供附加价值。提供独特且相关的内容,使用户首先有理由访问您的网站。

(请注意,我们不希望您从其他网站那里抄袭内容,但是如果其他人抄袭了您的网站就是另外一回事了;如果您担心别人抄袭了您的网站,请您参考这篇文章)。

但 是我听到的一些担心重复性内容的网站管理员所谈论的并不是抄袭或者域名农场(domain farms);他们讨论的是诸如在同一个域上有多个网址指向相同的内容。比如,www.example.com/skates.asp?color= black&brand=riedell
和www.example.com/skates.asp?brand=riedell&color=black。这种类型的重复性内容可能会对您网站在搜索结果中的表现有潜在的影响,但是它不会使您的网站受到惩罚。下面这段文字来自我们关于重复内容的帮助文章:

除非重复内容看起来意在欺骗用户并操纵搜索引擎结果,否则,我们不会对有重复内容的网站采取特别措施。如果您的网站存在重复内容问题,而您又未遵循上述建议,我们会自行以恰当的方式选择在搜索结果中显示的内容版本。

这种非恶意的重复是比较常见的,特别是很多内容管理系统(CMS)缺省条件下对此处理的并不是很好。因此,当人们谈到此种类型的重复性内容会影响您的网站时,并不是因为您可能会因此受到处罚,而仅仅是由于网站和搜索引擎的工作方式所造成的。

大多数搜索引擎都力求保持一定程度的多样性:他们想在搜索结果页上向您展示十个不同的搜索结果,而不是含有相同内容的十个不同的网址。为此,谷歌试着去掉重复的内容从而使用户较少看到这些多余的重复性的内容。您可以在这篇博客里了解更多的细节,其中谈到

1. 当我们探测重复内容时,比如由网址参数造成的衍生网址,我们会将这些相似的网址放在同一组里。
2. 我们会选择我们认为最能代表这一组的网址在搜索结果里进行展示。
3. 我们还会对这一组网址的特性进行相应的整理,像链接的受欢迎程度,并将其合并到此代表性网址上。

作为网站管理员,上述过程可能会影响到您的是:

* 在步骤二中,谷歌所认为最具有代表性的网址并不一定和您的想法一致。如果您想控制究竟是 www.example.com/skates.asp?color=black&brand=riedell 还是www.example.com/skates.asp?brand=riedell&color=black出现在我们的搜索结果中的话, 您或许想采取适当措施以减少您的重复内容。告诉我们哪一个是您比较喜欢的网址的有效方法之一就是将其列入您的网站地图(Sitemap) 里。
* 在步骤三中,如果我们无法探测出某一特定页面的所有重复性页面的话,我们在对其页面特性进行整合时就不可能包括所有这些重复性页面的特性。这可能会削弱这一特定内容的排名竞争力,因为他们被分散分配到了多个网址上。

在 大多数情况下,谷歌可以很好的处理此类重复内容。然而,对于那些不同域名上的重复性内容,您或许需要再考虑一下。尤其是,当您决定建立一个网站而它的目的 从本质上来讲就是内容抄袭和重复的话,如果您的商业模式又依赖于搜索引擎的流量,那么除非您可以给用户带来很多的附加价值,不然对于建立此类网站您还是要 三思而后行。举个例子,我们有时听到来自 Amazon.com 的联盟网站说他们网站上那些完全由 Amazon 提供的内容很难有好的排名。这难道是因为谷歌想阻止他们卖《Everyone Poops》 这本书吗?不;这是因为如果他们的网站提供完全一样的内容的话,他们怎么可能会比 Amazon 的排名更好呢?对于在线购物来讲,Amazon 在很多方面具有权威性(对于一个典型的 Amazon 联盟网站来说更是如此),一般的谷歌搜索用户可能想看到的是 Amazon 上的原始信息,除非这个联盟网站提供了相当数量的、额外的附加值给用户。

最 后,想一下重复内容给您网站带宽带来的影响吧。重复内容会造成抓取效率低下:当 Googlebot 在您的网站上发现了十个网址,在它知道这些网址含有完全相同的内容之前(如上所述,也就是在我们能够对他们进行归类之前),它必须对这十个网址逐一进行抓 取。Googlebot 耗费在抓取重复性内容上的时间和资源越多,它用来抓取其他内容的时间也就相对变少了。

总而言之,网站上的重复性内容会以多种方式影响您的网站。但是除非您是恶意抄袭造成内容重复,否则这些方式不会构成对您网站的处罚。这也意味着:

* 当您清除了无恶意的重复性内容时,您无须提交重新收录的请求。
* 如果您是一个介于初级到中级经验值之间的网络管理员,您可能不需花费过多精力来担心重复性内容,因为大多数搜索引擎都有方法来处理它。
* 通过澄清和杜绝关于重复性内容处罚的杜撰之说,您可以帮到您的网站管理员同行们!解决重复性内容的方法完全在您的掌控之中,这里有几篇较好的文章您可以参考

2008年11月8日星期六

网页栅格系统研究(3):粒度问题

研究(2)中讨论了栅格系统的基础知识。这一篇将集中探讨栅格系统的粒度问题。(注:如非特别指明,栅格系统均指24列960栅格系统) 淘宝的首页目前尚未严格遵守栅格系统,如果重构的话,宽度方向可以考虑采用下面的栅格布局(只考虑页面主体部分,忽略高度的比例):

(图1)

纷乱的高度世界

我们来看下图1左上角。左上角部分目前的宽度为256px, 重构的话可以将宽度缩小到230px以符合栅格(不可避免的要调整内容,比如人气宝贝中将只能放下3张图片)。来仔细看下高度方向:

(图2)
高度方向的布局是:90 : 117 : 100, 第一个间隔是8, 总高度为325. 很明显,高度方向没有任何栅格化的迹象。实际上,

即便是严格遵守栅格系统的Yahoo!首页,高度方向上也没有严格栅格化。

这究竟是为何?

一切皆有可能

我们缩小关注点:

(图3)
上图中,图像的大小是70 x 70, 刚好是24列960栅格系统两列的宽度。对于右边的文字,采取了如下样式:
font-size: 12px;
line-height: 150%; /* 12 x 150% = 18px */

中文字体是宋体,line-height的计算值是18px. 注意图3中文字部分可视区域的高度为65, 上下各有4px和1px的间隙。为什么会产生这么奇怪的间隙呢?我们来看下图:

(图4)
从上图中我们可以得知,12px的宋体中文字,实际高度只有11px. line-height减去11多出来的高度,则“均匀”分布在上下间隙中(如果多出来的高度为偶数,则上下均分;为奇数时,上面比下面多1px)。这样,对于70px的高度来说,要布局4行文字时,假设行高多出来的上半部分为x, 下半部分为y, 在最理想的情况下,应该满足以下公式:

11 * 4 + 4 * x + 3 * y = 70

x = y 或 x = y + 1

不难推出,x最理想的整数解为4. 从而line-height为 4 + 11 + 3 = 18. 因此:

对于24列960栅格系统来说,如果要在高度方向上实现栅格,font-size为12px时,line-height的最佳取值是18px(150%).

追求完美点话,还可以将文字部分margin-top: -1px, 使得65上下的间隙为3和2.

至此,我们可以初步判断:

高度方向上是有可能严格栅格化的。一切皆有可能!

然而,现实总那么残酷


(图5)
上图中的标题高度为22, 这在24列960栅格系统中是无法对齐的。而且总高度为100, 在24列960栅格系统中也不存在(110才可以)。或许高度方向上我们可以细化行宽为20, 但依旧没法解决上面两个问题(22是明显不能解决的,而对于100px的高度,也无法通过细化行宽来解决。可选高度永远是10的奇数倍,如果进一步细化, 小于10后,会变得非常繁琐,没什么实际应用价值)

宽度世界里会好些吗


(图6)
上面是Yahoo!首页上的两个小模块,我都不想去标注模块里面的布局宽度了(因为一点都不符合24列960栅格系统)。宽度世界里,和高度世界一样充满希望但现实却残酷无比。

银弹是不存在的

栅格系统是美好的。但如果我们一味地追求将所有设计都栅格化(必须承认我曾有这个幻想),则立刻会陷入地狱一般的黑暗中。这篇文章中的艰难尝试(我 分析了20多个小模块),让我突然醒悟到一个粒度问题:任何设计都有适用范围,超出最佳适用范围,强行使用只会带来无尽的烦恼。对于栅格系统(这里指所有 栅格系统,包括多种栅格系统混合使用的情景)来说,我觉得以下场景非常适合:

  1. 页面的总体宽度布局,比如两栏、三栏等布局
  2. 一些固定区块的尺寸,比如广告图片的尺寸
  3. 区块之间的间距,可以参考栅格系统的槽宽(Gutter)
  4. 一些可以栅格化的小区域,比如图3中的例子,暗合栅格往往能简化布局上的考虑

除了上面这些应用场景,强行使用栅格系统,往往会束手束脚,适得其反。这篇文章的目的,就是尝试用最啰嗦最费神貌似很科学实际很无聊的分析来指出栅 格系统应用时的粒度问题。在粒度问题上达成一致后,下一篇中我们将讨论栅格系统的技术实现,最后一篇则讨论栅格系统的压轴好戏:模块化开发。

2008年11月6日星期四

网页栅格系统研究(2):蛋糕的切法

首先澄清一个应用场景问题。研究(1)中指出,对于结构复杂的网站,不少设计师们喜欢采用960固定宽度布局。但要注意的是,960并不是万能钥匙,大部分网站没有也不需要栅格系统。Amazon采用的是宽度自适应布局,最大限度的呈现信息。Google更是简简单单,主题部分就一个列表。eBay的页面非常简洁,商品页面宽度自适应,信息自然流畅,噪音少,购物很踏实。类似的站点还有很多,对于这些站点来说,宽度自适应布局更受青睐。

有个很有意思的网站是Yahoo!, 看起来是固定宽度布局,实际上在CSS中只要去掉一行,就能摇身一变自适应宽度了:

#page {
width: 70em;
}

为什么Yahoo!最后选择了定宽布局呢?这很可能是因为定宽布局比宽度自适应布局更容易控制。对于结构复杂的网站来说,可维护性和可扩展性非常重要。Yahoo!是以信息展示为主的门户型网站,960的宽度对于信息的阅读比较友善(Joe Clark写了一篇屏幕阅读时有关行长的有趣文章)。种种因素使得Yahoo!最后采用了定宽布局(Tommy Olsson总结了每种布局设计的优缺点)。

这里将只关注定宽布局,适用的场景是搭建复杂的门户型网站。对于宽度自适应布局和相应的栅格系统,暂不讨论(根据实现的技术手段不同,宽度自适应布局又分为流体布局和弹性布局。我个人蛮喜欢弹性布局,以后有时间再研究)。

好了,已经将范围缩小到定宽布局的网页栅格系统,那我们开始吧。

并不遥远的750

还记得800×600的显示器不?虽然才时隔几年,感觉却好像是上个世纪的事了。Mark Boulton做了最早的探索

将750分割成均等的6份,这就形成了栅格系统,稍加组合划分就形成了两栏布局和三栏布局。Mark Boulton还研究了Gutter(垂直栏之间的间隙)对栅格的影响,有兴趣的可以阅读原文,或者跟着我往下看吧,下面将详细阐述。

几个术语和一个公式

一个标准的栅格系统,包括以下部分:

将Flowline的总宽度标记为W, Column的宽度标记为c, Gutter宽度标记为g, Margin的宽度标记为m, Column的个数标记为N, 我们可以得到以下公式:
W = c * N + g * (N - 1) + 2 * m

一般来说,Gutter的宽度是Margin的两倍,上面的公式可以简化为:

W = c * N + g * (N - 1) + g = (c + g) * N

将c+g标记为C, 公式变得非常简单:

W = C * N

上面的公式就是栅格系统的基础,很简单吧。

950的来历

具体应用时,Margin其实是一个空白边,从视觉上看并不属于总宽度。不少栅格设计里习惯性地设定Gutter为10px, 这样Margin就是5px. 当W为960,分割成6列时,栅格如下图:

上图的处理是左右Margin各为5px. 也可以将Margin集中放在一边,比如右边:



无论Margin放在何处(这只影响技术实现,不影响设计),我们真正要关注的是去除Margin之后的部分:

这就是我们要真正关注的950!将W的含义变为去除Margin的总宽度,公式变化为:
W = N * C - g

将上面的公式实例化一下:

950 = 12 * 80 - 10
950 = 16 * 60 - 10
950 = 24 * 40 - 10

这就形成了960蛋糕的三种常见切法。

12 x 80

16 x 60

24 x 40

上面三种切法,N越大,灵活度越高。可以根据网页的实际复杂度来选用对应的切法。在960 Grid System首页中,展示了12 x 80的应用:

我们来看下 研究(1)中开头列举的网站的栅格应用情况。

Yahoo!是很标准的 24 x 40 栅格:

淘宝网目前只有商城上部分使用了栅格系统(大的两栏布局遵守了 24 x 40 的栅格化,主体部分使用的另一套740的栅格划分):

网易很不错,采用的是 16 x 60 的栅格系统:

研究(1)中的其它站点都没有真正严格地采用栅格系统。

栅格系统的优势

上面的“发现”是让人有点沮丧的。目前严格采用栅格系统的站点非常少,为什么我们还要努力的让网页栅格化呢?

栅格系统具有以下优势:

  1. 能大大提高网页的规范性。在栅格系统下,页面中所有组件的尺寸都是有规律的。这对于大型网站的开发和维护来说,能节约不少成本。
  2. 基于栅格进行设计,可以让整个网站各个页面的布局保持一致。这能增加页面的相似度,提升用户体验。
  3. 对于设计师们来说,灵活地运用栅格系统,能做出很多优秀和独特的设计。(详见《超越CSS》一书)

对于大型网站来说,我相信栅格化将是一种潮流和趋势。

下面讨论栅格系统中的黄金分割。

黄金分割

黄金分割可以归结为数学问题:对于长度为1的线段,将其分成两部分 x 和 1 - x, 使得:

x / 1 = (1 - x) / x

化为简单的二次方程:

x^2 + x - 1 = 0

正数解为:

x = (sqrt(5) - 1) / 2 ~= 0.618

这就是黄金分割。这个比例不仅仅出现在诸如绘画、雕塑、音乐、建筑等艺术领域,在管理、工程设计等方面也有着不可忽视的作用。 (这是个自然界的魔数,类似的还有真空光速、普朗克常数、精细结构等等,感兴趣的Google吧)

在平面设计领域,黄金分割点被广泛采用。比如下面这种图:

数一数上面有多少黄金分割? 对于960栅格,实际宽度是950. 两栏布局时,黄金分割为:

对于 24 x 40 的情景,最接近黄金分割的两栏布局是 350 : 590, 栏数比例为 9 : 15. 但实际使用时,因为窄栏经常用来做导航或放辅助信息,并不需要350px这么宽。因此实际情况下经常被采用的布局是:

上面讲的都是宽度方向上的栅格化,下面我们看看高度方向上如何应用。

高度方向上的栅格

还记得研究(1)中那张红红的很刺眼的图吗?注意高度值560也是很神奇的。

N(560) = N(2^4 * 5 * 7) = 18

560 / 960 ~= 0.583
N(560)比较大,同时可以让高宽比接近黄金分割。针对560, 我们采用 14 x 40 栅格:

这样,我们就在宽度和高度两个方向上都实现了栅格化。

下一篇将详细阐述960栅格系统的模块化应用。

网页栅格系统研究(1):960的秘密

研究网页栅格系统前,来看一组数据:

网站 首页页面宽度 px
Yahoo! 950
淘宝 950
MySpace 960
新浪 950
网易 960
Live Search 958
搜狐 950
优酷 960
AOL 960

上面列举的都是Alexa全球排名前100的站点,它们的首页宽度为950px/960px. 除了微软的Live Search, 这些站点有个共同特点:页面结构较复杂,都可以认为是门户型网站。

再来看看Google, YouTube, Facebook, Flickr!, eBay等知名站点,它们的首页宽度没什么固定规律,共同的特点是:功能专一,页面结构相对简单。

根据上面的简单分析可以认为:当搭建页面结构复杂的门户型网站时,开发工程师们不约而同地都选择将页面宽度定为950px/960px.

这是一件很有趣的事情,为什么要选择这个宽度呢?这个宽度值究竟有什么魔力

神奇的960

设计师们对苹果情有独衷。在 1024 x 768 的分辨率下,打开Firefox:


自然状态下,Firefox窗体的大小约为 974 x 650. 减掉左右两边7px的边框,网页的实际大小为上图中的红色部分,高宽为 960 x 650.

有趣的960就这样出现了。是的,可以认为一切就这么简单。栅格系统最早出现在平面设计领域,设计师们爱用苹果,苹果下浏览器的默认宽度为960px, 于是960就这么“自然”地出现了。

数字背后的奥妙

上面的“自然”出现,细究自然是不让人信服的。苹果系统的设计者们在没有喝醉酒的情况下选择了960,而不是其它什么1000之类的整数,自然另有奥妙。

科学界有很多问题都可以归结到数学问题上,我们也从数学着手:

960可以分解为2的6次方乘以3和5, 这使得960可以分割成以下宽度的整数倍:

2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 20, 24, 30, 32, 40,
48, 60, 64, 80, 96, 120, 160, 192, 240, 320, 480

共26种(26 = 7 * 2 * 2 - 2, 减去2是去掉1和960自身),我们标记为:

N(960) = N(2^6 * 3 * 5) = 26

根据上面的算法,可以得到:

N(360) = N(2^3 * 3^2 * 5) = 22
N(480) = N(2^5 * 3 * 5) = 22
N(720) = N(2^4 * 3^2 * 5) = 28
N(750) = N(2 * 3 * 5^3) = 14
N(800) = N(2^5 * 5^2) = 16
N(960) = N(2^6 * 3 * 5) = 26
N(1000) = N(2^3 * 5^3) = 14
N(1024) = N(2^10) = 9
N(1440) = N(2^6 * 3^2 * 5) = 40
N(1920) = N(2^7 * 3 * 5) = 30

根据直觉(严格证明也不难,不过还是留给数学系的学生去证明吧),我们得到一个有趣的结论:

要使得N(width)最大,width的取值有两个系列:
A系列: …, 320, 720, 1440, …
B系列: …, 480, 960, 1920, …

N越大,可组合的宽度值就越多。对栅格系统来说,这意味着越灵活!

目前绝大多数显示器都支持 1024 x 768 及其以上分辨率。为了有效的利用屏幕宽度同时保证栅格的灵活度,可以看出960是非常合适的。这样,在目前主流显示器下,960就成为网页栅格系统中的最佳宽度了。(也许不久的将来,将会流行1440)

细心的你也许会记得,本文开头列举的宽度值中,950也出现了好几次。950是怎么来的?和960是啥关系?这些疑问,请关注本系列的下一篇文章。

2008年11月5日星期三

QQ游戏百万人同时在线服务器架构实现

QQ游戏于前几日终于突破了百万人同时在线的关口,向着更为远大的目标迈进,这让其它众多传统的棋牌休闲游戏平台黯然失色,相比之下,联众似乎已经根本不是QQ的对手,因为QQ除了这100万的游戏在线人数外,它还拥有3亿多的注册量(当然很多是重复注册的)以及QQ聊天软件900万的同时在线率,我们已经可以预见未来由QQ构建起来的强大棋牌休闲游戏帝国。


  那么,在技术上,QQ游戏到底是如何实现百万人同时在线并保持游戏高效率的呢?
  事实上,针对于任何单一的网络服务器程序,其可承受的同时连接数目是有理论峰值的,通过C++中对TSocket的定义类型:word,我们可以判定这个连接理论峰值是65535,也就是说,你的单个服务器程序,最多可以承受6万多的用户同时连接。但是,在实际应用中,能达到一万人的同时连接并能保证正常的数据交换已经是很不容易了,通常这个值都在2000到5000之间,据说QQ的单台服务器同时连接数目也就是在这个值这间。
  如果要实现2000到5000用户的单服务器同时在线,是不难的。在windows下,比较成熟的技术是采用IOCP--完成端口。与完成端口相关的资料在网上和CSDN论坛里有很多,感兴趣的朋友可以自己搜索一下。只要运用得当,一个完成端口服务器是完全可以达到2K到 5K的同时在线量的。但,5K这样的数值离百万这样的数值实在相差太大了,所以,百万人的同时在线是单台服务器肯定无法实现的。
  要实现百万人同时在线,首先要实现一个比较完善的完成端口服务器模型,这个模型要求至少可以承载2K到5K的同时在线率(当然,如果你MONEY多,你也可以只开发出最多允许100人在线的服务器)。在构建好了基本的完成端口服务器之后,就是有关服务器组的架构设计了。之所以说这是一个服务器组,是因为它绝不仅仅只是一台服务器,也绝不仅仅是只有一种类型的服务器。
  简单地说,实现百万人同时在线的服务器模型应该是:登陆服务器+大厅服务器+房间服务器。当然,也可以是其它的模型,但其基本的思想是一样的。下面,我将逐一介绍这三类服务器的各自作用。
  登陆服务器:一般情况下,我们会向玩家开放若干个公开的登陆服务器,就如QQ登陆时让你选择的从哪个QQ游戏服务器登陆一样,QQ登陆时让玩家选择的六个服务器入口实际上就是登陆服务器。登陆服务器主要完成负载平衡的作用。详细点说就是,在登陆服务器的背后,有N个大厅服务器,登陆服务器只是用于为当前的客户端连接选择其下一步应该连接到哪个大厅服务器,当登陆服务器为当前的客户端连接选择了一个合适的大厅服务器后,客户端开始根据登陆服务器提供的信息连接到相应的大厅上去,同时客户端断开与登陆服务器的连接,为其他玩家客户端连接登陆服务器腾出套接字资源。在设计登陆服务器时,至少应该有以下功能:N 个大厅服务器的每一个大厅服务器都要与所有的登陆服务器保持连接,并实时地把本大厅服务器当前的同时在线人数通知给各个登陆服务器,这其中包括:用户进入时的同时在线人数增加信息以及用户退出时的同时在线人数减少信息。这里的各个大厅服务器同时在线人数信息就是登陆服务器为客户端选择某个大厅让其登陆的依据。举例来说,玩家A通过登陆服务器1连接到登陆服务器,登陆服务器开始为当前玩家在众多的大厅服务器中根据哪一个大厅服务器人数比较少来选择一个大厅,同时把这个大厅的连接IP和端口发给客户端,客户端收到这个IP和端口信息后,根据这个信息连接到此大厅,同时,客户端断开与登陆服务器之间的连接,这便是用户登陆过程中,在登陆服务器这一块的处理流程。
  大厅服务器:大厅服务器,是普通玩家看不到的服务器,它的连接IP和端口信息是登陆服务器通知给客户端的。也就是说,在QQ游戏的本地文件中,具体的大厅服务器连接IP和端口信息是没有保存的。大厅服务器的主要作用是向玩家发送游戏房间列表信息,这些信息包括:每个游戏房间的类型,名称,在线人数,连接地址以及其它如游戏帮助文件URL的信息。从界面上看的话,大厅服务器就是我们输入用户名和密码并校验通过后进入的游戏房间列表界面。大厅服务器,主要有以下功能:一是向当前玩家广播各个游戏房间在线人数信息;二是提供游戏的版本以及下载地址信息;三是提供各个游戏房间服务器的连接IP和端口信息;四是提供游戏帮助的URL信息;五是提供其它游戏辅助功能。但在这众多的功能中,有一点是最为核心的,即:为玩家提供进入具体的游戏房间的通道,让玩家顺利进入其欲进入的游戏房间。玩家根据各个游戏房间在线人数,判定自己进入哪一个房间,然后双击服务器列表中的某个游戏房间后玩家开始进入游戏房间服务器。
  游戏房间服务器:游戏房间服务器,具体地说就是如“斗地主1”,“斗地主2”这样的游戏房间。游戏房间服务器才是具体的负责执行游戏相关逻辑的服务器。这样的游戏逻辑分为两大类:一类是通用的游戏房间逻辑,如:进入房间,离开房间,进入桌子,离开桌子以及在房间内说话等;第二类是游戏桌子逻辑,这个就是各种不同类型游戏的主要区别之处了,比如斗地主中的叫地主或不叫地主的逻辑等,当然,游戏桌子逻辑里也包括有通用的各个游戏里都存在的游戏逻辑,比如在桌子内说话等。总之,游戏房间服务器才是真正负责执行游戏具体逻辑的服务器。
  这里提到的三类服务器,我均采用的是完成端口模型,每个服务器最多连接数目是5000人,但是,我在游戏房间服务器上作了逻辑层的限定,最多只允许300 人同时在线。其他两个服务器仍然允许最多5000人的同时在线。如果按照这样的结构来设计,那么要实现百万人的同时在线就应该是这样:首先是大厅, 1000000/5000=200。也就是说,至少要200台大厅服务器,但通常情况下,考虑到实际使用时服务器的处理能力和负载情况,应该至少准备 250台左右的大厅服务器程序。另外,具体的各种类型的游戏房间服务器需要多少,就要根据当前玩各种类型游戏的玩家数目分别计算了,比如斗地主最多是十万人同时在线,每台服务器最多允许300人同时在线,那么需要的斗地主服务器数目就应该不少于:100000/300=333,准备得充分一点,就要准备 350台斗地主服务器。
  除正常的玩家连接外,还要考虑到:
  对于登陆服务器,会有250台大厅服务器连接到每个登陆服务器上,这是始终都要保持的连接;
  而对于大厅服务器而言,如果仅仅有斗地主这一类的服务器,就要有350多个连接与各个大厅服务器始终保持着。所以从这一点看,我的结构在某些方面还存在着需要改进的地方,但核心思想是:尽快地提供用户登陆的速度,尽可能方便地让玩家进入游戏中。

服务器网页缓存的深入分析

Expires、Cache-Control、Last-Modified、ETag是RFC 2616(HTTP/1.1)协议中和网页缓存相关的几个字段。前两个用来控制缓存的失效日期,后两个用来验证网页的有效性。要注意的是, HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。我们这里以Apache2.0服务器为例,只讨论HTTP/1.1协议。
Expires
Expires字段声明了一个网页或URL地址不再被浏览器缓存的时间,一旦超过了这个时间,浏览器都应该联系原始服务器。RFC告诉我们:“由于推断的失效时间也许会降低语义透明度,应该被谨慎使用,同时我们鼓励原始服务器尽可能提供确切的失效时间。”
对于一般的纯静态页面,如html、gif、jpg、css、js,默认安装的Apache服务器,不会在响应头添加这个字段。Firefox浏览器接受到相应后,如果发现没有Expires字段,浏览器根据文件的类型和“Last-Modified”字段来推断出一个合适的失效时间,并存储在客户端。推测出的时间一般是接受到响应时间后的三天左右。
Apache的expires_module模块可以在Http响应头部自动加上Expires字段。在Apache的httpd.conf文件中进行如下配置:
#启用expires_module模块
LoadModule expires_module modules/mod_expires.so
# 启用有效期控制
ExpiresActive On
# GIF有效期为1个月
ExpiresByType image/gif A2592000
# HTML文档的有效期是最后修改时刻后的一星期
ExpiresByType text/html M604800
#以下的含义类似
ExpiresByType text/css “now plus 2 month”
ExpiresByType text/js “now plus 2 day”
ExpiresByType image/jpeg “access plus 2 month”
ExpiresByType image/bmp “access plus 2 month”
ExpiresByType image/x-icon “access plus 2 month”
ExpiresByType image/png “access plus 2 month”
对于动态页面,如果在页面内部没有通过函数强制加上Expires,例如header(”Expires: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服务器会把Wed, 11 Jan 1984 05:00:00 GMT作为Expires字段内容,返回给浏览器。即认为动态页面总是失效的。而浏览器仍然会保存已经失效的动态页面。
可以发现Firefox浏览器总是缓存所有页面,不管失效、不失效还是没有声明失效时间。即使缓存中声明了一个网页的实效日期是 1970-01- 01 08:00:00,浏览器仍然会发送该文件在缓存中的Last-Modified和ETag字段。如果在服务器端验证通过,返回304状态,浏览器就还会使用此缓存。
Cache-Control
Cache-Control字段中可以声明多些元素,例如no-cache, must-revalidate, max-age=0等。这些元素用来指明页面被缓存最大时限,如何被缓存的,如何被转换到另一个不同的媒介,以及如何被存放在持久媒介中的。但是任何一个 Cache-Control指令都不能保证隐私性或者数据的安全性。“private”和“no-store”指令可以为隐私性和安全性方面提供一些帮助,但是他们并不能用于替代身
份验证和加密。
Apache的mod_cern_meta模块允许文件级Http响应头部的控制,同时它也可以配置Cache-Control头(或任何其他头)。响应头文件是放在原始目录的子目录中,根据原始文件名所命名的一个文件。具体用法请参阅Apache的官方网站。其中Cache-Control : max-age表示失效日期。如果没有启动mod_cern_meta模块,Apache服务器会把Expires字段中的日期换算成以秒为单位的一个 delta值,赋值给max-age。如果启动mod_cern_meta模块,并且配置了max-age值,Apache会将这个覆盖Expires字段。同时,max-age隐含了Canche-Control: public。这样浏览器接受到的Cache-Control : max-age和Expires值就是一致的。
如果失效日期Cache-Control : max-ag=0或者是负值,浏览器会在对应的缓存中把Expires设置为1970-01-01 08:00:00。
Last-Modified
Last-Modified和ETag是条件请求(Conditional Request)相关的两个字段。如果一个缓存收到了针对一个页面的请求,它发送一个验证请求询问服务器页面是否已经更改,在HTTP头里面带上” ETag”和”If Modify Since”头。服务器根据这些信息判断是否有更新信息,如果没有,就返回HTTP 304(NotModify);如果有更新,返回HTTP 200和更新的页面内容,并且携带新的”ETag”和”LastModified”。
使用这个机制,能够避免重复发送文件给浏览器,不过仍然会产生一个HTTP请求。
一般纯静态页面本身都会有Last-Modified信息,Apache服务器会读取页面文件中的Last-Modified信息,并添加到http响应头部。
对于动态页面,如果在页面内部没有通过函数强制加上Last-Modified,例如header(”Last-Modified: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服务器会把当前时间作为Last-Modified,返回给浏览器。
无论是纯静态页面还是动态页面,Firefox浏览器巧妙地按照接受到服务器响应的时间设置缓存页面的Last-Modified,而不是按照http响应头部中的Last-Modified字段。
ETag
既然有了Last-Modified,为什么还要用ETag字段呢?因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确。因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。
Apache服务器默认情况下,会对所有的静态、动态文件的响应头添加ETag字段。在Apache的httpd.conf文件中可以通过FileETag指令配置该选项。
FileETag指令配置了当文档是基于一个文件时用以创建 Etag(entity tag)响应头的文件的属性。在Apache 1.3.22及以前,ETag的值是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。如果一个目录的配置包含了‘FileETag INode MTime Size’而其一个子目录包含了‘FileETag -INode’那么这个子目录的设置(并会被其下任何没有进行覆盖的子目录继承)将等价于‘FileETag MTime Size’。
在多台负载平衡的服务器环境下,同一个文件会有不同的etag或者文件修改日期,浏览器每次都会重新下载。设置‘FileETag None’可以使响应头不再包含ETag字段。

三种典型web服务器Header设置内容过期方法
一、Internet 信息服务 (IIS)的内容过期设置
如果IIS 网站中有时间敏感信息,可以配置设置来保证过期信息不被代理服务器或 Web 浏览器缓存。可以配置网站内容,使之在任
何的时间自动过期。当启用内容过期时,Web 浏览器将比较当前日期和截止日期,以便决定是显示缓存页还是从服务器请求更新的页
。Microsoft ASP.NET 这样的服务器端技术可用于动态更改提供的内容。通常,时间敏感信息只限于单个文件、目录或网站;不过,您也可以为某台计算机上的所有网站设置内容过期。
必须是本地计算机上 Administrators 组的成员或者必须被委派了相应的权限,才能执行下列步骤。作为安全性的最佳操作,请使用不属于 Administrators 组的帐户登录计算机,然后使用运行方式命令以管理员身份运行 IIS管理器
在命令提示符下,键入 runas /user:administrative_accountname "mmc %systemroot%\system32\inetsrv\iis.msc"。
设置网站内容的过期时间
1. 在 IIS 管理器中,展开本地计算机;右键单击要设置内容过期的网站、虚拟目录或文件,然后单击“属性”。
2. 单击“HTTP 头”选项卡。
3. 选中“启用内容过期”复选框。
4. 单击“立即过期”、“此时间段后过期”或“过期时间”,然后在对应的框中输入所需的过期信息。
5. 单击“确定”。

二、APACHE服务的内容过期设置
Apache配置摘录及解释
i. 过期相关设置
LoadModule headers_module modules/mod_headers.so
#Load 修改header的模块。
LoadModule expires_module modules/mod_expires.so
#Load 设定过期header的模块。
Header append Via: CCN-BJ-4-502
#增加一个Via header,值配置成设备的hostname。
KeepAliveTimeout 60
#设置连接的保持时间为60秒。
ExpiresActive On
#启用过期header功能。
ExpiresDefault A604800
#缺省过期时间为“访问后的604800秒”


Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
ExpiresByType text/html A300
#text/html类型文件的过期设置为“访问后的300秒”
ExpiresByType text/css A259200
#text/css类型文件的过期设置为“访问后的259200秒”
ExpiresByType application/x-javascript A300
# application/x-javascript类型文件的过期设置为“访问后的300秒”
ExpiresByType image/gif A2592000
#image/gif类型文件的过期设置为“访问后的2592000秒”
ExpiresByType application/x-shockwave-flash A2592000
# application/x-shockwave-flash类型文件的过期设置为“访问后的2592000秒”

上述配置文件中load的两个模块:mod_headers.so 和mod_expires.so 可以让Apache具有对header的一些定制功能。
ExpiresByType: 表示按照文件类型-MIME-TYPE设定过期策略;
A300: 表示在Access后300秒后过期;
ExpiresByType text/css A2592000: 表示Mime type是text/css的文件,在Access后2592000秒过期。
ExpiresDefault A604800: 表示除了单独制定的文件类型等过期策略外的其他内容,按照这个缺省的策略设定:访问后604800秒过期。
上面的方法可以实现根据web发布的不同文件类型,针对不同的发布目录进行过期策略设置。在按照如上方法设置后,Apache会自动的产生两个相关的http header,举例如下:
HTTP/1.1 200 OK
Date: Tue, 27 Mar 2007 17:44:21 GMT
Server: Apache/2.0.54 (Unix)
Last-Modified: Thu, 25 Jan 2007 07:45:45 GMT
ETag: “72df3a-93-99499c40”
Accept-Ranges: bytes
Content-Length: 147
Cache-Control: max-age=2592000
Expires: Thu, 26 Apr 2007 17:44:21 GMT
Via: CCN-BJ-4-575
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: image/gif
Length: 147 [image/gif]
其中:Date + Max-age = Expires. Max-age是个时间长度,对应web server上面设置的过期时间;Expires是根据max-age算出来的过期时间点,两者是一致的,不同cache在判断内容是否过期时会严格比较系统时间和上述过期时间,或者比较age(在cache中存住的时间长度)和max-age的值。

三、lighttpd
lighttpd默认是没有开启expire模块的,需要我们在使用是手工开启这个模块支持。把mod_expire前面的“#”号去掉。
# vi /usr/local/lighttpd/etc/lighttpd.conf
"mod_expire",
设定过期时间
* 设定指定url的过期时间:
expire.url = (
"/images/" => "access 3 hours",
"/admin/" => "access 3 hours",
"/area/" => "access 3 hours",
"/calendar/" => "access 3 hours",
"/common/" => "access 3 hours",
"/front/" => "access 3 hours",
"/inc/" => "access 3 hours",
"/jeditor/" => "access 3 hours",
"/js/" => "access 3 hours",
"/script/" => "access 3 hours",
"/theme/" => "access 3 hours",
"/upload/" => "access 3 hours",
"/view/" => "access 3 hours",
"/help/" => "access 3 hours",
"/htm/" => "access 5 minutes"
)
设置Etag
在配置文件中增加,etag.use-inode="disable"(i节点不参与etag的运算),保证多台服务器生成的Etag值一致。