偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

MetrAutoAPI系統(tǒng)架構(gòu)設(shè)計(jì)

開發(fā) 前端
商用數(shù)據(jù)庫(kù)不是開發(fā)者的玩具,而是要被用戶長(zhǎng)期使用的,不斷升級(jí)的技術(shù)不應(yīng)該讓使用者的知識(shí)不斷的過(guò)期,保持知識(shí)與接口的兼容性方面,我們的國(guó)產(chǎn)數(shù)據(jù)庫(kù)還是有很多地方要多學(xué)學(xué)Oracle。?

1.背景

公司正在進(jìn)行數(shù)據(jù)戰(zhàn)略轉(zhuǎn)型,因此我們面臨的數(shù)據(jù)需求越來(lái)越多,而我們擁有的指標(biāo)數(shù)據(jù)越來(lái)越豐富。不過(guò),僅僅擁有數(shù)據(jù)并不夠,我們需要能夠更加靈活高效的使用這些數(shù)據(jù),以應(yīng)對(duì)頻繁多變的數(shù)據(jù)需求。傳統(tǒng)的數(shù)據(jù)業(yè)務(wù)開發(fā)流程效率低下,無(wú)法及時(shí)響應(yīng)變化的需求。因此,我們必須找到一種快速、靈活的解決方案,以滿足我們快速變化的需求。

2.MetrAutoAPI設(shè)計(jì)

2.1平臺(tái)介紹

MetrAutoAPI(Metric Automate API即指標(biāo)自動(dòng)化API)將指標(biāo)數(shù)據(jù)與應(yīng)用層做分離,MetrAutoAPI僅負(fù)責(zé)管理和處理數(shù)據(jù)信息,對(duì)外提供了一個(gè)通用的API接口,所有的數(shù)據(jù)請(qǐng)求和響應(yīng)都通過(guò)這個(gè)接口進(jìn)行傳輸和處理。

MetrAutoAPI支持多個(gè)數(shù)據(jù)源集成,其API建模功能靈活可配置,可通過(guò)頁(yè)面拖拽和配置生成SQL查詢語(yǔ)句,幫助用戶快速準(zhǔn)確地獲取所需數(shù)據(jù)。此外,規(guī)則引擎服務(wù)可以對(duì)查詢結(jié)果進(jìn)行靈活的運(yùn)算,幫助用戶實(shí)現(xiàn)自動(dòng)化計(jì)算和分析,從而提高效率。

2.2架構(gòu)設(shè)計(jì)

圖片圖片

物理查詢層:通過(guò)統(tǒng)一查詢引擎,實(shí)現(xiàn)對(duì)不同來(lái)源數(shù)據(jù)庫(kù)的查詢

語(yǔ)義模型層:負(fù)責(zé)指標(biāo)元數(shù)據(jù)的管理,并對(duì)API-SQL模型進(jìn)行管理。

統(tǒng)一服務(wù)層:提供指標(biāo)維度的API構(gòu)建功能,以及基于指標(biāo)維度的數(shù)據(jù)查詢和規(guī)則引擎配置服務(wù)。

統(tǒng)一接口層:提供一個(gè)對(duì)外的API接口,所有的數(shù)據(jù)請(qǐng)求和響應(yīng)都通過(guò)這個(gè)接口進(jìn)行傳輸和處理。

此方案對(duì)比傳統(tǒng)開發(fā)模式:

圖片圖片

2.3使用場(chǎng)景

以下是MetrAutoAPI的一些使用場(chǎng)景的介紹:

?數(shù)據(jù)看板展示

圖片圖片

2.4核心功能

?2.4.1 SQL建模服務(wù)

利用Zealot與MySqlStatementParser實(shí)現(xiàn)SQL建模功能

可以根據(jù)不同的查詢條件和參數(shù)動(dòng)態(tài)生成對(duì)應(yīng)的SQL語(yǔ)句,從而避免手動(dòng)拼接SQL語(yǔ)句帶來(lái)的代碼冗余和錯(cuò)誤,可以很好地支持參數(shù)的綁定和傳遞,可以通過(guò)占位符或命名參數(shù)的方式傳遞參數(shù),同時(shí)支持參數(shù)類型的自動(dòng)轉(zhuǎn)換

