袋鼠雲代碼檢查服務,揭秘高質量代碼背後的秘密

来源:https://www.cnblogs.com/DTinsight/archive/2023/09/27/17732968.html
-Advertisement-
Play Games

質量是產品的生命線,代碼檢查是軟體開發過程中至關重要的一環,它可以幫助我們發現並糾正潛在的錯誤,提高軟體質量,降低維護成本。 在袋鼠雲產品中也存在這個問題,由於離線數據開發人員 SQL 水平不一,導致代碼書寫混亂、SQL 代碼運行問題較多。本文將介紹在離線產品中如何利用 SQL 檢查規則規範化 SQ ...


質量是產品的生命線,代碼檢查是軟體開發過程中至關重要的一環,它可以幫助我們發現並糾正潛在的錯誤,提高軟體質量,降低維護成本。

袋鼠雲產品中也存在這個問題,由於離線數據開發人員 SQL 水平不一,導致代碼書寫混亂、SQL 代碼運行問題較多。本文將介紹在離線產品中如何利用 SQL 檢查規則規範化 SQL 代碼,對代碼書寫問題進行攔截,便於統一管理,用於預防引入需要治理的問題。

通過本文的介紹,我們希望您能夠認識到代碼檢查的重要性,並瞭解如何通過最佳實踐來提高代碼質量和開發效率。

何時進行代碼規則檢查?

SQL 任務在離線產品界面開發完成之後,點擊運行的按鈕,會先經過代碼規則檢查,如果代碼規則不滿足則會提示到用戶具體的原因。

file

數據資產模塊內置了 5 種代碼檢查規則,用戶可以根據需要選擇性開啟。

file

開啟後在離線項目管理中可以選擇使用的代碼規則檢查項、生效範圍和 SQL 任務類型。

file

在離線 SQL 任務中去運行一條 SQL 前會根據選擇的規則先進行代碼檢查,如果代碼檢查不通過則會反饋給用戶,用戶可以根據實際需要判斷要不要執行該 SQL。

file

在數據資產的代碼檢查時間中可以看到已經觸發的檢查歷史以及相應的統計數據。

file

如何實現代碼檢查規則?

在 CodeCheck 包下定義了通用的代碼規則檢查的介面。

public interface ICheck {
 Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo);
 CodeCheckType getCheckType();
}

分區表查詢必須帶分區規則為例,會先調用 SQLParser 組件進行 SQL 解析,SQLParseInfo 即為 SQL 解析結果,檢查時會先判斷 SQL 語句是不是查詢語句,如果是則判斷查詢的表是不是分區表,再判斷是否有查詢條件,最後判斷查詢條件中是否包含分區欄位來判斷是否檢查通過。

