亚洲国产成人精品久久_欧美日韩国产综合一区二区_亚洲精品理论电影_色综合久久中文字幕

程序員該如何利用“有狀態(tài)的服務(wù)”升級(jí)打怪?

放大字體  縮小字體 發(fā)布日期:2019-12-04  來源:來自互聯(lián)網(wǎng)  作者:來自互聯(lián)網(wǎng)  瀏覽次數(shù):217
導(dǎo)讀

在眾多的并發(fā)模型中,最適合有狀態(tài)服務(wù)設(shè)計(jì)的莫過于Actor模型了,actor模型天生就具備了一致性這種特點(diǎn),讓我們?cè)趯?duì)業(yè)務(wù)進(jìn)行抽象的時(shí)候,不必考慮一致性的問題,而且每一個(gè)請(qǐng)求都是異步模式,在對(duì)象內(nèi)部…

作者 | 菜v菜

責(zé)編 | maozz

YY妹:菜菜哥,你換形象啦?

菜菜:這么巧,你也換啦!聽說是不會(huì)畫畫的菜嫂經(jīng)過九牛二虎之力的功勞哦!結(jié)果.....

YY妹:前幾天我出去面試了,面試官問我微服務(wù)的知識(shí),我回答的可好了

菜菜:看來微服務(wù)你真的下工夫研究了呀

YY妹:是呀是呀,但是碰到一個(gè)問題,有狀態(tài)的服務(wù)是什么意思呢?

菜菜:看來你又掛在這個(gè)問題上了,且聽這次分解

YY妹:菜菜哥,你換形象啦?

菜菜:這么巧,你也換啦!聽說是不會(huì)畫畫的菜嫂經(jīng)過九牛二虎之力的功勞哦!結(jié)果.....

YY妹:前幾天我出去面試了,面試官問我微服務(wù)的知識(shí),我回答的可好了

菜菜:看來微服務(wù)你真的下工夫研究了呀

YY妹:是呀是呀,但是碰到一個(gè)問題,有狀態(tài)的服務(wù)是什么意思呢?

菜菜:看來你又掛在這個(gè)問題上了,且聽這次分解

簡(jiǎn)介

對(duì)于初學(xué)者,心里對(duì)“有狀態(tài)服務(wù)”的理解可能比較模糊,但是從面向?qū)ο缶幊趟枷氲慕嵌热ダ斫庖苍S會(huì)明朗很多。面向?qū)ο缶幊趟枷胩岢氖怯镁幊陶Z言去描述世間萬物,所以面向?qū)ο缶幊痰恼Z言都會(huì)提供描述對(duì)象的容器以及對(duì)象行為的表達(dá)方式。

舉一個(gè)很簡(jiǎn)單的栗子,在c#或者java中,表達(dá)對(duì)象的容器就是class,對(duì)象的行為通過一系列的接口或者函數(shù)來表達(dá)。更進(jìn)一步,對(duì)象抽象出來之后,大多數(shù)對(duì)象都有自己的內(nèi)部狀態(tài),體現(xiàn)到代碼上也就是常見的類的屬性。

面向?qū)ο缶幊痰幕舅枷氡举|(zhì)上是對(duì)現(xiàn)實(shí)世界的一種抽象,萬物皆可抽象。

面向?qū)ο缶幊痰幕舅枷氡举|(zhì)上是對(duì)現(xiàn)實(shí)世界的一種抽象,萬物皆可抽象。

根據(jù)業(yè)務(wù)把對(duì)象抽象出來之后,每一個(gè)實(shí)例化的對(duì)象其實(shí)都可以有自己的狀態(tài),比如:在最常見的游戲場(chǎng)景中,每一個(gè)玩家都是“玩家"這類對(duì)象的一個(gè)實(shí)例,每一個(gè)玩家都有自己的名字,性別,等級(jí),HP等屬性,這些屬性本質(zhì)上就是玩家的狀態(tài),隨著時(shí)間的推移,每個(gè)玩家的HP,等級(jí)等屬性會(huì)隨之變化,這些變化其實(shí)就是這個(gè)玩家狀態(tài)的變化。

