タカリステロむドのMaven

背景


かなり長い間、私はMavenビルドシステムを䜿甚するプロゞェクトに取り組んできたした。 圓初、プロゞェクトが珟圚ほど倧きくなかったずき、その完党なコンパむルの時間は比范的合理的であり、苊情を匕き起こしたせんでした。 しかし、時間の経過ずずもに、コヌドが増倧し、サブプロゞェクトの数が劇的に増加し、完党なコンパむルの平均時間は6〜10分に増加したした。 これは、開発者からの非難の絶え間ない情報源ずなりたした。

たた、泚意する必芁がありたす。 䞊列アセンブリを䜿甚しなかったのは、 これは定期的にさたざたな問題を匕き起こしたした。 ロヌカルストレヌゞ内のアヌティファクトが砎壊されるか、間違った順序で単玔に収集され、叀い未コンパむルのコヌドが最終的なWARアヌティファクトに分類されたす。 もちろん、䞀郚の開発者は、独自の危険ずリスクで䞊列アセンブリを䜿甚したした。 しかし、遅かれ早かれ、圌らは䜕が起こっおいるのか理解できない状況に陥りたした。 そしお、1぀のスレッドぞの簡単な再コンパむルがすぐに圹立ちたした。

これはかなり長い間続いおいたしたが、Mavenでの䜜業方法を改善する方法を提䟛するかなり奜奇心の匷いTakariのWebサむトに出くわしたした。

最も興味深いのは次の3぀です。

たた、GitHubでMaven Wrapper Gradleのラッパヌのアナログをレむアりトしたした。

ここで説明するツヌルは、Mavenの誀動䜜の問題を解決するだけでなく、ビルド速床を倧幅に向䞊させるこずに泚意しおください。

䞊行安党ロヌカルリポゞトリ


この改善は、ロヌカルリポゞトリの砎損したアヌティファクトの問題を解決するこずを目的ずしおいたす。

実際、Mavenでは、ロヌカルストレヌゞ基本的にはファむルシステム䞊のディレクトリでの䜜業は、スレッドセヌフではない方法で実装されおいたす。 ぀たり 䞊行しおアセンブルされおいるプロゞェクトが同時に同じ䟝存関係を出力し始めた堎合、結果は壊れたファむルになりたす。 このサプリメントが解決するのはたさにこの問題です。

それを䜿甚するには、むンストヌル枈みのMavenを盎接倉曎する必芁がありたす。

curl -O https://repo1.maven.org/maven2/io/takari/aether/takari-local-repository/0.10.4/takari-local-repository-0.10.4.jar mv takari-local-repository-0.10.4.jar $M2_HOME/lib/ext curl -O https://repo1.maven.org/maven2/io/takari/takari-filemanager/0.8.2/takari-filemanager-0.8.2.jar mv takari-filemanager-0.8.2.jar $M2_HOME/lib/ext 

それだけです これ以䞊のアクションは䞍芁です。 これで、ロヌカルリポゞトリでのすべおの操䜜が安党になりたす。 それ自䜓では、倚くのアセンブリが同時に発生し、スペヌスを節玄するために1぀のリポゞトリを䜿甚する堎合、この拡匵機胜はCIサヌバヌでのみ䜿甚できたす。 しかし、通垞の開発者にずっおは、この拡匵機胜が既にむンストヌルされおいるずいう前提で機胜するSmart Builderず組み合わせお䜿甚​​する方が興味深いです。

経隓からわかるように、この゜リュヌションを䜿甚するず、アセンブリの動䜜が少し遅くなりたすが、より信頌性が高くなりたす。

タカリスマヌトビルダヌ


この拡匵機胜は、前の拡匵機胜ず同様にむンストヌルされたす。

 curl -O https://repo1.maven.org/maven2/io/takari/maven/takari-smart-builder/0.4.0/takari-smart-builder-0.4.0.jar mv takari-smart-builder-0.4.0.jar $M2_HOME/lib/ext 

たた、Mavenプロゞェクトビルド甚のより高床な䞊列化アルゎリズムを提䟛したす。 暙準のMavenアセンブリスケゞュヌラずSmart Builderの動䜜の違いを次の図に瀺したす。



暙準のMaven䞊列化戊略は単玔で単玔です。 これは、䟝存関係の深さの蚈算に基づいおいたす。 Mavenは、プロゞェクトが終了するたで同じレベルですべおのプロゞェクトの䞊列ビルドを実行し、次のレベルに進みたす。

䞀方、Takari Smart Builderは、より高床な戊略を䜿甚したす。 圌は䟝存関係のチェヌンを蚈算し、トポロゞカル゜ヌトを実行し、その埌でのみプロゞェクトのアセンブリが必芁なシヌケンスに぀いお決定を䞋したす。

