使用gradle对vertx工程的多环境配置和打包

公司日前使用vertx构建rest服务,vertx工程跟普通的工程没有什么区别。我们使用gradle进行构建。后来随着部署发布的频繁,在打包之后再进行配置的修改,会出现很多的问题,很容易出错,然后排查问题花费很多时间,所以每次发布版本就跟打仗一样,提心吊胆的。后来经过研究,找到了两种多环境打包方式。第一种:将所有的配置文件打包到jar文件中,将所有的配置文件提出来单独放置到一个文件夹(利于查看配置)。我倾向于第一种,但是领导选择了第二种。

第一种,配置文件打包到jar文件


这种方式是利用gradle脚本的sourceSets设置,将配置文件包含进来,脚本如下:
plugins {
  id 'application'
  id 'com.github.johnrengelman.shadow' version '1.2.3'
  id 'eclipse'
}

repositories {
  jcenter()
}
def ver = System.getProperty("version")?:"1.0-SNAPSHOT";
//version = '1.0-SNAPSHOT'
version = ver
sourceCompatibility = '1.8'
mainClassName = 'io.vertx.core.Launcher'
applicationDefaultJvmArgs = ["-Dlogback.configurationFile=config/logback.xml"]
def vertxVersion = '3.3.3'
def mainVerticleName = 'io.vertx.starter.MainVerticle'
def watchForChange = 'src/**/*'
def doOnChange = './gradlew classes'
def env = System.getProperty("env")?:"prod"

dependencies {
  compile "io.vertx:vertx-core:$vertxVersion"
  compile "com.englishtown.vertx:vertx-jersey:4.5.2"
  compile "com.englishtown.vertx:vertx-hk2:2.4.0"
  compile 'com.jfinal:jfinal:2.2'
  compile 'com.mchange:c3p0:0.9.5.2'
  compile 'mysql:mysql-connector-java:5.1.40'
  compile 'ch.qos.logback:logback-core:1.1.7'
  compile 'ch.qos.logback:logback-classic:1.1.7'
  compile 'org.json:json:20160810'
  compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
  compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
  compile group: 'com.alibaba', name: 'fastjson', version: '1.1.43'
  compile 'commons-configuration:commons-configuration:1.10'
  compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.24.1'
  compile ('com.sun.jersey:jersey-json:1.19.3'){
    exclude group:'javax.ws.rs', module: 'jsr311-api'
  }
  testCompile "junit:junit:4.12"
  testCompile "io.vertx:vertx-unit:$vertxVersion"
}
sourceSets {
    main {
        resources {
            srcDirs = ["src/main/resources", "src/main/profile/$env"]
        }
    }
}

startScripts {
    doLast {
        unixScript.text = unixScript.text.replace('$CLASSPATH', '$APP_HOME/lib/*')
        windowsScript.text = windowsScript.text.replace('%CLASSPATH%', '%APP_HOME%\\lib\\*')
    }
}
shadowJar {
  classifier = 'fat'
  manifest {
      attributes "Main-Verticle": mainVerticleName
  }
  mergeServiceFiles {
    include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
  }
}

run {
  args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange"]
}

task wrapper(type: Wrapper) {
  gradleVersion = '3.1'
}
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

打包之后的结构如下

所有的配置就在jar包中,所以代码里面需要从jar包中加载配置文件

1.loadJsonConfig【从jar中加载】

JsonConfigUtil.loadJarConfig(CONFIG_PATH + "config.json");
public static JsonObject loadJarConfig(String name){
        if(null == name || "".equals(name)){
            return null;
        }
        if(!name.startsWith("/")){// config/config.json
            name = "/" + name;/// config/config.json
        }
        InputStream stream = JsonConfigUtil.class.getResourceAsStream(name);


        Scanner scanner = new Scanner(stream, "UTF-8").useDelimiter("\\A");


        return scanner.hasNext() ? new JsonObject(scanner.next()) : new JsonObject();
    }

2.properties【PropertiesConfiguration从jar中加载】

