Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
設(shè)計(jì)網(wǎng)站時(shí),經(jīng)常需要做圖標(biāo)響應(yīng),例如用戶(hù)點(diǎn)擊圖標(biāo),后臺(tái)響應(yīng)用戶(hù)的操作。本文對(duì)圖像分區(qū)響應(yīng)的設(shè)計(jì)方式進(jìn)行介紹。
圖像響應(yīng)一般是通過(guò)在圖像上設(shè)置超鏈接實(shí)現(xiàn)的,代碼示例如下:
<a href="這里寫(xiě)鏈接地址 "> //設(shè)置超鏈接
<img src="圖片名稱(chēng).圖片格式" > //定義圖像
</a>
例如圖像示例如下:
圖標(biāo)示例
這種情況,沒(méi)有對(duì)圖像分區(qū)處理,因此只要點(diǎn)擊頁(yè)面中的任意位置(包括圖像上的任意位置或者頁(yè)面的空白處),均會(huì)跳轉(zhuǎn)到對(duì)應(yīng)的鏈接。
但是有時(shí)候一張圖,可能在用戶(hù)點(diǎn)擊不同的位置,需要不同的響應(yīng),此時(shí)需要進(jìn)行分區(qū)響應(yīng),具體代碼示例如下:
<img src="圖像名稱(chēng).圖片格式" usemap="#名稱(chēng)1"> //定義圖像,以及圖像的名稱(chēng)
<map name="名稱(chēng)1"> //引用前文中的圖像
<area href="鏈接地址1" shape="rect" coords="a1,b1,a2,b2"> //定義圖像區(qū)域的超鏈接和在圖像中的像素位置
<area href="鏈接地址2" shape="rect" coords="c1,d1,c2,d2">//同上
</map>
其中,shape表示圖像區(qū)域的形狀,例如rect/circle等等。圖像中某個(gè)圖像分區(qū)的位置可以通過(guò)前文form實(shí)現(xiàn),例如:
<form>
<input type="image" src="圖像名稱(chēng).圖片格式">
</form>
當(dāng)顯示圖像之后,可以點(diǎn)擊圖像的任意位置,此時(shí)鏈接處會(huì)顯示該點(diǎn)擊位置在圖像中的像素位置,例如:
像素位置
TML是一種用來(lái)描述網(wǎng)頁(yè)的標(biāo)記性語(yǔ)言。學(xué)習(xí)HTML可能并不難,主要是要記一些HTML標(biāo)簽和標(biāo)簽代表的含義。下面PHP程序員雷雪松根據(jù)使用的情況,整理出平時(shí)常用的HTML標(biāo)簽。
HTML基礎(chǔ)之HTML常用標(biāo)簽-PHP程序員雷雪松的博客
<!--<!DOCTYPE> 是HTML5聲明,<!DOCTYPE> 必須是 HTML 文檔的第一行,位于 <html> 標(biāo)簽之前。<!DOCTYPE>是指示 web 瀏覽器關(guān)于頁(yè)面使用哪個(gè) HTML 版本進(jìn)行編寫(xiě)的指令。-->
<!DOCTYPE html>
<html>
<!-- head標(biāo)簽是所有頭部元素的容器。head標(biāo)簽內(nèi)的元素可包含腳本、樣式表和提供頁(yè)面的元信息等等。以下標(biāo)簽都可以添加到 head 部分:title、base、link、meta、script 以及style。頭部的內(nèi)容不會(huì)顯示在瀏覽器的。 -->
<head>
<!-- 設(shè)置字符集,如果字符集不對(duì),可能導(dǎo)致亂碼。一般建議utf-8國(guó)際編碼 -->
<meta http-equiv="Content-Type" content="text/html; charset=gb2312或utf-8或gbk" />
<!-- SEO相關(guān)標(biāo)簽,title定義文檔的標(biāo)題,百度建議一般不要超過(guò)32位,meta定義頁(yè)面關(guān)鍵詞和頁(yè)面的描述-->
<title>網(wǎng)頁(yè)標(biāo)題</title>
<meta name="keywords" content="PHP程序員,技術(shù)博客,個(gè)人博客,雷雪松" />
<meta name="description" content="PHP程序員,雷雪松(Raykaeso)的博客是一個(gè)優(yōu)秀的個(gè)人技術(shù)博客。PHP程序員雷雪松的博客記錄了Linux學(xué)習(xí),PHP開(kāi)發(fā)與編程,Web前端開(kāi)發(fā),MySQL學(xué)習(xí)和教程,NoSQL數(shù)據(jù)庫(kù)教程以及個(gè)人的人生經(jīng)歷和觀點(diǎn)。" />
<link rel="stylesheet" type="text/css" href="main.css" />
<script type="text/javascript" src="main.js"></script>
</head>
<!-- 正文部分,所有在瀏覽器上可見(jiàn)的內(nèi)容必須寫(xiě)在body標(biāo)簽內(nèi)部 -->
<body>
</body>
</html>
a、布局標(biāo)簽
div標(biāo)簽定義文檔中的分區(qū)或節(jié)(division/section),可以把文檔分割為獨(dú)立的、不同的部分,主要用于布局。
aside標(biāo)簽的內(nèi)容可用作文章的側(cè)欄,<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
header標(biāo)簽定義頁(yè)面的頭部(介紹信息),<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
section標(biāo)簽定義文檔中的節(jié)(section、區(qū)段)。比如章節(jié)、頁(yè)眉、頁(yè)腳或文檔中的其他部分,<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
footer 標(biāo)簽定義文檔或節(jié)的頁(yè)腳,通常包含文檔的作者、版權(quán)信息、使用條款鏈接、聯(lián)系信息等等,<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
article標(biāo)簽規(guī)定文章獨(dú)立的其他內(nèi)容,比如:標(biāo)題、內(nèi)容、評(píng)論,<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
b、文本標(biāo)簽
h1-h6標(biāo)簽可定義標(biāo)題
p標(biāo)簽定義段落
b/strong標(biāo)簽加粗
em標(biāo)簽來(lái)表示強(qiáng)調(diào)的文本,斜體
strong標(biāo)簽表示重要文本
u標(biāo)簽下劃線
s標(biāo)簽刪除線
br標(biāo)簽表示回車(chē)換行
hr標(biāo)簽表示水平線
span標(biāo)簽被用來(lái)組合文檔中的行內(nèi)元素。
blockquote標(biāo)簽表示塊引用
pre標(biāo)簽可定義預(yù)格式化的文本,保持原有格式的一種標(biāo)簽。
sub標(biāo)簽下標(biāo),
sup>標(biāo)簽上標(biāo)
表示一個(gè)空格
©表示版權(quán)符
<表示<
>表示>
c、a標(biāo)簽定義超鏈接,指定頁(yè)面間的跳轉(zhuǎn)。鏈接可以指向外部鏈接或者頁(yè)面內(nèi)部id錨點(diǎn),可以在當(dāng)前頁(yè)面打開(kāi),新開(kāi)窗口。
<a href="指向的鏈接地址或者網(wǎng)址#ID名" target="_blank|_self|_top|_parent">百度</a>
d、多媒體標(biāo)簽
img標(biāo)簽主要在網(wǎng)頁(yè)中插入圖像,可以定義圖片替換文本、顯示寬度和高度、是否帶邊框,建議等比例設(shè)置,否則圖像會(huì)變形。
<img src="圖片地址" alt="替換文本,圖片打不開(kāi)的時(shí)候顯示" width="圖片寬度" height="高度" border="0" />
audio標(biāo)簽定義聲音,比如音樂(lè)或其他音頻流。<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
<audio src="someaudio.wav">您的瀏覽器不支持 audio 標(biāo)簽。</audio>
video標(biāo)簽定義視頻,比如電影片段或其他視頻流。<span style="color: #ff0000;">html5新增標(biāo)簽</span>。
<video src="movie.ogg" controls="controls">您的瀏覽器不支持 video 標(biāo)簽。</video>
e、序列化標(biāo)簽
ul和li無(wú)序列表標(biāo)簽
<ul>
<li>HTML</li>
<li>JS</li>
<li>PHP</li>
</ul>
ol和li有序列表標(biāo)簽,可以使用type屬性規(guī)定有序列表符號(hào)的類(lèi)型。1 按數(shù)字有序排列,為默認(rèn)值,(1、2、3、4);a 按小寫(xiě)字母有序排列,(a、b、c、d);A 按字母大寫(xiě)有序排列,(A、B、C、D)。i 按小寫(xiě)羅馬字母有序,(i, ii, iii, iv);I 按小寫(xiě)羅馬字母有序,(I, II, III, IV)。
<ol>
<li>HTML</li>
<li>JS</li>
<li>PHP</li>
</ol>
dl標(biāo)簽定義了定義列表(definition list),dl標(biāo)簽用于結(jié)合 dt(定義列表中的項(xiàng)目)和 dd(描述列表中的項(xiàng)目)。
<dl>
<dt>計(jì)算機(jī)</dt>
<dd>用來(lái)計(jì)算的儀器 ... ...</dd>
</dl>
f、表格標(biāo)簽
table標(biāo)簽和tr標(biāo)簽,th標(biāo)簽和td標(biāo)簽,合并單元格。
<table width="100%" height="193" border="1" cellpadding="0" cellspacing="0" bordercolor="#FF0000" bgcolor="#000000" background="">
<tr>
<th>標(biāo)題</th>
<th>標(biāo)題</th>
</tr>
<tr>
<!-- 合并橫向單元格 -->
<td colspan="2" nowrap="nowrap">&nbsp;</td>
</tr>
<tr>
<td></td>
<!-- 合并縱向單元格 -->
<td rowspan="2"> </td>
</tr>
<tr>
<td height="16"> </td>
</tr>
</table>
g、表單標(biāo)簽
form標(biāo)簽定義提交方式、提交地址、表單字符集以及如何對(duì)其進(jìn)行編碼,需要提交的表單一定要放在form標(biāo)簽內(nèi)。
<form id="form1" name="form1" method="post|get" enctype="multipart/form-data" action="提交到的地址"></form>
input標(biāo)簽用于搜集用戶(hù)信息
<input name="userName" type="text" maxlength="5" size="100" value="asdfasdfasfd" />
密碼,輸入的字符會(huì)被掩碼(顯示為星號(hào)或原點(diǎn))
<input name="pwd" type="password" maxlength="5" size="100" value="" />
文件類(lèi)型的表單,上傳文件時(shí),form表單一定要設(shè)置為enctype="multipart/form-data"
<input type="file" name="file" />
隱藏表單
<input type="hidden" name="country" value="China" />
提交
<input type="submit" name="Submit" value="提交" disabled="disabled" />
重置
<input type="reset" name="Submit2" value="重置" />
radio單選
<input name="sex" type="radio" value="1" />男
<input name="sex" type="radio" value="2" checked="checked" />女
checkbox多選
<input name="skill" type="checkbox" value="1" checked="checked" />PHP
<input name="skill" type="checkbox" value="2" />前端
<input name="skill" type="checkbox" value="2" />數(shù)據(jù)庫(kù)
<span style="color: #ff0000;">注:checked="checked"可以簡(jiǎn)寫(xiě)成checked</span>
label標(biāo)簽為input元素定義標(biāo)注,如果您點(diǎn)擊label元素文本,就會(huì)觸發(fā)此input控件。
textarea標(biāo)簽,設(shè)置文本區(qū)內(nèi)的可見(jiàn)行數(shù)和寬度
<textarea name="content" cols="30" rows="10">大段文本輸入框</textarea>
button標(biāo)簽定義一個(gè)按鈕
提交按鈕
<button type="submit" value="提交">提交</button>
重置按鈕
<button type="reset" value="重置">重置</button>
select標(biāo)簽和option標(biāo)簽下拉列表
單選菜單列表框
<select name="user">
<option value="1">ray</option>
<option value="2" selected="selected">raykaeso</option>
</select>
多選列表下拉框,shift加鼠標(biāo)單擊,可以連續(xù)選擇多個(gè)選擇,CTRL+鼠標(biāo)點(diǎn)擊,可以點(diǎn)擊多個(gè)。
<select name="user" size="10" multiple="multiple">
<option value="1">雷雪松</option>
<option value="2" selected="selected">ray</option>
<option value="3">raykaeso</option>
</select>
注:selected="selected"可簡(jiǎn)寫(xiě)成selected,表示選中
a、HTML標(biāo)簽和屬性是不區(qū)分大小寫(xiě)的,建議HTML標(biāo)簽和屬性都小寫(xiě),屬性值必須用雙引號(hào)包圍。
b、HTML標(biāo)簽都是以開(kāi)始標(biāo)簽起始,以結(jié)束標(biāo)簽終止。大部分HTML標(biāo)簽都是成對(duì)出現(xiàn)的,稱(chēng)為雙標(biāo)簽,比如:p標(biāo)簽、div標(biāo)簽,也有的HTML標(biāo)簽在開(kāi)始標(biāo)簽中結(jié)束的標(biāo)簽,稱(chēng)為單標(biāo)簽,比如:hr標(biāo)簽、br標(biāo)簽。大多數(shù) HTML 元素可擁有屬性,文本內(nèi)容都是寫(xiě)在開(kāi)始標(biāo)簽與結(jié)束標(biāo)簽之間。
c、HTML標(biāo)簽之間盡量縮進(jìn)與換行,每行代碼不要過(guò)長(zhǎng),方便閱讀和維護(hù)。
d、HTML標(biāo)簽使用必須符合標(biāo)簽嵌套規(guī)則。禁止a標(biāo)簽嵌套a標(biāo)簽,p標(biāo)簽嵌套div標(biāo)簽。
e、建議不使用HTML已經(jīng)廢棄的或者不贊成使用的標(biāo)簽,少使用table布局、iframe框架嵌套以及flash播放器。
來(lái)源:PHP程序員雷雪松的博客 -HTML基礎(chǔ)之HTML常用標(biāo)簽(http://www.leixuesong.cn/2045)
譯者 | 彎月
設(shè)計(jì)一個(gè)能夠支持?jǐn)?shù)億用戶(hù)的系統(tǒng)并非易事,對(duì)軟件架構(gòu)師來(lái)說(shuō)是一個(gè)很大的挑戰(zhàn)。
以下是本文涵蓋的一些主題:
從最簡(jiǎn)單的開(kāi)始:一個(gè)服務(wù)器搞定一切。
可擴(kuò)展性的藝術(shù):向外擴(kuò)展,向上擴(kuò)展。
擴(kuò)展關(guān)系數(shù)據(jù)庫(kù):主從復(fù)制、主主復(fù)制、聯(lián)合、分片、反規(guī)范化和 SQL 調(diào)優(yōu)。
使用哪個(gè)數(shù)據(jù)庫(kù):NoSQL 還是 SQL?
高級(jí)概念:緩存、CDN、geoDNS.等。
本文不打算討論高性能計(jì)算中常見(jiàn)的問(wèn)題,例如容錯(cuò)、可靠性、高可用性等。
下面,我們開(kāi)始。
下圖是我設(shè)計(jì)的一個(gè)最基本的應(yīng)用。最簡(jiǎn)單的方法是將整個(gè)應(yīng)用程序部署在一個(gè)服務(wù)器上。這可能也是我們大多數(shù)人入門(mén)時(shí)期采用的方式。
一個(gè)網(wǎng)站(包括 API)在Apache(或 Tomcat)之類(lèi)的Web服務(wù)器上運(yùn)行。
一個(gè)Oracle(或 MySQL)之類(lèi)的數(shù)據(jù)庫(kù)。
同一臺(tái)物理機(jī)器上同時(shí)擁有網(wǎng)絡(luò)服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器
但是,這樣的架構(gòu)存在以下缺點(diǎn):
如果數(shù)據(jù)庫(kù)出現(xiàn)故障,系統(tǒng)就會(huì)出現(xiàn)故障。
如果網(wǎng)絡(luò)服務(wù)器出現(xiàn)故障,整個(gè)系統(tǒng)就會(huì)出現(xiàn)故障。
在這種情況下,我們沒(méi)有故障轉(zhuǎn)移和冗余。一旦服務(wù)器宕機(jī)就會(huì)導(dǎo)致整個(gè)系統(tǒng)宕機(jī)。
使用 DNS 服務(wù)器解析主機(jī)名和 IP 地址
在上圖中,為了獲取托管系統(tǒng)的服務(wù)器IP地址,用戶(hù)(或客戶(hù)端)需要連接到 DNS系統(tǒng)。在獲得 IP 地址后,請(qǐng)求將直接發(fā)送到我們的系統(tǒng)。
每次訪問(wèn)網(wǎng)站時(shí),計(jì)算機(jī)都會(huì)執(zhí)行 DNS 查找。
通常,域名系統(tǒng)(Domain Name System,DNS)服務(wù)器都會(huì)使用托管公司提供的付費(fèi)服務(wù),無(wú)需在自己的服務(wù)器上運(yùn)行。
可擴(kuò)展性的藝術(shù)
由于數(shù)據(jù)量、工作量(例如交易數(shù)量)以及用戶(hù)數(shù)量的增加等多種原因,我們的系統(tǒng)必須具備可擴(kuò)展性。
可擴(kuò)展性通常意味著能夠通過(guò)添加更多資源來(lái)處理更多用戶(hù)、客戶(hù)端、數(shù)據(jù)、事務(wù)或請(qǐng)求,同時(shí)還不會(huì)影響用戶(hù)體驗(yàn)。
我們必須決定如何擴(kuò)展系統(tǒng)。在我們的這個(gè)例子中,有以下兩種擴(kuò)展類(lèi)型:向上擴(kuò)展(scale-up)和向外擴(kuò)展(scale-out)。
向上擴(kuò)展 vs 向外擴(kuò)展
向上擴(kuò)展:向現(xiàn)有服務(wù)器添加更多內(nèi)存和 CPU
向上擴(kuò)展也稱(chēng)為“垂直擴(kuò)展”,指的是系統(tǒng)的資源最大化,以擴(kuò)展其處理不斷增加的負(fù)載的能力。例如,我們可以通過(guò)添加內(nèi)存和CPU來(lái)增強(qiáng)服務(wù)器的能力。
如果我們的服務(wù)器擁有8GB內(nèi)存,則只需更換或添加硬件就可以輕松升級(jí)到32GB甚至128GB。
垂直擴(kuò)展的方法有很多,如下所示:
通過(guò)向 RAID 陣列添加更多硬盤(pán)來(lái)增加 I/O 容量。
通過(guò)使用固態(tài)硬盤(pán)(SSD)來(lái)改善 I/O 的訪問(wèn)時(shí)間。
使用具有更多處理器的服務(wù)器。
通過(guò)升級(jí)網(wǎng)絡(luò)接口或安裝其他接口來(lái)提高網(wǎng)絡(luò)吞吐量。
通過(guò)增加內(nèi)存來(lái)減少 I/O 的操作。
對(duì)于小型系統(tǒng)來(lái)說(shuō),垂直擴(kuò)展是一個(gè)不錯(cuò)的選擇,因?yàn)橛布?jí)的成本較低,但這種方式也有如下限制:
不可能無(wú)限擴(kuò)展單個(gè)服務(wù)器的能力。主要取決于操作系統(tǒng)以及服務(wù)器的內(nèi)存總線寬度。
在升級(jí)系統(tǒng)的內(nèi)存時(shí),必須關(guān)閉服務(wù)器,因此,如果系統(tǒng)只有一臺(tái)服務(wù)器,停機(jī)是不可避免的。
功能強(qiáng)大的計(jì)算機(jī)通常比流行的硬件貴很多。
向上擴(kuò)展不僅適用于硬件,同時(shí)也適用于軟件,例如,優(yōu)化查詢(xún)和應(yīng)用程序代碼。
隨著用戶(hù)數(shù)量的增長(zhǎng),一臺(tái)服務(wù)器是遠(yuǎn)遠(yuǎn)不夠的。這時(shí),我們需要考慮將單個(gè)服務(wù)器分成多個(gè)服務(wù)器。
隨著用戶(hù)數(shù)據(jù)增長(zhǎng),一臺(tái)服務(wù)器永遠(yuǎn)都不夠
這種架構(gòu)有以下優(yōu)點(diǎn):
Web 服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器可以分別調(diào)優(yōu);
Web 服務(wù)器需要更好的 CPU,而數(shù)據(jù)庫(kù)服務(wù)器則需要更多內(nèi)存;
Web 層和數(shù)據(jù)層可以使用單獨(dú)的服務(wù)器,并獨(dú)立地?cái)U(kuò)展。
向外擴(kuò)展也稱(chēng)為“橫向擴(kuò)展”,我們可以向資源池添加更多實(shí)體(機(jī)器、服務(wù))。水平擴(kuò)展比垂直擴(kuò)展更難實(shí)現(xiàn),因?yàn)槲覀冃枰跇?gòu)建系統(tǒng)之前考慮好。
通常,水平擴(kuò)展的初始成本較高,因?yàn)榧词故亲罨镜墓δ芤残枰嗯_(tái)服務(wù)器來(lái)處理,但后期的回報(bào)更豐富。因此,我們需要權(quán)衡利弊。
增加服務(wù)器數(shù)量意味著需要維護(hù)的資源也更多。
需要修改系統(tǒng)的代碼,以實(shí)現(xiàn)在多臺(tái)服務(wù)器上的并行處理和工作負(fù)載分?jǐn)偂?/span>
負(fù)載均衡器是一種專(zhuān)門(mén)的硬件或軟件組件,可將流量分散到服務(wù)器集群中,以提高系統(tǒng)(包括但不限于應(yīng)用程序、網(wǎng)站或數(shù)據(jù)庫(kù))的響應(yīng)能力和可用性。
使用負(fù)載均衡器來(lái)平衡所有節(jié)點(diǎn)之間的流量
通常,負(fù)載均衡器位于客戶(hù)端與服務(wù)器之間,接收傳入的網(wǎng)絡(luò)和應(yīng)用程序流量,并通過(guò)各種算法在多個(gè)后端服務(wù)器之間分配流量。所以,它也可以用在多種地方,例如;Web 服務(wù)器與數(shù)據(jù)庫(kù)服務(wù)器之間,以及客戶(hù)端與 Web 服務(wù)器之間。
HAProxy 和 NGINX 是兩種流行的開(kāi)源負(fù)載均衡軟件。
負(fù)載均衡技術(shù)是一種保證容錯(cuò)的方法,可按如下方式提高可用性:
如果服務(wù)器 1 離線,所有流量都將路由到服務(wù)器 2 和服務(wù)器 3。網(wǎng)站不會(huì)離線。此時(shí)你需要向服務(wù)器池添加一個(gè)健康的新服務(wù)器,以平衡負(fù)載。
當(dāng)流量快速增長(zhǎng)時(shí),你只需要在 Web 服務(wù)器池中添加更多服務(wù)器,負(fù)載均衡器就會(huì)將流量路由到新的服務(wù)器上。
負(fù)載均衡器采用各種策略和工作分配算法來(lái)優(yōu)化負(fù)載的分配,如下所示:
輪轉(zhuǎn):在這種情況下,每個(gè)服務(wù)器按先進(jìn)先出 (FIFO) 的順序接收請(qǐng)求。
最少連接數(shù):請(qǐng)求將被定向到連接數(shù)量最少的服務(wù)器。
最快響應(yīng)時(shí)間:請(qǐng)求將被定向到響應(yīng)時(shí)間最快(最近或頻繁)的服務(wù)器。
加權(quán):更強(qiáng)大的服務(wù)器收到的請(qǐng)求比較弱的服務(wù)器更多。
IP Hash:在這種情況下,根據(jù)計(jì)算的客戶(hù)端 IP 地址的哈希值將請(qǐng)求重定向到服務(wù)器。
平衡多個(gè)服務(wù)器間請(qǐng)求的最直接的方法是使用硬件設(shè)備:
直接向共享 IP 添加服務(wù)器,或刪除服務(wù)器。
可以根據(jù)需要進(jìn)行負(fù)載平衡。
軟件負(fù)載平衡比硬件負(fù)載平衡器更為廉價(jià)。這里的負(fù)載均衡在第 4 層(網(wǎng)絡(luò)層)和第 7 層(應(yīng)用層)運(yùn)行。
第 4 層:負(fù)載均衡器使用網(wǎng)絡(luò)層的 TCP 協(xié)議提供的信息。這一層的負(fù)載均衡在選擇服務(wù)器時(shí)通常不會(huì)查看請(qǐng)求內(nèi)容。
第 7 層:可以根據(jù)查詢(xún)字符串、cookie 或任何頭部信息平衡請(qǐng)求,也可以使用源地址、目標(biāo)地址等常規(guī)的層信息來(lái)平衡請(qǐng)求。
擴(kuò)展關(guān)系數(shù)據(jù)庫(kù)
在簡(jiǎn)單的系統(tǒng)中,我們可以使用Oracle 或 MySQL之類(lèi)的關(guān)系型數(shù)據(jù)庫(kù)來(lái)保存數(shù)據(jù)項(xiàng)。但是關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)有其自身的挑戰(zhàn),尤其是當(dāng)我們需要擴(kuò)展它們時(shí)。
有許多技術(shù)可以擴(kuò)展關(guān)系數(shù)據(jù)庫(kù):主從復(fù)制、主主復(fù)制、聯(lián)合、分片、非規(guī)范化和 SQL 調(diào)優(yōu)。
復(fù)制指的是一種將相同數(shù)據(jù)的多個(gè)副本存儲(chǔ)在不同的機(jī)器上的技術(shù)。
聯(lián)合(或功能分區(qū))會(huì)按功能拆分?jǐn)?shù)據(jù)庫(kù)。
分片是一種與分區(qū)相關(guān)的數(shù)據(jù)庫(kù)架構(gòu)模式,可以將不同的數(shù)據(jù)放在不同的服務(wù)器上,不同的用戶(hù)可以訪問(wèn)不同的數(shù)據(jù)。
反規(guī)范化可以將數(shù)據(jù)寫(xiě)入多個(gè)表,從而避免昂貴的連接,以犧牲部分寫(xiě)入性能為代價(jià)來(lái)提高讀取性能。
SQL 調(diào)優(yōu)。
主從復(fù)制
主從復(fù)制技術(shù)能夠?qū)?shù)據(jù)從一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器(主服務(wù)器)復(fù)制到一臺(tái)或多臺(tái)數(shù)據(jù)庫(kù)服務(wù)器(從服務(wù)器),如下圖所示。
主節(jié)點(diǎn)更新
更新數(shù)據(jù)時(shí),客戶(hù)端需要連接到主服務(wù)器。
接著,數(shù)據(jù)會(huì)被復(fù)制到從服務(wù)器,直到所有數(shù)據(jù)在服務(wù)器之間保持一致。
這種方法仍然存在一些瓶頸:
如果主服務(wù)器由于某種原因宕機(jī),仍然可以通過(guò)從服務(wù)器讀取數(shù)據(jù),只不過(guò)無(wú)法寫(xiě)入新數(shù)據(jù)了。
我們需要額外的算法來(lái)將從服務(wù)器提升為主服務(wù)器。
下面是一些解決方案,可以實(shí)現(xiàn)只有一臺(tái)服務(wù)器處理更新請(qǐng)求的情況。
同步解決方案:數(shù)據(jù)修改事務(wù)需要等到所有服務(wù)器都接受后才提交(分布式事務(wù)),因此不會(huì)在故障轉(zhuǎn)移時(shí)丟失數(shù)據(jù)。
異步解決方案:提交 -> 延遲 -> 復(fù)制到的其他服務(wù)器,因此在故障轉(zhuǎn)移時(shí)可能會(huì)丟失一些數(shù)據(jù)更新。
如果同步解決方案太慢,則可以改為異步解決方案。
每個(gè)數(shù)據(jù)庫(kù)服務(wù)器都可以與其他服務(wù)器同時(shí)擔(dān)任主服務(wù)器。在某個(gè)時(shí)間點(diǎn),所有主服務(wù)器進(jìn)行同步,以確保它們保存了正確以及最新的數(shù)據(jù)。
節(jié)點(diǎn)讀寫(xiě)數(shù)據(jù)庫(kù)
主主復(fù)制的優(yōu)勢(shì)在于:
如果某個(gè)主服務(wù)器出現(xiàn)故障,其他數(shù)據(jù)庫(kù)服務(wù)器可以正常運(yùn)行,而且還可以擔(dān)負(fù)起主服務(wù)器的責(zé)任。當(dāng)數(shù)據(jù)庫(kù)服務(wù)器重新上線后,可以通過(guò)復(fù)制來(lái)更新數(shù)據(jù)。
主站可以位于多個(gè)物理站點(diǎn),并且可以分布在整個(gè)網(wǎng)絡(luò)中。
但服務(wù)器的更新能力受限于主服務(wù)器。
聯(lián)合(或功能分區(qū))會(huì)按功能拆分?jǐn)?shù)據(jù)庫(kù)。例如,你可以擁有三個(gè)數(shù)據(jù)庫(kù),分別用于論壇、用戶(hù)和產(chǎn)品,這樣就可以減少每個(gè)數(shù)據(jù)庫(kù)的讀寫(xiě)流量,從而減少?gòu)?fù)制延遲。
按功能拆分?jǐn)?shù)據(jù)庫(kù)
更小的數(shù)據(jù)庫(kù)可以將更多的數(shù)據(jù)保存在內(nèi)存中,這樣可以改善緩存的局部性,進(jìn)而提高緩存命中率。由于沒(méi)有單一的中央主序列化寫(xiě)入,你可以實(shí)現(xiàn)并行寫(xiě)入,從而提高吞吐量。
分片(也稱(chēng)為數(shù)據(jù)分區(qū))是一種將大數(shù)據(jù)庫(kù)分成許多小塊的技術(shù),每個(gè)數(shù)據(jù)庫(kù)只能管理數(shù)據(jù)的一個(gè)子集。
在理想情況下,每個(gè)用戶(hù)都使用不同的數(shù)據(jù)庫(kù)節(jié)點(diǎn)。這種方式助于提高系統(tǒng)的可管理性、性能、可用性和負(fù)載均衡。
每個(gè)用戶(hù)只需與一臺(tái)服務(wù)器對(duì)話,因此可以快速獲得服務(wù)器的響應(yīng)。
服務(wù)器之間的負(fù)載均衡更好,例如,如果我們有五臺(tái)服務(wù)器,則每臺(tái)服務(wù)器只需處理 20% 的負(fù)載。
在實(shí)踐中,有許多不同的技術(shù)可以將數(shù)據(jù)庫(kù)分解為多個(gè)小塊。
這種技術(shù)會(huì)將不同的行放入不同的表中。例如,如果我們將用戶(hù)的個(gè)人資料存儲(chǔ)在一個(gè)表中,則可以將ID小于1000的用戶(hù)存儲(chǔ)在一個(gè)表中,同時(shí)將ID大于1001且小于2000的用戶(hù)存儲(chǔ)在另一個(gè)表中。
不同行放入不同表中
在這種情況下,我們根據(jù)服務(wù)器中保存的與特定功能相關(guān)的表來(lái)劃分?jǐn)?shù)據(jù)。例如,如果我們正在構(gòu)建一個(gè)類(lèi)似 Instagram 的系統(tǒng),我們需要在數(shù)據(jù)庫(kù)中存儲(chǔ)與用戶(hù)、上傳的照片以及他們關(guān)注的人相關(guān)的數(shù)據(jù),我們可以將用戶(hù)個(gè)人資料信息放在一個(gè)數(shù)據(jù)庫(kù)服務(wù)器上,將好友列表放在另一個(gè)服務(wù)器上,而第三個(gè)服務(wù)器上則保存照片。
把劃分?jǐn)?shù)據(jù)存儲(chǔ)在相應(yīng)的表中
如果想以松散耦合的方式解決這個(gè)問(wèn)題,則需要?jiǎng)?chuàng)建一個(gè)查找服務(wù),該服務(wù)知道當(dāng)前的分區(qū)模式,并擁有一份每個(gè)實(shí)體到其所屬的數(shù)據(jù)庫(kù)分片的映射。
當(dāng)數(shù)據(jù)存儲(chǔ)的擴(kuò)展超出單個(gè)存儲(chǔ)節(jié)點(diǎn)的可用資源,或者需要通過(guò)減少數(shù)據(jù)存儲(chǔ)的競(jìng)爭(zhēng)來(lái)提高性能時(shí),我們就可以采用這種方法。但請(qǐng)記住,分片技術(shù)存在以下一些常見(jiàn)問(wèn)題:
多表連接會(huì)變得更加昂貴,并且在某些情況下無(wú)法實(shí)現(xiàn)。
分片會(huì)損害數(shù)據(jù)庫(kù)參照完整性。
數(shù)據(jù)庫(kù)架構(gòu)變更可能會(huì)變得非常昂貴。
數(shù)據(jù)分布不均勻,有些分片的負(fù)載很高。
反規(guī)范化會(huì)以犧牲部分寫(xiě)入性能為代價(jià)來(lái)提高讀取性能。數(shù)據(jù)的冗余副本會(huì)被寫(xiě)入多個(gè)表,以避免昂貴的多表連接。
當(dāng)數(shù)據(jù)的分布采用聯(lián)合和分片等技術(shù)之后,跨數(shù)據(jù)中心的管理連接會(huì)進(jìn)一步增加復(fù)雜性。反規(guī)范化可以規(guī)避這種復(fù)雜的連接。
在大多數(shù)系統(tǒng)中,讀取的次數(shù)大大超過(guò)了寫(xiě)入的次數(shù),比例為 100:1,甚至 1000:1。因此,每當(dāng)讀取涉及復(fù)雜的數(shù)據(jù)庫(kù)連接時(shí),就可能會(huì)非常昂貴,并在磁盤(pán)操作上花費(fèi)大量時(shí)間。
有些關(guān)系數(shù)據(jù)庫(kù),比如 PostgreSQL 和 Oracle 支持物化視圖,它們會(huì)存儲(chǔ)冗余信息,并保持冗余副本一致。
在數(shù)據(jù)庫(kù)領(lǐng)域,有兩種主要的解決方案:SQL 和 NoSQL。二者的構(gòu)建方式、存儲(chǔ)信息的類(lèi)型以及使用的存儲(chǔ)方法都不同。
關(guān)系數(shù)據(jù)庫(kù)以行和列的形式存儲(chǔ)數(shù)據(jù)。每一行包含關(guān)于一個(gè)實(shí)體的所有信息,每一列包含所有的單獨(dú)數(shù)據(jù)點(diǎn)。
最流行的關(guān)系數(shù)據(jù)庫(kù)包括 MySQL、Oracle、MS SQL Server、SQLite、Postgres 以及 MariaDB等。
NoSQL又稱(chēng)為非關(guān)系數(shù)據(jù)庫(kù)。這些數(shù)據(jù)庫(kù)通常分為五個(gè)主要類(lèi)別:鍵值數(shù)據(jù)庫(kù)、圖數(shù)據(jù)庫(kù)、列數(shù)據(jù)庫(kù)、文檔數(shù)據(jù)庫(kù)以及 Blob 數(shù)據(jù)庫(kù)。
數(shù)據(jù)存儲(chǔ)在鍵值對(duì)數(shù)組中。“鍵”是鏈接到“值”的屬性名稱(chēng)。常見(jiàn)的鍵值存儲(chǔ)包括 Redis、Voldemort 和 Dynamo。
在這些數(shù)據(jù)庫(kù)中,數(shù)據(jù)存儲(chǔ)在文檔中(而不是表中的行和列),并且這些文檔歸類(lèi)成集合。每個(gè)文檔可以具有完全不同的結(jié)構(gòu)。
常見(jiàn)的文檔數(shù)據(jù)庫(kù)包括 CouchDB 和 MongoDB。
列式數(shù)據(jù)庫(kù)中,沒(méi)有“表”,只有列,它們是行的容器。與關(guān)系數(shù)據(jù)庫(kù)不同,我們不需要預(yù)先知道所有的列,每一行也不必具有相同的列數(shù)。
列式數(shù)據(jù)庫(kù)最適合分析大型數(shù)據(jù)集,常見(jiàn)的有 Cassandra 和 HBase。
這些數(shù)據(jù)庫(kù)常用于存儲(chǔ)關(guān)系最適合用圖表示的數(shù)據(jù)。數(shù)據(jù)保存在擁有節(jié)點(diǎn)(實(shí)體)、屬性(關(guān)于實(shí)體的信息)和線(實(shí)體之間的連接)的圖結(jié)構(gòu)中。
常見(jiàn)的圖數(shù)據(jù)庫(kù)包括 Neo4J 和 InfiniteGraph。
Blob 數(shù)據(jù)庫(kù)就好像文件的鍵/值存儲(chǔ),可通過(guò)API訪問(wèn),如 Amazon S3、Windows Azure Blob Storage、Google Cloud Storage、Rackspace Cloud Files 或 OpenStack Swift 等。
數(shù)據(jù)庫(kù)技術(shù)的選擇沒(méi)有統(tǒng)一的標(biāo)準(zhǔn)。這就是為什么許多企業(yè)同時(shí)使用 SQL 和 NoSQL 數(shù)據(jù)庫(kù)來(lái)滿(mǎn)足不同需求的原因。
如何選擇?
以上,我們談到了數(shù)據(jù)層的擴(kuò)展,下面我們來(lái)看看Web層的擴(kuò)展。為了擴(kuò)展Web層,我們需要將用戶(hù)會(huì)話(狀態(tài))的數(shù)據(jù)存儲(chǔ)在關(guān)系數(shù)據(jù)庫(kù)或 NoSQL 等數(shù)據(jù)庫(kù)中,將用戶(hù)會(huì)話(狀態(tài))的數(shù)據(jù)移出 Web 層。這也稱(chēng)為無(wú)狀態(tài)架構(gòu)。
無(wú)狀態(tài)系統(tǒng)很簡(jiǎn)單
不要使用有狀態(tài)的架構(gòu)。
我們必須盡可能選擇無(wú)狀態(tài)架構(gòu),因?yàn)闋顟B(tài)的實(shí)現(xiàn)限制了可擴(kuò)展性,降低了可用性,并增加了成本。
在上述情況下,負(fù)載均衡器的效率最高,因?yàn)樗梢赃x擇任何服務(wù)器來(lái)處理請(qǐng)求。
高級(jí)概念
負(fù)載均衡可以幫助你在數(shù)量不斷增加的服務(wù)器上進(jìn)行水平擴(kuò)展,但緩存能夠更好地利用現(xiàn)有資源,在后續(xù)請(qǐng)求期間更快地提供數(shù)據(jù)。
如果數(shù)據(jù)不在緩存中,則從數(shù)據(jù)庫(kù)中獲取,然后將其保存到緩存中并從中讀取
通過(guò)向服務(wù)器添加緩存,我們可以避免直接從服務(wù)器讀取網(wǎng)頁(yè)或數(shù)據(jù),從而減少響應(yīng)時(shí)間,并降低服務(wù)器的負(fù)載。這也有助于提升應(yīng)用程序的可擴(kuò)展性。
緩存可以應(yīng)用于許多層,例如數(shù)據(jù)庫(kù)層、Web 服務(wù)器層和網(wǎng)絡(luò)層。
CDN 服務(wù)器保存著內(nèi)容(如圖像、網(wǎng)頁(yè)等)的緩存副本,并選擇地理位置最近的服務(wù)器處理請(qǐng)求。
使用CDN 可以縮短了用戶(hù)的頁(yè)面加載時(shí)間,因?yàn)閿?shù)據(jù)都是從地理位置最近的服務(wù)器上加載的。這也有助于提高內(nèi)容的可用性,因?yàn)閿?shù)據(jù)存儲(chǔ)在多個(gè)位置。
CDN 的使用縮短了用戶(hù)的頁(yè)面加載時(shí)間,因?yàn)閿?shù)據(jù)是在最接近它的位置檢索的
CDN 服務(wù)器向Web 服務(wù)器發(fā)出請(qǐng)求以驗(yàn)證緩存的內(nèi)容,并在需要時(shí)更新緩存。緩存的內(nèi)容通常是靜態(tài)的,例如 HTML 頁(yè)面、圖像、JavaScript 文件、CSS 文件等。
當(dāng)應(yīng)用開(kāi)始進(jìn)軍全球市場(chǎng)時(shí),你需要在世界各地建立和運(yùn)維數(shù)據(jù)中心,以確保產(chǎn)品可以全天候不間斷地提供服務(wù)。傳入的請(qǐng)求被路由到基于 GeoDNS 的“最佳”數(shù)據(jù)中心。
當(dāng)應(yīng)用走向全球
GeoDNS 是一項(xiàng) DNS 服務(wù),允許根據(jù)客戶(hù)的位置將域名解析為 IP 地址。從亞洲連接的客戶(hù)端獲得的IP地址可能不同于從歐洲連接的客戶(hù)端。
通過(guò)迭代應(yīng)用本文中的技術(shù),例如無(wú)狀態(tài)架構(gòu)、應(yīng)用負(fù)載均衡器、盡可能多地使用緩存數(shù)據(jù)、支持多個(gè)數(shù)據(jù)中心、在 CDN 上托管靜態(tài)資產(chǎn)、通過(guò)分片擴(kuò)展數(shù)據(jù)庫(kù)規(guī)模等。我們就可以輕松地將系統(tǒng)擴(kuò)展到 1 億用戶(hù)。
縮放是一個(gè)迭代過(guò)程
原文鏈接:https://levelup.gitconnected.com/how-to-design-a-system-to-scale-to-your-first-100-million-users-4450a2f9703d
參考鏈接:
https://httpd.apache.org
http://tomcat.apache.org
https://www.oracle.com/database/
https://www.mysql.com
https://en.wikipedia.org/wiki/Domain_Name_System
https://www.facebook.com/note.php?note_id=10150468255628920
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。