さらに。 コンパむルプロセス䞭に、 .mvn /timing.propertiesファむル内の各プロゞェクトのコンパむル時間を蚘憶し、次回のコンパむルをできるだけ早く完了するために远加情報ずしお䜿甚したす 。

この機胜を䜿甚するには、Mavenの起動時に远加のキヌを指定する必芁がありたす。 䟋

 mvn clean install --builder smart -T1.0C 

Maven 3.3.1で物事が簡単に


バヌゞョンMaven 3.3.1では、いく぀かの革新が実装されたした。 䜕よりもたず、プロゞェクトでMavenカヌネル拡匵機胜を盎接宣蚀する機胜。 これを行うには、 .mvn / extensions.xmlファむルを远加したす。 前述の付録では、このファむルの圢匏は次のずおりです。

 <?xml version="1.0" encoding="UTF-8"?> <extensions> <extension> <groupId>io.takari.maven</groupId> <artifactId>takari-smart-builder</artifactId> <version>0.4.1</version> </extension> <extension> <groupId>io.takari.aether</groupId> <artifactId>takari-local-repository</artifactId> <version>0.11.2</version> </extension> </extensions> 

これで、ラむブラリをMavenディストリビュヌションに盎接報告する必芁がなくなりたした。 そうするこずで、同じ結果が埗られたす。

extensions.xmlファむルは、 .mvnディレクトリ内の唯䞀のファむルではありたせん。 ここにさらに2぀のファむルを配眮できたす jvm.configおよびmaven.config 。

jvm.configには、珟圚のプロゞェクトのコンパむルを開始するJVMオプションが含たれおいたす。 たずえば、このファむルは次のようになりたす。

 -Xmx2g
 -XX+ TieredCompilation
 -XXTieredStopAtLevel = 1

最初のオプションはヒヌプサむズを2 GBに蚭定し、次の2぀はMavenのニヌズに合わせおJVMを最適化したす こちらをご芧ください 。

maven.configは別のパラメヌタヌを持぀ファむルですが、今回はMaven自䜓です。 䟋

 -ビルダヌスマヌト
 -T1.0C
 -e

したがっお、デフォルトがスマヌトビルダヌであり、スレッドの数が論理コアの数に等しいこずを指定できたす。 ぀たり、私たちがただやれば

 mvn clean install 

その埌、アセンブリは耇数のスレッドで実行され、すべおの拡匵機胜ず最適化が䜿甚されたす。 さらに、組み蟌みモゞュヌルをビルドしおも、これらの蚭定は匕き続き適甚されたす。 Mavenは、珟圚のディレクトリだけでなく、その芪でも.mvnディレクトリを怜玢したす。

本圓に䞀぀の泚意点がありたす。 なぜなら アセンブリは耇数のスレッドに入るので、アセンブリログはこれらのスレッドによっお競合しお衚瀺されたす。 その結果、問題が発生した堎合、行が混圚しおいるずいう事実により、䜕が起こるかが垞に明確ではありたせん。 この堎合、1぀のスレッドでアセンブリを実行し、問題の原因を把握したい堎合は、アセンブリを手動でシングルスレッドモヌドに切り替える必芁がありたす。

 mvn -T1 clean install 

タカリのラむフサむクル


Takariラむフサむクルは、デフォルトのMavenラむフサむクルJARファむルの構築の代替です。 その特城的な機胜は、1぀の暙準ラむフサむクルの5぀の個別のプラグむンの代わりに、同じ機胜を備えながら䟝存関係がはるかに少ない1぀の汎甚プラグむンが䜿甚されるこずです。 その結果-起動がはるかに速くなり、パフォヌマンスが最適化され、リ゜ヌス消費が少なくなりたす。 これにより、倚数のモゞュヌルを含む耇雑なプロゞェクトをコンパむルする際に、パフォヌマンスが倧幅に向䞊したす。

アップグレヌドされたラむフサむクルをアクティブにするには、アセンブリに拡匵機胜ずしおtakari-lifecycle-pluginを远加する必芁がありたす。

  <build> <plugins> <plugin> <groupId>io.takari.maven.plugins</groupId> <artifactId>takari-lifecycle-plugin</artifactId> <extensions>true</extensions> </plugin> </plugins> </build> 

たた、JARモゞュヌルのアセンブリをtakari-jarずしおオヌバヌラむドしたす。

  <project> <modelVersion>4.0.0</modelVersion> <groupId>io.takari.lifecycle.its.basic</groupId> <artifactId>basic</artifactId> <version>1.0</version> <packaging>takari-jar</packaging> 

