大數據應用常用打包方式

来源:https://www.cnblogs.com/heibaiying/archive/2019/09/05/11466568.html
-Advertisement-
Play Games

一、簡介 在提交大數據作業到集群上運行時,通常需要先將項目打成 JAR 包。這裡以 Maven 為例,常用打包方式如下: 不加任何插件,直接使用 mvn package 打包; 使用 maven assembly plugin 插件; 使用 maven shade plugin 插件; 使用 mav ...


一、簡介

在提交大數據作業到集群上運行時,通常需要先將項目打成 JAR 包。這裡以 Maven 為例,常用打包方式如下:

  • 不加任何插件,直接使用 mvn package 打包;
  • 使用 maven-assembly-plugin 插件;
  • 使用 maven-shade-plugin 插件;
  • 使用 maven-jar-plugin 和 maven-dependency-plugin 插件;

以下分別進行詳細的說明。

二、mvn package

不在 POM 中配置任何插件,直接使用 mvn package 進行項目打包,這對於沒有使用外部依賴包的項目是可行的。但如果項目中使用了第三方 JAR 包,就會出現問題,因為 mvn package 打的 JAR 包中是不含有依賴包,會導致作業運行時出現找不到第三方依賴的異常。這種方式局限性比較大,因為實際的項目往往很複雜,通常都會依賴第三方 JAR。

大數據框架的開發者也考慮到這個問題,所以基本所有的框架都支持在提交作業時使用 --jars 指定第三方依賴包,但是這種方式的問題同樣很明顯,就是你必須保持生產環境與開發環境中的所有 JAR 包版本一致,這是有維護成本的。

基於上面這些原因,最簡單的是採用 All In One 的打包方式,把所有依賴都打包到一個 JAR 文件中,此時對環境的依賴性最小。要實現這個目的,可以使用 Maven 提供的 maven-assembly-pluginmaven-shade-plugin 插件。

三、maven-assembly-plugin插件

Assembly 插件支持將項目的所有依賴、文件都打包到同一個輸出文件中。目前支持輸出以下文件類型:

  • zip
  • tar
  • tar.gz (or tgz)
  • tar.bz2 (or tbz2)
  • tar.snappy
  • tar.xz (or txz)
  • jar
  • dir
  • war

3.1 基本使用

在 POM.xml 中引入插件,指定打包格式的配置文件 assembly.xml(名稱可自定義),並指定作業的主入口類:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptors>
                    <descriptor>src/main/resources/assembly.xml</descriptor>
                </descriptors>
                <archive>
                    <manifest>
                        <mainClass>com.heibaiying.wordcount.ClusterWordCountApp</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

assembly.xml 文件內容如下:

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 
                              http://maven.apache.org/xsd/assembly-2.0.0.xsd">
    
    <id>jar-with-dependencies</id>

    <!--指明打包方式-->
    <formats>
        <format>jar</format>
    </formats>

    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
            <!--這裡以排除 storm 環境中已經提供的 storm-core 為例,演示排除 Jar 包-->
            <excludes>
                <exclude>org.apache.storm:storm-core</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
</assembly>

3.2 打包命令

採用 maven-assembly-plugin 進行打包時命令如下:

# mvn assembly:assembly 

打包後會同時生成兩個 JAR 包,其中尾碼為 jar-with-dependencies 是含有第三方依賴的 JAR 包,尾碼是由 assembly.xml<id> 標簽指定的,可以自定義修改。

四、maven-shade-plugin插件

maven-shade-pluginmaven-assembly-plugin 功能更為強大,比如你的工程依賴很多的 JAR 包,而被依賴的 JAR 又會依賴其他的 JAR 包,這樣,當工程中依賴到不同的版本的 JAR 時,並且 JAR 中具有相同名稱的資源文件時,shade 插件會嘗試將所有資源文件打包在一起時,而不是和 assembly 一樣執行覆蓋操作。

通常使用 maven-shade-plugin 就能夠完成大多數的打包需求,其配置簡單且適用性最廣,因此建議優先使用此方式。

4.1 基本配置