public class CodeCheckImplType01 extends AbstractCheck {
 private static final Logger LOGGER = LoggerFactory.getLogger(CodeCheckImplType01.class);
 @Autowired
 private DataTableColumnThirdService dataTableColumnThirdService;
 @Autowired
 private DataTableThirdService dataTableThirdService;
 @Override
 public Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo) {
 if (!isQuery(sqlParseInfo.getSqlType())) {
 return Result.buildSuccessResult();
 }
 try {
 MetadataSearchParam searchParam = new MetadataSearchParam();
 searchParam.setDbName(sqlParseInfo.getMainTable().getDb());
 searchParam.setTableName(sqlParseInfo.getMainTable().getName());
 searchParam.setDataSourceType(dataSourceType);
 searchParam.setTenantId(tenantId);
 List<TableDTO> tableDTOS = dataTableThirdService.tableList(searchParam);
 // 獲取表信息
 for (TableDTO tableDTO : tableDTOS) {
 List<DataTableColumn> tableColumns = dataTableColumnThirdService.listColumnByTableIds(Lists.newArrayList(tableDTO.getTableId()));
 if (CollectionUtils.isEmpty(tableColumns)) {
 continue;
 }
 List<String> partitionColumnNameList = tableColumns.stream()
 .filter(Objects::nonNull)
 .filter(t -> HavePartitionEnum.have_partition.getPartitionValue().equals(t.getIsPartition()))
 .map(DataTableColumn::getColumnName)
 .collect(Collectors.toList());
 // 非分區表直接返回
 if (CollectionUtils.isEmpty(partitionColumnNameList)) {
 continue;
 }
 if (CollectionUtils.isEmpty(sqlParseInfo.getColumnIdentifierList())) {
 // 沒有查詢條件則校驗失敗
 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName()));
 }
 List<String> columnList = sqlParseInfo.getColumnIdentifierList().stream()
 .filter(c -> StringUtils.equals(c.getDb(), searchParam.getSchemaName()) && StringUtils.equals(c.getTable(), searchParam.getTableName()))
 .map(ColumnIdentifier::getColumn).collect(Collectors.toList());
 boolean disjoint = Collections.disjoint(partitionColumnNameList, columnList);
 if (disjoint) {
 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName()));
 }
 }
 } catch (Exception e) {
 // 異常情況先通過
 LOGGER.error("code check error, check content: {}, defaultDb: {}, checkType: {}", checkContent, defaultDb, getCheckType().name());
 }
 return Result.buildSuccessResult();
 }
 @Override
 public CodeCheckType getCheckType() {
 return CodeCheckType.TYPE_01;
 }
}

如何自定義代碼檢查規則?

如果內置的代碼檢查規則不滿足客戶的使用場景,客戶可以通過上傳 jar 的方式自定義代碼檢查規則。

file

自定義代碼檢查規則使用 SPI 機制載入用戶上傳的自定義 jar,併在代碼檢測時調用 CodeCheck 方法,在資源關閉時調用 close 方法,用戶需要將配置文件說明中的 jar 依賴自己的項目中。具體如下:

● 創建一個類實現介面

創建一個類實現介面 com.dtstack.assets.spi.codecheck.ICodeCheckClient 並實現 CodeCheck 和 close 方法,書寫相關邏輯代碼,如果校驗通過需要將 CheckResult 對象中 success 設置為 true,失敗時設置 success 欄位為 false 並設置校驗不通過的理由。

package com.dtstack.assets.spi.codecheck;
import java.util.Map;
public interface ICodeCheckClient {
 /**
 * 代碼檢查
 *
 * @param checkContent 檢查內容
 * @param extMap 擴展配置
 * @return 檢查結果
 */
 CheckResult codeCheck(String checkContent, Map<String, Object> extMap);
 /**
 * 釋放資源, 調用時需要關閉所使用的資源
 */
 void close();
}

· 入參欄位解釋

– checkContent 為單條 SQL 信息

– extMap 會設置一些平臺的屬性,包含任務名稱、任務類型等

· 出參欄位解釋

– success 為是否校驗通過,必須設置

– checkResult 為校驗結果,校驗不通過時不能為空

package com.dtstack.demo;
import com.dtstack.assets.spi.codecheck.CheckResult;
import java.util.Map;
public class CodeCheckImpl implements com.dtstack.assets.spi.codecheck.ICodeCheckClient{
 @Override
 public CheckResult codeCheck(String checkContent, Map<String, Object> extMap) {
 // 代碼檢查相關邏輯
 CheckResult checkResult = new CheckResult();
 checkResult.setSuccess(false);
 checkResult.setCheckResult("校驗不通過的理由");
 return checkResult;
 }
 @Override
 public void close() {
 // 關閉相關資源
 }
}

● 在 resource 目錄下創建 META-INF/services 目錄

file

● 在 META-INF/services 目錄下創建文件

文件名稱為 com.dtstack.assets.spi.codecheck.ICodeCheckClient ,文件內容為實現 ICodeCheckClient 介面類的許可權定類名。

file

文件名稱和內容示例:

file

● 打包當前工程併在數據資產頁面註冊代碼校驗規則

不符合條件的 jar 會給出提示。

