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

来源: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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...