在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一種接口依賴關系分層方案

OSC開源社區 ? 來源:OSCHINA 社區 ? 2023-06-30 10:25 ? 次閱讀

1、背景

到店商詳迭代過程中,需要提供的對外能力越來越多,如預約日歷、附近門店、為你推薦等。這其中不可避免會出現多個上層能力依賴同一個底層接口的場景。最初采用的方案是對外 API 入口進來后獲取對應的能力,并發調用多項能力,由能力層調用對應的數據鏈路,進行業務處理。

然而,隨著接入功能的增多,這種情況導致了底層數據服務的重復調用,如商品配置信息,在一次 API 調用過程中重復調了 3 次,當流量增大或能力項愈多時,對底層服務的壓力會成倍增加。

正值 618 大促,各方接口的調用都會大幅度增加。通過梳理接口依賴關系來減少重復調用,對本系統而言,降低了調用數據接口時的線程占用次數,可以有效降級 CPU。對調用方來說,減少了調用次數,可減少調用方的資源消耗,保障底層服務的穩定性。

原始調用方式:

e6fe81fe-1666-11ee-962d-dac502259ad0.jpg

2、優化

基于上述問題,采用底層接口依賴分層調用的方案。梳理接口依賴關系,逐層向上調用,注入數據,如此將同一接口的調用抽取到某層,僅調用一次,即可在整條鏈路使用。

改進調用方式:

e717736c-1666-11ee-962d-dac502259ad0.jpg

只要分層后即可在每層采用多線程并發的方式調用,因為同一層級中的接口無先后依賴關系。

3、如何分層?

接下來,如何梳理接口層級關系就至關重要。

接口梳理分層流程如下:

e751f6b8-1666-11ee-962d-dac502259ad0.jpg

第一步:構建層級結構 首先獲取到能力層依賴項并遍歷,然后調用生成數據節點方法。方法流程如下:構建當前節點,檢測循環依賴(存在循環依賴會導致棧溢出),獲取并遍歷節點依賴項,遞歸生成子節點,存放子節點。

第二步:節點平鋪 定義 Map 維護平鋪結構,調用平鋪方法。方法流程如下:遍歷層級結構,判斷當前節點是否已存在 map 中,存在時與原節點比較將層級大的節點放入(去除重復項),不存在時直接放入即可。然后處理子節點,遞歸調用平鋪方法,處理所有節點。

第三步:分層(分組排序) 流處理平鋪結構,處理層級分組,存儲在 TreeMap 中維護自然排序。對應 key 中的數據節點 Set 需用多線程并發調用,以保證鏈路調用時間

1 首先,定義數據結構用于維護調用鏈路

Q1:為什么需要定義祖先節點?

A1:為了判斷接口是否存在循環依賴。如果接口存在循環依賴而不檢測將導致調用棧溢出,故而在調用過程中要避免并檢測循環依賴。在遍歷子節點過程中,如果發現當前節點的祖先已經包含當前子節點,說明依賴關系出現了環路,即循環依賴,此時拋異常終止后續流程避免棧溢出。

public class DataNode {
    /**
     * 節點名稱
     */
    private String name;
    /**
     * 節點層級
     */
    private int level;
    /**
     * 祖先節點
     */
    private List ancestors;
    /**
     * 子節點
     */
    private List children;
}

2 獲取能力層的接口依賴,并生成對應的數據節點

Q1:生成節點時如何維護層級?

A1:從能力層依賴開始,層級從 1 遞加。每獲取一次底層依賴,底層依賴所生成的節點層級即父節點層級 + 1。

/**
 * 構建層級結構
 *
 * @param handlers 接口依賴
 * @return 數據節點集
 */
private List buildLevel(Set handlers) {
    List result = Lists.newArrayList();

    for (String next : handlers) {
        DataNode dataNode = generateNode(next, 1, null, null);
        result.add(dataNode);
    }
    return result;
}

/**
 * 生成數據節點
 *
 * @param name 節點名稱
 * @param level 節點層級
 * @param ancestors 祖先節點(除父輩)
 * @param parent 父節點
 * @return DataNode 數據節點
 */
private DataNode generateNode(String name, int level, List ancestors, String parent) {
    AbstractInfraHandler abstractInfraHandler = abstractInfraHandlerMap.get(name);
    Set infraDependencyHandlerNames = abstractInfraHandler.getInfraDependencyHandlerNames();
    // 根節點
    DataNode dataNode = new DataNode(name);
    dataNode.setLevel(level);
    dataNode.putAncestor(ancestors, parent);
    if (CollectionUtils.isNotEmpty(dataNode.getAncestors()) && dataNode.getAncestors().contains(name)) {
        throw new IllegalStateException("依賴關系中存在循環依賴,請檢查以下handler:" + JsonUtil.toJsonString(dataNode.getAncestors()));
    }
    if (CollectionUtils.isNotEmpty(infraDependencyHandlerNames)) {
        // 存在子節點,子節點層級+1
        for (String next : infraDependencyHandlerNames) {
            DataNode child = generateNode(next, level + 1, dataNode.getAncestors(), name);
            dataNode.putChild(child);
        }
    }
    return dataNode;
}