對(duì)應(yīng)到有狀態(tài)的服務(wù)也是如此,之所以稱之為有狀態(tài),是因?yàn)榉?wù)內(nèi)部的對(duì)象狀態(tài)會(huì)隨著業(yè)務(wù)有著對(duì)應(yīng)的變動(dòng),而這些變動(dòng)只發(fā)生在這個(gè)服務(wù)內(nèi)部,在外界看來,這個(gè)服務(wù)好像是有狀態(tài)的。

有狀態(tài)的服務(wù)本質(zhì)上是一些有狀態(tài)對(duì)象的集合,這些對(duì)象狀態(tài)的變化只發(fā)生在當(dāng)前服務(wù)進(jìn)程中。

有狀態(tài)的服務(wù)本質(zhì)上是一些有狀態(tài)對(duì)象的集合,這些對(duì)象狀態(tài)的變化只發(fā)生在當(dāng)前服務(wù)進(jìn)程中。

優(yōu)勢(shì)和劣勢(shì)

有狀態(tài)服務(wù)之所以被稱為有狀態(tài),一個(gè)很大的原因是它可以追溯狀態(tài)的變化過程,也就是說一個(gè)有狀態(tài)的服務(wù)保存著狀態(tài)變化的記錄,并可以根據(jù)這些歷史記錄恢復(fù)到指定的狀態(tài),這在很多場(chǎng)景下非常有用。

舉一個(gè)很簡(jiǎn)單的栗子:我們平時(shí)玩的斗地主游戲,三個(gè)玩家,當(dāng)有一個(gè)玩家因?yàn)榫W(wǎng)絡(luò)原因掉線,經(jīng)過一段時(shí)間,這個(gè)玩家又重新上線,需要根據(jù)某些記錄來恢復(fù)玩家掉線期間系統(tǒng)自動(dòng)出牌的記錄,這些出牌記錄在這個(gè)業(yè)務(wù)中其實(shí)就是這個(gè)玩家的狀態(tài)變化記錄。在有狀態(tài)的服務(wù)中,很容易做到這一點(diǎn)。

其實(shí)實(shí)際開發(fā)中很多場(chǎng)景不需要記錄每個(gè)狀態(tài)的變化,只保留最新狀態(tài)即可,不單單是因?yàn)楸4婷總€(gè)狀態(tài)的變化需要大量的存儲(chǔ)和架構(gòu)設(shè)計(jì),更因?yàn)槭呛芏鄻I(yè)務(wù)根本不需要這些狀態(tài)變化記錄,業(yè)務(wù)需要的只是最新的狀態(tài),所以大部分有狀態(tài)的服務(wù)只保存著最新的狀態(tài)。

有狀態(tài)的服務(wù)在設(shè)計(jì)難度上比無狀態(tài)的服務(wù)要大很多,不僅僅是因?yàn)殚_發(fā)設(shè)計(jì)人員需要更好的抽象能力,更多的是一致性的設(shè)計(jì)問題。

現(xiàn)代的分布式系統(tǒng),都是由多個(gè)服務(wù)器組成一個(gè)集群來對(duì)外提供服務(wù),當(dāng)一個(gè)對(duì)象在服務(wù)器A產(chǎn)生之后,如果請(qǐng)求被分配到了服務(wù)器B上,這種情況下有狀態(tài)的服務(wù)毫無意義,為什么呢?

當(dāng)一個(gè)相同的業(yè)務(wù)對(duì)象存在于不同的服務(wù)器上的時(shí)候,本質(zhì)上就違背了現(xiàn)實(shí)世界的規(guī)則,你能說一個(gè)人,即出生在中國,又出生在美國嗎?

所以有狀態(tài)的服務(wù)對(duì)于一致性問題有著天然的要求,這種思想和微服務(wù)設(shè)計(jì)理想不謀而合,舉個(gè)栗子:一個(gè)用戶信息的服務(wù),對(duì)外提供查詢修改能力,凡是用戶信息的業(yè)務(wù)必須通過這個(gè)服務(wù)來實(shí)現(xiàn)。同理,一個(gè)對(duì)象狀態(tài)的查詢修改以及這個(gè)對(duì)象的行為,必須由這個(gè)對(duì)象的服務(wù)來完成。

有狀態(tài)的服務(wù)要求相同業(yè)務(wù)對(duì)象的請(qǐng)求必須被路由到同一個(gè)服務(wù)進(jìn)程。

