做storm的开发,一直有一个问题困扰,就是第三方依赖的包都要合并打成一个包,才能放到服务器上去运行,随着需求功能的增加,打的包也就越来越大。而我们的生产环境在云上,每次发布包,几百兆的文件都要传好久。
所以,决定把这个问题彻底解决了,Storm的安装目录下有一个extlib的目录,分析bin/storm文件,发现,topo在启动运行的时候,会到这个目录下寻找是否有要加入到classpath中的文件。这个就是我们解决问题的地方啦。
我们是通过maven打包,所以这个时候就要修改maven的pom文件,先来支持依赖分离。
配置如下,主要是插件部分:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>]
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>package.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
再配置,将依赖打包成zip文件。
package.xml
<assembly>
<id>bin</id>
<!-- 最终打包成一个用于发布的zip文件 -->
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
<dependencySet>
<!--
不使用项目的artifact,第三方jar不要解压,打包进zip文件的lib目录
-->
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>/</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<!-- 把项目自己编译出来的jar文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.build.directory}/lib</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
<excludes>
<exclude>storm-core-1.0.1.jar</exclude> <!-- 与节点上安装的storm 有冲突 -->
</excludes>
</fileSet>
</fileSets>
</assembly>
这样,打包之后,依赖全部放在了target/lib 目录下,而程序包,放在target目录下。
第一次发布会麻烦一点,因为所有依赖包要发布到所有storm节点上,之后再发布,就只用发布程序包了。如果使用jenkins,那就更方便,可以配置成自动化发布,就不用手工去各个节点上发布了。