`
qindongliang1922
  • 浏览: 2180927 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117400
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:125817
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59783
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71224
社区版块
存档分类
最新评论

浅谈Java项目打包方式

    博客分类:
  • JAVA
阅读更多



大家都知道在Java里面开发一个web服务非常繁琐,首先需要各种框架,各种配置,完事之后,需要打成一个war包,最后需要一个servlet容器,Tomcat或者Jetty,Jboss,来运行发布,同样的事情,你会发现在其他的语言中,是非常简单的,比如python里面的Django或者tornado,ruby里面的rails等,随着近年来微服务越来越流行,一个简单,强大,灵活,易配置,易开发的web服务迫在眉睫,而它就是Spring Boot,统一了Java web开发的各个需要的框架,提供了大而全的功能支持。 这里就不在具体介绍了,有需要的朋友,可以看散仙写过的几篇关于它的文章http://qindongliang.iteye.com/blog/2205633


Spring Boot为什么容易开发微服务?当然它也不仅仅限于微服务,它还可以与Dubbo集成,实现企业级服务化,因为Spring Boot内嵌了servlet容器,发布服务时,仅仅需要一个jar包,所有有关的依赖全部在这个jar包中,所以不需要你额外下载一个tomcat或者jetty来运行服务,这个jar包,拷贝到任何含有JDK的环境的机器上,都可以任意运行,除此之外,因为仅仅只有一个jar包,所以与Jekins和Docker的集成都非常方便,这种方式以后会逐渐流行,而以war包+外置容器的发布方式散仙预测以后会逐渐没落,这里就不在具体介绍这种打包方式了。

接着上面谈,由于所有的东西,都在这个jar包中,当你依赖越来越多时,这个jar包的体积,就会上升的厉害,在我们的一个应用场景中,集成了dubbo,redis,solr,hadoop,hbase,最后一个jar包体积,快接近100M了,不过,体积大到是次要的,只要服务能正常运行,可以忽略这个小缺点,之后启动,停止脚本也非常简洁:
启动脚本:

#!/bin/bash
JAVA_HOME=/tool/server/jdk
CLASSPATH=.:$JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH

nohup  java -jar   work.jar    &>task.log &   echo $! >pid& 


停止脚本:

kill -9 `cat pid`


上面散仙谈到的spring boot能够封装所有的依赖进入一个jar包中,前提是需要提前配置好各个运行参数,然后编译打包,运行这个jar,假如在已经发布到服务器上,我想改一些参数配置,应该如何操作呢? 这时候就会发现面对一个jar,你无法干任何事,除非回到maven工程中,改里面的配置参数,然后重新打包,接着用Jenkins发布到docker里面,假如这时候,你上传到服务器的网速非常慢,几十kb/秒,偏偏你又有一个100M的jar,还不得发布到猴年马月,这里说的不夸张,是实际开发中可能遇到的一种情况。


那么如何比较好的处理这种问题呢?其实也不难,在打包的时候,分离工程,形成一个基本的目录如下:

bin/    //存放处理脚本
lib/    //存放jar包
conf/ //存放配置文件
logs/ //存放log


看到上面的这个目录,大伙是不是有种回到了Ant的年代的感觉呢,其实不然在Maven中,我们可以使用maven-assembly-plugin插件,来完成更优雅的打包
方式,仅需要项目中,改动下面两个部分即可完成:

(1)在pom文件中,添加如下插件:

   <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <!--<appendAssemblyId>true</appendAssemblyId>-->
                    <descriptors> <!--描述文件路径-->
                        <descriptor>src/main/assemble/package.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-zip</id>
                        <!-- 绑定到package生命周期阶段上 -->
                        <phase>package</phase>
                        <goals>
                            <!-- 绑定到package生命周期阶段上 -->
                            <goal>single</goal>
                        </goals>

                    </execution>
                </executions>
            </plugin>

        </plugins>

    </build>



(2) 在main下面新建一个assemble文件夹,并在该文件夹下新建一个package.xml文件,内容如下:

<?xml version="1.0"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

    <!--项目标识,设置的话,生成后的zip文件会加上此后缀-->
    <id></id>
    <!--打包格式-->
    <formats>
        <format>zip</format>
    </formats>
    <!--是否包含根目录文件夹-->
    <includeBaseDirectory>true</includeBaseDirectory>

    <fileSets>

        <!--<fileSet>-->
        <!--<directory>${project.basedir}\src\main\resources</directory>-->
        <!--<outputDirectory>\</outputDirectory>-->
        <!--<includes>-->
        <!--<include>some/path</include>-->
        <!--</includes>-->
        <!--<excludes>-->
        <!--<exclude>some/path1</exclude>-->
        <!--</excludes>-->
        <!--</fileSet>-->

        <!--自定义文件描述集-->
        <fileSet>
            <!--自定义脚本目录打包-->
            <directory>${project.basedir}\src\main\bin</directory>
            <outputDirectory>\bin</outputDirectory>
            <includes>
                <include>*.*</include>
            </includes>
            <!--设置权限-->
            <fileMode>0755</fileMode>
        </fileSet>


        <!--<fileSet>-->
            <!--<!&ndash;外部配置文件打包&ndash;>-->
            <!--<directory>${project.basedir}\src\main\config</directory>-->
            <!--<outputDirectory>\config</outputDirectory>-->
            <!--<includes>-->
                <!--<include>*.*</include>-->
            <!--</includes>-->
            <!--<fileMode>0644</fileMode>-->
        <!--</fileSet>-->

    </fileSets>

    <dependencySets>

        <dependencySet>
            <useProjectArtifact>true</useProjectArtifact>
            <outputDirectory>lib</outputDirectory>
            <!-- 将scope为runtime的依赖包打包到lib目录下。 -->
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>

</assembly>



当然这种启动,停止脚本,稍微复杂点,需要把所有的jar包和配置文件cp到一个JVM里面,然后执行:
启动脚本:

cs=`echo /ROOT/tmp/z_check_hbase/lib/*jar | sed 's/ /:/g'`
#配置文件的目录
conf="$cdir/conf:"
#追加进入cp中
cs=$cs$conf
#打印
echo $cs
#执行
nohup java -cp  $cs  com.tools.HbaseDaoImpl   &>/dev/null  &   echo $! >pid&

停止脚本:
kill -9 `cat pid`




总结:

对比spring boot中的单一jar的打包方式,这种方式,则将jar包和配置分离,我们可以随时改配置参数,然后重新启动,这样做灵活性大大提高了,而且在远程传入服务器时,除了第一次需要传所有的依赖文件,以后,改动代码后,只需要传主jar即可,因为依赖的jar基本都不会变,而当使用单一的jar时,任何改动都需要上传整个jar。这在jar包体积比较大时,网速比较慢时,是非常耗时的,但由于分离了配置文件和jar,复杂性会稍微提高,当然这算不了什么,因为我们可以用zip或者tar.gz将它压缩成一个整体,然后可以部署到任意机器上。




在Java里面,除了Spring Boot外,另外一个比较给力的Web服务框架就是Scala的Play2了,目前最新版本是2.5,采用sbt管理依赖,引入Netty实现高性能http服务,不再维持会话状态,如果你需要会话状态,就自己采用redis或者memcache等来实现,它打包后会自动生成压缩包,压缩包里面包含了分离的lib和conf以及win和linux部署脚本,这一点与我们上面说的第二种方式,大致上是一致的,对上线发布非常友好,当然这里并没有绝对的好坏之分:

单一jar的打包方式总体来说对微服务比较友好
分离jar的打包方式总体来说对企业级大型服务比较友好

当然你也可以混搭,只要是适合自己场景的方式,就是最好,最优雅的方式。


有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,与君同行。

  • 大小: 26.5 KB
  • 大小: 44.7 KB
1
0
分享到:
评论

相关推荐

    浅谈Java 将图片打包到jar中的路径问题

    今天,我们将深入浅谈该问题,并提供两种解决方法:通过使用外部资源文件的方式和通过使用内部资源文件的方式。 问题描述 当我们将 Java 项目打包成 Jar 文件后,发现图片无法加载。这是因为 Jar 文件中的路径问题...

    浅谈Java程序的性能优化

    【Java程序性能优化】在Java程序开发中,性能优化是一个重要的环节,因为它直接影响到程序运行效率和用户体验。本文将从基础优化和GUI设计时的优化两个方面探讨如何提升Java程序的性能。 一、基础优化 1. **避免...

    借《浅谈PHP与Java之Web开发整合技术》说LAJP

    《浅谈PHP与Java之Web开发整合技术》一文深入探讨了PHP与Java两种语言在Web开发中的结合应用,尤其聚焦于三种关键技术:SOAP、Quercus和PHP/JavaBridge,为开发人员提供了宝贵的整合思路。 ### 一、SOAP(Simple ...

    浅谈java实现背包算法(0-1背包问题)

    浅谈java实现背包算法(0-1背包问题) 本篇文章主要介绍了java实现背包算法的基本概念和实现方法,特别是针对0-1背包问题的解决方案。下面将对标题、描述、标签和部分内容进行详细解释,并结合java实现代码,总结出...

    浅谈将JNI库打包入jar文件

    标题《浅谈将JNI库打包入jar文件》所涉及的知识点涵盖了Java Native Interface(JNI)和Java归档文件(jar)两个重要的Java技术领域。 在Java开发中,JNI是一个用于编写Java本地方法的应用程序接口,它允许Java代码...

    浅谈java 执行jar包中的main方法

    对于独立的可执行Java程序,这些通常被打包成JAR(Java Archive)文件。本文将深入探讨如何在JAR包中执行特定的`main`方法。 首先,当JAR文件包含了`MANIFEST.MF`文件,并且在这个文件中指定了`Main-Class`属性,...

    浅谈Java工程读取resources中资源文件路径的问题

    在Java工程中读取某路径下的文件时,可以采用绝对路径和相对路径两种方式。绝对路径是指从根目录开始的完整路径,例如`C:\Users\username\Documents\file.txt`。相对路径则是相对于当前类的路径,例如`src/main/...

    cos应用浅谈

    标题“cos应用浅谈”可能指的是腾讯云的对象存储服务(Cloud Object Storage,简称COS),这是一个云端存储解决方案,用于存放大量的非结构化数据,如文本、图片、视频等。在这个场景下,我们可以从多个角度来深入...

    浅谈springboot的三种启动方式

    浅谈Spring Boot的三种启动方式 Spring Boot是一种流行的Java框架,提供了简洁的配置和自动装配机制,能够快速构建现代化的基于Spring的应用程序。启动Spring Boot项目有多种方式,本文将详细介绍其中的三种启动...

    浅谈maven的jar包和war包区别 以及打包方法

    浅谈maven的jar包和war包区别以及打包方法 Maven是一个流行的项目管理和构建工具,它提供了许多实用的功能,例如依赖管理、项目构建、测试、打包等。在Maven中,jar包和war包是两个常见的打包格式,但它们之间有着...

    java中Class.forName的作用浅谈

    在Java编程语言中,`Class.forName()`方法是一个非常重要的功能,它主要用于动态加载类到Java虚拟机(JVM)中。这个方法的主要作用是根据给定的全限定类名(包括包名和类名)来查找并加载对应的类。下面我们将深入...

    浅谈IDEA中Maven配置问题全解决

    Maven则是 Java 项目管理和构建工具,用于管理项目依赖关系和编译、打包、部署项目。然而,在使用 IDEA 和 Maven 时,许多开发者会遇到一些配置问题,导致项目构建失败或依赖关系无法解决。因此,本文将详细介绍浅谈...

    浅谈Android ASM自动埋点方案实践

    "浅谈Android ASM自动埋点方案实践" ...本文主要介绍了浅谈Android ASM自动埋点方案实践,通过使用AOP概念、Transform Android打包流程和Gradle插件实现,可以实现自动埋点追踪、性能监控等功能。

    线程详解-打包(3 合1)下载

    《浅谈Windows中的多线程编程》文档可能以更通俗易懂的方式探讨Windows下的线程概念。它可能涵盖线程的生命周期、线程间交互的基本原理,以及处理线程安全问题的策略。文档可能会针对初学者,解释线程在日常软件开发...

    浅谈Android Studio导出javadoc文档操作及问题的解决

    "浅谈Android Studio导出javadoc文档操作及问题的解决" Android Studio是当前Android应用开发的主流IDE之一,但是在实际开发中,我们经常需要生成javadoc文档以便于其他开发者或团队成员了解我们的代码结构和设计...

    浅谈Maven包冲突的原理及解决方法

    Maven包冲突是Java开发中常见的问题,理解其原理和解决方法对于优化项目构建和提高代码质量至关重要。通过合理地配置POM文件,使用Maven的特性以及辅助工具,可以有效地管理项目依赖,避免和解决包冲突,确保项目的...

Global site tag (gtag.js) - Google Analytics