ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产成人精品av,亚洲精品第一区二区三区,亚洲精品乱码久久久久久日本蜜臀 http://www.aygfsteel.com/huyi0616/archive/2016/05/11/430436.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Wed, 11 May 2016 03:54:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2016/05/11/430436.htmlhttp://www.aygfsteel.com/huyi0616/comments/430436.htmlhttp://www.aygfsteel.com/huyi0616/archive/2016/05/11/430436.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/430436.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/430436.html
  1. 对前端开发äh员的能力和数量要求急剧增大åQŒä»¥å‰ä¸€ä¸ªå¼€å‘äh员搞定前端、后端,现在前端采用node.jsåQŒè¿™ä¸ªåŽå°å¼€å‘äh员介入不了只能前台去å?/li>
  2. 后台开发äh员只负责接口开发,注意“å?#8221;˜q™ä¸ªå­—,接口开发äh员这时就有了局限性,你前端要什么我是不清楚的,你要什么我ž®Þq»™ä½ å¼€å‘什么,造成接口数量多,不规èŒ?/li>
  3. 接着问题2åQŒå‰å°å¼€å‘äh员需要什么就向后台要åQŒé€ æˆåŽŸå…ˆåŽå°ä¸€ä¸ªæŽ¥å£å°±å¯ä»¥æžå®šçš„äº‹æƒ…ï¼Œå‰ç«¯¾l†åˆ†åˆ?-5个接口去做,开发效率低åQŒé¡µé¢ä¸æ–­è¯·æ±‚,性能较差åQŒæŽ¥å£æ‰¿è½½çš„压力也是骤增åQ?/li>

解决æ–ÒŽ(gu¨©)¡ˆåQ?/p>

  1. 现在前端的压力还是比较大åQŒæ€¥éœ€å¢žåŠ å‰ç«¯çš„äh员招聘,后端人员也需要è{入前端开发,有一定的学习(f¨¤n)瓉™¢ˆå’Œè¿‡æ¸¡æ—¶æœŸï¼›
  2. 需要架构师从统½Ž¡è§’度一致协调,避免接口滥用åQ?/li>
  3. 减少接口è¯äh±‚‹Æ¡æ•°åQŒåŽ‹¾~©é¡µé¢æŽ¥å£æ•°åQŒå¯¹èƒ½å¤Ÿ¾~“存的一些基¼‹€æ•°æ®åQŒåœ¨å‰ç«¯å¢žåŠ ¾~“å­˜

¾l“æžœåQ?/p>

  1. 现在™åµé¢å“åº”速度åœ?00个高òq¶å‘æ—Óž¼Œòq›_‡å€ég»Ž20s减少åˆ?såQŒåŸºæœ¬è¾ƒ?y¨­u)®‘服务器压力åQŒè¿˜æœ‰ä¼˜åŒ–空é—?/li>
  2. 其他人是否有更好办法åQ?br />


]]>
使IE‹¹è§ˆå™¨é»˜è®¤ä‹É用最新的版本昄¡¤º™åµé¢åQŒåŽ»æŽ‰å…¼å®ÒŽ(gu¨©)¨¡å¼?/title><link>http://www.aygfsteel.com/huyi0616/archive/2016/04/07/430004.html</link><dc:creator>一杯清èŒ?/dc:creator><author>一杯清èŒ?/author><pubDate>Thu, 07 Apr 2016 02:16:00 GMT</pubDate><guid>http://www.aygfsteel.com/huyi0616/archive/2016/04/07/430004.html</guid><wfw:comment>http://www.aygfsteel.com/huyi0616/comments/430004.html</wfw:comment><comments>http://www.aygfsteel.com/huyi0616/archive/2016/04/07/430004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/huyi0616/comments/commentRss/430004.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/huyi0616/services/trackbacks/430004.html</trackback:ping><description><![CDATA[<span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;">昨天看淘宝页面源代码<meta http-equiv=”X-UA-Compatible” content=”IE=7, IE=9″>加了个ã€?nbsp;</span><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;">不过现在已经æ”ÒŽ(gu¨©)ˆäº?nbsp;</span><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;"><meta http-equiv="X-UA-Compatible" content="IE=edge" > </span><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;">不知用意åQŒè¯·æ•™é«˜äººå¥½å¤šéƒ½ä¸æ¸…楚ã€?nbsp;</span><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;">查阅资料发现åQŒé‚£ä¸ªæ˜¯è‹±æ–‡çš„,基础差ã€?nbsp;</span><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><br style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;" /><span style="font-family: tahoma, arial, 宋体; line-height: 25.2000007629395px; background-color: #ffffff;">大致¾˜»è¯‘是如果你有一个ä‹É用X-UA-Compatible Meta 标签或者http header 让网™åµåœ¨IE7标准模式解释的旧¾|‘ç«™åQŒé‚£ä¹ˆè¿™é‡Œæœ‰ä¸€ä¸ªç»¼åˆç¤ºä¾‹èƒ½å¤Ÿè®©ie8用ie7的标准模式呈现页面,ie9使用ie9的标准模式呈现页面。用自己的话ž®±æ˜¯ä½¿ç”¨ä¸Šé¢<meta http-equiv=”X-UA-Compatible” content=”IE=7, IE=9″>åQŒä‹ÉIE7 IE8‹¹è§ˆå™¨ä‹É用IE7模式渲染。IE9ž®Þq”¨è‡ªå·±çš„IE9模式渲染。互不媄å“?/span><img src ="http://www.aygfsteel.com/huyi0616/aggbug/430004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/huyi0616/" target="_blank">一杯清èŒ?/a> 2016-04-07 10:16 <a href="http://www.aygfsteel.com/huyi0616/archive/2016/04/07/430004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>svnhttp://www.aygfsteel.com/huyi0616/archive/2013/05/02/398686.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Thu, 02 May 2013 09:21:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2013/05/02/398686.htmlhttp://www.aygfsteel.com/huyi0616/comments/398686.htmlhttp://www.aygfsteel.com/huyi0616/archive/2013/05/02/398686.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/398686.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/398686.html阅读全文

]]>
修改SQL数据库中表字ŒD늱»åž‹æ—¶åQŒæŠ¥â€œä¸€ä¸ªæˆ–多个对象讉K—®æ­¤åˆ—”错误的解决æ–ÒŽ(gu¨©)³• http://www.aygfsteel.com/huyi0616/archive/2011/06/13/352187.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Mon, 13 Jun 2011 06:52:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2011/06/13/352187.htmlhttp://www.aygfsteel.com/huyi0616/comments/352187.htmlhttp://www.aygfsteel.com/huyi0616/archive/2011/06/13/352187.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/352187.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/352187.html转自:
http://www.cnblogs.com/coloeme/archive/2010/03/09/1681201.html

在SQL数据库中使用SQL语句åQˆæ ¼å¼ï¼šalter table [tablename] alter column [colname] [newDataType]åQ‰ä¿®æ”ÒŽ(gu¨©)Ÿè¡¨çš„字段¾cÕdž‹æ—Óž¼ŒæŠ¥ä¸€ä¸‹é”™è¯?

“**********************************

对象'DF__******' 依赖��column1'�
***********************************
ç”׃ºŽä¸€ä¸ªæˆ–多个对象讉K—®æ­¤åˆ—åQŒALTER TABLE ******** å¤ÞpÓ|ã€?#8221;

  æ ÒŽ(gu¨©)®ä¸Šè¿°æç¤ºåœ¨ç½‘上搜索结果,得知发生该错误的原因在于要修改的字段存在Default¾U¦æŸåQŒè§£å†Ïx–¹æ³•:

1.æŸ¥æ‰¾å‡ø™¡¨ä¸­è¯¥å­—段的约束名¿UŽÍ¼ˆæˆ–根据已有的提示及对è±?DF__******'åQ?/p>

declare @name varchar(50)
select  @name =b.name from sysobjects b join syscolumns a on b.id = a.cdefault
where a.id = object_id('TableName')
and a.name ='ColumName'

2. 删除存在的约�/p>

exec('alter table TableName drop constraint ' + @name)

3. 再执行修改字ŒD늱»åž‹çš„脚本卛_¯

  ¾l¼åˆæŸ¥é˜…资料发现åQšå°†è¡¨ä¸­çš„å­—ŒDµè®¾¾|®äØ“NOT NULLåQˆä¸ä¸ºç©ºåQ‰ã€ç»™å­—段增加Defaultå€û|¼ˆé»˜è®¤å€û|¼‰˜q™æ ·çš„æ“ä½œéƒ½ä¼šç»™è¯¥å­—ŒD‰|·»åŠ çº¦æŸï¼Œå¢žåŠ äº†è¿™äº›çº¦æŸåŽåQŒåœ¨ç”¨SQL脚本修改字段¾cÕdž‹ã€åˆ é™¤å­—ŒD늚„时候均会发生类似错误,需要查找该字段上已存在的约束,òq¶åˆ é™¤å­˜åœ¨çš„¾U¦æŸåQŒå†‹Æ¡æ‰§è¡Œä¿®æ”?删除脚本卛_¯ã€?/p>

  资料引用åQ?/p>

  1. 修改字段¾cÕdž‹æ—¶å‡ºçŽ°çš„ 依赖äº?列Classinfo_ShowType,å› äØ“æœ‰ä¸€ä¸ªæˆ–å¤šä¸ªå¯¹è±¡è®‰K—®æ­¤åˆ—åQˆé‚¹å»ø™¯·˜q›ï¼‰

  2. ç”׃ºŽä¸€ä¸ªæˆ–多个对象讉K—®æ­¤åˆ—错误的解军_Šžæ³?/a>

  3. SQL Server】sql语句删除表的有默认值的�/a>

  4. Alter Table修改表结构的错误及解å†Ïx–¹æ³?/a>



]]>
jquery.validate.js表单验证http://www.aygfsteel.com/huyi0616/archive/2010/08/10/328368.html一杯清�/dc:creator>一杯清�/author>Tue, 10 Aug 2010 01:38:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2010/08/10/328368.htmlhttp://www.aygfsteel.com/huyi0616/comments/328368.htmlhttp://www.aygfsteel.com/huyi0616/archive/2010/08/10/328368.html#Feedback6http://www.aygfsteel.com/huyi0616/comments/commentRss/328368.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/328368.html

 

一、用前必å¤?br /> 官方¾|‘ç«™åQ?a >http://bassistance.de/jquery-plugins/jquery-plugin-validation/
API: http://jquery.bassistance.de/api-browser/plugins.html
当前版本åQ?.5.5
需要JQuery版本åQ?.2.6+, 兼容 1.3.2
<script src="../js/jquery.js" type="text/javascript"></script>
<script src="../js/jquery.validate.js" type="text/javascript"></script>