file
file

如何載入自定義代碼規則對應的 jar ?

我們會為上傳的每個規則對應的 jar 初始化一個唯一的自定義 classloader,該 classloader 繼承 URLClassLoader 並保證子類載入器優先載入。

file

在第一次調用時進行載入並緩存對應的 client。

file

在用戶重新上傳或者編輯規則後清除舊的 classloader 和載入的 client 並釋放資源。

file

《數棧產品白皮書》:https://www.dtstack.com/resources/1004?src=szsm

《數據治理行業實踐白皮書》下載地址:https://www.dtstack.com/resources/1001?src=szsm

想瞭解或咨詢更多有關袋鼠雲大數據產品、行業解決方案、客戶案例的朋友,瀏覽袋鼠雲官網:https://www.dtstack.com/?src=szbky

同時,歡迎對大數據開源項目有興趣的同學加入「袋鼠雲開源框架釘釘技術qun」,交流最新開源技術信息,qun號碼:30537511,項目地址:https://github.com/DTStack


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:背景 1. 講故事 今天本來想寫一篇 非托管泄露 的生產事故分析,但想著昨天就上了一篇非托管文章,連著寫也沒什麼意思,換個口味吧,剛好前些天有位朋友也找到我,說他們的拍攝監控軟體卡死了,讓我幫忙分析下為什麼會卡死,聽到這種軟體,讓我不禁想起了前些天 在程式員桌子上安裝監控 的新聞,參考如下: 我 ...
  • 前言 JSON Web Token(JWT)是一個非常輕巧的規範。這個規範允許我們使用 JWT 在用戶和伺服器之間傳遞安全可靠的信息。一個 JWT 實際上就是一個字元串,它由三部分組成,頭部、載荷與簽名。前兩部分需要經過 Base64 編碼,後一部分通過前兩部分 Base64 編碼後再加密而成。針對 ...
  • 出於對新工具和新技術的好奇,我開始嘗試在deepin上用Fleet開發一個SpringBoot 3.0.0項目,繼續我的SpringBoot學習。 ...
  • 情況說明:在VMware vsphere的虛擬化平臺下,為了快速部署虛擬伺服器,我們常常使用模板部署虛擬機。但真實業務有時要求的文件系統分區和大小常常與模板不同,這時便需要自定義硬體資源和使用 LVM 方式擴容。在定義硬碟的時候我們可以在原有的硬碟上直接增加,然後虛擬機創建完成後再進入系統進行擴容, ...
  • 對於最小化安裝的 Debian11.7 ,起初有一個問題給我造成了困擾:那就是當我使用 vi 編輯文本文件時,我無法通過鍵入“i”來切換到輸入模式,或者說,其實的確進入了輸入模式,但是底部行並沒有顯式進行提示,另外,我無法使用 Backspace 鍵來刪除字元,Delete 鍵是可以刪除字元的,不過 ...
  • 1. 概述 1.1. 複製解決的基本問題是讓一臺伺服器的數據與其他伺服器保持同步 1.2. 在源伺服器(source server)上,任何數據修改和數據結構變更的事件(event)都會被寫入日誌文件中 1.3. 副本伺服器從源伺服器上的日誌文件中讀取這些事件併在本地重放執行 1.4. 一個非同步處理 ...
  • 日常Bug排查系列都是一些簡單Bug排查。問題雖小,但經常遇到,瞭解這些問題,會讓我們少走點彎路,提升效率。說不定有些問題你遇到過哦:) Bug現場 業務開發同學突然問了筆者一個問題,從庫讀會不會沒有原子性?我下意識的反應怎麼可能,只要是遵守MySQL主從Replication協議的原子性至少是能夠 ...
  • 1. explain命令是什麼東西? explain 是MySql提供的SQL語句查詢性能的工具,是我們優化SQL的重要指標手段,要看懂explain返回的結果集就尤為重要 2. explain命令返回列解讀 + + + + + + + + + + + + + | id | select_type ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...