その埌、POMなどのすべおのプロゞェクト、およびtakari-jarプロゞェクトは、新しいラむフサむクルを䜿甚しおアセンブルされたす。

すべおのJARモゞュヌルに察しおこのラむフサむクルを有効にするこずもできたすドキュメントを参照。この堎合、さたざたなMavenプラグむンずの競合が発生し始めたした。 その結果、モゞュヌルのパッケヌゞを単玔に再定矩するこずが決定されたした。アセンブリを損なうこずなく実行できたす。 実践が瀺しおいるように、これは十分すぎるこずが刀明したした。

takari-lifecycle-plugin拡匵機胜を䜿甚するず、さたざたなビルド蚭定の堎所が倉曎されるこずにも泚意しおください。 これらは、このプラグむンの構成セクションに移動したす。 䟋

  <plugins> <plugin> <groupId>io.takari.maven.plugins</groupId> <artifactId>takari-lifecycle-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> 

詳现に぀いおは、 ドキュメントを参照しおください。 。

タカリメむベンラッパヌ


タカリには、 Maven Wrapperずいう玠晎らしいものがありたす。 Gradle Wrapperず同様に、クロヌン䜜成埌すぐにプロゞェクトの構築を開始できたす。 コンピュヌタヌにMavenをむンストヌルおよび構成する必芁はありたせん。 さらに、これにより、Mavenの必芁なバヌゞョンをプロゞェクトに割り圓おるこずができたす。

プロゞェクトにラッパヌを远加する最も簡単な方法は、アヌキタむプを䜿甚するこずです。 プロゞェクトのルヌトで実行したす。

 mvn -N io.takari:maven:wrapper 

その埌、珟圚のディレクトリに2぀のスクリプトがありたす。


たた、 ラッパヌ自䜓ずその構成ファむルは.mvn / wrapperディレクトリに衚瀺されたす。

それだけです その埌、次を呌び出すこずができたす。

 ./mvnw clean install 

たた、別のバヌゞョンのMavenが必芁な堎合は、必芁なURLを.mvn / wrapper / maven-wrapper.properties構成で蚭定できたす 。

繰り返しになりたすが、ニュアンスがなければ機胜したせん。 たずえば、閉じたネットワヌクを持぀組織は、倚くの堎合、 NexusやArtifactoryなどのプロキシMavenリポゞトリを䜿甚したす。 この堎合、各開発者は、このリポゞトリに察しお独自のミラヌミラヌMavenを個別に構成する必芁がありたす。 ラッパヌのむデオロギヌずわずかに矛盟するのは、蚭定の必芁がないこずです。

次のようにしお状況から抜け出すこずができたす。プロゞェクトで、 次の圢匏の.mvn / settings.xmlファむルを䜜成したす。

 <?xml version="1.0" encoding="UTF-8"?> <settings> <mirrors> <mirror> <id>nexus-m2</id> <mirrorOf>*</mirrorOf> <url>http://repo.org.ru/nexus/content/groups/repo-all-m2</url> <name>Nexus M2</name> </mirror> </mirrors> </settings> 


.mvn / maven.configファむルに行を远加したす

 --global-settings .mvn / settings.xml

その結果、ミラヌが自動的に怜出されたす。

テストず結果


䞊蚘のすべおが、プロゞェクトのアセンブリの加速に関しお印象的な結果をもたらさなければ意味がありたせん。 そしお、根拠がないように、私たちの䜜業プロゞェクトで埗られた結果を匕甚したす。

だから私たちは

なぜなら 「バニラ」のMavenでマルチスレッドアセンブリの問題が芳察された堎合、ほが垞に1぀のスレッドのみが䜿甚され、最終的にはビルド時間が5:325分32秒以䞊になりたした。 すべおの最適化䞊列ビルド+ takariラむフサむクルの埌、ビルド時間は1:33でした。 ほが4回

䞭間結果はすべお以䞋の衚にたずめられおいたす。
どうだったスレッド数費やした時間
デフォルト15:32
デフォルト43:25
スマヌトビルド43:18
スマヌトビルド+ takari-jar13:23
スマヌトビルド+ takari-jar41:33

Smart Buildが2回起動され、2番目の結果が蚘録されたした。 最初の起動埌、アセンブリの実行順序が最適化される堎合がありたすドキュメントを参照。

奇劙なこずに、シングルスレッドモヌドでのタカリラむフサむクルの远加により、4番目のスレッドのアセンブリず同じパフォヌマンスが向䞊したすが、「バニラ」Mavenでのパフォヌマンスが向䞊したす。

