解决æ–ÒŽ(gu¨©)¡ˆåQ?/p>
¾l“æžœåQ?/p>
“**********************************
对象'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>
  2. ç”׃ºŽä¸€ä¸ªæˆ–多个对象讉K—®æ¤åˆ—错误的解军_Šžæ³?/a>
  3. SQL Server】sqlè¯å¥åˆ 除表的有默认值的åˆ?/a>
  4. Alter Table修改表结构的错误åŠè§£å†Ïx–¹æ³?/a>
一ã€ç”¨å‰å¿…å¤?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"> </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 as text for IE
label.html(" ").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>
上é¢çš„说明过于枯燥,我们æ¥çœ‹å‡ 个具体的例å。需è¦ç‰¹åˆ«æ³¨æ„的两点是:
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ލ.
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));转自å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ºï¼š
˜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ºï¼š
˜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ºï¼š
˜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ºï¼š
˜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]-->
˜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]-->
˜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]-->
˜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ºï¼š
˜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]-->
<!--[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]-->
<!--[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>