PropertiesConfiguration serverConfig = new PropertiesConfiguration(CONFIG_PATH + "server.properties");
        System.out.println("adminPrefix=============" + serverConfig.getString(SystemConfig.ADMIN_PREFIX));

3.properties【Properties从jar中加载】

Properties prop = io.vertx.starter.util.Utils.loadJarProp(CONFIG_PATH + "jdbc.properties");
        System.out.println("password===========" + prop.getProperty("password"));
public static Properties loadJarProp(String name){
        if(null == name || "".equals(name)){
            return null;
        }
        if(!name.startsWith("/")){// config/config.json
            name = "/" + name;/// config/config.json
        }
        InputStream stream = Utils.class.getResourceAsStream(name);


        Properties properties = new Properties();
        try{
            properties.load(stream);
        }
        catch(IOException e){
            e.printStackTrace();
        }
        return properties;
    }



第二种,配置文件单独分离出来


这种方式利用拷贝任务将配置拷贝至dist目录下,打包的时候就把这些文件打包到发布目录下,脚本如下:
plugins {
  id 'application'
  id 'com.github.johnrengelman.shadow' version '1.2.3'
  id 'eclipse'
}

repositories {
  jcenter()
}

version = System.getProperty("version")?:"1.0-SNAPSHOT"
def env = System.getProperty("env")?:"prod"


sourceCompatibility = '1.8'
mainClassName = 'io.vertx.core.Launcher'
applicationDefaultJvmArgs = ["-Dlogback.configurationFile=config/logback.xml"]
def vertxVersion = '3.3.3'
def mainVerticleName = 'io.vertx.starter.MainVerticle'
def watchForChange = 'src/**/*'
def doOnChange = './gradlew classes'

dependencies {
  compile "io.vertx:vertx-core:$vertxVersion"
  compile "com.englishtown.vertx:vertx-jersey:4.5.2"
  compile "com.englishtown.vertx:vertx-hk2:2.4.0"
  compile 'com.jfinal:jfinal:2.2'
  compile 'com.mchange:c3p0:0.9.5.2'
  compile 'mysql:mysql-connector-java:5.1.40'
  compile 'ch.qos.logback:logback-core:1.1.7'
  compile 'ch.qos.logback:logback-classic:1.1.7'
  compile 'org.json:json:20160810'
  compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
  compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
  compile group: 'com.alibaba', name: 'fastjson', version: '1.1.43'
  compile 'commons-configuration:commons-configuration:1.10'
  compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.24.1'
  compile ('com.sun.jersey:jersey-json:1.19.3'){
    exclude group:'javax.ws.rs', module: 'jsr311-api'
  }
  testCompile "junit:junit:4.12"
  testCompile "io.vertx:vertx-unit:$vertxVersion"
}
startScripts {
    doLast {
        unixScript.text = unixScript.text.replace('$CLASSPATH', '$APP_HOME/lib/*')
        windowsScript.text = windowsScript.text.replace('%CLASSPATH%', '%APP_HOME%\\lib\\*')
    }
}
shadowJar {
  classifier = 'fat'
  manifest {
      attributes "Main-Verticle": mainVerticleName
  }
  mergeServiceFiles {
    include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
  }
}

run {
  args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange"]
}

task wrapper(type: Wrapper) {
  gradleVersion = '3.1'
}
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}
task copyRightConfig(type: Copy) {
 File file1 = new File("src/main/dist/");
 file1.deleteDir();
 copy{
  println('copyRightConfig task begins')
  from("src/main/profile/$env") {
   //include('**/*.*')
  }
  into('src/main/dist/')
  println('copyRightConfig task ends')
 }
}
/*
task('copyRightConfig', type: Copy) {
    println('copyRightConfig task begins')
    from(file('src/main/profile/profile/prod/config'))
    into('src/main/dist')
	
	println('copyRightConfig task ends')
}*/
//assembleDist.mustRunAfter copyRightConfig
assembleDist.dependsOn copyRightConfig
打包之后的结构

配置被单独拎出来了

1.loadJsonConfig【从jar中加载】