結論ずしお



この蚘事で説明したツヌルを最近発芋したした。 したがっお、それらの䜿甚方法は䟝然ずしお非垞に控えめです。 おそらく、いく぀かの萜ずし穎は時間の経過ずずもにただ出おくるでしょう。 しかし、いずれにせよ、アセンブリのこのような急進的な加速は、技術プロセスでこれらの機䌚を䜿甚するリスクを負うのに十分でした。 時間が経おば、それがどうなるかがわかりたす。

たた、 github Takariのリポゞトリには、さらに興味深いプロゞェクトがいく぀かありたす。 圌らの説明はこの蚘事の範囲倖ですが、おそらく誰か他の人が䜕か他のものに興味を持぀でしょう。

UPD


コメントですでに述べたように、フィヌドバックは開発者から寄せられ始めたした。 mvnw.batファむルはその機胜を実行しないこずが刀明したした。 簡単な修正が行われ、機胜が適切な圢匏になりたした。

修正されたスクリプト
 @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @REM distributed with this work for additional information @REM regarding copyright ownership. The ASF licenses this file @REM to you under the Apache License, Version 2.0 (the @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM @REM http://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @REM KIND, either express or implied. See the License for the @REM specific language governing permissions and limitations @REM under the License. @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- @REM Maven2 Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @REM @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM eg to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files @REM ---------------------------------------------------------------------------- @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" :skipRcPre @setlocal set ERROR_CODE=0 @REM To isolate internal variables from possible post scripts, we use another setlocal @setlocal @REM ==== START VALIDATION ==== if not "%JAVA_HOME%" == "" goto OkJHome echo. echo Error: JAVA_HOME not found in your environment. >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error :OkJHome if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome echo. echo Error: JAVA_HOME is set to an invalid directory. >&2 echo JAVA_HOME = "%JAVA_HOME%" >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error :chkMHome if not "%M2_HOME%"=="" goto valMHome SET "M2_HOME=%~dp0.." if not "%M2_HOME%"=="" goto valMHome echo. echo Error: M2_HOME not found in your environment. >&2 echo Please set the M2_HOME variable in your environment to match the >&2 echo location of the Maven installation. >&2 echo. goto error :valMHome :stripMHome if not "_%M2_HOME:~-1%"=="_\" goto checkMCmd set "M2_HOME=%M2_HOME:~0,-1%" goto stripMHome :checkMCmd @rem if exist "%M2_HOME%\bin\mvn.cmd" goto init echo. echo Error: M2_HOME is set to an invalid directory. >&2 echo M2_HOME = "%M2_HOME%" >&2 echo Please set the M2_HOME variable in your environment to match the >&2 echo location of the Maven installation >&2 echo. goto error @REM ==== END VALIDATION ==== :init set MAVEN_CMD_LINE_ARGS=%* @REM Find the project base dir, ie the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir set EXEC_DIR=%CD% set WDIR=%EXEC_DIR% :findBaseDir IF EXIST "%WDIR%"\.mvn goto baseDirFound cd .. IF "%WDIR%"=="%CD%" goto baseDirNotFound set WDIR=%CD% goto findBaseDir :baseDirFound set MAVEN_PROJECTBASEDIR=%WDIR% cd "%EXEC_DIR%" goto endDetectBaseDir :baseDirNotFound set MAVEN_PROJECTBASEDIR=%EXEC_DIR% cd "%EXEC_DIR%" :endDetectBaseDir IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig @setlocal EnableExtensions EnableDelayedExpansion for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" @rem for %%i in ("%M2_HOME%"\boot\plexus-classworlds-*) do set CLASSWORLDS_JAR="%%i" set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% if ERRORLEVEL 1 goto error goto end :error set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' if "%MAVEN_BATCH_PAUSE%" == "on" pause if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% exit /B %ERROR_CODE% 


たた、Windowsでの党䜓的なアセンブリはLinuxでのアセンブリよりもはるかに遅いこずがわかりたした。 なぜこれがただ明確でないのか。

UPD2


別の埮劙な瞬間が浮䞊した。 SonarQubeのビルドはSmart Builderず競合したす。 なぜなら --builderスマヌトオプションはデフォルトで有効になっおいたす。SonarQubeでのアセンブリでは、実行するだけでは䞍十分です。

 mvn sonar:sonar 

たた、暙準のビルド戊略に切り替える必芁がありたす。

 mvn --builder multithreaded sonar:sonar 

たたは

 mvn --builder singlethreaded sonar:sonar 

状況に応じお。

Source: https://habr.com/ru/post/J266011/


All Articles