層級結構如下:

e768abec-1666-11ee-962d-dac502259ad0.png

3 數據節點平鋪(遍歷出所有后代節點)

Q1:如何處理接口依賴過程中的重復項?

A1:遍歷所有的子節點,將所有子節點平鋪到一層,平鋪時如果節點已經存在,比較層級,保留層級大的即可(層級大說明依賴位于更底層,調用時要優先調用)。

/**
 * 層級結構平鋪
 *
 * @param dataNodes 數據節點
 * @param dataNodeMap 平鋪結構
 */
private void flatteningNodes(List dataNodes, Map dataNodeMap) {
    if (CollectionUtils.isNotEmpty(dataNodes)) {
        for (DataNode dataNode : dataNodes) {
            DataNode dataNode1 = dataNodeMap.get(dataNode.getName());
            if (Objects.nonNull(dataNode1)) {
                // 存入層級大的即可,避免重復
                if (dataNode1.getLevel() < dataNode.getLevel()) {
                    dataNodeMap.put(dataNode.getName(), dataNode);
                }
            } else {
                dataNodeMap.put(dataNode.getName(), dataNode);
            }
            // 處理子節點
            flatteningNodes(dataNode.getChildren(), dataNodeMap);
        }
    }
}

平鋪結構如下:

e7b9af24-1666-11ee-962d-dac502259ad0.png

4 分層(分組排序)

Q1:如何分層?

A1:節點平鋪后已經去重,此時借助 TreeMap 的自然排序特性將節點按照層級分組即可。

/**
 * @param dataNodeMap 平鋪結構
 * @return 分層結構
 */
private TreeMap> processLevel(Map dataNodeMap) {
    return dataNodeMap.values().stream().collect(Collectors.groupingBy(DataNode::getLevel, TreeMap::new, Collectors.toSet()))
}
分層如下:

e7f2bfc6-1666-11ee-962d-dac502259ad0.png

1. 根據分層 TreeMap 的 key 倒序即為調用的層級順序 對應 key 中的數據節點 Set 需用多線程并發調用,以保證鏈路調用時間

4、分層級調用

梳理出調用關系并分層后,使用并發編排工具調用即可。這里梳理的層級關系,level 越大,表示越優先調用。 這里以京東內部并發編排框架為例,說明調用流程:

/**
 * 構建編排流程
 *
 * @param infraDependencyHandlers 依賴接口
 * @param workerExecutor 并發線程
 * @return 執行數據
 */
public Sirector buildSirector(Set infraDependencyHandlers, ThreadPoolExecutor workerExecutor) {
    Sirector sirector = new Sirector<>(workerExecutor);
    long start = System.currentTimeMillis();
    // 依賴順序與執行順序相反
    TreeMap> levelNodes;
    TreeMap> cacheLevelNodes = localCacheManager.getValue("buildSirector");
    if (Objects.nonNull(cacheLevelNodes)) {
        levelNodes = cacheLevelNodes;
    } else {
        levelNodes = getLevelNodes(infraDependencyHandlers);
        ExecutorUtil.executeVoid(asyncTpExecutor, () -> localCacheManager.putValue("buildSirector", levelNodes));
    }
    log.info("buildSirector 梳理依賴關系耗時:{}", System.currentTimeMillis() - start);
    // 最底層接口執行
    Integer firstLevel = levelNodes.lastKey();
    EventHandler[] beginHandlers = levelNodes.get(firstLevel).stream().map(node -> abstractInfraHandlerMap.get(node.getName())).toArray(EventHandler[]::new);
    EventHandlerGroup group = sirector.begin(beginHandlers);

    Integer lastLevel = levelNodes.firstKey();
    for (int i = firstLevel - 1; i >= lastLevel; i--) {
        EventHandler[] thenHandlers = levelNodes.get(i).stream().map(node -> abstractInfraHandlerMap.get(node.getName())).toArray(EventHandler[]::new);
        group.then(thenHandlers);
    }
    return sirector;
}

5、 個人思考

作為接入內部 RPC、Http 接口實現業務處理的項目,在使用過程中要關注調用鏈路上的資源復用,尤其長鏈路的調用,要深入考慮內存資源的利用以及對底層服務的壓力。

要關注對外服務接口與底層數據接口的響應時差,分析調用邏輯與流程是否合理,是否存在優化項。

多線程并發調用多個平行數據接口時,如何使得各個線程的耗時方差盡可能?。?/p>




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RPC
    RPC
    +關注

    關注

    0

    文章

    111

    瀏覽量

    11544
  • HTTP接口
    +關注

    關注

    0

    文章

    21

    瀏覽量

    1822

