快照版本和发布版本区别

原创 2018年04月16日 12:55:17

在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次。我们知道,maven的依赖管理是基于版本管理的,对于发布状态的artifact,如果版本号相同,即使我们内部的镜像服务器上的组件比本地新,maven也不会主动下载的。如果我们在开发阶段都是基于正式发布版本来做依赖管理,那么遇到这个问题,就需要升级组件的版本号,可这样就明显不符合要求和实际情况了。但是,如果是基于快照版本,那么问题就自热而然的解决了,而maven已经为我们准备好了这一切。

      maven中的仓库分为两种,snapshot快照仓库和release发布仓库。snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),如下:

  1. <groupId>cc.mzone</groupId>
  2. <artifactId>m1</artifactId>
  3. <version>0.1-SNAPSHOT</version>
  4. <packaging>jar</packaging>

      maven2会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。如果是快照版本,那么在mvn deploy时会自动发布到快照版本库中,会覆盖老的快照版本,而在使用快照版本的模块,在不更改版本号的情况下,直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。如果是正式发布版本,那么在mvn deploy时会自动发布到正式版本库中,而使用正式版本的模块,在不更改版本号的情况下,编译打包时如果本地已经存在该版本的模块则不会主动去镜像服务器上下载

      所以,我们在开发阶段,可以将公用库的版本设置为快照版本,而被依赖组件则引用快照版本进行开发,在公用库的快照版本更新后,我们也不需要修改pom文件提示版本号来下载新的版本,直接mvn执行相关编译、打包命令即可重新下载最新的快照库了,从而也方便了我们进行开发。

 

目前在JAVA的世界中,maven已经成为事实上的构建标准,很多开源库的管理构建也是基于maven的,maven本身的学习曲线比较陡峭,遵循“约定优于配置”的理念,maven存在很多约定。本次我先描述下,关于版本的定义的选择,SNAPSHOT or RELEASE?

版本之争

在maven的约定中,依赖的版本分为两类——SNAPSHOT和RELEASE。SNAPSHOT依赖泛指以-SNAPSHOT为结尾的版本号,例如1.0.1-SNAPSHOT。除此之外,所有非-SNAPSHOT结尾的版本号则都被认定为RELEASE版本,即正式版,虽然会有beta、rc之类说法,但是这些只是软件工程角度的测试版,对于maven而言,这些都是RELEASE版本。既然Maven提供了这两类版本号,那么他们之前的优劣势是什么?分别在什么场景下使用?

解读SNAPSHOT

同一个SNAPSHOT版本的依赖可以多次发布(deploy)到仓库中,也就是说同一个SNAPSHOT版本的依赖可以在仓库中存在多份,每一份都是代码在某一个特定时间的快照,这也是SNAPSHOT的含义。SNAPSHOT不是一个特定的版本,而是一系列的版本的集合,其中HEAD总是指向最新的快照,对外界可见的一般也是最新版,这种给人的假象是新的覆盖了老的,从而使得使用SNAPSHOT依赖的客户端总是通过重新构建(有时候需要-U强制更新)就可以拿到最新的代码。例如:A-->B-1.3.8-SNAPSHOT(理解为A依赖了B的1.3.8-SNAPSHOT版本),那么B-1.3.8-SNAPSHOT更新之后重新deploy到仓库之后,A只需要重新构建就可以拿到最新的代码,并不需要改变依赖B的版本。由此可见,这样达到了变更传达的透明性,这对于开发过程中的团队协作的帮助不言而喻。

SNAPSHOT之殇

SNAPSHOT版本的依赖因为存在变更传达的透明性的优势而被赏识,甚至被“溺爱”,有很多团队索性直接使用SNAPSHOT到生产环境中,这样对于变更直接生效,很方便。但是作为技术人员的我们其实应该很严谨地看待变更传达的透明性,变更就意味着风险,透明性更是把风险彻底隐藏了起来,生产环境中存在这样的现象更是心惊胆战。例如:A-->B.1.0.3-SNAPSHOT,B对一个A使用的功能实现进行了调整,直接发布到仓库,A重新构建或许就会失败,更糟糕的是构建成功,运行时异常。这个时候A甚至完全没有代码变更就突然失败了,会带来更多的困惑。