二、默认校验规åˆ?br /> (1)required:true               必输字段
(2)remote:"check.php"          使用ajaxæ–ÒŽ(gu¨©)³•调用check.php验证输入å€?br /> (3)email:true                  必须输入正确格式的电(sh¨´)子邮ä»?br /> (4)url:true                    必须输入正确格式的网址
(5)date:true                   必须输入正确格式的日æœ?br /> (6)dateISO:true                必须输入正确格式的日æœ?ISO)åQŒä¾‹å¦‚:2009-06-23åQ?998/01/22 只验证格式,不验证有效æ€?br /> (7)number:true                 必须输入合法的数å­?è´Ÿæ•°åQŒå°æ•?
(8)digits:true                 必须输入整数
(9)creditcard:                 必须输入合法的信用卡å?br /> (10)equalTo:"#field"           输入值必™åÕd’Œ#field相同
(11)accept:                    输入拥有合法后缀名的字符ä¸ÔŒ¼ˆä¸Šä¼ æ–‡äšg的后¾~€åQ?br /> (12)maxlength:5                输入长度最多是5的字½W¦ä¸²(汉字½Ž—一个字½W?
(13)minlength:10               输入长度最ž®æ˜¯10的字½W¦ä¸²(汉字½Ž—一个字½W?
(14)rangelength:[5,10]         输入长度必须介于 5 å’?10 之间的字½W¦ä¸²")(汉字½Ž—一个字½W?
(15)range:[5,10]               输入值必™åÖM»‹äº?5 å’?10 之间
(16)max:5                      输入å€ég¸èƒ½å¤§äº?
(17)min:10                     输入å€ég¸èƒ½å°äº?0

三、默认的提示
messages: {
    required: "This field is required.",
    remote: "Please fix this field.",
    email: "Please enter a valid email address.",
    url: "Please enter a valid URL.",
    date: "Please enter a valid date.",
    dateISO: "Please enter a valid date (ISO).",
    dateDE: "Bitte geben Sie ein g眉ltiges Datum ein.",
    number: "Please enter a valid number.",
    numberDE: "Bitte geben Sie eine Nummer ein.",
    digits: "Please enter only digits",
    creditcard: "Please enter a valid credit card number.",
    equalTo: "Please enter the same value again.",
    accept: "Please enter a value with a valid extension.",
    maxlength: $.validator.format("Please enter no more than {0} characters."),
    minlength: $.validator.format("Please enter at least {0} characters."),
    rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
    range: $.validator.format("Please enter a value between {0} and {1}."),
    max: $.validator.format("Please enter a value less than or equal to {0}."),
    min: $.validator.format("Please enter a value greater than or equal to {0}.")
},
如需要修改,可在js代码中加入:
jQuery.extend(jQuery.validator.messages, {
        required: "必选字ŒD?,
remote: "请修正该字段",
email: "误‚¾“入正¼‹®æ ¼å¼çš„ç”?sh¨´)子邮äšg",
url: "误‚¾“入合法的¾|‘址",
date: "误‚¾“入合法的日期",
dateISO: "误‚¾“入合法的日期 (ISO).",
number: "误‚¾“入合法的数字",
digits: "只能输入整数",
creditcard: "误‚¾“入合法的信用卡号",
equalTo: "请再‹Æ¡è¾“入相同的å€?,
accept: "误‚¾“入拥有合法后¾~€åçš„字符ä¸?,
maxlength: jQuery.validator.format("误‚¾“入一个长度最多是 {0} 的字½W¦ä¸²"),
minlength: jQuery.validator.format("误‚¾“入一个长度最ž®‘是 {0} 的字½W¦ä¸²"),
rangelength: jQuery.validator.format("误‚¾“入一个长度介äº?{0} å’?{1} 之间的字½W¦ä¸²"),
range: jQuery.validator.format("误‚¾“入一个介äº?{0} å’?{1} 之间的å€?),
max: jQuery.validator.format("误‚¾“å…¥ä¸€ä¸ªæœ€å¤§äØ“ {0} çš„å€?),
min: jQuery.validator.format("误‚¾“入一个最ž®äØ“ {0} çš„å€?)
});
推荐做法åQŒå°†æ­¤æ–‡ä»¶æ”¾å…¥messages_cn.js中,在页面中引入
<script src="../js/messages_cn.js" type="text/javascript"></script>

四、ä‹É用方å¼?br /> 1.ž®†æ ¡éªŒè§„则写到控件中
<script src="../js/jquery.js" type="text/javascript"></script>
<script src="../js/jquery.validate.js" type="text/javascript"></script>
<script src="./js/jquery.metadata.js" type="text/javascript"></script>
$().ready(function() {
$("#signupForm").validate();
});

<form id="signupForm" method="get" action="">
    <p>
        <label for="firstname">Firstname</label>
        <input id="firstname" name="firstname" class="required" />
    </p>
<p>
<label for="email">E-Mail</label>
<input id="email" name="email" class="required email" />
</p>
<p>
<label for="password">Password</label>
<input id="password" name="password" type="password" class="{required:true,minlength:5}" />
</p>
<p>
<label for="confirm_password">¼‹®è®¤å¯†ç </label>
<input id="confirm_password" name="confirm_password" type="password" class="{required:true,minlength:5,equalTo:'#password'}" />
</p>
    <p>
        <input class="submit" type="submit" value="Submit"/>
    </p>
</form>
使用class="{}"的方式,必须引入包:jquery.metadata.js
可以使用如下的方法,修改提示内容åQ?br /> class="{required:true,minlength:5,messages:{required:'误‚¾“入内å®?}}"
在ä‹É用equalTo关键字时åQŒåŽé¢çš„内容必须加上引号åQŒå¦‚下代码:
class="{required:true,minlength:5,equalTo:'#password'}"
另外一个方式,使用关键字:metaåQˆäؓ了元数据使用其他插äšg你要包装 你的验证规则 在他们自å·Þqš„™å¹ç›®ä¸­å¯ä»¥ç”¨˜q™ä¸ªç‰ÒŽ(gu¨©)®Šçš„选项åQ?br /> Tell the validation plugin to look inside a validate-property in metadata for validation rules.
例如åQ?br /> meta: "validate"
<input id="password" name="password" type="password" class="{validate:{required:true,minlength:5}}" />

再有一¿Uæ–¹å¼ï¼š
$.metadata.setType("attr", "validate");
˜q™æ ·å¯ä»¥ä½¿ç”¨validate="{required:true}"的方式,或者class="required"åQŒä½†class="{required:true,minlength:5}"ž®†ä¸èµ·ä½œç”?br />
2.ž®†æ ¡éªŒè§„则写åˆîC»£ç ä¸­

$().ready(function() {
$("#signupForm").validate({
        rules: {
   firstname: "required",
   email: {
    required: true,
    email: true
   },
   password: {
    required: true,
    minlength: 5
   },
   confirm_password: {
    required: true,
    minlength: 5,
    equalTo: "#password"
   }
},
        messages: {
   firstname: "误‚¾“入姓å?,
   email: {
    required: "误‚¾“å…¥Email地址",
    email: "误‚¾“入正¼‹®çš„email地址"
   },
   password: {
    required: "误‚¾“入密ç ?,
    minlength: jQuery.format("密码不能ž®äºŽ{0}个字½W?)
   },
   confirm_password: {
    required: "误‚¾“入确认密ç ?,
    minlength: "¼‹®è®¤å¯†ç ä¸èƒ½ž®äºŽ5个字½W?,
    equalTo: "两次输入密码不一致不一è‡?
   }
}
    });
});
//messages处,如果某个控äšg没有messageåQŒå°†è°ƒç”¨é»˜è®¤çš„ä¿¡æ?/p>

<form id="signupForm" method="get" action="">
    <p>
        <label for="firstname">Firstname</label>
        <input id="firstname" name="firstname" />
    </p>
<p>
<label for="email">E-Mail</label>
<input id="email" name="email" />
</p>
<p>
<label for="password">Password</label>
<input id="password" name="password" type="password" />
</p>
<p>
<label for="confirm_password">¼‹®è®¤å¯†ç </label>
<input id="confirm_password" name="confirm_password" type="password" />
</p>
    <p>
        <input class="submit" type="submit" value="Submit"/>
    </p>
</form>
required:true 必须有å€?br /> required:"#aa:checked"表达式的å€égؓ真,则需要验è¯?br /> required:function(){}˜q”回为真åQŒè¡¨æ—‰™œ€è¦éªŒè¯?br /> 后边两种常用于,表单中需要同时填或不填的元素

五、常用方法及注意问题
1.用其他方式替代默认的SUBMIT
$().ready(function() {
$("#signupForm").validate({
        submitHandler:function(form){
            alert("submitted");   
            form.submit();
        }    
    });
});
可以讄¡½®validate的默认å€û|¼Œå†™æ³•如下åQ?br /> $.validator.setDefaults({
submitHandler: function(form) { alert("submitted!");form.submit(); }
});
如果æƒÏxäº¤è¡¨å? 需要ä‹É用form.submit()而不要ä‹Éç”?(form).submit()

2.debugåQŒå¦‚果这个参æ•îCØ“trueåQŒé‚£ä¹ˆè¡¨å•不会提交,只进行检查,调试时十分方ä¾?br /> $().ready(function() {
$("#signupForm").validate({
        debug:true
    });
});
如果一个页面中有多个表单,�br /> $.validator.setDefaults({
   debug: true
})

3.ignoreåQšå¿½ç•¥æŸäº›å…ƒç´ ä¸éªŒè¯
ignore: ".ignore"

4.errorPlacementåQšCallback Default: 把错误信息放在验证的元素后面
指明错误攄¡½®çš„位¾|®ï¼Œé»˜è®¤æƒ…况是:error.appendTo(element.parent());åÏxŠŠé”™è¯¯ä¿¡æ¯æ”‘Öœ¨éªŒè¯çš„元素后é?
errorPlacement: function(error, element) {  
    error.appendTo(element.parent());  
}
//½CÞZ¾‹åQ?br /> <tr>
    <td class="label"><label id="lfirstname" for="firstname">First Name</label></td>
    <td class="field"><input id="firstname" name="firstname" type="text" value="" maxlength="100" /></td>
    <td class="status"></td>
</tr>
<tr>
    <td style="padding-right: 5px;">
        <input id="dateformat_eu" name="dateformat" type="radio" value="0" />
        <label id="ldateformat_eu" for="dateformat_eu">14/02/07</label>
    </td>
    <td style="padding-left: 5px;">
        <input id="dateformat_am" name="dateformat" type="radio" value="1" />
        <label id="ldateformat_am" for="dateformat_am">02/14/07</label>
    </td>
    <td></td>
</tr>
<tr>
    <td class="label">&nbsp;</td>
    <td class="field" colspan="2">
        <div id="termswrap">
            <input id="terms" type="checkbox" name="terms" />
            <label id="lterms" for="terms">I have read and accept the Terms of Use.</label>
        </div>
    </td>
</tr>
errorPlacement: function(error, element) {
    if ( element.is(":radio") )
        error.appendTo( element.parent().next().next() );
    else if ( element.is(":checkbox") )
        error.appendTo ( element.next() );
    else
        error.appendTo( element.parent().next() );
}
代码的作用是åQšä¸€èˆ¬æƒ…况下把错误信息显½Cºåœ¨<td class="status"></td>中,如果是radio昄¡¤ºåœ?lt;td></td>中,如果是checkbox昄¡¤ºåœ¨å†…容的后面
errorClassåQšString Default: "error"
指定错误提示的css¾cÕdåQŒå¯ä»¥è‡ªå®šä¹‰é”™è¯¯æç¤ºçš„æ ·å¼?br /> errorElementåQšString Default: "label"
用什么标½{¾æ ‡è®°é”™è¯¯ï¼Œé»˜è®¤çš„æ˜¯label你可以改成em
errorContaineråQšSelector
昄¡¤ºæˆ–者隐藏验证信息,可以自动实现有错误信息出现时把容器属性变为显½Cºï¼Œæ— é”™è¯¯æ—¶éšè—åQŒç”¨å¤„不å¤?br /> errorContainer: "#messageBox1, #messageBox2"
errorLabelContaineråQšSelector
把错误信息统一攑֜¨ä¸€ä¸ªå®¹å™¨é‡Œé¢ã€?br /> wrapperåQšString
用什么标½{‘Ö†æŠŠä¸Šè¾¹çš„errorELement包è“væ?br /> 一般这三个属性同时ä‹É用,实现在一个容器内昄¡¤ºæ‰€æœ‰é”™è¯¯æ½Cºçš„功能åQŒåƈ且没有信息时自动隐藏
errorContainer: "div.error",
errorLabelContainer: $("#signupForm div.error"),
wrapper: "li"

讄¡½®é”™è¯¯æç¤ºçš„æ ·å¼ï¼Œå¯ä»¥å¢žåŠ å›¾æ ‡æ˜„¡¤º
input.error { border: 1px solid red; }
label.error {
background:url("./demo/images/unchecked.gif") no-repeat 0px 0px;
padding-left: 16px;
padding-bottom: 2px;
font-weight: bold;
color: #EA5200;
}
label.checked {
background:url("./demo/images/checked.gif") no-repeat 0px 0px;
}
successåQšString,Callback
要验证的元素通过验证后的动作åQŒå¦‚果跟一个字½W¦ä¸²åQŒä¼šå½“做一个css¾c»ï¼Œä¹Ÿå¯è·Ÿä¸€ä¸ªå‡½æ•?br /> success: function(label) {
    // set &nbsp; as text for IE
    label.html("&nbsp;").addClass("checked");
    //label.addClass("valid").text("Ok!")
}
æ·ÕdŠ "valid" 到验证元ç´? 在CSS中定义的样式<style>label.valid {}</style>
success: "valid"


nsubmitåQ?Boolean Default: true
提交旉™ªŒè¯? 讄¡½®å”¯falsež®Þq”¨å…¶ä»–æ–ÒŽ(gu¨©)³•去验è¯?br /> onfocusoutåQšBoolean Default: true
失去焦点是验�不包括checkboxes/radio buttons)
onkeyupåQšBoolean Default: true
在keyupæ—‰™ªŒè¯?
onclickåQšBoolean Default: true
在checkboxes å’?radio 点击旉™ªŒè¯?br /> focusInvalidåQšBoolean Default: true
提交表单后,未通过验证的表å?½W¬ä¸€ä¸ªæˆ–提交之前获得焦点的未通过验证的表å?会获得焦ç‚?br /> focusCleanupåQšBoolean Default: false
如果是true那么当未通过验证的元素获得焦ç‚ÒŽ(gu¨©)—¶åQŒç§»é™¤é”™è¯¯æ½Cºã€‚避免和 focusInvalid 一èµïL(f¨¥ng)”¨

// 重置表单
$().ready(function() {
var validator = $("#signupForm").validate({
        submitHandler:function(form){
            alert("submitted");   
            form.submit();
        }    
    });
    $("#reset").click(function() {
        validator.resetForm();
    });
});

remoteåQšURL
使用ajax方式˜q›è¡ŒéªŒè¯åQŒé»˜è®¤ä¼šæäº¤å½“前验证的值到˜qœç¨‹åœ°å€åQŒå¦‚果需要提交其他的å€û|¼Œå¯ä»¥ä½¿ç”¨data选项
remote: "check-email.php"
remote: {
    url: "check-email.php",     //后台处理½E‹åº
    type: "post",               //数据发送方å¼?br />     dataType: "json",           //接受数据格式   
    data: {                     //要传递的数据
        username: function() {
            return $("#username").val();
        }
    }
}

˜qœç¨‹åœ°å€åªèƒ½è¾“出 "true" æˆ?"false"åQŒä¸èƒ½æœ‰å…¶å®ƒè¾“出


addMethodåQšname, method, message
自定义验证方�/p>

// 中文字两个字�br /> jQuery.validator.addMethod("byteRangeLength", function(value, element, param) {
    var length = value.length;
    for(var i = 0; i < value.length; i++){
        if(value.charCodeAt(i) > 127){
            length++;
        }
    }
return this.optional(element) || ( length >= param[0] && length <= param[1] );   
}, $.validator.format("è¯ïL(f¨¥ng)¡®ä¿è¾“入的值在{0}-{1}个字节之é—?一个中文字½Ž?个字èŠ?"));

// 邮政¾~–码验证   
jQuery.validator.addMethod("isZipCode", function(value, element) {   
    var tel = /^[0-9]{6}$/;
    return this.optional(element) || (tel.test(value));
}, "è¯äh­£¼‹®å¡«å†™æ?zh¨¨n)¨çš„邮政编ç?);

radio和checkbox、select的验�br /> radio的required表示必须选中一�br /> <input type="radio" id="gender_male" value="m" name="gender" class="{required:true}" />
<input type="radio" id="gender_female" value="f" name="gender"/>
checkbox的required表示必须选中
<input type="checkbox" class="checkbox" id="agree" name="agree" class="{required:true}" />
checkboxçš„minlength表示必须选中的最ž®ä¸ªæ•?maxlength表示最大的选中个数,rangelength:[2,3]表示选中个数区间
<input type="checkbox" class="checkbox" id="spam_email" value="email" name="spam[]" class="{required:true, minlength:2}" />
<input type="checkbox" class="checkbox" id="spam_phone" value="phone" name="spam[]" />
<input type="checkbox" class="checkbox" id="spam_mail" value="mail" name="spam[]" />

select的required表示选中的value不能为空
<select id="jungle" name="jungle" title="Please select something!" class="{required:true}">
    <option value=""></option>
    <option value="1">Buga</option>
    <option value="2">Baga</option>
    <option value="3">Oi</option>
</select>
selectçš„minlength表示选中的最ž®ä¸ªæ•ŽÍ¼ˆå¯å¤šé€‰çš„selectåQ?maxlength表示最大的选中个数,rangelength:[2,3]表示选中个数区间
<select id="fruit" name="fruit" title="Please select at least two fruits" class="{required:true, minlength:2}" multiple="multiple">
    <option value="b">Banana</option>
    <option value="a">Apple</option>
    <option value="p">Peach</option>
    <option value="t">Turtle</option>
</select>



]]>
JAVA String.format æ–ÒŽ(gu¨©)³•使用介绍http://www.aygfsteel.com/huyi0616/archive/2010/07/07/325456.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Wed, 07 Jul 2010 07:32:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2010/07/07/325456.htmlhttp://www.aygfsteel.com/huyi0616/comments/325456.htmlhttp://www.aygfsteel.com/huyi0616/archive/2010/07/07/325456.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/325456.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/325456.html
    在JDK1.5中,String¾cÕd¢žåŠ äº†ä¸€ä¸ªéžå¸¸æœ‰ç”¨çš„é™æ€å‡½æ•°format(String  format, Objece...  argues)åQŒå¯ä»¥å°†å„ç±»æ•°æ®æ ¼å¼åŒ–äØ“å­—ç¬¦ä¸²åÆˆè¾“å‡ºã€‚å…¶ä¸­format参数指定了输出的格式åQŒæ˜¯æœ€å¤æ‚也是最难掌握的一点,而argues则是一¾pÕdˆ—½{‰å¾…被格式化的对象。该函数对c语言中printf函数的用法进行了一定的模仿åQŒå› æ­¤æœ‰c语言基础的ähå­¦è“v来会è½ÀL¾è®¸å¤šã€‚下面我们着重讨è®ÞZ¸€ä¸‹format 参数的格式及含义ã€?br />         format参数中可以包含不需要è{化的字符ä¸ÔŒ¼Œ˜q™äº›å­—符串是你写什么,最¾lˆå°±è¾“出什么。同时还包含一些特ŒDŠæ ¼å¼çš„内容åQŒæ¥æŒ‡å®šž®†å“ªä¸ªå¯¹è±¡æ¥è½¬æ¢åQŒä»¥åŠè{换成什么åŞ式。这¿Uç‰¹ŒDŠçš„æ ¼å¼é€šé€šä»¥%index$å¼€å¤ß_¼Œindexä»?开始取å€û|¼Œè¡¨ç¤ºž®†ç¬¬index个参数拿˜q›æ¥˜q›è¡Œæ ¼å¼åŒ–。这一ç‚ÒŽ(gu¨©)¯”c语言要强一点, c语言只能按照参数的顺序依‹Æ¡æ ¼å¼åŒ–åQŒè€Œjava可以选择½W¬n个参数来格式化。由于该函数可以对ä“Q意一个对象进行格式化åQŒä¸åŒçš„对象适用的参æ•îC¹Ÿä¸åŒåQŒå› æ­¤æˆ‘们下面分¾cÀL¥è®¨è®ºã€?br />
1.å¯?span style="color: #ff0000">æ•´æ•°˜q›è¡Œæ ¼å¼åŒ?/span>åQ?span style="color: #339966">%[index$][标识][最ž®å®½åº¦]转换方式
        我们可以看到åQŒæ ¼å¼åŒ–字符串由4部分¾l„成åQŒå…¶ä¸?span style="color: #ff0000">%[index$]的含ä¹?/span>我们上面已经讲过åQ?span style="color: #ff0000">[最ž®å®½åº¦]的含义也很好理解åQŒå°±æ˜¯æœ€¾lˆè¯¥æ•´æ•°è½¬åŒ–的字½W¦ä¸²æœ€ž®‘包含多ž®‘位数字。我们来看看剩下2个部分的含义吧:
标识åQ?nbsp;
'-'    åœ¨æœ€ž®å®½åº¦å†…左对齐,不可以与“ç”?å¡«å……”同时使用
'#'    åªé€‚用äº?˜q›åˆ¶å’?6˜q›åˆ¶åQ?˜q›åˆ¶æ—¶åœ¨¾l“果前面增加一ä¸?åQ?6˜q›åˆ¶æ—¶åœ¨¾l“果前面增加0x
'+'    ¾l“æžœæ€ÀL˜¯åŒ…æ‹¬ä¸€ä¸ªç¬¦åøP¼ˆä¸€èˆ¬æƒ…况下只适用äº?0˜q›åˆ¶åQŒè‹¥å¯¹è±¡ä¸ºBigInteger才可以用äº?˜q›åˆ¶å’?6˜q›åˆ¶åQ?br /> '  '    æ­£å€¼å‰åŠ ç©ºæ û|¼Œè´Ÿå€¼å‰åŠ è´ŸåøP¼ˆä¸€èˆ¬æƒ…况下只适用äº?0˜q›åˆ¶åQŒè‹¥å¯¹è±¡ä¸ºBigInteger才可以用äº?˜q›åˆ¶å’?6˜q›åˆ¶åQ?br /> '0'    ¾l“æžœž®†ç”¨é›¶æ¥å¡«å……
','    åªé€‚用äº?0˜q›åˆ¶åQŒæ¯3位数字之间用“åQ?#8221;分隔
'('    è‹¥å‚数是负数åQŒåˆ™¾l“果中不æ·ÕdŠ è´Ÿå·è€Œæ˜¯ç”¨åœ†æ‹¬å·æŠŠæ•°å­—æ‹¬èµäh¥åQˆåŒ‘+
’å…ähœ‰åŒæ ·çš„限åˆÓž¼‰

转换方式åQ?br /> d
-十进åˆ?nbsp;  o-å…«è¿›åˆ?nbsp;  x或X-十六˜q›åˆ¶

        上面的说明过于枯燥,我们来看几个具体的例子。需要特别注意的两点是:
1.大部分标识字½W¦å¯ä»¥åŒæ—¶ä‹Éç”?
2.String.format()æ–ÒŽ(gu¨©)³•定义如下:
public static String format(String format, Object ... args)
format()½W¬äºŒä¸ªå‚数类型是java 1.5引入的新ç‰ÒŽ(gu¨©)€?可支持传无限个参数进æ?
å› æ­¤1$代表args的第一个参æ•?2$代表args的第二个参数,以次¾cÀLލ.

          System.out.println(String.format("%1$,09d -> %2$+5d", -3123,123));
        System.out.println(String.format("%1$9d", -31));
        System.out.println(String.format("%1$-9d", -31));
        System.out.println(String.format("%1$(9d", -31));
        System.out.println(String.format("%1$#9x", 5689));
//¾l“果为:
//-0003,123 ->  +123
//      -31
//-31     
//     (31)
//   0x1639
2.å¯?span style="color: #ff0000">‹¹®ç‚¹æ•?/span>˜q›è¡Œæ ¼å¼åŒ?/span>åQ?/span>%[index$][标识][最ž®‘宽度][.¾_‘Öº¦]转换方式
        我们可以看到åQŒæÕQç‚ÒŽ(gu¨©)•°çš„è{换多了一ä¸?#8220;¾_‘Öº¦”选项åQŒå¯ä»¥æŽ§åˆ¶å°æ•°ç‚¹åŽé¢çš„位数ã€?

 

标识åQ?nbsp;
'-'    åœ¨æœ€ž®å®½åº¦å†…左对齐,不可以与“ç”?å¡«å……”同时使用
'+'    ¾l“æžœæ€ÀL˜¯åŒ…括一个符å?br /> '  '    æ­£å€¼å‰åŠ ç©ºæ û|¼Œè´Ÿå€¼å‰åŠ è´Ÿå?br /> '0'    ¾l“æžœž®†ç”¨é›¶æ¥å¡«å……
','    æ¯?位数字之间用“åQ?#8221;分隔åQˆåªé€‚用于fgGçš„è{换)
'('
    è‹¥å‚数是负数åQŒåˆ™¾l“果中不æ·ÕdŠ è´Ÿå·è€Œæ˜¯ç”¨åœ†æ‹¬å·æŠŠæ•°å­—æ‹¬èµäh¥åQˆåªé€‚用于eEfgGçš„è{换)

转换方式åQ?br />
'e', 'E'  --  ¾l“果被格式化为用计算机科学记数法表示的十˜q›åˆ¶æ•?br /> 'f'          --  ¾l“果被格式化为十˜q›åˆ¶æ™®é€šè¡¨½Cºæ–¹å¼?br /> 'g', 'G'    --  æ ÒŽ(gu¨©)®å…·ä½“情况åQŒè‡ªåŠ¨é€‰æ‹©ç”¨æ™®é€šè¡¨½Cºæ–¹å¼è¿˜æ˜¯ç§‘学计数法方式
'a', 'A'    --   ¾l“果被格式化为带有效位数和指数的十六˜q›åˆ¶‹¹®ç‚¹æ•?/span>

3.å¯?span style="color: #ff0000">字符˜q›è¡Œæ ¼å¼åŒ?/span>åQ?br />         对字½W¦è¿›è¡Œæ ¼å¼åŒ–是非常简单的åQŒc表示字符åQŒæ ‡è¯†ä¸­'-'表示左对齐,其他ž®±æ²¡ä»€ä¹ˆäº†ã€?/span>

4.å¯?span style="color: #ff0000">癑ֈ†æ¯”符å?/span>˜q›è¡Œæ ¼å¼åŒ?/span>åQ?br />         看了上面的说明,大家会发现百分比½W¦å·“%”是特ŒDŠæ ¼å¼çš„一个前¾~€ã€‚那么我们要输入一个百分比½W¦å·è¯¥æ€Žä¹ˆåŠžå‘¢åQŸè‚¯å®šæ˜¯éœ€è¦è{义字½W¦çš„,但是要注意的是,在这里è{义字½W¦ä¸æ˜?#8220;\”åQŒè€Œæ˜¯“%”。换句话è¯ß_¼Œä¸‹é¢˜q™æ¡è¯­å¥å¯ä»¥è¾“出一ä¸?#8220;12%”åQ?br /> System.out.println(String.format("%1$d%%", 12));

5.取得òq›_°ç‹¬ç«‹çš„行分隔½W?/span>åQ?br />         System.getProperty("line.separator")可以取得òq›_°ç‹¬ç«‹çš„行分隔½W¦ï¼Œä½†æ˜¯ç”¨åœ¨format中间未免昑־—˜q‡äºŽçƒ¦çäº†ã€‚于是format函数自带了一个åã^台独立的行分隔符那就æ˜?/span>String.format("%n")ã€?br />
6.å¯?span style="color: #ff0000">日期¾cÕdž‹˜q›è¡Œæ ¼å¼åŒ?/span>åQ?br />          以下日期和时间è{æ¢çš„åŽç¼€å­—ç¬¦æ˜¯äØ“ 't' å’?'T' 转换定义的。这些类型相ä¼égºŽä½†ä¸å®Œå…¨½{‰åŒäºŽé‚£äº›ç”± GNU date å’?POSIX strftime(3c) 定义的类型。提供其他è{换类型是ä¸ÞZº†è®‰K—®ç‰¹å®šäº?Java 的功能(如将 'L' 用作¿U’中的毫¿U’)ã€?br />
以下转换字符用来格式化时é—ß_¼š

'H'     24 ž®æ—¶åˆ¶çš„ž®æ—¶åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¸¤ä½æ•ŽÍ¼Œå?00 - 23ã€?/span>
'I'     12 ž®æ—¶åˆ¶çš„ž®æ—¶åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¸¤ä½æ•ŽÍ¼Œå?01 - 12ã€?/span>
'k'     24 ž®æ—¶åˆ¶çš„ž®æ—¶åQŒå³ 0 - 23ã€?/span>
'l'     12 ž®æ—¶åˆ¶çš„ž®æ—¶åQŒå³ 1 - 12ã€?/span>
'M'     ž®æ—¶ä¸­çš„分钟åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¸¤ä½æ•ŽÍ¼Œå?00 - 59ã€?/span>
'S'     分钟中的¿U’,被格式化为必要时带前导零的两位数åQŒå³ 00 - 60 åQ?60" 是支持闰¿U’所需的一个特ŒDŠå€û|¼‰ã€?/span>
'L'     ¿U’中的毫¿U’,被格式化为必要时带前导零的三位数åQŒå³ 000 - 999ã€?/span>
'N'     ¿U’中的毫微秒åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¹?ji¨¦)位敎ͼŒå?000000000 - 999999999ã€?/span>
'p'     特定于语­a€çŽ¯å¢ƒçš?上午或下å?标记以小写åŞ式表½Cºï¼Œä¾‹å¦‚ "am" æˆ?"pm"。ä‹É用è{换前¾~€ 'T' å¯ä»¥å¼ø™¡Œž®†æ­¤è¾“出转换为大写åŞ式ã€?/span>
'z'     相对äº?GMT çš?RFC 822 格式的数字时区偏¿U»é‡åQŒä¾‹å¦?-0800ã€?/span>
'Z'     表示时区¾~©å†™å½¢å¼çš„å­—½W¦ä¸²ã€‚Formatter 的语­a€çŽ¯å¢ƒ?y¨­u)®†å–代参数的语言环境åQˆå¦‚果有åQ‰ã€?/span>
's'     自协调世界时 (UTC) 1970 òq?1 æœ?1 æ—?00:00:00 至现在所¾lè¿‡çš„秒敎ͼŒå?Long.MIN_VALUE/1000 ä¸?Long.MAX_VALUE/1000 之间的差倹{€?/span>
'Q'     自协调世界时 (UTC) 1970 òq?1 æœ?1 æ—?00:00:00 至现在所¾lè¿‡çš„æ¯«¿U’æ•°åQŒå³ Long.MIN_VALUE ä¸?Long.MAX_VALUE 之间的差倹{€?/span>

以下转换字符用来格式化日期:
'B'     特定于语­a€çŽ¯å¢ƒçš„æœˆä»½å…¨¿UŽÍ¼Œä¾‹å¦‚ "January" å’?"February"ã€?/span>
'b'     特定于语­a€çŽ¯å¢ƒçš„æœˆä»½ç®€¿UŽÍ¼Œä¾‹å¦‚ "Jan" å’?"Feb"ã€?/span>
'h'     ä¸?'b' 相同ã€?/span>
'A'     特定于语­a€çŽ¯å¢ƒçš„æ˜ŸæœŸå‡ å…¨ç§°åQŒä¾‹å¦?"Sunday" å’?"Monday"
'a'     特定于语­a€çŽ¯å¢ƒçš„æ˜ŸæœŸå‡ ½Ž€¿UŽÍ¼Œä¾‹å¦‚ "Sun" å’?"Mon"
'C'     除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数åQŒå³ 00 - 99
'Y'     òq´ä†¾åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„å››ä½æ•ŽÍ¼ˆè‡›_°‘åQ‰ï¼Œä¾‹å¦‚åQ?092 ½{‰äºŽæ ¼é‡Œé«˜åˆ©åŽ†çš„ 92 CEã€?/span>
'y'     òq´ä†¾çš„æœ€åŽä¸¤ä½æ•°åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¸¤ä½æ•ŽÍ¼Œå?00 - 99ã€?/span>
'j'     一òq´ä¸­çš„天敎ͼŒè¢«æ ¼å¼åŒ–为必要时带前导零的三位数åQŒä¾‹å¦‚,对于格里高利历是 001 - 366ã€?/span>
'm'     月䆾åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶çš„ä¸¤ä½æ•ŽÍ¼Œå?01 - 13ã€?/span>
'd'     一个月中的天数åQŒè¢«æ ¼å¼åŒ–äØ“å¿…è¦æ—¶å¸¦å‰å¯¼é›¶ä¸¤ä½æ•°åQŒå³ 01 - 31
'e'     一个月中的天数åQŒè¢«æ ¼å¼åŒ–äØ“ä¸¤ä½æ•ŽÍ¼Œå?1 - 31ã€?/span>

以下转换字符用于格式化常见的日期/æ—‰™—´¾l„合ã€?/span>
'R'     24 ž®æ—¶åˆ¶çš„æ—‰™—´åQŒè¢«æ ¼å¼åŒ–䨓 "%tH:%tM"
'T'     24 ž®æ—¶åˆ¶çš„æ—‰™—´åQŒè¢«æ ¼å¼åŒ–䨓 "%tH:%tM:%tS"ã€?/span>
'r'     12 ž®æ—¶åˆ¶çš„æ—‰™—´åQŒè¢«æ ¼å¼åŒ–䨓 "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位¾|®å¯èƒ½ä¸Žè¯­è¨€çŽ¯å¢ƒæœ‰å…³ã€?/span>
'D'     日期åQŒè¢«æ ¼å¼åŒ–䨓 "%tm/%td/%ty"ã€?/span>
'F'     ISO 8601 格式的完整日期,被格式化ä¸?"%tY-%tm-%td"ã€?/span>
'c'     日期和时é—ß_¼Œè¢«æ ¼å¼åŒ–ä¸?"%ta %tb %td %tT %tZ %tY"åQŒä¾‹å¦?"Sun Jul 20 16:17:00 EDT 1969"ã€?/span>


]]>
Spring in Action 学习(f¨¤n)½W”记—第五章 事务½Ž¡ç†http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319479.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Tue, 27 Apr 2010 06:24:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2010/04/27/319479.htmlhttp://www.aygfsteel.com/huyi0616/comments/319479.htmlhttp://www.aygfsteel.com/huyi0616/archive/2010/04/27/319479.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/319479.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/319479.html阅读全文

]]>
Spring事务配置的五¿Uæ–¹å¼?/title><link>http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319478.html</link><dc:creator>一杯清èŒ?/dc:creator><author>一杯清èŒ?/author><pubDate>Tue, 27 Apr 2010 06:19:00 GMT</pubDate><guid>http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319478.html</guid><wfw:comment>http://www.aygfsteel.com/huyi0616/comments/319478.html</wfw:comment><comments>http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/huyi0616/comments/commentRss/319478.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/huyi0616/services/trackbacks/319478.html</trackback:ping><description><![CDATA[     摘要: 转自åQšhttp://www.aygfsteel.com/robbie/archive/2009/04/05/264003.html         å‰æ®µæ—‰™—´å¯¹Spring的事务配¾|®åšäº†æ¯”较深入的研究åQŒåœ¨æ­¤ä¹‹é—´å¯¹Spring的事务配¾|®è™½è¯´ä¹Ÿé…ç½®˜q‡ï¼Œä½†æ˜¯ä¸€ç›´æ²¡æœ‰ä¸€ä¸ªæ¸…楚的认识。通过˜q™æ¬¡çš„å­¦ä¹?f¨¤n)发觉Spring的事务配¾|®åª...  <a href='http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319478.html'>阅读全文</a><img src ="http://www.aygfsteel.com/huyi0616/aggbug/319478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/huyi0616/" target="_blank">一杯清èŒ?/a> 2010-04-27 14:19 <a href="http://www.aygfsteel.com/huyi0616/archive/2010/04/27/319478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZZ-大型¾|‘站架构演变和知识体¾p?http://www.aygfsteel.com/huyi0616/archive/2010/04/14/318225.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Wed, 14 Apr 2010 01:55:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2010/04/14/318225.htmlhttp://www.aygfsteel.com/huyi0616/comments/318225.htmlhttp://www.aygfsteel.com/huyi0616/archive/2010/04/14/318225.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/318225.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/318225.html
 

转自åQšhttp://www.aygfsteel.com/sterning/archive/2009/11/06/301468.html


        ä¹‹å‰ä¹Ÿæœ‰ä¸€äº›ä»‹¾lå¤§åž‹ç½‘站架构演变的文章åQŒä¾‹å¦‚LiveJournal的、ebay的,都是非常值得参考的åQŒä¸˜q‡æ„Ÿè§‰ä»–们讲的更多的是每‹Æ¡æ¼”变的¾l“æžœåQŒè€Œæ²¡æœ‰å¾ˆè¯¦ç»†çš„讲ä¸ÞZ»€ä¹ˆéœ€è¦åš˜q™æ ·çš„æ¼”å˜ï¼Œå†åŠ ä¸Šè¿‘æ¥æ„Ÿè§‰æœ‰ä¸å°‘åŒå­¦éƒ½å¾ˆéš¾æ˜Žç™½äØ“ä»€ä¹ˆä¸€ä¸ªç½‘ç«™éœ€è¦é‚£ä¹ˆå¤æ‚çš„æŠ€æœ¯ï¼ŒäºŽæ˜¯æœ‰äº†å†™è¿™½‹‡æ–‡ç« çš„æƒÏx³•åQŒåœ¨˜q™ç¯‡æ–‡ç« ä¸?ž®†é˜˜qîC¸€ä¸ªæ™®é€šçš„¾|‘站发展成大型网站过½E‹ä¸­çš„一¿Uè¾ƒä¸ºå…¸åž‹çš„æž¶æž„演变历程和所需掌握的知识体¾p»ï¼Œå¸Œæœ›èƒ½ç»™æƒ³ä»Žäº‹äº’联网行业的同学一点初步的概念åQ?)åQŒæ–‡ä¸­çš„不对之处也请各位多给点徏议,让本文真正è“v到抛砖引玉的效果ã€?/p>

 

架构演变½W¬ä¸€æ­¥ï¼šç‰©ç†åˆ†ç¦»webserver和数据库

最开始,ç”׃ºŽæŸäº›æƒÏx³•åQŒäºŽæ˜¯åœ¨äº’联¾|‘上搭徏了一个网站,˜q™ä¸ªæ—¶å€™ç”šè‡Ïxœ‰å¯èƒ½ä¸ÀLœºéƒ½æ˜¯¿UŸå€Ÿçš„åQŒä½†ç”׃ºŽ˜q™ç¯‡æ–‡ç« æˆ‘们只关注架构的演变历程åQŒå› æ­¤å°±å‡è®¾˜q™ä¸ªæ—¶å€?已经是托½Ž¡äº†ä¸€åîC¸»æœºï¼Œòq¶ä¸”有一定的带宽了,˜q™ä¸ªæ—¶å€™ç”±äºŽç½‘站具备了一定的特色åQŒå¸å¼•äº†éƒ¨åˆ†äºø™®¿é—®ï¼Œé€æ¸ä½ å‘现系¾lŸçš„压力­‘Šæ¥­‘Šé«˜åQŒå“åº”速度­‘Šæ¥­‘Šæ…¢åQŒè€Œè¿™ä¸ªæ—¶å€™æ¯”较明昄¡š„是数据库和应用互相媄响,应用出问题了åQŒæ•°æ®åº“也很å®ÒŽ(gu¨©)˜“出现问题åQŒè€Œæ•°æ®åº“出问题的时候,应用也容易出问题åQŒäºŽæ˜¯è¿›å…¥äº†½W¬ä¸€æ­¥æ¼”变阶ŒDµï¼šž®†åº”用和数据库从物理上分¼›»ï¼Œå˜æˆäº†ä¸¤å°æœºå™¨ï¼Œ˜q™ä¸ªæ—¶å€™æŠ€æœ¯ä¸Šæ²¡æœ‰ä»€ä¹ˆæ–°çš„要求,但你发现¼‹®å®žèµ·åˆ°æ•ˆæžœäº†ï¼Œ¾pȝ»Ÿåˆæ¢å¤åˆ°ä»¥å‰çš„响应速度了,òq¶ä¸”支撑住了更高的流量,òq¶ä¸”ä¸ä¼šå› äØ“æ•°æ®åº“å’Œåº”ç”¨å½¢æˆäº’ç›¸çš„åª„å“ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

˜q™ä¸€æ­¥æž¶æž„演变对技术上的知识体¾pÕdŸºæœ¬æ²¡æœ‰è¦æ±‚ã€?/p>

 

架构演变½W¬äºŒæ­¥ï¼šå¢žåŠ ™åµé¢¾~“å­˜

好景不长åQŒéšç€è®‰K—®çš„äh­‘Šæ¥­‘Šå¤šåQŒä½ å‘现响应速度又开始变慢了åQŒæŸ¥æ‰‘ÖŽŸå› ï¼Œå‘çŽ°æ˜¯è®¿é—®æ•°æ®åº“çš„æ“ä½œå¤ªå¤šï¼Œå¯ÆD‡´æ•°æ®˜qžæŽ¥ç«žäº‰‹È€çƒˆï¼Œæ‰€ä»¥å“åº”变慢,但数据库˜q?接又不能开太多åQŒå¦åˆ™æ•°æ®åº“机器压力会很高,因此考虑采用¾~“存机制来减ž®‘数据库˜qžæŽ¥èµ„源的竞争和å¯ÒŽ(gu¨©)•°æ®åº“è¯Èš„压力åQŒè¿™ä¸ªæ—¶å€™é¦–å…ˆä¹Ÿè®æ€¼šé€‰æ‹©é‡‡ç”¨squid ½{‰ç±»ä¼¼çš„æœºåˆ¶æ¥å°†¾pȝ»Ÿä¸­ç›¸å¯šw™æ€çš„™åµé¢åQˆä¾‹å¦‚一两天才会有更新的™åµé¢åQ‰è¿›è¡Œç¼“存(当然åQŒä¹Ÿå¯ä»¥é‡‡ç”¨ž®†é¡µé¢é™æ€åŒ–的方案)åQŒè¿™æ ïL(f¨¥ng)¨‹åºä¸Šå¯ä»¥ä¸åšä¿®æ”¹åQŒå°±èƒ½å¤Ÿ 很好的减ž®‘对webserver的压力以及减ž®‘数据库˜qžæŽ¥èµ„源的竞争,OKåQŒäºŽæ˜¯å¼€å§‹é‡‡ç”¨squid来做相对静态的™åµé¢çš„缓存ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

前端™åµé¢¾~“存技术,例如squidåQŒå¦‚想用好的话还得深入掌握下squid的实现方式以及缓存的失效½Ž—法½{‰ã€?/p>

 

架构演变½W¬ä¸‰æ­¥ï¼šå¢žåŠ ™åµé¢ç‰‡æ®µ¾~“å­˜

增加了squid做缓存后åQŒæ•´ä½“ç³»¾lŸçš„速度¼‹®å®žæ˜¯æå‡äº†åQŒwebserver的压力也开始下降了åQŒä½†éšç€è®‰K—®é‡çš„增加åQŒå‘现系¾lŸåˆå¼€å§‹å˜çš„æœ‰äº›æ…¢äº†ï¼Œåœ¨å° åˆîCº†squid之类的动态缓存带来的好处后,开始想能不能让现在那些动态页面里相对静态的部分也缓存è“v来呢åQŒå› æ­¤è€ƒè™‘采用¾cÖM¼¼ESI之类的页面片ŒD늼“存策略,OKåQŒäºŽæ˜¯å¼€å§‹é‡‡ç”¨ESI来做动态页面中相对静态的片段部分的缓存ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

™åµé¢ç‰‡æ®µ¾~“存技术,例如ESI½{‰ï¼Œæƒ³ç”¨å¥½çš„话同样需要掌握ESI的实现方式等åQ?/p>

 

架构演变½W¬å››æ­¥ï¼šæ•°æ®¾~“å­˜

在采用ESI之类的技术再‹Æ¡æé«˜äº†¾pȝ»Ÿçš„缓存效果后åQŒç³»¾lŸçš„压力¼‹®å®ž˜q›ä¸€æ­¥é™ä½Žäº†åQŒä½†åŒæ ·åQŒéšç€è®‰K—®é‡çš„增加åQŒç³»¾lŸè¿˜æ˜¯å¼€å§‹å˜æ…¢ï¼Œ¾lè¿‡æŸ¥æ‰¾åQŒå¯èƒ½ä¼šå‘现¾p?¾lŸä¸­å­˜åœ¨ä¸€äº›é‡å¤èŽ·å–æ•°æ®ä¿¡æ¯çš„åœ°æ–¹åQŒåƒèŽ·å–ç”¨æˆ·ä¿¡æ¯½{‰ï¼Œ˜q™ä¸ªæ—¶å€™å¼€å§‹è€ƒè™‘是不是可以将˜q™äº›æ•°æ®ä¿¡æ¯ä¹Ÿç¼“å­˜è“v来呢åQŒäºŽæ˜¯å°†˜q™äº›æ•°æ®¾~“存到本地内存,改变完毕后,完全½W¦åˆé¢„期åQŒç³»¾lŸçš„响应速度又恢复了åQŒæ•°æ®åº“的压力也再度降低了不ž®‘ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

¾~“存技术,包括像Map数据¾l“构、缓存算法、所选用的框架本íw«çš„实现机制½{‰ã€?/p>

 

架构演变½W¬äº”步: 增加webserver

好景不长åQŒå‘现随着¾pȝ»Ÿè®‰K—®é‡çš„再度增加åQŒwebserver机器的压力在高峰期会上升到比较高åQŒè¿™ä¸ªæ—¶å€™å¼€å§‹è€ƒè™‘增加一台webserveråQŒè¿™ä¹Ÿæ˜¯ä¸ÞZº†åŒæ—¶è§£å†³å¯ç”¨æ€§çš„问题åQŒé¿å…å•台的webserver down机的话就没法使用了,在做了这些考虑后,军_®šå¢žåŠ ä¸€å°webserveråQŒå¢žåŠ ä¸€å°webserveræ—Óž¼Œä¼šç¢°åˆîC¸€äº›é—®é¢˜ï¼Œå…¸åž‹çš„æœ‰åQ?/p>

1、如何让讉K—®åˆ†é…åˆ°è¿™ä¸¤å°æœºå™¨ä¸Šï¼Œ˜q™ä¸ªæ—¶å€™é€šå¸¸ä¼šè€ƒè™‘的方案是Apache自带的负载均衡方案,或LVS˜q™ç±»çš„èÊY件负载均衡方案;

2、如何保持状态信息的同步åQŒä¾‹å¦‚用户session½{‰ï¼Œ˜q™ä¸ªæ—¶å€™ä¼šè€ƒè™‘的方案有写入数据库、写入存储、cookie或同步session信息½{‰æœºåˆ¶ç­‰åQ?/p>

3、如何保持数据缓存信息的同步åQŒä¾‹å¦‚之前缓存的用户数据½{‰ï¼Œ˜q™ä¸ªæ—¶å€™é€šå¸¸ä¼šè€ƒè™‘的机制有¾~“存同步或分布式¾~“å­˜åQ?/p>

4、如何让上传文äšg˜q™äº›¾cÖM¼¼çš„功能ç‘ô¾l­æ­£å¸¸ï¼Œ˜q™ä¸ªæ—¶å€™é€šå¸¸ä¼šè€ƒè™‘的机制是使用å…׃ínæ–‡äšg¾pȝ»Ÿæˆ–存储等åQ?/p>

在解决了˜q™äº›é—®é¢˜åŽï¼Œ¾lˆäºŽæ˜¯æŠŠwebserver增加ä¸ÞZº†ä¸¤å°åQŒç³»¾lŸç»ˆäºŽæ˜¯åˆæ¢å¤åˆ°äº†ä»¥å¾€çš„速度ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

<!--[if !vml]-->大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

负蝲均衡技术(包括但不限于¼‹¬äšg负蝲均衡、èÊY件负载均衡、负载算法、linux转发协议、所选用的技术的实现¾l†èŠ‚½{‰ï¼‰ã€ä¸»å¤‡æŠ€æœ¯ï¼ˆåŒ…括但不限于ARP‹Æºéª—、linux heart-beat½{‰ï¼‰ã€çŠ¶æ€ä¿¡æ¯æˆ–¾~“存同步技术(包括但不限于Cookie技术、UDP协议、状态信息广播、所选用的缓存同步技术的实现¾l†èŠ‚½{‰ï¼‰ã€å…±äº«æ–‡ä»¶æŠ€æœ¯ï¼ˆåŒ…括但不限于NFS½{‰ï¼‰ã€å­˜å‚¨æŠ€æœ¯ï¼ˆåŒ…括但不限于存储讑֤‡½{‰ï¼‰ã€?/p>

 

架构演变½W¬å…­æ­¥ï¼šåˆ†åº“

享受了一ŒD‰|—¶é—´çš„¾pȝ»Ÿè®‰K—®é‡é«˜é€Ÿå¢žé•¿çš„òq¸ç¦åŽï¼Œå‘现¾pȝ»Ÿåˆå¼€å§‹å˜æ…¢äº†åQŒè¿™‹Æ¡åˆæ˜¯ä»€ä¹ˆçж况呢åQŒç»˜q‡æŸ¥æ‰¾ï¼Œå‘现数据库写入、更新的˜q™äº›æ“ä½œçš„部分数据库˜qžæŽ¥çš?资源竞争非常‹È€çƒˆï¼Œå¯ÆD‡´äº†ç³»¾lŸå˜æ…¢ï¼Œ˜q™ä¸‹æ€Žä¹ˆåŠžå‘¢åQŒæ­¤æ—¶å¯é€‰çš„æ–ÒŽ(gu¨©)¡ˆæœ‰æ•°æ®åº“集群和分库策略,集群斚w¢åƒæœ‰äº›æ•°æ®åº“æ”¯æŒçš„åÆˆä¸æ˜¯å¾ˆå¥½åQŒå› æ­¤åˆ†åº“ä¼šæˆäØ“æ¯”è¾ƒæ™®éçš„ç­–ç•¥ï¼Œåˆ†åº“ä¹Ÿå°±æ„å‘³ç€è¦å¯¹åŽŸæœ‰½E‹åº˜q›è¡Œä¿®æ”¹åQŒä¸€é€šä¿®æ”¹å®žçŽ°åˆ†åº“åŽåQŒä¸é”™ï¼Œç›®æ ‡è¾‘Öˆ°äº†ï¼Œ¾pȝ»Ÿæ¢å¤ç”šè‡³é€Ÿåº¦æ¯”以前还快了ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

<!--[if !vml]-->大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

˜q™ä¸€æ­¥æ›´å¤šçš„æ˜¯éœ€è¦ä»Žä¸šåŠ¡ä¸Šåšåˆç†çš„åˆ’åˆ†ï¼Œä»¥å®žçŽ°åˆ†åº“ï¼Œå…·ä½“æŠ€æœ¯ç»†èŠ‚ä¸Šæ²¡æœ‰å…¶ä»–çš„è¦æ±‚ï¼›

但同旉™šç€æ•°æ®é‡çš„增大和分库的˜q›è¡ŒåQŒåœ¨æ•°æ®åº“的设计、调优以及维护上需要做的更好,因此对这些方面的技术还是提å‡ÞZº†å¾ˆé«˜çš„要求的ã€?/p>

 

架构演变½W¬ä¸ƒæ­¥ï¼šåˆ†è¡¨ã€DAL和分布式¾~“å­˜

随着¾pȝ»Ÿçš„不断运行,数据量开始大òq…度增长åQŒè¿™ä¸ªæ—¶å€™å‘现分库后查询仍然会有些慢åQŒäºŽæ˜¯æŒ‰ç…§åˆ†åº“的思想开始做分表的工作,当然åQŒè¿™ä¸å¯é¿å…çš„会需要对½E‹åº ˜q›è¡Œä¸€äº›ä¿®æ”¹ï¼Œä¹Ÿè®¸åœ¨è¿™ä¸ªæ—¶å€™å°±ä¼šå‘现应用自å·Þp¦å…›_¿ƒåˆ†åº“分表的规则等åQŒè¿˜æ˜¯æœ‰äº›å¤æ‚çš„åQŒäºŽæ˜¯èŒç”Ÿèƒ½å¦å¢žåŠ ä¸€ä¸ªé€šç”¨çš„æ¡†æž¶æ¥å®žçŽ°åˆ†åº“åˆ†è¡¨çš„æ•°æ®è®¿é—®ï¼Œ˜q™ä¸ªåœ¨ebay的架构中对应的就是DALåQŒè¿™ä¸ªæ¼”变的˜q‡ç¨‹ç›¸å¯¹è€Œè¨€éœ€è¦èŠ±è´¹è¾ƒé•¿çš„æ—‰™—´åQŒå½“ç„Óž¼Œä¹Ÿæœ‰å¯èƒ½˜q™ä¸ªé€šç”¨çš„æ¡†æž¶ä¼š½{‰åˆ°åˆ†è¡¨åšå®ŒåŽæ‰å¼€å§‹åšåQŒåŒæ—Óž¼Œåœ¨è¿™ä¸ªé˜¶ŒDµå¯ èƒ½ä¼šå‘çŽ°ä¹‹å‰çš„ç¼“å­˜åŒæ­¥æ–¹æ¡ˆå‡ºçŽ°é—®é¢˜ï¼Œå› äØ“æ•°æ®é‡å¤ªå¤§ï¼Œå¯ÆD‡´çŽ°åœ¨ä¸å¤ªå¯èƒ½ž®†ç¼“存存在本圎ͼŒç„¶åŽåŒæ­¥çš„æ–¹å¼ï¼Œéœ€è¦é‡‡ç”¨åˆ†å¸ƒå¼¾~“å­˜æ–ÒŽ(gu¨©)¡ˆäº†ï¼ŒäºŽæ˜¯åQŒåˆæ˜¯ä¸€é€šè€ƒå¯Ÿå’ŒæŠ˜¼‚¨ï¼Œ¾lˆäºŽæ˜¯å°†å¤§é‡çš„æ•°æ®ç¼“å­˜è{¿UÕdˆ°åˆ†å¸ƒå¼ç¼“存上了ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

<!--[if !vml]-->大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

 

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

分表更多的同æ äh˜¯ä¸šåŠ¡ä¸Šçš„åˆ’åˆ†åQŒæŠ€æœ¯ä¸Šæ¶‰åŠåˆ°çš„会有动态hash½Ž—法、consistent hash½Ž—法½{‰ï¼›

DAL涉及到比较多的复杂技术,例如数据库连接的½Ž¡ç†åQˆè¶…时、异常)、数据库操作的控åˆÓž¼ˆ­‘…时、异常)、分库分表规则的ž®è£…½{‰ï¼›

 

架构演变½W¬å…«æ­¥ï¼šå¢žåŠ æ›´å¤šçš„webserver

在做完分库分表这些工作后åQŒæ•°æ®åº“上的压力已经降到比较低了åQŒåˆå¼€å§‹è¿‡ç€æ¯å¤©çœ‹ç€è®‰K—®é‡æš´å¢žçš„òq¸ç¦ç”Ÿæ´»äº†ï¼Œ½Hç„¶æœ‰ä¸€å¤©ï¼Œå‘现¾pȝ»Ÿçš„访问又开始有变慢的趋åŠ?了,˜q™ä¸ªæ—¶å€™é¦–先查看数据库åQŒåŽ‹åŠ›ä¸€åˆ‡æ­£å¸¸ï¼Œä¹‹åŽæŸ¥çœ‹webserveråQŒå‘现apacheé˜Õd¡žäº†å¾ˆå¤šçš„è¯äh±‚åQŒè€Œåº”用服务器å¯ÒŽ(gu¨©)¯ä¸ªè¯·æ±‚也是比较快的,看来 æ˜¯è¯·æ±‚æ•°å¤ªé«˜å¯ÆD‡´éœ€è¦æŽ’队等待,响应速度变慢åQŒè¿™˜q˜å¥½åŠžï¼Œä¸€èˆ¬æ¥è¯ß_¼Œ˜q™ä¸ªæ—¶å€™ä¹Ÿä¼šæœ‰äº›é’±äº†ï¼ŒäºŽæ˜¯æ·ÕdŠ ä¸€äº›webserver服务器,在这个添åŠ?webserver服务器的˜q‡ç¨‹åQŒæœ‰å¯èƒ½ä¼šå‡ºçް几¿UæŒ‘战:

1、Apacheçš„èÊY负蝲或LVS软负载等无法承担巨大的web讉K—®é‡ï¼ˆè¯äh±‚˜qžæŽ¥æ•°ã€ç½‘¾lœæµé‡ç­‰åQ‰çš„调度了,˜q™ä¸ªæ—¶å€™å¦‚果经费允许的话,会采取的æ–ÒŽ(gu¨©)¡ˆæ˜¯è´­ 买硬件负载,例如F5、Netsclar、Athelon之类的,如经费不允许的话åQŒä¼šé‡‡å–的方案是ž®†åº”用从逻辑上做一定的分类åQŒç„¶åŽåˆ†æ•£åˆ°ä¸åŒçš„èÊY负蝲集群中;

2、原有的一些状态信息同步、文件共享等æ–ÒŽ(gu¨©)¡ˆå¯èƒ½ä¼šå‡ºçŽ°ç“¶é¢ˆï¼Œéœ€è¦è¿›è¡Œæ”¹˜q›ï¼Œä¹Ÿè®¸˜q™ä¸ªæ—¶å€™ä¼šæ ÒŽ(gu¨©)®æƒ…况¾~–写½W¦åˆ¾|‘站业务需求的分布式文件系¾lŸç­‰åQ?/p>

在做完这些工作后åQŒå¼€å§‹è¿›å…¥ä¸€ä¸ªçœ‹ä¼¼å®Œ¾ŸŽçš„æ— é™ä¼¸ç¾ƒçš„æ—¶ä»£ï¼Œå½“网站流量增加时åQŒåº”对的解决æ–ÒŽ(gu¨©)¡ˆž®±æ˜¯ä¸æ–­çš„æ·»åŠ webserverã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

                                                   大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

åˆîCº†˜q™ä¸€æ­¥ï¼Œéšç€æœºå™¨æ•°çš„不断增长、数据量的不断增长和对系¾lŸå¯ç”¨æ€§çš„要求­‘Šæ¥­‘Šé«˜åQŒè¿™ä¸ªæ—¶å€™è¦æ±‚å¯¹æ‰€é‡‡ç”¨çš„æŠ€æœ¯éƒ½è¦æœ‰æ›´äØ“æ·±å…¥çš„ç†è§£ï¼Œòq‰™œ€è¦æ ¹æ®ç½‘站的需求来做更加定制性质的äñ”品ã€?/p>

 

架构演变½W¬ä¹(ji¨¦)步:数据è¯Õd†™åˆ†ç¦»å’Œå»‰ä»·å­˜å‚¨æ–¹æ¡?/p>

½Hç„¶æœ‰ä¸€å¤©ï¼Œå‘现˜q™ä¸ªå®Œç¾Žçš„æ—¶ä»£ä¹Ÿè¦ç»“束了åQŒæ•°æ®åº“的噩梦又一‹Æ¡å‡ºçŽ°åœ¨çœ¼å‰äº†ï¼Œç”׃ºŽæ·ÕdŠ çš„webserverå¤ªå¤šäº†ï¼Œå¯ÆD‡´æ•°æ®åº“连接的资源˜q˜æ˜¯ä¸å¤Ÿç”¨ï¼Œè€Œè¿™ä¸ªæ—¶å€™åˆå·²ç»åˆ†åº“分表了,开始分析数据库的压力状况,可能会发现数据库的读写比很高åQŒè¿™ä¸ªæ—¶å€™é€šå¸¸ä¼šæƒ³åˆ°æ•°æ®è¯»å†™åˆ†¼›Èš„æ–ÒŽ(gu¨©)¡ˆåQŒå½“ç„Óž¼Œ˜q™ä¸ªæ–ÒŽ(gu¨©)¡ˆè¦å®žçŽ°åÆˆä¸?å®ÒŽ(gu¨©)˜“åQŒå¦å¤–,可能会发çŽîC¸€äº›æ•°æ®å­˜å‚¨åœ¨æ•°æ®åº“上有些‹¹ªè´¹åQŒæˆ–者说˜q‡äºŽå ç”¨æ•°æ®åº“资源,因此在这个阶ŒDµå¯èƒ½ä¼šå½¢æˆçš„æž¶æž„演变是实现数据è¯Õd†™åˆ†ç¦»åQŒåŒæ—¶ç¼–写一些更为廉ä»ïL(f¨¥ng)š„存储æ–ÒŽ(gu¨©)¡ˆåQŒä¾‹å¦‚BigTable˜q™ç§ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

<!--[if !vml]-->大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

<!--[endif]-->

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

数据è¯Õd†™åˆ†ç¦»è¦æ±‚å¯ÒŽ(gu¨©)•°æ®åº“的复制、standby½{‰ç­–略有深入的掌握和理解åQŒåŒæ—¶ä¼šè¦æ±‚具备自行实现的技术;

廉ä­h(hu¨¢n)存储æ–ÒŽ(gu¨©)¡ˆè¦æ±‚对OS的文件存储有深入的掌握和理解åQŒåŒæ—¶è¦æ±‚对采用的语­a€åœ¨æ–‡ä»¶è¿™å—的实现有深入的掌握ã€?/p>

 

架构演变½W¬åæ­¥ï¼š˜q›å…¥å¤§åž‹åˆ†å¸ƒå¼åº”用时代和廉ä­h(hu¨¢n)服务器群梦想时代

¾lè¿‡ä¸Šé¢˜q™ä¸ªæ¼«é•¿è€Œç—›è‹¦çš„˜q‡ç¨‹åQŒç»ˆäºŽæ˜¯å†åº¦˜qŽæ¥äº†å®Œ¾ŸŽçš„æ—¶ä»£åQŒä¸æ–­çš„增加webserverž®±å¯ä»¥æ”¯æ’‘越来越高的讉K—®é‡äº†åQŒå¯¹äºŽå¤§åž‹ç½‘站而言åQŒäh气的重要æ¯?庸置疑,随着人气的越来越高,各种各样的功能需求也开始爆发性的增长åQŒè¿™ä¸ªæ—¶å€™çªç„¶å‘玎ͼŒåŽŸæ¥éƒ¨çÖv在webserver上的那个web应用已经非常庞大 了,当多个团队都开始对其进行改动时åQŒå¯çœŸæ˜¯ç›¸å½“的不方便åQŒå¤ç”¨æ€§ä¹Ÿç›¸å½“¾pŸç³•åQŒåŸºæœ¬æ˜¯æ¯ä¸ªå›¢é˜Ÿéƒ½åšäº†æˆ–多或ž®‘重复的事情åQŒè€Œä¸”部çÖv和维护也是相当的éºÈƒ¦åQ?å› äØ“åºžå¤§çš„åº”ç”¨åŒ…åœ¨N台机器上复制、启动都需要耗费不少的时é—ß_¼Œå‡ºé—®é¢˜çš„æ—¶å€™ä¹Ÿä¸æ˜¯å¾ˆå¥½æŸ¥ï¼Œå¦å¤–一个更¾pŸç³•的状冉|˜¯å¾ˆæœ‰å¯èƒ½ä¼šå‡ºçŽ°æŸä¸ªåº”ç”¨ä¸Šçš„bugž®±å¯¼ 致了全站都不可用åQŒè¿˜æœ‰å…¶ä»–çš„åƒè°ƒä¼˜ä¸å¥½æ“ä½œï¼ˆå› äØ“æœºå™¨ä¸Šéƒ¨¾|²çš„应用什么都要做åQŒæ ¹æœ¬å°±æ— æ³•˜q›è¡Œé’ˆå¯¹æ€§çš„调优åQ‰ç­‰å› ç´ åQŒæ ¹æ®è¿™æ ïL(f¨¥ng)š„分析åQŒå¼€å§‹ç—›ä¸‹å†³å¿ƒï¼Œž®?¾pȝ»Ÿæ ÒŽ(gu¨©)®èŒè´£˜q›è¡Œæ‹†åˆ†åQŒäºŽæ˜¯ä¸€ä¸ªå¤§åž‹çš„分布式应用就诞生了,通常åQŒè¿™ä¸ªæ­¥éª¤éœ€è¦è€—费相当长的旉™—´åQŒå› ä¸ÞZ¼š¼„°åˆ°å¾ˆå¤šçš„æŒ‘战:

1、拆成分布式后需要提供一个高性能、稳定的通信框架åQŒåƈ且需要支持多¿Uä¸åŒçš„通信和远½E‹è°ƒç”¨æ–¹å¼ï¼›

2、将一个庞大的应用拆分需要耗费很长的时é—ß_¼Œéœ€è¦è¿›è¡Œä¸šåŠ¡çš„æ•´ç†å’Œç³»¾lŸä¾èµ–å…³¾pÈš„æŽ§åˆ¶½{‰ï¼›

3、如何运¾lß_¼ˆä¾èµ–½Ž¡ç†ã€è¿è¡Œçжå†ëŠ®¡ç†ã€é”™è¯¯è¿½ítªã€è°ƒä¼˜ã€ç›‘控和报警½{‰ï¼‰å¥½è¿™ä¸ªåºžå¤§çš„分布式应用ã€?/p>

¾lè¿‡˜q™ä¸€æ­¥ï¼Œå·®ä¸å¤šç³»¾lŸçš„æž¶æž„˜q›å…¥ç›¸å¯¹½E›_®šçš„阶ŒDµï¼ŒåŒæ—¶ä¹Ÿèƒ½å¼€å§‹é‡‡ç”¨å¤§é‡çš„廉ä­h(hu¨¢n)机器来支撑着巨大的访问量和数据量åQŒç»“合这套架构以及这么多‹Æ¡æ¼”变过½E‹å¸å–çš„¾léªŒæ¥é‡‡ç”¨å…¶ä»–各¿Uå„æ ïL(f¨¥ng)š„æ–ÒŽ(gu¨©)³•来支撑着­‘Šæ¥­‘Šé«˜çš„访问量ã€?/p>

看看˜q™ä¸€æ­¥å®ŒæˆåŽ¾pȝ»Ÿçš„图½Cºï¼š

<!--[if !vml]-->大型¾|‘站架构演变和知识体¾p? - 怪狗 - 怪狗

<!--[endif]-->

˜q™ä¸€æ­¥æ¶‰åŠåˆ°äº†è¿™äº›çŸ¥è¯†ä½“¾p»ï¼š

˜q™ä¸€æ­¥æ¶‰åŠçš„知识体系非常的多åQŒè¦æ±‚对通信、远½E‹è°ƒç”¨ã€æ¶ˆæ¯æœºåˆ¶ç­‰æœ‰æ·±å…¥çš„理解和掌握,要求的都是从理论、硬件çñ”、操作系¾lŸçñ”以及所采用的语­a€çš„实现都有清楚的理解ã€?/p>

˜qç»´˜q™å—涉及的知识体¾pÖM¹Ÿéžå¸¸çš„多åQŒå¤šæ•°æƒ…况下需要掌握分布式òq¶è¡Œè®¡ç®—、报表、监控技术以及规则策略等½{‰ã€?/p>

说è“v来确实不怎么费力åQŒæ•´ä¸ªç½‘站架构的¾lå…¸æ¼”变˜q‡ç¨‹éƒ½å’Œä¸Šé¢æ¯”较的类ä¼û|¼Œå½“ç„¶åQŒæ¯æ­¥é‡‡å–çš„æ–ÒŽ(gu¨©)¡ˆåQŒæ¼”变的步骤有可能有不同åQŒå¦å¤–,ç”׃ºŽ¾|‘站的业务不同,会有不同的专业技术的需求,˜q™ç¯‡blog更多的是从架构的角度来讲解演变的˜q‡ç¨‹åQŒå½“ç„Óž¼Œå…¶ä¸­˜q˜æœ‰å¾ˆå¤šçš„æŠ€æœ¯ä¹Ÿæœªåœ¨æ­¤æåŠï¼Œåƒæ•°æ®åº“集群、数据挖掘、搜索等åQŒä½†åœ¨çœŸå®žçš„æ¼”变˜q‡ç¨‹ä¸­è¿˜ä¼šå€ŸåŠ©åƒæå‡ç¡¬ä»‰™…¾|®ã€ç½‘¾lœçŽ¯å¢ƒã€æ”¹é€ æ“ä½œç³»¾lŸã€CDN镜像½{‰æ¥æ”¯æ’‘更大的流量,因此在真实的发展˜q‡ç¨‹ä¸­è¿˜ä¼šæœ‰å¾ˆå¤šçš„不同,另外一个大型网站要做到的远˜qœä¸ä»…仅上面˜q™äº›åQŒè¿˜æœ‰åƒå®‰å…¨ã€è¿¾l´ã€è¿è¥ã€æœåŠ¡ã€å­˜å‚¨ç­‰åQŒè¦åšå¥½ä¸€ä¸ªå¤§åž‹çš„¾|‘站真的很不å®ÒŽ(gu¨©)˜“åQŒå†™˜q™ç¯‡æ–‡ç« æ›´å¤šçš„æ˜¯å¸Œæœ›èƒ½å¤Ÿå¼•出更多大型¾|‘站架构演变的介¾lï¼Œ:)ã€?/p>

ps:最后附上几½‹‡LiveJournal架构演变的文章:

从LiveJournal后台发展看大规模¾|‘站性能优化æ–ÒŽ(gu¨©)³•

http://blog.zhangjianfeng.com/article/743   

另外从这里:http://www.danga.com/words/大家可以扑ֈ°æ›´å¤šå…³äºŽçŽ°åœ¨LiveJournal¾|‘站架构的介¾lã€?/p>

 



]]>
JS¾_„¡¡®è®¡ç®—http://www.aygfsteel.com/huyi0616/archive/2010/03/29/316794.html一杯清èŒ?/dc:creator>一杯清èŒ?/author>Mon, 29 Mar 2010 03:05:00 GMThttp://www.aygfsteel.com/huyi0616/archive/2010/03/29/316794.htmlhttp://www.aygfsteel.com/huyi0616/comments/316794.htmlhttp://www.aygfsteel.com/huyi0616/archive/2010/03/29/316794.html#Feedback0http://www.aygfsteel.com/huyi0616/comments/commentRss/316794.htmlhttp://www.aygfsteel.com/huyi0616/services/trackbacks/316794.html 1function accAdd(arg1,arg2)
 2        var r1,r2,m; 
 3        try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
 4        try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
 5        m=Math.pow(10,Math.max(r1,r2)) 
 6        return (arg1*m+arg2*m)/
 7}
 
 8function accSub(arg1,arg2)
 9        var r1,r2,m; 
10        try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
11        try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
12        m=Math.pow(10,Math.max(r1,r2)) 
13        return (arg1*m-arg2*m)/
14}

15function accDiv(arg1,arg2)
16    var t1=0,t2=0,r1,r2; 
17    try{t1=arg1.toString().split(".")[1].length}catch(e){} 
18    try{t2=arg2.toString().split(".")[1].length}catch(e){} 
19    with(Math)
20        r1=new Number(arg1.toString().replace(".","")) 
21        r2=new Number(arg2.toString().replace(".","")) 
22        return (r1/r2)*pow(10,t2-t1); 
23    }
 
24}
 

]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ¹ó¸ÛÊÐ| ÎÚËÕÊÐ| Ò¦°²ÏØ| ÈôÇ¼ÏØ| °Í³þÏØ| ÖÐÎÀÊÐ| ÑÀ¿ËʯÊÐ| ÁøºÓÏØ| ×ñÒåÊÐ| ÎýÁÖºÆÌØÊÐ| Ì©ÐËÊÐ| ½ÒÎ÷ÏØ| ½ðÌÃÏØ| ÕòÔ¶ÏØ| Æ½Ô¶ÏØ| À³ÎßÊÐ| ȪÖÝÊÐ| äµÔ´ÏØ| ÍòÉ½ÌØÇø| À´±öÊÐ| ÅíÔóÏØ| ¹§³Ç| ãòÎ÷ÏØ| ½¨ÑôÊÐ| ËçÑôÏØ| ËÞËÉÏØ| ³µÖÂ| ËìÏªÏØ| Èð°²ÊÐ| Èê³ÇÏØ| Ä®ºÓÏØ| ¶Ø»ÍÊÐ| ¶«ÑôÊÐ| ³¤¸ðÊÐ| ·áË³ÏØ| º£Ô­ÏØ| Î÷³ÇÇø| Ð˺ÍÏØ| ºâË®ÊÐ| °¢Í¼Ê²ÊÐ| ±±°²ÊÐ|