String path = new PropertiesConfiguration(CONFIG_PATH + "config.json").getPath();
        System.out.println(path);
        JsonObject config = JsonConfigUtil.loadConfig(path);
public static JsonObject loadConfig(String name) {


        try (InputStream is = new FileInputStream(name)) {
            try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
                return scanner.hasNext() ? new JsonObject(scanner.next()) : new JsonObject();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }

2.properties【PropertiesConfiguration从拎出来的中加载】

PropertiesConfiguration serverConfig = new PropertiesConfiguration(CONFIG_PATH + "server.properties");
SystemConfig.initSystemConfig(serverConfig);

3.properties【Properties从拎出来的地方加载】

PropertiesConfiguration jdbcConfig = null;
        jdbcConfig = new PropertiesConfiguration(CONFIG_PATH + "jdbc.properties");
        C3p0Plugin c3p0Plugin = new C3p0Plugin(jdbcConfig.getString("jdbcUrl"), jdbcConfig.getString("user"),
                jdbcConfig.getString("password"));
上面的脚本会导致clean和build的时候都执行拷贝操作,很不爽。一个更好的脚本如下,在build之前拷贝。
plugins {
  id 'application'
  id 'com.github.johnrengelman.shadow' version '1.2.3'
  id 'eclipse'
}

repositories {
  jcenter()
}

version = System.getProperty("version")?:"1.0-SNAPSHOT"
def env = System.getProperty("env")?:"prod"


sourceCompatibility = '1.8'
mainClassName = 'io.vertx.core.Launcher'
applicationDefaultJvmArgs = ["-Dlogback.configurationFile=config/logback.xml"]
def vertxVersion = '3.3.3'
def mainVerticleName = 'io.vertx.starter.MainVerticle'
def watchForChange = 'src/**/*'
def doOnChange = './gradlew classes'

dependencies {
  compile "io.vertx:vertx-core:$vertxVersion"
  compile "com.englishtown.vertx:vertx-jersey:4.5.2"
  compile "com.englishtown.vertx:vertx-hk2:2.4.0"
  compile 'com.jfinal:jfinal:2.2'
  compile 'com.mchange:c3p0:0.9.5.2'
  compile 'mysql:mysql-connector-java:5.1.40'
  compile 'ch.qos.logback:logback-core:1.1.7'
  compile 'ch.qos.logback:logback-classic:1.1.7'
  compile 'org.json:json:20160810'
  compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
  compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
  compile group: 'com.alibaba', name: 'fastjson', version: '1.1.43'
  compile 'commons-configuration:commons-configuration:1.10'
  compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.24.1'
  compile ('com.sun.jersey:jersey-json:1.19.3'){
    exclude group:'javax.ws.rs', module: 'jsr311-api'
  }
  testCompile "junit:junit:4.12"
  testCompile "io.vertx:vertx-unit:$vertxVersion"
}
startScripts {

    doFirst {
	  println 'build start'
	  File file1 = new File("src/main/dist/");
	  file1.deleteDir();
	  copy{
		  println('copyRightConfig task begins')
		  from("src/main/profile/$env") {
		   //include('**/*.*')
		  }
		  into('src/main/dist/')
		  println('copyRightConfig task ends')
	 }  
	}
    doLast {
        unixScript.text = unixScript.text.replace('$CLASSPATH', '$APP_HOME/lib/*')
        windowsScript.text = windowsScript.text.replace('%CLASSPATH%', '%APP_HOME%\\lib\\*')
    }
}
shadowJar {
  classifier = 'fat'
  manifest {
      attributes "Main-Verticle": mainVerticleName
  }
  mergeServiceFiles {
    include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
  }
}

run {
  args = ['run', mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$mainClassName", "--on-redeploy=$doOnChange"]
}

task wrapper(type: Wrapper) {
  gradleVersion = '3.1'
}
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}


两者的运行命令都是
gradle clean
gradle build -Denv=prod -Dversion=1.2.3
gradle build -Denv=test -Dversion=1.2.4

猜你喜欢

转载自blog.csdn.net/xxssyyyyssxx/article/details/73321564