这也是maven经常遭人诟病的一个因素,对于同一份代码,构建结果却不具备确定性,让很多人沮丧。当然这个不完全是因为依赖的问题,也有maven插件的问题,maven之前的版本寻找插件策略的方式也存在不确定性,maven在版本2的时候,会去寻找最新的插件版本(如果没配置的话)来执行构建,经常会找到SNAPSHOT版本的插件,所以依赖了一个不稳定的插件来执行构建,不确定性就大大增加。不过maven在3版本就改变了这个策略,会寻找最新稳定版的插件来执行构建,使得构建具备了确定性,稳定性也好多了。说明maven本身也在SNAPSHOT的问题上狠狠摔了一跤。

归根到底,这些问题的根源就是SNAPSHOT是变化的,是不稳定的,而应用(软件)依赖于变化并且不稳定的SNAPSHOT的依赖会导致自身也在变化和不稳定中,这是稳定性的一个大忌,依赖不稳定的服务或者依赖,上述的maven2的问题就是一个典型反例。

RELEASE简介

RELEASE版本和SNAPSHOT是相对的,非SANPSHOT版本即RELEASE版本,RELEASE版本是一个稳定的版本号,看清楚咯,是一个,不是一系列,可以认为RELEASE版本是不可变化的,一旦发布,即永远不会变化。

虽然RELEASE版本是稳定不变的,但是仓库还是有策略让这个原则变得可配置,有的仓库会配置成redeploy覆盖,这样RELEASE版本就变成SNAPSHOT了,伪装成RELEASE的SNAPSHOT,会让问题更费解和棘手,我一般称这类人为“挖坑专家”。

记住,RELEASE一旦发布,就不可改变。

如何选择

那么什么时候使用SNAPSHOT?什么时候使用RELEASE?这个可以从他们各自的特性上来看,SNAPSHOT版本的库是一直在变化的,或者说随时都会变化的,这样虽然可以获取到最新的特性,但是也存在不稳定因素,依赖一个不稳定的模块或者库会让模块自身也变得不稳定,尤其是自身对被依赖模块的变化超出掌控的情况。即使可以掌控被依赖模块的变化,也会带来不稳定的因素,因为每次变更都有引入bug的可能性。如果这么说,那么我们是不是要摒弃SANPSHOT了呢?答案肯定是否定的。

想象下,什么情况下,模块会一直变化或者变化比较剧烈?开发新特性的时候,所以对于团队之间协同开发的时候,模块之间出现依赖,变化会非常剧烈,如模块A依赖模块B,模块A必然需要最方便地获取模块B的特性,在开发期间,方便性比稳定性更重要。可以反证下,假设模块B使用RELEASE版本1.0.0,模块A依赖1.0.0,现在模块A出现了bug,需要修复下,那么A就要提供一个版本号1.0.1,这样所有依赖A模块都需要更新版本号,因为开发期间这种事情是如此多,所以会带来巨变。反观SNAPSHOT方案,如果模块B的版本是1.0.0-SNAPSHOT,模块A完全不需要修改版本号即可获取模块B的新特性。当开发进入预发布阶段,为了生产环境的稳定性,依赖应该是RELEASE版本,因为此时SNAPSHOT版本的模块自动获取新特性的特点恰恰会造成生产环境的不稳定性,生产环境上,稳定性重于一切。

魔幻之手

现在已经很明确了,在开发期间,活跃模块的版本号使用SNAPSHOT,在生产期间,依赖RELEASE版本模块。貌似,我们找到了银弹,不过这个只是理想状态,即所有的模块的版本都在自己的掌控或者间接掌控下,只有这样你才能影响对应模块的版本号。往往是理想很丰满,现实却很骨感,如果你依赖的一个模块只有SNAPSHOT版本,并且该模块也很活跃,最无助的是模块的维护人不理会你的请求,那么是否就没辙了,只能把应用构建在不稳定模块上呢?介绍一款maven插件——versions,这是一个非常强大的版本管理插件,其中有个对依赖版本加锁的特性——lock-snapshots,并且提供了参数可以控制锁定的依赖,就可以实现对特定的SNAPSHOT模块锁定版本,执行的命令如下:mvn versions:lock-snapshots -DincludesList="groupId:artifactId:type:classifier:version",执行这个命令之后,对应的版本号会变化,比如1.0.0-SNAPSHOT会变成1.0.0.20090327.172306-4,即完成了锁定,此时这个SNAPSHOT就变成了固定小版本的稳定版本,不会在变化了,也相当于正式版的功能了。当然以后也可以解锁,详细请看对应文档。