原文標題:一種接口依賴關系分層方案

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    一種PCIe接口的視頻采集解決方案

    一種PCIe接口的視頻采集解決方案
    發表于 04-30 06:29

    一種低成本高速USB接口的設計方案

    一種基于DSP平臺的低成本高速USB接口方案
    發表于 05-10 07:13

    分享一種智能卡接口的設計方案

    分享一種智能卡接口的設計方案
    發表于 05-27 06:01

    介紹一種差分串行接口方案

    折疊式手機面臨哪些問題?一種滿足手機高速圖像數據傳輸的差分串行接口方案
    發表于 06-01 06:51

    如何去實現一種高速通信接口的設計?

    一種FPGA與DSP的高速通信接口設計與實現方案
    發表于 06-02 06:07

    一種基于TMS320C6xll接口的圖像獲取方案

    本文提出了一種基于TMS320C6xll接口的圖像獲取方案。
    發表于 06-03 06:53

    分享一種CH451與AMEG32的接口方案

    分享一種CH451與AMEG32的接口方案
    發表于 06-04 06:06

    基于mcu的一種分層軟件架構的相關資料分享

    基于mcu的一種分層軟件架構()1、寫在前面先來個圖:經過了段時間的琢磨與思考。借鑒操作系統的分層原理,也搞出來了
    發表于 11-03 06:46

    一種基于負載均衡的分層副本定位方法

    提出一種基于負載均衡的分層副本定位方法――RepliLoc。從副本信息存儲和副本定位計算2負載考慮,將副本定位問題劃分為社區層和社區聯合層。分別采用應用層廣播方式和基于P2
    發表于 04-16 08:49 ?16次下載

    一種高效、低延時的會議密鑰管理方案

    提出一種高效、低延時的會議密鑰管理方案——分層分組式密鑰管理(DCKM)方案,DCKM解決了其他密鑰管理方案中數據在子組間傳遞時必須經過多次
    發表于 04-23 10:48 ?21次下載

    一種包含異常傳播的類間數據依賴分析方法

    類間數據依賴分析是類間數據流測試的基礎。本文通過分析類簇級測試中的異常傳播對程序數據依賴的影響,提出一種包括異常結構在內的類間C++程序數據依賴分析方法,根據類間
    發表于 03-01 14:54 ?9次下載

    一種有效的多關系聚類算法

    一種有效的多關系聚類算法_鄧左祥
    發表于 01-03 15:24 ?0次下載

    一種新的識別和保留模型特征的自適應分層算法

    針對3D打印中已有自適應分層算法不能有效保留模型特征的問題,提出了一種新的識別和保留模型特征的自適應分層算法。首先,擴展了模型特征的定義,引入了模型特征丟失和偏移的概念;然后,提出了一種
    發表于 01-05 10:48 ?0次下載
    <b class='flag-5'>一種</b>新的識別和保留模型特征的自適應<b class='flag-5'>分層</b>算法

    基于mcu的一種分層軟件架構

    基于mcu的一種分層軟件架構()1、寫在前面先來個圖:經過了段時間的琢磨與思考。借鑒操作系統的分層原理,也搞出來了
    發表于 10-28 09:51 ?13次下載
    基于mcu的<b class='flag-5'>一種</b><b class='flag-5'>分層</b>軟件架構

    介紹一種基于分層聚類方法的木馬通信行為檢測模型

    一種基于分層聚類方法的木馬通信行為檢測模型
    的頭像 發表于 07-30 11:51 ?1219次閱讀
    介紹<b class='flag-5'>一種</b>基于<b class='flag-5'>分層</b>聚類方法的木馬通信行為檢測模型
    主站蜘蛛池模板: 欧洲一卡二卡乱码新区| 久久99热精品免费观看无卡顿| 天天操天天操天天| 人人cao| 精品国产午夜久久久久九九| 华人被黑人粗大猛然进| jiucao视频在线观看| 91免费视频网站| 东京加勒比| 桃色婷婷| 免费看黄色一级毛片| 国产精品免费观看网站| 夜夜爽66| 黄色日本视频| 一区二区三区视频在线观看| 国语一区| 手机在线观看a| 久久五月天婷婷| 最色网在线观看| 精品一区二区三区18| hd性欧美| 亚洲天堂不卡| 欧美成人福利| 国产精品7m凸凹视频分类大全| 午夜香蕉网| 1024国产你懂的日韩| 美女扒开尿囗给男人玩的动图| 亚洲国产成+人+综合| 你懂得在线播放| 在线理论视频| 亚洲啪啪网站| 中国一级特黄真人毛片| 欧美一级在线观看视频| www.91久久| 成人国产永久福利看片| 久久99热久久精品23| 日本欧美色图| 躁天天躁中文字幕在线| 2021国产成人午夜精品| 最好看最新的中文字幕1| 日韩亚洲欧洲在线com91tv |