PGET橙困,一個(gè)簡單瞧掺、易用的并行獲取數(shù)據(jù)框架

用場景

當(dāng)我們的服務(wù)收到一個(gè)請求后,需要大量調(diào)用下游服務(wù)獲取業(yè)務(wù)數(shù)據(jù)凡傅,然后對數(shù)據(jù)進(jìn)行轉(zhuǎn)換辟狈、計(jì)算后,響應(yīng)給請求方。

如果我們采用串行獲取下游數(shù)據(jù)哼转,勢必會增加響應(yīng)時(shí)長明未,降低接口的qps。如果是并行獲取下游數(shù)據(jù)壹蔓,則是不錯的趟妥。

最直接想到的并行獲取方法,無非是將一個(gè)個(gè)獲取數(shù)據(jù)的方法封裝成一個(gè)個(gè)task佣蓉,然后放到線程池里執(zhí)行披摄。但這種沒經(jīng)過設(shè)計(jì)的使用方式,易用性很低勇凭,可復(fù)用性也很低疚膊。

經(jīng)本人在實(shí)際的業(yè)務(wù)系統(tǒng)中,多次思考與設(shè)計(jì)虾标。終于設(shè)計(jì)出當(dāng)前這個(gè)框架寓盗。

特點(diǎn):絕對的簡單、絕對的易用夺巩。

相關(guān)概念

  • BizData

業(yè)務(wù)數(shù)據(jù)對象贞让。用于將下游獲取到的數(shù)據(jù)封裝到此對象中。

開發(fā)者需自定義此對象柳譬,并實(shí)現(xiàn)IBizData接口

  • BizDataProvider

業(yè)務(wù)數(shù)據(jù)對象提供者喳张。此對象類似于分層結(jié)構(gòu)中的Service層,其調(diào)用下游數(shù)據(jù)源(可以是rpc調(diào)用等)將得到的數(shù)據(jù)封裝到BizData對象中美澳。

此類需要添加@BizDataProvider注解销部。其方法返回值一定要是BizData對象

使用

在spring的xml中配置:

<!-- 初始化框架,并設(shè)置用于并行獲取業(yè)務(wù)數(shù)據(jù)的線程池配置  -->
    <bean class="com.dyz.pget.core.BizDataManager" init-method="init" destroy-method="destroy">
        <property name="corePoolSize" value="12"/>
        <property name="maximumPoolSize" value="200"/>
        <property name="keepAliveTime" value="0"/>
        <property name="queueSize" value="1000"/>
    </bean>

第一步:自定義BizData對象

public class UserInfoBizData implements IBizData{
    private Long userId;
    private String name;
    private Integer age;

    /**
     * 必須提供默認(rèn)構(gòu)造參數(shù)
     */
    public UserInfoBizData() {
    }

    public UserInfoBizData(Long userId, String name, Integer age) {
        this.userId = userId;
        this.name = name;
        this.age = age;
    }

    /**
     * 如果此數(shù)據(jù)對象獲取失敗時(shí)的默認(rèn)兜底值制跟。如果不支持兜底舅桩,則返回null即可。
     * @return
     */
    @Override
    public IBizData defaultBizData() {
        return null;
    }

    @Override
    public String format2String() {
        return new StringBuilder()
                .append("ID:").append(userId)
                .append(",名字:").append(name)
                .append(",年齡:").append(age)
                .toString();
    }
}
//篇幅問題雨膨,此處只貼了一個(gè)BizData的代碼

第二步:編寫對應(yīng)的BizDataProvider

@BizDataProvider
public class TestBizDataProvider {

    /**
     * 異常要拋出擂涛,框架會捕獲
     * @param userId
     * @return
     * @throws Exception
     */
    public UserInfoBizData getUserInfoBizData(long userId)throws Exception{
        //調(diào)用遠(yuǎn)程rpc或者其他數(shù)據(jù)源得到數(shù)據(jù),并封裝到UserInfoBizData對象中
        return new UserInfoBizData(userId,"張三",20);
    }

    public ProductInfoBizData getProductInfoBizData(long shopId,long productId)throws Exception{
        //調(diào)用遠(yuǎn)程rpc或者其他數(shù)據(jù)源得到數(shù)據(jù)聊记,并封裝到ProductInfoBizData對象中
        return new ProductInfoBizData(productId,shopId,"啤酒");
    }
}

第三步:獲取數(shù)據(jù)

①Getter模式:

使用案例代碼:

@Test
    public void testGetter() throws BizDataFetchException {
        long userId = 1345L;
        long shopId = 11L;
        long productId = 11011L;
        //并行獲取用戶信息撒妈、商品信息、門店信息三個(gè)數(shù)據(jù)排监。超時(shí)時(shí)間是100毫秒
        List<IBizData> bizDataList = BizDataGetter.build()
                .get(UserInfoBizData.class,userId)
                .get(ProductInfoBizData.class,shopId,productId)
                .get(ShopInfoBizData.class,shopId)
                .doGet(100L);

        UserInfoBizData userInfoBizData = (UserInfoBizData)bizDataList.get(0);
        ProductInfoBizData productInfoBizData = (ProductInfoBizData)bizDataList.get(1);
        ShopInfoBizData shopInfoBizData = (ShopInfoBizData)bizDataList.get(2);

        System.out.println(userInfoBizData.format2String());
        System.out.println(productInfoBizData.format2String());
        System.out.println(shopInfoBizData.format2String());
    }

