<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我開(kāi)源的代碼竟然有人說(shuō)看不懂

          共 3355字,需瀏覽 7分鐘

           ·

          2021-11-30 17:10

          大家好,我是3y

          79ae7437b94ee430442e7c3d2bd5e3fc.webp

          今天繼續(xù)更新austin項(xiàng)目,如果還沒(méi)看過(guò)該系列的同學(xué)可以點(diǎn)開(kāi)我的歷史文章回顧下,在看的過(guò)程中不要忘記了點(diǎn)贊喲!建議不要漏了或者跳著看,不然這篇就看不懂了,之前寫(xiě)過(guò)的知識(shí)點(diǎn)和業(yè)務(wù)我就不再贅述啦。

          今天要做的就是實(shí)現(xiàn)austin-apiaustin-api-impl模塊的部分代碼,這塊完成了之后模塊之間的一整條鏈路就打通咯

          d0cedf2fd629ad99d622727c56e37bb2.webp

          01、接口設(shè)計(jì)

          austini-api模塊下定義發(fā)送消息的接口,在austin-api-impl下實(shí)現(xiàn)具體的邏輯。我的接口實(shí)現(xiàn)定義:

          public?interface?SendService?{


          ????/**
          ?????*?單模板單文案發(fā)送接口
          ?????*?@param?sendRequest
          ?????*?@return
          ?????*/

          ????SendResponse?send(SendRequest?sendRequest);


          ????/**
          ?????*?單模板多文案發(fā)送接口
          ?????*?@param?batchSendRequest
          ?????*?@return
          ?????*/

          ????SendResponse?batchSend(BatchSendRequest?batchSendRequest);

          }

          對(duì)外提供的接口,除了需要提供Single接口,最好還提供個(gè)Batch接口。因?yàn)楹苡锌赡軜I(yè)務(wù)方是需要一次批量執(zhí)行的(如果只有Single接口,那就需要多次遠(yuǎn)程調(diào)用,這樣對(duì)業(yè)務(wù)而言就不太合適了)

          692fb2f964f057729e1ab264c6973715.webp我所定義的接口參數(shù)如下:

          public?class?SendRequest?{

          ????/**
          ?????*?執(zhí)行業(yè)務(wù)類(lèi)型
          ?????*/

          ????private?String?code;

          ????/**
          ?????*?消息模板Id
          ?????*/

          ????private?Long?messageTemplateId;


          ????/**
          ?????*?消息相關(guān)的參數(shù)
          ?????*/

          ????private?MessageParam?messageParam;
          ????
          }

          通過(guò)messageTemplateId可以去數(shù)據(jù)庫(kù)查出整個(gè)模板的信息,而MessageParam則是業(yè)務(wù)自行傳入的參數(shù)(重要的是接收者以及文案的參數(shù)信息),而code則代表著當(dāng)前請(qǐng)求要執(zhí)行什么業(yè)務(wù)類(lèi)型的(可基于該code擴(kuò)展,后面會(huì)繼續(xù)聊到)

          36bda7558f7f1ecbf62b6d500f2cb8b6.webp

          02、代碼實(shí)現(xiàn)

          從流程可以看到,austin-api接收到請(qǐng)求之后,是把消息發(fā)到MQ

          d597015c3fac7e3529cf20e3f01fa960.webp

          這樣做有什么好處呢?假設(shè)某消息的服務(wù)超時(shí),austin-api如果是直接調(diào)用下發(fā)接口服務(wù),那可能會(huì)存在超時(shí)風(fēng)險(xiǎn),拖垮整個(gè)接口性能。MQ在這是為了做異步和解耦,并且在一定程度上抗住業(yè)務(wù)流量。

          對(duì)于絕大多數(shù)發(fā)送的消息而言,業(yè)務(wù)方也不太關(guān)心是不是能在接口調(diào)用時(shí)就知道發(fā)送結(jié)果,并且某些渠道在發(fā)送的時(shí)候也不知道發(fā)送的結(jié)果(最后的結(jié)果是異步告知的,比如短信和PUSH推送)

          基于以上的原因,引入MQ來(lái)承載接口的流量以及做異步,是非常合理的事。

          2f6cdf5b05fadfaa042e530905b1eaaa.webp

          前兩天我在博客平臺(tái)上發(fā)了一篇文章《面試官:系統(tǒng)需求多變時(shí)如何設(shè)計(jì)?》,有網(wǎng)友評(píng)論了一把:

          面試官:我懂了,回去等通知吧。……?

          leader:小王,咱們那個(gè)可變系統(tǒng)的重構(gòu)計(jì)劃寫(xiě)的怎么樣了?

          小王:沒(méi)問(wèn)題了,首先按找咱們的業(yè)務(wù)區(qū)分出責(zé)任鏈,然后在每個(gè)具體的步驟中部署腳本,上層再增加一個(gè)服務(wù)編排的接口統(tǒng)一管理……?

          leader:聽(tīng)起來(lái)有點(diǎn)意思,今天的候選人怎么樣?小王:別提了,嘴上說(shuō)5年經(jīng)驗(yàn)有大型系統(tǒng)設(shè)計(jì),連redis都沒(méi)用過(guò)。這不是快招聘季了嗎,招兩個(gè)實(shí)習(xí)生工具人進(jìn)來(lái)給我打打下手就夠了。

          leader:好,把時(shí)間節(jié)點(diǎn)和里程碑劃分一下,confluence上立項(xiàng)開(kāi)干吧。小王:好嘞。

          在這次實(shí)現(xiàn)中,我也是用了責(zé)任鏈模式,具體完整的代碼大家就去Gitee拉就好了。很多同學(xué)拉完代碼發(fā)現(xiàn)看不懂了,大家可以按照下面的圖去梳理下責(zé)任鏈的各個(gè)角色。如果實(shí)在看不懂,建議翻下我以前寫(xiě)過(guò)的責(zé)任鏈文章(已經(jīng)投稿過(guò)兩篇了)

          4d7089f2dbbdef08a7b1e95f5085f436.webp

          回到代碼實(shí)現(xiàn)吧,這次我實(shí)現(xiàn)的業(yè)務(wù)是:參數(shù)前置檢查->參數(shù)拼裝->發(fā)送消息

          e4ea45935ce09080922088ceffb1c3d4.webp3ecd84a5d1e6668494030178350f996a.webp

          呀,都畫(huà)了這么多圖了,先點(diǎn)個(gè)贊,關(guān)注一波先咯。

          在這幾個(gè)流程中,可能你下次拉代碼的時(shí)候,會(huì)看到有“后置檢查”,或者別的什么的。但不管怎么樣,加這種邏輯我再也不用在同一個(gè)類(lèi)上寫(xiě)各種if else啦。只要在某個(gè)節(jié)點(diǎn)處添加一個(gè)Action就完事了。

          (注:這是第一版實(shí)現(xiàn),后面肯定會(huì)在基礎(chǔ)上添加邏輯或注釋的,其實(shí)已經(jīng)在寫(xiě)了,但我一般是有個(gè)小階段再push代碼,所以記得star下gitee方便看最新的代碼)

          先來(lái)說(shuō)前置檢查吧,主要就判斷模板ID是否有傳入,消息參數(shù)是否有傳入(對(duì)參數(shù)的常規(guī)檢查,如果有問(wèn)題,直接break掉鏈路,返回告訴調(diào)用方有問(wèn)題)

          ab4777d7f4dd4a22b793778dfeb8db44.webp

          接著來(lái)看參數(shù)拼裝,這塊主要就是通過(guò)模板ID去查整個(gè)模板的內(nèi)容,然后根據(jù)業(yè)務(wù)入?yún)?/strong>拼裝出自己的TaskInfo(任務(wù)消息)。

          ab51a7cf3cd288fb349c6210761d2a04.webp

          可能有同學(xué)會(huì)有疑問(wèn)?:為什么不能直接用模板的POJO呢?反而需要拼裝成TaskInfo?

          其實(shí)還是比較好理解的,模板是作為給用戶(hù)去配置該消息的信息,這是最最原始的信息。但是我們發(fā)送的時(shí)候是需要做處理的。比如,我要在用戶(hù)寫(xiě)好的URL鏈接上拼接參數(shù),我要對(duì)占位符進(jìn)行替換真實(shí)的值,我要在模板的基礎(chǔ)上增加業(yè)務(wù)ID進(jìn)而追蹤數(shù)據(jù) 等等等。

          說(shuō)白了,TaskInfo是基于模板的,在模板的基礎(chǔ)上添加了某些平臺(tái)性的字段(businessId),解析出用戶(hù)設(shè)置的模板而想要發(fā)送的真實(shí)內(nèi)容等等。

          5f55408e38dc50d4edf56c88cda2347c.webp

          在這里,值得要說(shuō)明的是msgContent該字段的說(shuō)明。在模板中,該字段我在數(shù)據(jù)庫(kù)注釋所下的定義是(這個(gè)字段存入數(shù)據(jù)庫(kù)一定是JSON格式的):

          `msg_content`???varchar(600)?COLLATE?utf8mb4_unicode_ci?NOT?NULL?DEFAULT?''?COMMENT?'消息內(nèi)容?占位符用{$var}表示',

          不同的渠道的JSON結(jié)構(gòu)還不一樣:

          • 短信:{"content":"","url":""}
          • 郵件:{"content":"","subTitle":""}
          • Push:{"content":"","subTitle":"","phoneImgUrl":""}
          • 小程序:{"content":"","pagePath":"" .......}

          第一反應(yīng),我是想把所有渠道可能用到的字段都定義在TaskInfo下。后來(lái)感覺(jué)這樣不太好看,于是我就定義了各種Model(不同的發(fā)送渠道擁有著自己的內(nèi)容模型)

          0b8d38c3a507b311ff028e941ce8553b.webp

          于是,我在組裝TaskInfo的時(shí)候利用反射來(lái)進(jìn)行映射,替換占位符則借助的是PropertyPlaceholderHelper

          25ec3e18b099b10e99a93b1fb8c471ad.webp

          而發(fā)送則很簡(jiǎn)單了,我是直接把TaskInfo序列化為JSON,然后讀取的時(shí)候再反序列化就好了。

          值得注意的是,因?yàn)門(mén)askInfo用的是ContentModel來(lái)存儲(chǔ)著內(nèi)容模型,所以我們?cè)谛蛄谢疛SON的時(shí)候需要把"類(lèi)信息"寫(xiě)進(jìn)去,不然在反序列的時(shí)候是拿不到子類(lèi)的數(shù)據(jù)的。

          3329d37b812ff4cd5b318003c67b0bee.webp

          03、總結(jié)

          對(duì)于有源碼的項(xiàng)目,其實(shí)我是不太愿意每一步講解我寫(xiě)的代碼的。因?yàn)槲艺J(rèn)為我本身寫(xiě)得也沒(méi)那么復(fù)雜,也沒(méi)有炫技的成分在內(nèi)。

          但自從push了代碼以后,在群里提醒各位跟著做項(xiàng)目的小伙伴后,有好幾位向我反饋看不太懂,所以這篇我就單獨(dú)拎出來(lái)講講。

          再回過(guò)頭看,其實(shí)在austin-api層接收到請(qǐng)求之后,在發(fā)送消息至MQ之前,在這里的操作都是非常簡(jiǎn)單。其實(shí)是可以把通用業(yè)務(wù)做在這(比如平臺(tái)去重的功能),但經(jīng)我考慮之后,認(rèn)為不太合適。

          austin-api算是一個(gè)接入層,到目前為止它只是通過(guò)id去數(shù)據(jù)庫(kù)讀取配置,就沒(méi)有耗時(shí)的操作(這意味著該系統(tǒng)能承載的并發(fā)是極大的)。假設(shè)通過(guò)ID去數(shù)據(jù)庫(kù)讀取將來(lái)存在瓶頸,我們還可以考慮將配置從Redis甚至本地內(nèi)存里取。

          這是由業(yè)務(wù)可以決定的:一個(gè)模板的變更往往并不多,即便緩存存在強(qiáng)一致性的問(wèn)題,但就那點(diǎn)點(diǎn)時(shí)間是完全可接受的??赡?span>到最后,接口的瓶頸可能就在網(wǎng)絡(luò)消耗上

          點(diǎn)贊?? ? 星標(biāo)? ?在看?? 讓我看見(jiàn)你們還在支持我寫(xiě)下去。austin項(xiàng)目閱讀原文即可獲取源碼

          fd3357e66b489cdaa3d3d6b30b84d996.webp

          對(duì)線(xiàn)面試官》公眾號(hào)還在持續(xù)分享面試題,沒(méi)關(guān)注的同學(xué)可以關(guān)注一波!這是austin項(xiàng)目的上一個(gè)系列,質(zhì)量桿桿的

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区无码在线 | 国产一级A片视频 | 国产视频高清 | 免费无码高清视频 | 免费看日韩无码AV中文字幕 |