﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-CONAN ZONE-文章分类-web技术</title><link>http://www.blogjava.net/conans/category/45477.html</link><description>你越挣扎我就越兴奋</description><language>zh-cn</language><lastBuildDate>Sun, 27 Nov 2011 10:14:36 GMT</lastBuildDate><pubDate>Sun, 27 Nov 2011 10:14:36 GMT</pubDate><ttl>60</ttl><item><title>js获取网页高度</title><link>http://www.blogjava.net/conans/articles/364566.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Tue, 22 Nov 2011 07:01:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/364566.html</guid><description><![CDATA[<p>&lt;script&gt; <br />function getInfo() <br />{ <br />var s = ""; <br />s += " 网页可见区域宽："+ document.body.clientWidth; <br />s += " 网页可见区域高："+ document.body.clientHeight; <br />s += " 网页可见区域宽："+ document.body.offsetWidth + " (包括边线和滚动条的宽)"; <br />s += " 网页可见区域高："+ document.body.offsetHeight + " (包括边线的宽)"; <br />s += " 网页正文全文宽："+ document.body.scrollWidth; <br />s += " 网页正文全文高："+ document.body.scrollHeight; <br />s += " 网页被卷去的高(ff)："+ document.body.scrollTop; <br />s += " 网页被卷去的高(ie)："+ document.documentElement.scrollTop; <br />s += " 网页被卷去的左："+ document.body.scrollLeft; <br />s += " 网页正文部分上："+ window.screenTop; <br />s += " 网页正文部分左："+ window.screenLeft; <br />s += " 屏幕分辨率的高："+ window.screen.height; <br />s += " 屏幕分辨率的宽："+ window.screen.width; <br />s += " 屏幕可用工作区高度："+ window.screen.availHeight; <br />s += " 屏幕可用工作区宽度："+ window.screen.availWidth; <br />s += " 你的屏幕设置是 "+ window.screen.colorDepth +" 位彩色"; <br />s += " 你的屏幕设置 "+ window.screen.deviceXDPI +" 像素/英寸"; <br />//alert (s); <br />} <br />getInfo(); <br />&lt;/script&gt; <br />在我本地测试当中： <br />在IE、FireFox、Opera下都可以使用 <br />document.body.clientWidth <br />document.body.clientHeight <br />即可获得，很简单，很方便。 <br />而在公司项目当中： <br />Opera仍然使用 <br />document.body.clientWidth <br />document.body.clientHeight <br />可是IE和FireFox则使用 <br />document.documentElement.clientWidth <br />document.documentElement.clientHeight <br />原来是W3C的标准在作怪啊 <br />&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; <br />如果在页面中添加这行标记的话 <br /><br />在IE中： <br />document.body.clientWidth ==&gt; BODY对象宽度 <br />document.body.clientHeight ==&gt; BODY对象高度 <br />document.documentElement.clientWidth ==&gt; 可见区域宽度 <br />document.documentElement.clientHeight ==&gt; 可见区域高度 <br />在FireFox中： <br />document.body.clientWidth ==&gt; BODY对象宽度 <br />document.body.clientHeight ==&gt; BODY对象高度 <br />document.documentElement.clientWidth ==&gt; 可见区域宽度 <br />document.documentElement.clientHeight ==&gt; 可见区域高度 <br />? <br />在Opera中： <br />document.body.clientWidth ==&gt; 可见区域宽度 <br />document.body.clientHeight ==&gt; 可见区域高度 <br />document.documentElement.clientWidth ==&gt; 页面对象宽度（即BODY对象宽度加上Margin宽） <br />document.documentElement.clientHeight ==&gt; 页面对象高度（即BODY对象高度加上Margin高） <br />而如果没有定义W3C的标准，则 <br />IE为： <br />document.documentElement.clientWidth ==&gt; 0 <br />document.documentElement.clientHeight ==&gt; 0 <br />FireFox为： <br />document.documentElement.clientWidth ==&gt; 页面对象宽度（即BODY对象宽度加上Margin宽）document.documentElement.clientHeight ==&gt; 页面对象高度（即BODY对象高度加上Margin高） <br />Opera为： <br />document.documentElement.clientWidth ==&gt; 页面对象宽度（即BODY对象宽度加上Margin宽）document.documentElement.clientHeight ==&gt; 页面对象高度（即BODY对象高度加上Margin高） <br />真是一件麻烦事情，其实就开发来看，宁可少一些对象和方法，不使用最新的标准要方便许多啊。<br /><br /><br /><br />有时候需要取页面的底部, 就会用到document.body.clientHeight , 在HTML 标准中(这一句就能取到整个页面的高度, 不论body 的实际内容到底有多高, 例如, 1074*768 的分辨率, 页面最大化时, 这个高度约为720 , 即使页面上只有一句&#8221;hello world&#8221; , 也仍然取到720.</p>
<p>可是在XHTML中, 如果body 体中只有一行, 则document.body.clientHeight 只能取到那一行的高度, 约20px, 这时如何还想取到整个页面的高度, 就要用document.documentElement.clientHeight 来获取了.</p>
<p>原因是: 在HTML 中, body 是整个DOM 的根, 而在XHTML 中, document 才是根, body 不再是根, 所以取body 的属性时, 不能再取到整个页面的值.</p>
<p>区别新旧标准的行是:<br />&lt;!DOCTYPE HTML PUBLIC &#8220;-//W3C//DTD HTML 4.0 Transitional//EN&#8221; &gt;<br />&lt;!DOCTYPE html PUBLIC &#8220;-//W3C//DTD XHTML 1.0 Transitional//EN&#8221; &#8220;<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><span style="color: rgb(169,0,3)">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</span></a>&#8220;&gt;<br />前者指明该页面使用旧标准, 后者指明该页面使用新标准.</p>
<p>总结:<br />XHTML中用 document.documentElement.clientHeight 代替<br />document.body.clientHeight<br /><br /></p><img src ="http://www.blogjava.net/conans/aggbug/364566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2011-11-22 15:01 <a href="http://www.blogjava.net/conans/articles/364566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>主题：session的混乱与安全</title><link>http://www.blogjava.net/conans/articles/338674.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Mon, 22 Nov 2010 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/338674.html</guid><description><![CDATA[<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">[说明: 本文为&nbsp;<a style="font-size: 15px; background-color: transparent; vertical-align: baseline; text-decoration: none; padding: 0px; margin: 0px;" href="http://www.smithfox.com/?e=32"><span style="color: #000000;">http://www.smithfox.com/?e=32</span></a>&nbsp;原创, 转载请注明原文, 谢谢]</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">session的安全有两层意思:</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">1&gt; 对最终客户来说, 不会因为session的share和造成混乱, 使end-user的信息泄漏以及其他安全问题</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">2&gt; 对系统本身来说, 不会因为有hacker通过模拟sessionid和cookie来获取server信任进而进行恶意破坏</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">让我们逐层解释和展开问题:</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">1&gt; 首先说明, 本文所有session专指Servlet HttpSession</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">2&gt;
后台Session和Browser之间通过JSESSIONID来关联, JSESSIONID是Servlet标准,也是关键字,
Servle规定Browser用Mem Cookie来存储JSESSIONID, 注意并不是disk
cookie.一旦浏览器关闭后JSESSIONID就从PC消失, 更加安全.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">3&gt; Session也是一种很好的安全认证机制, 后台会标识session是不是已经被认证了, 如果是,就不会让用户再输入password. JSESSIONID可以被理解成为一个已经认证的key, 所以Session有安全问题.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">4&gt; Servlet容器不会构造相同的JSESSIONID, 客户端也很难预期JSESSIONID</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">5&gt;&nbsp;HTTPS SSL等技术可以防止网络传输中有人恶意篡改JSESSIONID</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">6&gt; 禁用Cookie的情况JSESSIONID就必须用URLRewrite. 我们可以通过对URL本身采用摘要算法，自认证来防止恶意篡改JSESSIONID.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">比如: &nbsp;http://www.smithfox.com/abc?x=x&amp;y=y&amp;JSESSIONID=sdfdfsdfsdfsdfsdf&amp;<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;"><strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">HWD=4FE23AD9892C</strong></span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;"><span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">HWD的值是对整个URL的一个摘要算法, 如果有人改动了URL，这个HWD值就对不上了, 前提应该是这个算法别人不知道的.</span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;"><span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">7&gt; 用户在自己的PC上肯定是可以看到当前的JSESSIONID的,&nbsp;就象就你在自己的日记中看到了自己备忘的password一样, 这个不是技术安全问题.</span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;"><span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">8&gt;
一台机器有多个自然人在使用， 出现的JSESSIONID欺骗， 应该没有技术办法可以解决.
只能是end-user自己小心，用完就关闭Browser. 我想这应该是在情理之中的事, 你是合租被盗应该是怪不得小区保安的,
也是需要自己平时提高防盗意识，呵呵.</span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;"><span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">9&gt;&nbsp;最近看到Tomcat7有个新的特性说是支持"防JSESSIONID劫持", 这个需要更多了解.</span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10&gt; User和Session的关系.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">Session是只认JSESSIONID不认人的, 包括自然人和系统Account. 这个问题比较搞.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">我们用EndUser来表示自然人， User-Account表示系统帐号， 我们分析以下几种情况</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10.1&gt; 两个EndUser共用一个UserAccount并且在同一台PC, 这个混乱不是技术问题， 大家都可以理解</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10.2&gt; 两个EndUser分别使用不同的UserAccount在同一台PC, 这个是合租情况， 造成混乱不一定是技术问题</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10.3&gt; 某EndUser有两个UserAccount在同一台PC上, 我们需要考虑JSESSIONID在client端可以会混乱的问题.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">因为不同的浏览器对于Cookie share的策略不同， 我们按程序设计必须按最容易出问题的Case想，比如IE8.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">无论你是IE多窗口还是多TAB都是Share Cookie的. 所以总的指导方针是在client端做一些机制不允许用户这么做.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">Google
的gmail就是这么做的, 你可以一台机器上用IE打开两个不同的gmail
account(两个窗口或是两个TAB都行)，点新email或是其他需要和后台交互的行为时，gmail会退出一个，提示让你重新login并且
gmail account已经固定为后输入的User-Account.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;"><strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">具体在Client怎么防止两个Account还需高手指点.</strong></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10.4&gt;&nbsp;某EndUser<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">A</strong>用自己的UserAccount<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">A</strong>先已经login，再访问另一个UserAccount<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">B</strong>的资源，而且该资源是需要访问密码的.&nbsp;</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">这种情况，往往因为后台Session设计的层次不清晰，造成了UserAccount<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">A</strong>无需Password就直接访问到了UserAccount<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">B</strong>的资源. 而且这个解决方案不能放在Client端， 因为访问UserAccountB的资源可能就是一个在Email中的Link，这个click动作客户端程序JavaScript是无法拦截的.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">10.5&gt; 总结来说: &nbsp;</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">11&gt; 从第10&gt;点可以看出， session和自然人或是UserAccount有着千丝万缕的联系，但不是所有的系统只有User这一层业务概念，所以我们需要理解后台的Session分划和设计好Session.Attribute层次.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">我
们以一个假设业务模型为例说明问题: 这是一个只面向企业的图片共享web服务, 可以为多个公司(企业)提供服务, 用户必须属于某一个公司,
用户可以创建"图片分组", 图片分组可以设置为private(需要密码访问), 也可以直接公开.&nbsp;图片分组是公司财产,
user可以创建"图片分组", 但是图片分组资源是归属公司,&nbsp;同一公司内部的所有user可以直接访问图片分组(如果是公开),
也可以通过password(如果需要)访问图片分组.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">这个业务模型中, 既有比User更高层的概念, 比如公司. 也有比User更底的概念, 比如用户的上传图片分组(imageGroup).</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">11.1&gt;&nbsp;不同的war包部署在tomcat,不同的war包之间的session是不会混乱的, 这个是由tomcat架构决定的. 另他的没有做过调查, 也有可能是Servlet标准,&nbsp;<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">有高手可以帮确认一下</strong>.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">11.2&gt; 多个公司又是运行在同一个tomcat application内, 怎么防止不同公司之间的session混乱</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">可以采用类似于防止重复提交的技术, 首先做一个优先级很高的filter, 每次reqeust和response都需要经过这个filter</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">在
所有login模块, 设置一个ticket cookie,写入当前company信息, 每个reqeust到达的第一步就是检测client
cookie和当前的URL信息, 以及session信息是否一致,
如果enduser是从一个company中click了一个其他company的link, 该filter就会发现ticket信息不一致,
然后就强制logout, 再次让user login. 并且每次response时做ticket的改动, 使client无法模拟</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">11.3&gt; 怎么防止imageGroup信息混乱</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">Session本身是一个集合, 具体还是使用session.attribute["key"]</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">Session本身是User level的,&nbsp;<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;"><strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">对于低于User level的信息, 需要好好规划attribute key</strong></span></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">想像这样的case:</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">有两个imageGroup, 一个是public的, 一个是需要password的,&nbsp;</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">http://www.smithfox.com/companyIBM/<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">public_images</strong>/</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">http://www.smithfox.com/companyIBM/<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">password_images</strong>/</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">后台对imageGroup输入密码逻辑的伪代码如下:</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">boolean needpasswd = true;<br />
if(session.getAttribute("NEED_PASSWORD") == null){<br />
<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">session.</span>setA<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">ttribute</span>(<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">"NEED_PASSWORD"</span>,&nbsp;needpasswd);<br />
boolean needpasswd = 一个很耗时很复杂的验证函数(user, imageGroup, xxx);<br />
} else{<br />
<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">needpasswd&nbsp;</span>=&nbsp;<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">session.get</span>A<span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">ttribute("NEED_PASSWORD");<br />
</span>}<br />
if (needpasswd ){<br />
showPasswordDialog()&nbsp;;<br />
}&nbsp;</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">看出什么问题没?</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">应该将上面的代码中的所有attribute key改成 "NEED_PASSWORD"+<strong style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;"><span style="font-size: 15px; background-color: transparent; vertical-align: baseline; padding: 0px; margin: 0px;">{imageGroupID}</span></strong></p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">否则用户只要先看了一个public后, 后面的所有图片分组都无需passwd就可以访问了, 即使这个imageGroup是private的.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">13&gt; 在用session之前一定需要检查是否真的一定需要session来解决, 比如只是想传value到JSP page，&nbsp;request.setAttribte()更适合</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">14&gt; 比较小而多的业务对象，如果必须save在session一定要及时removeAttribute否则session用的内存会暴涨.</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">因为Session不会因为客户端不用了，就会自动清理，而是必须到SessionTimeOut才会，如果在SessionTimeOut期间内有很多的对象在Session内，就会有问题。所以需要即时清理已经不用的Session.Attribute</p>
<p style="margin: 1em 0px 0px; font-size: 15px; background-color: transparent; vertical-align: baseline; line-height: 20px; text-align: justify; font-family: Arial,Helvetica,sans-serif; padding: 0px;">15&gt; Cookie和Session一样, 同样需要注意 cookie key的层次问题，以及过期问题，domain, path问题等等</p>
<img src ="http://www.blogjava.net/conans/aggbug/338674.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2010-11-22 11:24 <a href="http://www.blogjava.net/conans/articles/338674.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各大型网站架构分析收集</title><link>http://www.blogjava.net/conans/articles/325054.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Fri, 02 Jul 2010 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/325054.html</guid><description><![CDATA[form: http://blog.csdn.net/lovingprince/archive/2008/11/26/3379710.aspx<br />
<br />
1. PlentyOfFish 网站架构学习<br />
<a href="http://www.dbanotes.net/arch/plentyoffish_arch.html" target="_blank">http://www.dbanotes.net/arch/plentyoffish_arch.html</a><br />
<br />
采取 Windows 技术路线的 Web 2.0 站点并不多，除了 MySpace ，另外就是这个
PlentyOfFish。这个站点提供 &#8220;Online Dating&#8221;
服务。一个令人津津乐道的、惊人的数据是这个只有一个人(创建人Markus Frind）的站点价值 10 亿，估计要让很多人眼热，更何况
Markus Frind 每天只用两个小时打理网站&#8211;可操作性很强嘛。<br />
<br />
2. 从LiveJournal后台发展看 大型网站系统架构以及性能优化方法<br />
<a href="http://www.example.net.cn/archives/2006/03/olivejournaloio.html" target="_blank">http://www.example.net.cn/archives/2006/03/olivejournaloio.html</a><br />
<br />
LiveJournal是99年始于校园中的项目，几个人出于爱好做了这样一个应用，以实现以下功能：<br />
* 博客，论坛<br />
* 社会性网络，找到朋友<br />
* 聚合，把朋友的文章聚合在一起<br />
<br />
LiveJournal采用了大量的开源软件，甚至它本身也是一个开源软件。<br />
<br />
在上线后，LiveJournal实现了非常快速的增长：<br />
* 2004年4月份：280万注册用户。<br />
* 2005年4月份：680万注册用户。<br />
* 2005年8月份：790万注册用户。<br />
* 达到了每秒钟上千次的页面请求及处理。<br />
* 使用了大量MySQL服务器。<br />
* 使用了大量通用组件。<br />
<br />
3. YouTube 的架构扩展<br />
<a href="http://www.dbanotes.net/opensource/youtube_web_arch.html" target="_blank">http://www.dbanotes.net/opensource/youtube_web_arch.html</a><br />
<br />
在西雅图扩展性的技术研讨会上，YouTube 的 Cuong Do 做了关于 YouTube Scalability
的报告。视频内容在 Google Video 上有(地址)，可惜国内用户看不到。<br />
Kyle Cordes 对这个视频中的内容做了介绍。里面有不少技术性的内容。值得分享一下。(Kyle Cordes
的介绍是本文的主要来源)<br />
<br />
4. WikiPedia 技术架构学习分享<br />
<a href="http://www.dbanotes.net/opensource/wikipedia_arch.html" target="_blank">http://www.dbanotes.net/opensource/wikipedia_arch.html</a><br />
<br />
维基百科(WikiPedia.org)位列世界十大网站，目前排名第八位。这是开放的力量。<br />
<br />
来点直接的数据：<br />
<br />
* 峰值每秒钟3万个 HTTP 请求<br />
* 每秒钟 3Gbit 流量, 近乎375MB<br />
* 350 台 PC 服务器<br />
<br />
5. Tailrank 网站架构<br />
<a href="http://www.dbanotes.net/review/tailrank_arch.html" target="_blank">http://www.dbanotes.net/review/tailrank_arch.html</a><br />
<br />
每天数以千万计的 Blog 内容中，实时的热点是什么? Tailrank 这个 Web 2.0 Startup
致力于回答这个问题。<br />
<br />
专门爆料网站架构的 Todd Hoff 对 Kevin Burton 进行了采访。于是我们能了解一下 Tailrank
架构的一些信息。每小时索引 2400 万的 Blog 与 Feed，内容处理能力为 160-200Mbps，IO
写入大约在10-15MBps。每个月要处理 52T 之多的原始数据。Tailrank
所用的爬虫现在已经成为一个独立产品：spinn3r。<br />
<br />
6. LinkedIn 架构笔记<br />
<a href="http://www.dbanotes.net/arch/linkedin.html" target="_blank">http://www.dbanotes.net/arch/linkedin.html</a><br />
<br />
LinkedIn 雇员有 180 个，在 Web 2.0 公司中算是比较多的，不过人家自从 2006 年就盈利了，这在 Web 2.0
站点中可算少的。用户超过 1600 万，现在每月新增 100 万，50％ 会员来自海外(中国用户不少，也包括我).<br />
<br />
7. Yahoo！社区架构<br />
<a href="http://www.dbanotes.net/arch/yahoo_arch.html" target="_blank">http://www.dbanotes.net/arch/yahoo_arch.html</a><br />
<br />
旧金山举行的 QCon
会议带给我们很多新鲜的信息。虽然没机会参加，但是看看各个网站&#8221;晒架构&#8221;也是个比较过瘾的事情。请参观并收藏这个页面：Architectures
you&#8217;ve always wondered about。<br />
<br />
8. Craigslist 的数据库架构<br />
<a href="http://www.dbanotes.net/database/craigslist_database_arch.html" target="_blank">http://www.dbanotes.net/database/craigslist_database_arch.html</a><br />
<br />
Craigslist 绝对是互联网的一个传奇公司。根据以前的一则报道：<br />
<br />
每月超过 1000 万人使用该站服务，月浏览量超过 30 亿次，(Craigslist每月新增的帖子近 10
亿条??)网站的网页数量在以每年近百倍的速度增长。Craigslist 至今却只有 18 名员工(现在可能会多一些了)。<br />
<br />
9. Fotolog.com 的技术信息拾零<br />
<a href="http://www.dbanotes.net/review/fotolog_arch.html" target="_blank">http://www.dbanotes.net/review/fotolog_arch.html</a><br />
<br />
尽管是世界上最大的图片服务网站, Fotolog.com 在国内的名气并不是很响亮, 每当提到图片服务, 很多人第一个会想起
Flickr. 但实际上 Fotolog 也的确是很猛的, Alexa 上的排名一直在 Flickr 前面, 目前注册用户超过
1100 万. 而前不久也卖了一个好价钱, 9000 万美金. 算下来的话, 1 个注册用户大约 9 美金. Yupoo
的刘平阳可以偷着算算自己的网站如果卖给老外是怎样一个价格了.<br />
<br />
10. Digg 网站架构<br />
<a href="http://www.dbanotes.net/arch/digg_arch_cache_and_shard.html" target="_blank">http://www.dbanotes.net/arch/digg_arch_cache_and_shard.html</a><br />
<br />
Digg 工程师采用 LAMP (Linux, Apache, MySQL and PHP) 模式。这个 Alexa 排名在 100
左右的、自我估价 1.5 亿美金的站点目前有超过 100 台的 PC 服务器(足够少了)，可以粗略分成三个部分：数据库服务器，Web
服务器，搜索服务器。<br />
<br />
11. Amazon 的 Dynamo 架构<br />
<a href="http://www.dbanotes.net/techmemo/amazon_dynamo.html" target="_blank">http://www.dbanotes.net/techmemo/amazon_dynamo.html</a><br />
<br />
我在 DBAnotes.net 上记录过不少比较大的网站架构分析(eg: eBay [1], eBay [2]) ，Amazon
一直找不到太多的资料。国庆期间读到了一篇关于 Amazon Dynamo 的论文，非常精彩。Amazon Dynamo
这个高可用、可扩展存储体系支撑了Amazon 不少核心服务.<br />
<br />
12. 财帮子（caibangzi.com）网站架构<br />
<a href="http://www.dbanotes.net/arch/caibangzi_web_arch.html" target="_blank">http://www.dbanotes.net/arch/caibangzi_web_arch.html</a><br />
<br />
财帮子(caibangzi.com) 定位在&#8221;基金理财社区&#8221;。是国内访问量最大的基于 Ruby on rails 的 startup
项目。&#8220;理财&#8221;这个词据说是光大银行发明的，且不去管，不可否认的是，目前国内&#8221;理财&#8221;是个很有潜力的切入点。财帮子网站潜在用户群还是很大的。<br />
<br />
13. 了解一下 Technorati 的后台数据库架构<br />
<a href="http://www.dbanotes.net/web/technorati_db_arch.html" target="_blank">http://www.dbanotes.net/web/technorati_db_arch.html</a><br />
<br />
目前处理着大约 10Tb 核心数据, 分布在大约 20 台机器上.通过复制, 多增加了 100Tb 数据, 分布在 200 台机器上.
每天增长的数据 1TB. 通过 SOA 的运用, 物理与逻辑的访问相隔离,　似乎消除了数据库的瓶颈. 值得一提的是,
该扩展过程始终是利用普通的硬件与开源软件来完成的. 毕竟 , Web 2.0 站点都不是烧钱的主.
从数据量来看，这绝对是一个相对比较大的 Web 2.0 应用.<br />
<br />
14. 说说大型高并发高负载网站的系统架构<br />
<a href="http://www.toplee.com/blog/?p=71" target="_blank">http://www.toplee.com/blog/?p=71</a><br />
<br />
我在CERNET做过拨号接入平台的搭建，而后在Yahoo&amp;3721从事过搜索引擎前端开发，又在MOP处理过大型社区猫扑大杂烩的架构升级等
工作，同时自己接触和开发过不少大中型网站的模块，因此在大型网站应对高负载和并发的解决方案上有一些积累和经验，可以和大家一起探讨一下。<br />
<br />
15. 大型高负载网站架构 的感想<br />
<a href="http://atman.memoab.com/articles/194" target="_blank">http://atman.memoab.com/articles/194</a>
<img src ="http://www.blogjava.net/conans/aggbug/325054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2010-07-02 11:24 <a href="http://www.blogjava.net/conans/articles/325054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型网站架构演变和知识体系</title><link>http://www.blogjava.net/conans/articles/325053.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Fri, 02 Jul 2010 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/325053.html</guid><description><![CDATA[<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;"><span style="font-family: 宋体;">架构演变第一步：物理分离</span>webserver<span style="font-family: 宋体;">和数据库</span></span></span></strong></p>
<p><span style="font-family: 宋体;">最开始，由于某些想法，于是在互联网上搭建
了一个网站，这个时候甚至有可能主机都是租借的，但由于这篇文章我们只关注架构的演变历程，因此就假设这个时候</span>
<span style="font-family: 宋体;">已经是托管了一台主机，并且有一定的带宽了，这个时候由于网站具备了一定的特色，吸引了
部分人访问，逐渐你发现系统的压力越来越高，响应速度越来越慢，而这个时候比较明显的是数据库和应用互相影响，应用出问题了，数据库也很容易出现问题，而
数据库出问题的时候，应用也容易出问题，于是进入了第一步演变阶段：将应用和数据库从物理上分离，变成了两台机器，这个时候技术上没有什么新的要求，但你
发现确实起到效果了，系统又恢复到以前的响应速度了，并且支撑住了更高的流量，并且不会因为数据库和应用形成互相的影响。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/1.PNG" height="99" width="195" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">这一步架构演变对技术上的知识体系基本没有
要求。</span><span><br />
<br />
</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第二步：增加页面缓存</span></span></strong></p>
<p><span style="font-family: 宋体;">好景不长，随着访问的人越来越多，你发现响
应速度又开始变慢了，查找原因，发现是访问数据库的操作太多，导致数据连接竞争激烈，所以响应变慢，但数据库连</span>
<span style="font-family: 宋体;">接又不能开太多，否则数据库机器压力会很高，因此考虑采用缓存机制来减少数据库连接资源
的竞争和对数据库读的压力，这个时候首先也许会选择采用</span>squid <span style="font-family: 宋体;">等类似的机制来将系统中相对静态的页面（例如一两天才会有更新的页面）进行缓存（当然，也可以采用将
页面静态化的方案），这样程序上可以不做修改，就能够</span>
<span style="font-family: 宋体;">很好的减少对</span>webserver<span style="font-family: 宋体;">的压力以及减少数据库连接资源的竞争，</span>OK<span style="font-family: 宋体;">，于是开始采用</span>squid<span style="font-family: 宋体;">来做相对静态的页面的缓存。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/2.PNG" height="156" width="195" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">前端页面缓存技术，例如</span>squid<span style="font-family: 宋体;">，如想用好的话还得深入掌握下</span>squid<span style="font-family: 宋体;">的实现方式以及缓存的失效算法
等。</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第三步：增加页面片段缓存</span></span></strong></p>
<p><span style="font-family: 宋体;">增加了</span>squid<span style="font-family: 宋体;">做缓存后，整体系统的速度确实是提
升了，</span>webserver<span style="font-family: 宋体;">的压力也开始下降了，但随着访问量的增加，发现系统又开始变的有些慢了，在尝</span> <span style="font-family: 宋体;">到了</span>squid<span style="font-family: 宋体;">之类的动态缓存带来的好处后，开始想能不能让现在那些动态页面里相对静态的部分也缓存起来呢，因此考
虑采用类似</span>ESI<span style="font-family: 宋体;">之
类的页面片段缓存策略，</span>OK<span style="font-family: 宋体;">，于是开始采用</span>ESI<span style="font-family: 宋体;">来做动态页面中相对静态的片段部分的缓存。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/3.PNG" height="235" width="337" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">页面片段缓存技术，例如</span>ESI<span style="font-family: 宋体;">等，想用好的话同样需要掌握</span>ESI<span style="font-family: 宋体;">的实现方式等；</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第四步：数据缓存</span></span></strong></p>
<p><span style="font-family: 宋体;">在采用</span>ESI<span style="font-family: 宋体;">之类的技术再次提高了系统的缓存效果
后，系统的压力确实进一步降低了，但同样，随着访问量的增加，系统还是开始变慢，经过查找，可能会发现系</span>
<span style="font-family: 宋体;">统中存在一些重复获取数据信息的地方，像获取用户信息等，这个时候开始考虑是不是可以将
这些数据信息也缓存起来呢，于是将这些数据缓存到本地内存，改变完毕后，完全符合预期，系统的响应速度又恢复了，数据库的压力也再度降低了不少。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/4.PNG" height="258" width="341" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">缓存技术，包括像</span>Map<span style="font-family: 宋体;">数据结构、缓存算法、所选用的框架本
身的实现机制等。</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;"><span style="font-family: 宋体;">架构演变第五步：</span> <span style="font-family: 宋体;">增加</span>webserver</span></span></strong></p>
<p><span style="font-family: 宋体;">好景不长，发现随着系统访问量的再度增加，</span>webserver<span style="font-family: 宋体;">机器的压力在高峰期会上
升到比较高，这个时候开始考虑增加一台</span>webserver<span style="font-family: 宋体;">，这也是为了同时解决可用性的问题，避免单台的</span><span>webserver
down</span><span style="font-family: 宋体;">机的话就没法使用了，在做了这些考虑后，决定增加一台</span>webserver<span style="font-family: 宋体;">，增加一台</span>webserver<span style="font-family: 宋体;">时，会碰到一些问题，典
型的有：</span><span><br />
1</span><span style="font-family: 宋体;">、如何让访问分配到这两台机器上，这个时候通常会考虑的方案是</span>Apache<span style="font-family: 宋体;">自带的负载均衡方案，或</span>LVS<span style="font-family: 宋体;">这类的软件负载均衡方案；</span><span><br />
2</span><span style="font-family: 宋体;">、如何保持状态信息的同步，例如用户</span>session<span style="font-family: 宋体;">等，这个时候会考虑的方案有写
入数据库、写入存储、</span>cookie<span style="font-family: 宋体;">或同步</span>session<span style="font-family: 宋体;">信息等机制等；</span><span><br />
3</span><span style="font-family: 宋体;">、如何保持数据缓存信息的同步，例如之前缓存的用户数据等，这个时候通
常会考虑的机制有缓存同步或分布式缓存；</span><span><br />
4</span><span style="font-family: 宋体;">、如何让上传文件这些类似的功能继续正常，这个时候通常会考虑的机制是
使用共享文件系统或存储等；</span><span><br />
</span><span style="font-family: 宋体;">在解决了这些问题后，终于是把</span>webserver<span style="font-family: 宋体;">增加为了两台，系统终于是
又恢复到了以往的速度。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/5.PNG" height="244" width="341" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">负载均衡技术（包括但不限于硬件负载均衡、
软件负载均衡、负载算法、</span>linux<span style="font-family: 宋体;">转发协议、所选用的技术的实现细节等）、主备技术（包括但不限于</span>ARP<span style="font-family: 宋体;">欺骗、</span><span>linux
heart-beat</span><span style="font-family: 宋体;">等）、状态信息或缓存同步技术（包括但不限于</span>Cookie<span style="font-family: 宋体;">技术、</span>UDP<span style="font-family: 宋体;">协议、状态信息广播、所选用的缓存同
步技术的实现细节等）、共享文件技术（包括但不限于</span>NFS<span style="font-family: 宋体;">等）、存储技术（包括但不限于存储设备等）。</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第六步：分库</span></span></strong></p>
<p><span style="font-family: 宋体;">享受了一段时间的系统访问量高速增长的幸福
后，发现系统又开始变慢了，这次又是什么状况呢，经过查找，发现数据库写入、更新的这些操作的部分数据库连接的</span>
<span style="font-family: 宋体;">资源竞争非常激烈，导致了系统变慢，这下怎么办呢，此时可选的方案有数据库集群和分库策
略，集群方面像有些数据库支持的并不是很好，因此分库会成为比较普遍的策略，分库也就意味着要对原有程序进行修改，一通修改实现分库后，不错，目标达到
了，系统恢复甚至速度比以前还快了。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/6.PNG" height="243" width="341" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">这一步更多的是需要从业务上做合理的划分，
以实现分库，具体技术细节上没有其他的要求；</span></p>
<p><font face="宋体">但同时随着数据量的增大和分库的进行，在数据库的设计、调优以及维护上需要
做的更好，因此对这些方面的技术还是提出了很高的要求的。</font></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;"><span style="font-family: 宋体;">架构演变第七步：分表、</span>DAL<span style="font-family: 宋体;">和分布式缓存</span></span></span></strong><span><br />
</span><span style="font-family: 宋体;">随着系统的不断运行，数据量开始大幅度增长，这个时候发现分库后查询仍然
会有些慢，于是按照分库的思想开始做分表的工作，当然，这不可避免的会需要对程序</span>
<span style="font-family: 宋体;">进行一些修改，也许在这个时候就会发现应用自己要关心分库分表的规则等，还是有些复杂
的，于是萌生能否增加一个通用的框架来实现分库分表的数据访问，这个在</span>ebay<span style="font-family: 宋体;">的架构中对应的就是</span>DAL<span style="font-family: 宋体;">，这个演变的过程相对而言需要花费较长的时间，当然，也有可能这个通用的框架会等到分表做完后才开
始做，同时，在这个阶段可</span>
<span style="font-family: 宋体;">能会发现之前的缓存同步方案出现问题，因为数据量太大，导致现在不太可能将缓存存在本
地，然后同步的方式，需要采用分布式缓存方案了，于是，又是一通考察和折磨，终于是将大量的数据缓存转移到分布式缓存上了。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/7.PNG" height="439" width="342" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">分表更多的同样是业务上的划分，技术上涉及
到的会有动态</span>hash<span style="font-family: 宋体;">算法、</span><span>consistent
hash</span><span style="font-family: 宋体;">算法等；</span></p>
<p>DAL<span style="font-family: 宋体;">涉及到比较多的复杂技术，例如数据库连接的管理（超时、异常）、数据库操作的控制（超时、异常）、分
库分表规则的封装等；</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;"><span style="font-family: 宋体;">架构演变第八步：增加更多的</span>webserver</span></span></strong></p>
<p><span style="font-family: 宋体;">在做完分库分表这些工作后，数据库上的压力
已经降到比较低了，又开始过着每天看着访问量暴增的幸福生活了，突然有一天，发现系统的访问又开始有变慢的趋势</span>
<span style="font-family: 宋体;">了，这个时候首先查看数据库，压力一切正常，之后查看</span>webserver<span style="font-family: 宋体;">，发现</span>apache<span style="font-family: 宋体;">阻塞了很多的请求，而应用服务
器对每个请求也是比较快的，看来</span> <span style="font-family: 宋体;">是请求数太高导致需要排队等待，响应速
度变慢，这还好办，一般来说，这个时候也会有些钱了，于是添加一些</span>webserver<span style="font-family: 宋体;">服务器，在这个添加</span> webserver<span style="font-family: 宋体;">服务器的过程，有可能会出现几种挑战：</span><span><br />
1</span><span style="font-family: 宋体;">、</span>Apache<span style="font-family: 宋体;">的软负载或</span>LVS<span style="font-family: 宋体;">软负载等无法承担巨大的</span>web<span style="font-family: 宋体;">访问量（请求连接数、网络流量等）的调度了，这个时候如果经费允许的话，会采取的方案是购</span>
<span style="font-family: 宋体;">买硬件负载，例如</span>F5<span style="font-family: 宋体;">、</span>Netsclar<span style="font-family: 宋体;">、</span>Athelon<span style="font-family: 宋体;">之类的，如经费不允许的话，会采取的方案是将应用从逻辑上做一定的分类，然后分散到不同的软负载集
群中；</span><span><br />
2</span><span style="font-family: 宋体;">、原有的一些状态信息同步、文件共享等方案可能会出现瓶颈，需要进行改
进，也许这个时候会根据情况编写符合网站业务需求的分布式文件系统等；</span><span><br />
</span><span style="font-family: 宋体;">在做完这些工作后，开始进入一个看似完美的无限伸缩的时代，当网站流量增
加时，应对的解决方案就是不断的添加</span>webserver<span style="font-family: 宋体;">。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/8.PNG" height="441" width="466" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">到了这一步，随着机器数的不断增长、数据量
的不断增长和对系统可用性的要求越来越高，这个时候要求对所采用的技术都要有更为深入的理解，并需要根据网站的需求来做更加定制性质的产品。</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第九步：数据读写分离和廉价存储方案</span></span></strong></p>
<p><span style="font-family: 宋体;">突然有一天，发现这个完美的时代也要结束
了，数据库的噩梦又一次出现在眼前了，由于添加的</span>webserver<span style="font-family: 宋体;">太多了，导致数据库连接的资源还是不够用，而这个时候又已经分库分表了，开始分析数据库的压力状况，
可能会发现数据库的读写比很高，这个时候通常会想到数据读写分离的方案，当然，这个方案要实现并不</span>
<span style="font-family: 宋体;">容易，另外，可能会发现一些数据存储在数据库上有些浪费，或者说过于占用数据库资源，因
此在这个阶段可能会形成的架构演变是实现数据读写分离，同时编写一些更为廉价的存储方案，例如</span>BigTable<span style="font-family: 宋体;">这种。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/9.PNG" height="398" width="555" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">数据读写分离要求对数据库的复制、</span>standby<span style="font-family: 宋体;">等策略有深入的掌握和理解，
同时会要求具备自行实现的技术；</span></p>
<p><span style="font-family: 宋体;">廉价存储方案要求对</span>OS<span style="font-family: 宋体;">的文件存储有深入的掌握和理解，同时要
求对采用的语言在文件这块的实现有深入的掌握。</span></p>
<p><strong><span style="font-family: 宋体;"><span style="font-size: 14pt;">架构演变第十步：进入大型分布式应用时代和廉价服务器群梦想时代</span></span></strong></p>
<p><span style="font-family: 宋体;">经过上面这个漫长而痛苦的过程，终于是再度
迎来了完美的时代，不断的增加</span>webserver<span style="font-family: 宋体;">就可以支撑越来越高的访问量了，对于大型网站而言，人气的重要毋</span>
<span style="font-family: 宋体;">庸置疑，随着人气的越来越高，各种各样的功能需求也开始爆发性的增长，这个时候突然发
现，原来部署在</span>webserver<span style="font-family: 宋体;">上的那个</span>web<span style="font-family: 宋体;">应用已经非常庞大</span> <span style="font-family: 宋体;">了，
当多个团队都开始对其进行改动时，可真是相当的不方便，复用性也相当糟糕，基本是每个团队都做了或多或少重复的事情，而且部署和维护也是相当的麻烦，</span>
<span style="font-family: 宋体;">因为庞大的应用包在</span>N<span style="font-family: 宋体;">台机器上复制、启动都需要耗费不少的时间，出问题的时候也不是很好查，另外一个更糟糕的状况是很有
可能会出现某个应用上的</span>bug<span style="font-family: 宋体;">就导</span> <span style="font-family: 宋体;">致了全站都不可用，还有其他的像调优不好操作（因为机
器上部署的应用什么都要做，根本就无法进行针对性的调优）等因素，根据这样的分析，开始痛下决心，将</span>
<span style="font-family: 宋体;">系统根据职责进行拆分，于是一个大型的分布式应用就诞生了，通常，这个步骤需要耗费相当
长的时间，因为会碰到很多的挑战：</span><span><br />
1</span><span style="font-family: 宋体;">、拆成分布式后需要提供一个高性能、稳定的通信框架，并且需要支持多种
不同的通信和远程调用方式；</span><span><br />
2</span><span style="font-family: 宋体;">、将一个庞大的应用拆分需要耗费很长的时间，需要进行业务的整理和系统
依赖关系的控制等；</span><span><br />
3</span><span style="font-family: 宋体;">、如何运维（依赖管理、运行状况管理、错误追踪、调优、监控和报警等）
好这个庞大的分布式应用。</span><span><br />
</span><span style="font-family: 宋体;">经过这一步，差不多系统的架构进入相对稳定的阶段，同时也能开始采用大量
的廉价机器来支撑着巨大的访问量和数据量，结合这套架构以及这么多次演变过程吸取的经验来采用其他各种各样的方法来支撑着越来越高的访问量。</span></p>
<p><span style="font-family: 宋体;">看看这一步完成后系统的图示：</span></p>
<p><span><!--[if gte vml 1]>
<![endif]--><img alt="" src="../../images/blogjava_net/bluedavy/arch/10.PNG" height="431" width="554" /><br />
<!--[if gte mso 9]><![endif]--></span></p>
<p><span style="font-family: 宋体;">这一步涉及到了这些知识体系：</span></p>
<p><span style="font-family: 宋体;">这一步涉及的知识体系非常的多，要求对通
信、远程调用、消息机制等有深入的理解和掌握，要求的都是从理论、硬件级、操作系统级以及所采用的语言的实现都有清楚的理解。</span></p>
<p><span style="font-family: 宋体;">运维这块涉及的知识体系也非常的多，多数情
况下需要掌握分布式并行计算、报表、监控技术以及规则策略等等。</span></p>
<p><span style="font-family: 宋体;">说起来确实不怎么费力，整个网站架构的经典演变过程都和上面比较的类似，当然，每步采取的方案，演变
的步骤有可能有不同，另外，由于网站的业务不同，会有不同的专业技术的需求，这篇</span>blog<span style="font-family: 宋体;">更多的是从架构的角度来讲解演变的过程，当然，其中还有很多的技术也未在此提及，像数据库集群、数
据挖掘、搜索等，但在真实的演变过程中还会借助像提升硬件配置、网络环境、改造操作系统、</span>CDN<span style="font-family: 宋体;">镜像等来支撑更大的流量，因此在真实的发展过程中还会有很多的不同，另外一个大型网站要做到的远远
不仅仅上面这些，还有像安全、运维、运营、服务、存储等，要做好一个大型的网站真的很不容易，写这篇文章更多的是希望能够引出更多大型网站架构演变的介
绍，</span>:)<span style="font-family: 宋体;">。</span></p>
<br />
ps:最后附上几篇LiveJournal架构演变的文章：<br />
从LiveJournal后台发展看大规模网站性能优化方法<br />
http://blog.zhangjianfeng.com/article/743&nbsp;&nbsp;&nbsp; <br />
另外从这里：http://www.danga.com/words/大家可以找到更多关于现在LiveJournal网站架构的介绍。
<img src ="http://www.blogjava.net/conans/aggbug/325053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2010-07-02 11:23 <a href="http://www.blogjava.net/conans/articles/325053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>