採用 maven-shade-plugin 進行打包時候,配置示例如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <configuration>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.sf</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.dsa</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                    <exclude>META-INF/*.rsa</exclude>
                    <exclude>META-INF/*.EC</exclude>
                    <exclude>META-INF/*.ec</exclude>
                    <exclude>META-INF/MSFTSIG.SF</exclude>
                    <exclude>META-INF/MSFTSIG.RSA</exclude>
                </excludes>
            </filter>
        </filters>
        <artifactSet>
            <excludes>
                <exclude>org.apache.storm:storm-core</exclude>
            </excludes>
        </artifactSet>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                       implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer
                       implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

以上配置來源於 Storm Github,在上面的配置中,排除了部分文件,這是因為有些 JAR 包生成時,會使用 jarsigner 生成文件簽名 (完成性校驗),分為兩個文件存放在 META-INF 目錄下:

  • a signature file, with a .SF extension;
  • a signature block file, with a .DSA, .RSA, or .EC extension。

如果某些包的存在重覆引用,這可能會導致在打包時候出現 Invalid signature file digest for Manifest main attributes 異常,所以在配置中排除這些文件。

4.2 打包命令

使用 maven-shade-plugin 進行打包的時候,打包命令和普通打包一樣:

# mvn package

打包後會生成兩個 JAR 包,提交到伺服器集群時使用非 original 開頭的 JAR。

五、其他打包需求

1. 使用非Maven倉庫中的Jar

通常上面兩種打包能夠滿足大多數的使用場景。但是如果你想把某些沒有被 Maven 管理 JAR 包打入到最終的 JAR 中,比如你在 resources/lib 下引入的其他非 Maven 倉庫中的 JAR,此時可以使用 maven-jar-pluginmaven-dependency-plugin 插件將其打入最終的 JAR 中。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                          <!--指定 resources/lib 目錄-->
                        <classpathPrefix>lib/</classpathPrefix>
                          <!--應用的主入口類-->
                        <mainClass>com.heibaiying.BigDataApp</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>compile</phase>
                    <goals>
                         <!--將 resources/lib 目錄所有 Jar 包打進最終的依賴中-->
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                         <!--將 resources/lib 目錄所有 Jar 包一併拷貝到輸出目錄的 lib 目錄下-->
                        <outputDirectory>
                            ${project.build.directory}/lib
                        </outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

2. 排除集群中已經存在的Jar

通常為了避免衝突,官方文檔都會建議你排除集群中已經提供的 JAR 包,如下:

Spark 官方文檔 Submitting Applications 章節:

When creating assembly jars, list Spark and Hadoop as provided dependencies; these need not be bundled since they are provided by the cluster manager at runtime.

Strom 官方文檔 Running Topologies on a Production Cluster 章節:

Then run mvn assembly:assembly to get an appropriately packaged jar. Make sure you exclude the Storm jars since the cluster already has Storm on the classpath.

按照以上說明,排除 JAR 包的方式主要有兩種:

  • 對需要排除的依賴添加 <scope>provided</scope> 標簽,此時該 JAR 包會被排除,但是不建議使用這種方式,因為此時你在本地運行也無法使用該 JAR 包;
  • 建議直接在 maven-assembly-pluginmaven-shade-plugin 的配置文件中使用 <exclude> 進行排除。

3. 打包Scala文件

如果你使用到 Scala 語言進行編程,此時需要特別註意 :預設情況下 Maven 是不會把 scala 文件打入最終的 JAR 中,需要額外添加 maven-scala-plugin 插件,常用配置如下:

<plugin>
    <groupId>org.scala-tools</groupId>
    <artifactId>maven-scala-plugin</artifactId>
    <version>2.15.1</version>
    <executions>
        <execution>
            <id>scala-compile</id>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <includes>
                    <include>**/*.scala</include>
                </includes>
            </configuration>
        </execution>
        <execution>
            <id>scala-test-compile</id>
            <goals>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

參考資料

關於 Maven 各個插件的詳細配置可以查看其官方文檔:

關於 maven-shade-plugin 的更多配置也可以參考該博客: maven-shade-plugin 入門指南

更多大數據系列文章可以參見 GitHub 開源項目大數據入門指南


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

-Advertisement-
Play Games
更多相關文章
  • 目錄 1. 系統服務管理 1. 文件管理 1. 查看日誌 1. 壓縮與解壓 1. 磁碟和網路管理 1. 防火牆 1. ftp操作 1. 軟體的安裝與管理 1. 其他 系統服務管理 systemctl 輸出系統中各個服務的狀態: systemctl list units type=service 查看 ...
  • 背景以 Jenkins 伺服器為例,在構建內部的這個項目時,CE 每部署一次服務,最快 6 分鐘,最慢將近 13 分鐘左右。遇到多個項目併發打包會因為資源占用等問題時間會延長,甚至出現過幾次 20 分鐘以上的情況。 所以經常收到一些友情提示:比如像這樣的截圖,往往對方只發一張圖,卻什麼都不說: 原因 ...
  • 本文簡單描述CentOS源碼安裝MySQL5.7,所有步驟都經過測試完成,在安裝的過程中最容易遇到的問題一般都是路徑和許可權導致的,所有需要安裝的時候思考和記錄路徑和許可權,這裡需要善於使用linux系統的指令查找路徑和許可權。 ...
  • 錯誤號碼1045 Access denied for user 'root'@xx.xxx.xxx.xx(using password:YES) 遠程登錄被拒絕的非正常解決辦法 ...
  • 解決mongodb 啟動告警 /sys/kernel/mm/transparent_hugepage/enabled is 'always'. /sys/kernel/mm/transparent_hugepage/defrag is 'always' soft rlimits too lo... ...
  • MySQL學習——約束 摘要:本文主要學習了資料庫的約束。 primary key(主鍵) 定義 主鍵約束是一個列或者多個列,其值能唯一地標識表中的每一行。這樣的一列或多列稱為表的主鍵,通過它可以強製表的實體完整性。 主鍵約束相當於唯一約束和非空約束的組合,主鍵約束列不允許重覆,也不允許出現空值。 ...
  • 與python交互之前我們需要安裝一個MySQL的驅動模塊Connector,這個驅動模塊直接在cmd命令行輸入 安裝是否成功可以接著輸入 進入自己的編輯器(pycharm)首先連接資料庫方式: 資料庫連接 1、當前模塊直接連接 2、導入配置文件進行連接 游標 游標的作用是執行sql語句,或者保存s ...
  • 【作者】 王棟:攜程技術保障中心資料庫專家,對資料庫疑難問題的排查和資料庫自動化智能化運維工具的開發有強烈的興趣。 【問題描述】 最近碰到有台MySQL實例出現了MySQL服務短暫hang死,表現為瞬間的併發線程上升,連接數暴增。 排查Error Log文件中有page_cleaner超時的信息,引 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...