Injector模式:

定義一個(gè)數(shù)據(jù)包裹對象狰右,存放所需要的數(shù)據(jù)對象

public class BizDataWrapper {
    private UserInfoBizData userInfoBizData;
    private ShopInfoBizData shopInfoBizData;
    private ProductInfoBizData productInfoBizData;

    public UserInfoBizData getUserInfoBizData() {
        return userInfoBizData;
    }

    public ShopInfoBizData getShopInfoBizData() {
        return shopInfoBizData;
    }

    public ProductInfoBizData getProductInfoBizData() {
        return productInfoBizData;
    }
}

使用案例代碼:

@Test
   public void testGetter() throws BizDataFetchException {
        long userId = 1345L;
        long shopId = 11L;
        long productId = 11011L;
        BizDataWrapper bizDataWrapper = new BizDataWrapper();
        //并行獲取用戶信息、商品信息舆床、門店信息三個(gè)數(shù)據(jù)棋蚌。并注入到bizDataWrapper中嫁佳,以方便使用。超時(shí)時(shí)間是100毫秒
        BizDataInjector.build(bizDataWrapper)
                .inject(UserInfoBizData.class,userId)
                .inject(ProductInfoBizData.class,shopId,productId)
                .inject(ShopInfoBizData.class,shopId)
                .doInject(100L);

        System.out.println(bizDataWrapper.getUserInfoBizData().format2String());
        System.out.println(bizDataWrapper.getProductInfoBizData().format2String());
        System.out.println(bizDataWrapper.getShopInfoBizData().format2String());
    }

結(jié)尾

相信你使用后谷暮,一定會覺著簡單實(shí)用蒿往。

不多說了,貼上github地址:https://github.com/yongzhidai/pget

注:使用時(shí)坷备,沒必要把源代碼粘到業(yè)務(wù)系統(tǒng)中熄浓,自己打個(gè)jar包情臭,讓業(yè)務(wù)系統(tǒng)依賴下就OK了省撑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俯在,隨后出現(xiàn)的幾起案子竟秫,更是在濱河造成了極大的恐慌,老刑警劉巖跷乐,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肥败,死亡現(xiàn)場離奇詭異,居然都是意外死亡愕提,警方通過查閱死者的電腦和手機(jī)馒稍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浅侨,“玉大人纽谒,你說我怎么就攤上這事∪缡洌” “怎么了鼓黔?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長不见。 經(jīng)常有香客問我澳化,道長,這世上最難降的妖魔是什么稳吮? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任缎谷,我火速辦了婚禮,結(jié)果婚禮上灶似,老公的妹妹穿的比我還像新娘列林。我一直安慰自己,他們只是感情好喻奥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布席纽。 她就那樣靜靜地躺著,像睡著了一般撞蚕。 火紅的嫁衣襯著肌膚如雪润梯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音纺铭,去河邊找鬼寇钉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛舶赔,可吹牛的內(nèi)容都是我干的扫倡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼竟纳,長吁一口氣:“原來是場噩夢啊……” “哼撵溃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锥累,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤缘挑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后桶略,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體语淘,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年际歼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惶翻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹅心,死狀恐怖吕粗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巴帮,我是刑警寧澤溯泣,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站榕茧,受9級特大地震影響垃沦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜用押,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一肢簿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜻拨,春花似錦池充、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至血崭,卻和暖如春卧惜,著一層夾襖步出監(jiān)牢的瞬間厘灼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工咽瓷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留设凹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓茅姜,卻偏偏與公主長得像闪朱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子钻洒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 巍峨五千里奋姿, 綿延五千年。 座座風(fēng)火煙何在航唆? 銀甲刀光劍影嘹歌憶猶還胀蛮。 長龍飛騰八達(dá)嶺, 鳳凰靈歌嘉峪關(guān)糯钙。 青磚殘...
    靖中北閱讀 426評論 7 6
  • 很多時(shí)候,我們會對一些事情失去正確的分析退腥。錯了并不可怕任岸,而在于分析錯了之后你能承擔(dān)多少責(zé)任。能不能深刻反省這件事的...
    坤玲的定投世界閱讀 499評論 0 0
  • 前言 好記性不如爛筆頭狡刘,量變引質(zhì)變享潜,記錄下git學(xué)習(xí)記錄。 開始 這里先介紹一種情況 你已經(jīng)有一個(gè)項(xiàng)目在電腦上嗅蔬,需...
    keien閱讀 152評論 0 1
  • 曹丕羨慕慕曹植的才華澜术,于是千方百計(jì)想要害死曹植艺蝴。于是曹植寫下了名垂千古的七步詩句。曹丕心胸狹隘鸟废,看不得別人比自己好...
    葉上初陽風(fēng)荷舉閱讀 492評論 0 3