SQL建模過(guò)程如下:

public static List<FieldVo> getFieldName(String sqlStr) {  
        MySqlStatementParser mySqlStatementParser = new MySqlStatementParser(sqlStr);  
        //使用parpser解析生成的AST,這里sqlStatement是AST,AST為抽象語(yǔ)法樹  
        SQLStatement sqlStatement = mySqlStatementParser.parseStatement();  
        MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();  
        sqlStatement.accept(visitor);  
  
        //list是存儲(chǔ)表名和字段名的集合  
        List<FieldVo> list = new ArrayList<>();  
        Collection<TableStat.Column> columns = visitor.getColumns();  
        //通過(guò)循環(huán)將表名和字段名解析出,并存儲(chǔ)到list集合中  
        columns.stream().forEach(row -> {  
            if (row.isSelect()) {  
                FieldVo fieldVo = new FieldVo();  
                fieldVo.setTableName(row.getTable());  
                fieldVo.setFieldName(row.getName());  
                list.add(fieldVo);  
            }  
        });  
  
        List<FieldVo> aliasList = getAliasField(sqlStr);  
        for (int i = 0 ; i < list.size() ; i ++) {  
            FieldVo vo = list.get(i);  
            FieldVo aliasVo = aliasList.get(i);  
            if (Objects.isNull(aliasVo.getAliasName())) {  
                vo.setAliasName(vo.getFieldName());  
            } else {  
                vo.setAliasName(aliasVo.getAliasName());  
            }  
        }  
        return list;  
    }

自動(dòng)生成API-SQL接口文檔說(shuō)明:

圖片圖片

?2.4.2 API-aviator規(guī)則引擎服務(wù)

Aviator是一個(gè)高性能、輕量級(jí)的java語(yǔ)言實(shí)現(xiàn)的表達(dá)式求值引擎,主要用于各種表達(dá)式的動(dòng)態(tài)求值,使用規(guī)則引擎可以把復(fù)雜、重復(fù)的業(yè)務(wù)規(guī)則同各個(gè)業(yè)務(wù)系統(tǒng)分離開,以提高業(yè)務(wù)邏輯的復(fù)用能力和開發(fā)效率。

圖片圖片

規(guī)則表達(dá)式設(shè)置如下:

圖片圖片

初始化規(guī)則引擎:

public class AviatorEvaluatorUtils {  
    private static AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();  
  
    public AviatorEvaluatorUtils() {  
    }  
  
    public static AviatorEvaluatorInstance getInstance() {  
        return instance;  
    }  
  
    static {  
        instance.addFunction(new TransNullToZeroRule());  
        instance.addFunction(new IsNullRuleFunction());  
        instance.addFunction(new CrrRadioRule());  
        instance.addFunction(new CrrRule());  
    }  
}

規(guī)則引擎服務(wù)會(huì)解析并執(zhí)行規(guī)則表達(dá)式。

private List<Map<String, Object>> expResult(List<RestApiVo> fieldList, List<Map<String, Object>> dataList) {  
       Stopwatch started = Stopwatch.createStarted();  
       List<Map<String, Object>> resultList = new ArrayList<>();  
       for (Map<String, Object> map : dataList) {  
           Map<String, Object> dataMap = new HashMap<>();  
           fieldList.forEach(e -> {  
               try {  
                   Expression exp = AviatorEvaluatorUtils.getInstance().compile(e.getFieldExp(), true);  
                   Object value = exp.execute(map);  
                   if (Objects.isNull(value)) {  
                       dataMap.put(e.getFieldName(), null);  
                   } else {  
                       if (e.getIsFormat().intValue() == 1) {  
                           BigDecimal decimal = new BigDecimal(value.toString());  
                           BigDecimal scale = decimal.setScale(e.getNumberFormat().intValue(), BigDecimal.ROUND_HALF_UP);  
                           dataMap.put(e.getFieldName(), scale);  
                       } else {  
                           dataMap.put(e.getFieldName(), value);  
                       }  
                   }  
               } catch (Exception ex) {  
                   log.error("解析表達(dá)式異常,字段:{},結(jié)果:{}", JsonUtil.serialize(e), JsonUtil.serialize(map), ex);  
                   dataMap.put(e.getFieldName(), null);  
               }  
           });  
           resultList.add(dataMap);  
       }  
       log.warn("轉(zhuǎn)換結(jié)果耗時(shí):{}", started.stop());  
       return resultList;  
   }