maven正式版本和快照版本的区别

在Nexus仓库中,一个仓库一般分为public(Release)仓库和SNAPSHOT仓。前者存放正式版本,后者存放快照版本。 在项目pom.xml中,指定版本号带-SNAPSHOT,那么打出的包...
  • lvhao2813
  • lvhao2813
  • 2018-01-17 14:58:01
  • 480

maven快照版本和发布版本

在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次。我们知道,maven的依赖管理是基于版本管理的,...
  • xuchuangqi
  • xuchuangqi
  • 2016-11-28 23:37:41
  • 645

软件发布版本区别介绍

Alpha:Alpha 是内部测试版,一般不向外部发布,会有很多Bug.除非你也是测试人员,否则不建议使用. 是希腊字母的第一位,表示最初级的版本 alpha就是α,beta就是β alpha版...
  • csdn_yudong
  • csdn_yudong
  • 2016-10-27 16:24:23
  • 2265

调试版本和发布版本的区别

一个发布版本一般意味着某些类型的优化,然而一个调试版本意味着没有优化。调试版本的优化选项为:禁用(/0d)发布版本的优化选项为:最大优化速度(/02)两个版本之间的明显不同还有调试版本由于对内存分配做...
  • Tinna_zhang
  • Tinna_zhang
  • 2011-07-20 10:16:43
  • 2323

【Maven】Snapshot和Release版本的区别

Snapshot版本代表不稳定、尚处于开发中的版本,快照版本。 Release版本则代表稳定的版本,发行版本。 什么时候用Snapshot版本? 依赖库中的jar正处于开发的阶段,会被经常被更新...
  • East_MrChiu
  • East_MrChiu
  • 2017-04-09 15:21:15
  • 2783

Windows程序调试--调试版本和发布版本的区别

 调试版本和发布版本的区别调试版本的编译选项链接选项含义/MDd,/MLd,或者/MTd使用调试版本的运行时刻函数库/Od关闭优化开关/D”_DEBUG”打开条件编译调试代码开关/ZI创建编辑继续的程...
  • linjasmine
  • linjasmine
  • 2008-10-28 09:21:00
  • 1141

VS调试版本和发布版本

一个发布版本一般意味着某些类型的优化,然而一个调试版本意味着没有优化。 调试版本的优化选项为:禁用(/0d) 发布版本的优化选项为:最大优化速度(/02) 对于发布版本,堆栈基址指针也许...
  • u011127019
  • u011127019
  • 2016-11-04 10:18:18
  • 1220

OpenWrt的发行版

说起OpenWrt的版本问题,真的让人又爱又恨。 我接触的版本不多,但是
  • qianguozheng
  • qianguozheng
  • 2014-07-23 20:30:18
  • 3194

java笔记-- maven中snapshot快照库和release发布库的区别和作用

maven中的仓库分为两种,snapshot快照仓库和release发布仓库。snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。定义一个组件/模...
  • u012482647
  • u012482647
  • 2016-02-26 17:41:34
  • 2226

Openstack liberty及mitaka中云主机快照实现对比分析

这是创建云主机实例快照源码分析系列的第二篇,在第一篇文章中分析了从镜像启动云主机,创建在线/离线快照的过程;本篇将分析从启动盘启动的云主机创建快照的过程,下面请看正文: 磁盘启动云主机,离线快照 ...
  • lzw06061139
  • lzw06061139
  • 2016-06-24 16:27:50
  • 6353
收藏助手
不良信息举报
您举报文章:快照版本和发布版本区别
举报原因:
原因补充:

(最多只允许输入30个字)