? ? ? ? 互聯(lián)網(wǎng)架構(gòu)的演變,這是一個(gè)老生常談的話題,現(xiàn)在網(wǎng)上有大量這樣的文章,基本都是從單機(jī)到水平拆分再到橫向拆分,最后分布式架構(gòu)、微服務(wù)等等。大家說(shuō)的都非常的精彩,但每個(gè)公司在真正實(shí)踐時(shí)卻非常非常的困難。比如:服務(wù)的橫向拆分中服務(wù)的邊界如何劃分,在數(shù)據(jù)水平拆分中很難找到一個(gè)全局的標(biāo)示來(lái)進(jìn)行拆分等等。今天我們就聊聊在各個(gè)階段演變過(guò)程中需要解決那些比較重要的問(wèn)題,及自己在實(shí)際工作中如何解決這些問(wèn)題的。
一、單機(jī)到集群?
? ? ? ? 這是一個(gè)比較簡(jiǎn)單和經(jīng)常發(fā)生的階段,在一個(gè)最初的小業(yè)務(wù)時(shí)都會(huì)進(jìn)行單機(jī)部署,但隨著業(yè)務(wù)的發(fā)展單機(jī)不能支撐整個(gè)業(yè)務(wù)的發(fā)展,最快的提升系統(tǒng)能力的方法就是集群化。單機(jī)到集群需要解決的問(wèn)題有:負(fù)載均衡器的引入、應(yīng)用的無(wú)狀態(tài)化。
? ? ? ?負(fù)載均衡器作為互聯(lián)網(wǎng)公司一般都會(huì)采用軟負(fù)載,比如:lvs、nginx等等。這個(gè)比較簡(jiǎn)單有非常成熟的方案。
? ? ? ? 應(yīng)用無(wú)狀態(tài)化:如果你的應(yīng)用從最開(kāi)始就是無(wú)狀態(tài)的那恭喜你這一步你就可以省略了,如果你的應(yīng)該不是無(wú)狀態(tài)的化,那就要進(jìn)行無(wú)狀態(tài)改造了。無(wú)狀態(tài)化也有非常多的成熟方案,比如:狀態(tài)集中管理、會(huì)話的分配策略等等。這里需要注意的一點(diǎn)是升級(jí)過(guò)程中的問(wèn)題,會(huì)有狀態(tài)丟失的可能,這一點(diǎn)要特殊注意。
二、數(shù)據(jù)庫(kù)壓力比較大緩存的引入
? ? ? ?緩存是一個(gè)非常神奇的東西,讓人又愛(ài)又恨啊,愛(ài)她,她會(huì)讓你的系統(tǒng)處理能力大大提升,恨她,由于她的不穩(wěn)定原因容易引起系統(tǒng)雪崩。一般在數(shù)據(jù)庫(kù)壓力比較大的時(shí)候第一個(gè)想到的方案都是在應(yīng)用和數(shù)據(jù)層加入緩存層,來(lái)減少數(shù)據(jù)層的壓力。其實(shí)引入緩存層主要是為了大大減少了數(shù)據(jù)庫(kù)的訪問(wèn)次數(shù),并且緩存層的數(shù)據(jù)大部分情況是在內(nèi)存中,獲取速度比較快。這里面有兩個(gè)問(wèn)題需要解決:1、一份數(shù)據(jù)存在兩個(gè)地方如何保證他們的一致性,2、如果緩存失效所有壓力會(huì)瞬間打入數(shù)據(jù)層,引起數(shù)據(jù)層雪崩。這兩個(gè)問(wèn)題不解決使用緩存相當(dāng)于在系統(tǒng)里引入了一個(gè)隨時(shí)可能爆炸的炸彈,引狼入室啊。
? ? ? ? 數(shù)據(jù)一致性問(wèn)題:這是一個(gè)永恒的話題,這是一個(gè)21世紀(jì)一定能完美解決的問(wèn)題。好吧我們回來(lái),一般在使用緩存的情況在新增和修改數(shù)據(jù)時(shí)會(huì)先在數(shù)據(jù)庫(kù)保證修改然后在同步修改緩存的數(shù)據(jù),但是但是如果在數(shù)據(jù)庫(kù)修改完整了系統(tǒng)出問(wèn)題了,緩存的數(shù)據(jù)沒(méi)有更新成功,咋辦咋辦?由于緩存中有數(shù)據(jù)會(huì)在一段時(shí)間使用老數(shù)據(jù),造成用戶獲取不到真正的數(shù)據(jù),用戶會(huì)蒙逼了。如果保證緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)強(qiáng)一致性這個(gè)很難做到,不一致有個(gè)時(shí)間窗口,如果這個(gè)時(shí)間窗口足夠小,并且業(yè)務(wù)可以接受,那這個(gè)問(wèn)題就不存在了。所以在同步更新緩存的情況下,加入一個(gè)異步更新緩存的功能,即在數(shù)據(jù)庫(kù)保存成功后同步修改緩存中的數(shù)據(jù),然后在發(fā)送一個(gè)異步消息通知緩存有數(shù)據(jù)修改了,然后緩存會(huì)去更新數(shù)據(jù)。這樣保證了同步修改失敗后,在非常短的時(shí)間內(nèi)可以再次修改緩存的數(shù)據(jù)。
? ? ? ? ?大量緩存失效問(wèn)題:如果發(fā)生這樣的問(wèn)題,基本都是災(zāi)難性的。多業(yè)務(wù)肯定會(huì)有一定損失的,在發(fā)生這樣的問(wèn)題時(shí),第一時(shí)間是降低業(yè)務(wù)的損失、最快的速度恢復(fù)業(yè)務(wù)。緩存的加載是需要時(shí)間的。雙緩存切換,同一份數(shù)據(jù)進(jìn)行兩次緩存,應(yīng)用使用的是實(shí)時(shí)緩存+異步更新,備份緩存是異步更新。在發(fā)送實(shí)時(shí)緩存大量失效是讓?xiě)?yīng)用切換實(shí)時(shí)緩存和備份緩存。備份緩存緩存了95%的數(shù)據(jù),對(duì)業(yè)務(wù)基本無(wú)損。
三、杜絕裸奔,監(jiān)控的重要
? ? ? 在系統(tǒng)比較簡(jiǎn)單、單一時(shí)監(jiān)控非常容易,并且感覺(jué)也不是那么重要,但當(dāng)系統(tǒng)越來(lái)越復(fù)雜,引入的元素越來(lái)越多是,會(huì)發(fā)現(xiàn)系統(tǒng)越來(lái)越難以控制。如果不引入監(jiān)控,就相當(dāng)于系統(tǒng)在裸奔。每一個(gè)環(huán)節(jié)的出錯(cuò)都會(huì)導(dǎo)致系統(tǒng)的雪崩,必須要能夠從全局的視覺(jué)監(jiān)控系統(tǒng)各個(gè)環(huán)節(jié)的運(yùn)行情況。負(fù)載均衡的監(jiān)控、應(yīng)用的監(jiān)控、jvm的監(jiān)控、服務(wù)器的監(jiān)控、緩存的監(jiān)控、數(shù)據(jù)庫(kù)的監(jiān)控等等。監(jiān)控的方式有很多,盡量采用對(duì)系統(tǒng)無(wú)侵入、無(wú)性能影響的監(jiān)控方式,比如采用日志分析的方式。采用日志分析的方式一定要有非常好的日志打印規(guī)范,做到日志打印格式統(tǒng)一、日志打印無(wú)死角、日志打印可降級(jí)等等。
今天就寫(xiě)到這后面繼續(xù)。