有狀態(tài)的服務(wù)要求相同業(yè)務(wù)對(duì)象的請(qǐng)求必須被路由到同一個(gè)服務(wù)進(jìn)程。

因此,有狀態(tài)的服務(wù)對(duì)于同一個(gè)對(duì)象的橫向擴(kuò)容是做不到的,就算是做的到,多個(gè)相同對(duì)象之間的狀態(tài)同步工作也必然會(huì)花費(fèi)更多的資源。

在很多場(chǎng)景下,有狀態(tài)的服務(wù)要注意熱點(diǎn)問題,例如最常見的秒殺,這里并非是說有狀態(tài)服務(wù)不適合大并發(fā)的場(chǎng)景,反而在高并發(fā)的場(chǎng)景下,有狀態(tài)的服務(wù)往往表現(xiàn)的比無狀態(tài)服務(wù)更加出色。

Actor模型

在眾多的并發(fā)模型中,最適合有狀態(tài)服務(wù)設(shè)計(jì)的莫過于Actor模型了,actor模型天生就具備了一致性這種特點(diǎn),讓我們?cè)趯?duì)業(yè)務(wù)進(jìn)行抽象的時(shí)候,不必考慮一致性的問題,而且每一個(gè)請(qǐng)求都是異步模式,在對(duì)象內(nèi)部修改對(duì)象的狀態(tài)不必加鎖,這在傳統(tǒng)的架構(gòu)中是做不到的。

基于actor模型,系統(tǒng)設(shè)計(jì)的難點(diǎn)在于抽象業(yè)務(wù)模型,一旦業(yè)務(wù)模型穩(wěn)定,我們完全可以用內(nèi)存方式來保存對(duì)象狀態(tài)(也可以定時(shí)去持久化),內(nèi)存方式比用其他網(wǎng)絡(luò)存儲(chǔ)(例如redis)要快上幾個(gè)量級(jí)。

既滿足了一致性,又可以利用進(jìn)程內(nèi)對(duì)象狀態(tài)來應(yīng)對(duì)高并發(fā)業(yè)務(wù)場(chǎng)景,何樂而不為呢?

有不少同學(xué)問過,actor模型要避免出現(xiàn)熱點(diǎn)問題,就算有內(nèi)存狀態(tài)為其加速,那并發(fā)數(shù)還是超過actor的處理能力怎么辦呢?

其實(shí)和傳統(tǒng)做法類似,所有的高并發(fā)系統(tǒng)設(shè)計(jì)無非就是“分”一個(gè)字,無論是簡(jiǎn)單的負(fù)載均衡,還是復(fù)雜的分庫分表策略,都是分治的一種體現(xiàn)。一臺(tái)服務(wù)器不夠,我就上十臺(tái),百臺(tái).....

所有的高并發(fā)系統(tǒng)設(shè)計(jì)都是基于分治思想,把每一臺(tái)服務(wù)器的能力發(fā)揮到極致,難度最大的還是其中的調(diào)度算法。

用actor模型來應(yīng)對(duì)高并發(fā),我們可以采用讀寫分離的思想,主actor負(fù)責(zé)寫請(qǐng)求,并利用某種通信機(jī)制把狀態(tài)的變化通知到多個(gè)從actor,從actor負(fù)責(zé)對(duì)外的讀請(qǐng)求,這個(gè)DB的讀寫分離思想一致,其中最難的當(dāng)屬actor的狀態(tài)同步問題了,解決問題的方式千百種,總有一種適合你,歡迎你留言寫下你認(rèn)為最好的解決方案。

案例(玩家信息服務(wù))

由于筆者是c#出身,對(duì)c#的Actor服務(wù)框架Orleans比較熟悉,這里就以O(shè)rleans為例,其他語言的coder不要見怪,Orleans是一個(gè)非常優(yōu)秀的Actor模型框架,而且支持最新的netcore 3.0版本,地址為:https://github/dotnet/orleans 有興趣的同學(xué)可以去看一下,而且分布式事物已經(jīng)出正式版,非常給力。其他語言的也非常出色java:https://github/akka/akka

golang:https://github/AsynkronIT/protoactor-go

1. 首先我們定義玩家的狀態(tài)信息

//玩家的信息,其實(shí)也就是玩家的狀態(tài)信息