?2.4.3 API統(tǒng)一查詢引擎

提供標(biāo)準(zhǔn)化的接口和協(xié)議,使得調(diào)用端可以通過(guò)一致的方式來(lái)請(qǐng)求和響應(yīng)多個(gè)不同的 API。這樣做可以簡(jiǎn)化開發(fā)人員的工作,加快應(yīng)用程序的開發(fā)速度,同時(shí)提高系統(tǒng)的可靠性和可維護(hù)性。

/** 
     * 統(tǒng)一API接口 
     * @param _appId appId 
     * @param params 入?yún)?
     * @return 
     */  
    @PostMapping("/restApi")  
    public Protocol<List<Map<String, Object>>> restApi(String _appId, @RequestBody Map<String, Object> params, String apiKey) {  
        ParamsValid valid = new ParamsValid();  
        valid.validNotNull("params", params)  
                .valid("apiId與apiKey不能同時(shí)為空", () -> {  
                    if (Objects.isNull(params.get("apiId"))  && Objects.isNull(params.get("apiKey"))) {  
                        return false;  
                    }  
                    return true;  
                }).valid("apiKey值不正確", () -> {  
                    if (Objects.nonNull(params.get("apiKey"))) {  
                        if (Strings.isNullOrEmpty(params.get("apiKey").toString())) {  
                            return false;  
                        }  
                    }  
                    return true;  
                });  
        if (!valid.isValid()) {  
            return valid.showInValidMessage();  
        }  
        Protocol<List<Map<String, Object>>> protocol = null;  
        try {  
            protocol = targetAutoService.restApi(params, _appId, 1);  
        } catch (DataSelfException ex) {  
            log.error("查詢數(shù)據(jù)異常:param:{},apiKey:{}", JsonUtil.serialize(params), apiKey, ex);  
            return new Protocol<>(-1, ex.toString());  
        } catch (Exception e) {  
            log.error("查詢信息異常:param:{}", JsonUtil.serialize(params), e);  
            return new Protocol<>(-1, "查詢異常,請(qǐng)重試");  
        }  
        return protocol;  
    }

流程如下:

圖片圖片

3.實(shí)踐過(guò)程中問(wèn)題及解決方案

3.1使用過(guò)程中遇到的難題

接口性能差:接口性能差,分析日志發(fā)現(xiàn)從數(shù)據(jù)庫(kù)中讀取配置與規(guī)則引擎信息耗時(shí)較長(zhǎng),性能較差。

解決方案:使用redis作為緩存,存儲(chǔ)模型元數(shù)據(jù)信息,統(tǒng)一API引擎在讀取配置數(shù)據(jù)前先從redis中獲取,如果獲取不到再?gòu)臉I(yè)務(wù)庫(kù)中讀取,并將讀取到的數(shù)據(jù)寫入redis緩存,設(shè)置過(guò)期時(shí)間,定期清除redis緩存中過(guò)期的數(shù)據(jù),避免占用過(guò)多的內(nèi)存;通過(guò)以上優(yōu)化,可以有效減少?gòu)臄?shù)據(jù)庫(kù)中讀取配置數(shù)據(jù)的時(shí)間,提高接口性能。

使用緩存后,性能對(duì)比:

圖片圖片

上線成本高:測(cè)試環(huán)境建模并驗(yàn)證完成后,還需要在線上環(huán)境再次建模,不僅重復(fù)操作并且可能因?yàn)槿藶槭韬鲈斐删€上線下模型不一致,從而造成嚴(yán)重后果。