publicclassPlayer{

///<summary>

///玩家id,同時(shí)也是玩家這個(gè)服務(wù)的主鍵

///</summary>

publiclongId { get; set; }

///<summary>

///玩家姓名

///</summary>

publicstringName { get; set; }

///<summary>

///玩家等級(jí)

///</summary>

publicintLevel { get; set; }

}

2. 接下來定義玩家的服務(wù)接口

/// <summary>

/// 玩家的服務(wù)接口

/// </summary>

interfaceIPlayerService: Orleans.IGrainWithIntegerKey

{

//獲取玩家名稱

Task<string> GetName;

//獲取玩家等級(jí)

Task<int> GetLevel;

//設(shè)置玩家等級(jí),這個(gè)操作會(huì)改變玩家的狀態(tài)

Task<int> SetLevel(intnewLevel);

}

3. 接下來實(shí)現(xiàn)玩家服務(wù)的接口

publicclassPlayerService: Grain, IPlayerService

{

//這里可以用玩家的信息來代表玩家的狀態(tài)信息,而且這個(gè)狀態(tài)信息又充當(dāng)了進(jìn)程內(nèi)緩存的作用

Player playerInfo;

publicasyncTask<int> GetLevel

{

return(awaitLoadPlayer).Level;

}

publicasyncTask<string> GetName

{

return(awaitLoadPlayer).Name;

}

publicasyncTask<int> SetLevel(intnewLevel)

{

varplayerInfo =awaitLoadPlayer;

if(playerInfo != null)

{

//先進(jìn)行數(shù)據(jù)庫的更新,然后在更新緩存的狀態(tài), 進(jìn)程內(nèi)緩存更新失敗的幾率幾乎為0

playerInfo.Level = newLevel;

}

return1;

}

privateasyncTask< Player> LoadPlayer

{

if(playerInfo == null)

{

varid = this.GetPrimaryKeyLong;

//這里模擬的信息,真實(shí)環(huán)境完全可以從持久化設(shè)備進(jìn)行讀取

playerInfo= newPlayer { Id = id, Name = "玩家姓名", Level = 1};

}

returnplayerInfo;

}

}

以上只是一個(gè)簡(jiǎn)單案例,有狀態(tài)的服務(wù)還有更多的設(shè)計(jì)方案,以上只供參考

本文為作者投稿,版權(quán)歸作者個(gè)人所有。

?蘋果公司 50% 員工沒大學(xué)學(xué)歷,細(xì)數(shù)不看學(xué)歷看能力的 IT 大佬!

 
 
免責(zé)聲明
本文為會(huì)員免費(fèi)發(fā)布,僅代表發(fā)布者個(gè)人觀點(diǎn),本站未對(duì)其內(nèi)容進(jìn)行核實(shí),請(qǐng)讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,作者需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請(qǐng)及時(shí)聯(lián)系我們刪除處理。
 
 
主站蜘蛛池模板: 国产成人精品久久| 日本不卡免费高清视频| 久久精品男人天堂| 国产精品美乳一区二区免费| 97成人在线免费视频| 不卡视频一区二区三区| 国产精品久久精品视| 岛国视频一区免费观看| 国产精品毛片一区视频| 国产精品久久久久久久久婷婷| 国产精品精品一区二区三区午夜版| 久久亚洲国产精品成人av秋霞| 天天综合五月天| 97久久精品视频| 久久久久久久久久久99| 精品亚洲欧美日韩| 国产精品永久在线| 国产中文字幕91| 国产在线精品自拍| 美女亚洲精品| 久久精品国产欧美激情| 亚洲精品国产一区| 亚洲精品无码久久久久久| 亚洲精品电影在线一区| 日本久久中文字幕| 国产精品国产自产拍高清av水多 | 中文字幕一区二区三区四区五区六区| 久久精品ww人人做人人爽| 精品丰满人妻无套内射| 精品国产一区二区三区久久狼黑人| 久久大香伊蕉在人线观看热2| 国产日韩欧美影视| 日本久久久久久久久| 欧美不卡视频一区发布| 久久视频在线观看免费| 国产精品热视频| 91精品在线观| 色综合久久久久久久久五月| 日韩中文视频免费在线观看| 欧美亚洲免费高清在线观看| 国产在线一区二区三区四区|