解決方案:使用信息復(fù)制可以簡(jiǎn)化測(cè)試環(huán)境到線上環(huán)境的配置過(guò)程,從而提高工作效率。具體實(shí)現(xiàn)步驟如下:

在測(cè)試環(huán)境中建模,并將模型元數(shù)據(jù)信息保存為一個(gè)JSON格式的數(shù)據(jù),通過(guò)粘貼板復(fù)制功能,將JSON信息復(fù)制到線上環(huán)境,通過(guò)權(quán)限控制來(lái)進(jìn)行安全控制(配置簡(jiǎn)單化),避免人為異常。

多API接口合并:由于調(diào)用方可能需要的指標(biāo)過(guò)于繁瑣,可能涉及多個(gè)指標(biāo)API接口的調(diào)用,造成調(diào)用方調(diào)用次數(shù)過(guò)多,造成并發(fā)多,壓力大,影響調(diào)用方的使用或者造成調(diào)用鏈過(guò)長(zhǎng)

解決方案:采用接口聚合的方式來(lái)解決。接口聚合是將多個(gè)API接口的數(shù)據(jù)聚合到一個(gè)API接口中,使得調(diào)用方只需要調(diào)用一個(gè)API接口就能獲取到需要的所有指標(biāo)數(shù)據(jù),避免了多次調(diào)用導(dǎo)致的并發(fā)過(guò)多和響應(yīng)時(shí)間過(guò)長(zhǎng)的問(wèn)題。同時(shí),也可以提高接口的可用性,避免接口出錯(cuò)或者異常導(dǎo)致調(diào)用失敗。

4.參考文獻(xiàn)

ApiJson:http://apijson.cn/doc/zh/

Mybatis:ttps://github.com/mybatis/mybatis-dynamic-sql

Zealot:ps://gitee.com/chenjiayin1990/zealot

Aviator:https://www.yuque.com/boyan-avfmj/aviatorscript

作者簡(jiǎn)介

李賀曉

  • 經(jīng)銷商技術(shù)部-i車商團(tuán)隊(duì)
  • 2018年加入汽車之家,任職于經(jīng)銷商技術(shù)部-i車商團(tuán)隊(duì),目前主要負(fù)責(zé)數(shù)據(jù)類產(chǎn)品開發(fā)和探索。
責(zé)任編輯:武曉燕 來(lái)源: 之家技術(shù)
相關(guān)推薦

2014-05-19 10:08:36

IM系統(tǒng)架構(gòu)設(shè)計(jì)

2023-08-16 12:34:16

同步備份異步備份

2024-10-17 08:26:53

ELKmongodb方案

2024-08-16 14:01:00

2013-05-27 10:58:28

Tumblr架構(gòu)設(shè)計(jì)雅虎收購(gòu)

2015-10-16 14:35:05

SaaSCRM架構(gòu)設(shè)計(jì)

2017-12-12 08:40:00

2010-08-10 10:10:28

系統(tǒng)架構(gòu)

2023-07-09 15:20:00

緩存平衡性能

2015-11-13 10:25:04

京東商品搜索架構(gòu)

2023-07-05 00:36:38

系統(tǒng)架構(gòu)設(shè)計(jì)

2023-07-06 00:41:03

SQLNoSQL數(shù)據(jù)庫(kù)

2018-05-17 10:10:17

架構(gòu)設(shè)計(jì)優(yōu)化

2015-06-02 04:17:44

架構(gòu)設(shè)計(jì)審架構(gòu)設(shè)計(jì)說(shuō)明書

2025-05-09 08:45:13

2025-04-15 04:00:00

2023-07-03 17:15:12

系統(tǒng)架構(gòu)設(shè)計(jì)

2015-06-02 04:34:05

架構(gòu)設(shè)計(jì)

2021-12-23 09:00:00

架構(gòu)微服務(wù)數(shù)據(jù)

2017-07-06 00:27:17

虛擬訂單中心京東數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)