文档章节

gradle + Jetty + docker 实现Java自动化打包

-外星人-
 -外星人-
发布于 2016/12/09 00:45
字数 1107
阅读 187
收藏 3

从去年开始,构建工具就从maven转向gradle了,servlet容器也从tomcat转向了jetty,直接使用内嵌的方式运行,然后用gradle打包成应用程序,直接启动bin目录下的运行文件即可运行,简单快捷。

首先说明一点,就是这种方式只适用于纯api项目,也就是无jsp,不然打包成jar会有问题。

项目框架 spring mvc + mybatis,数据库用mysql + redis,spring mvc 跟 mybatis 配置我就不多说了,主要介绍一下jetty的吧。

import com.alibaba.druid.support.http.WebStatFilter;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.Date;

public class AppServer {

    public static void main(String[] args) throws Exception {
        long startTime = System.currentTimeMillis();
        System.out.printf("USE SYSTEM %s %s %s \n", System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"));
        System.out.printf("USE JDK %s %s \n", System.getProperty("java.version"), System.getProperty("java.vm.specification.name"));
        int port = 8080;

        if (args.length > 0) {
            port = Integer.valueOf(args[0]);
        }

        ServletContextHandler servletContext = new ServletContextHandler();
        servletContext.setContextPath("/");

        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(port);
        server.setConnectors(new Connector[] { connector });
        HandlerCollection handlerCollection = new HandlerCollection();
        ServletContextHandler springMvcHandler = new ServletContextHandler();
        springMvcHandler.setContextPath("/");
        XmlWebApplicationContext context = new XmlWebApplicationContext();
        context.setConfigLocations(new String[]{"classpath:applicationContext.xml", "classpath:dispatcher-servlet.xml"});
        springMvcHandler.addEventListener(new ContextLoaderListener(context));

        springMvcHandler.addServlet(new ServletHolder("consult", ServletHandler.Default404Servlet.class), "/static");
        springMvcHandler.addServlet(new ServletHolder("druid", com.alibaba.druid.support.http.StatViewServlet.class), "/druid/*");
        springMvcHandler.addServlet(new ServletHolder("mvc", new DispatcherServlet(context)), "/*");
        // WEB监控
        FilterHolder webStatFilter = new FilterHolder(new WebStatFilter());
        webStatFilter.setInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        springMvcHandler.addFilter(webStatFilter, "/*", null);
        handlerCollection.setHandlers(new Handler[]{springMvcHandler});
        server.setHandler(handlerCollection);
        server.start();
        System.out.printf("Server started take %d ms, open your in browser http://localhost:%d/\n", (System.currentTimeMillis() - startTime), port);
        System.out.println("Start Time " + new Date());
        server.join();

    }

}

其实很简单,就是初始化spring容器,然后构建一个jetty 的 Server ,通过代码的形式把spring mvc的servlet配置好,因为我用的数据库驱动是durid,所以顺便配置了一个durid自带的监控servlet,可以看到SQL执行情况,还可以监控WEB的一些性能指标,然后直接启动就可以了

gradle 的配置

group 'com.xxxx'

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'main.AppServer'

sourceCompatibility = 1.8

repositories {
    jcenter()
}

dependencies {
    compile project(":core")
    compile "org.springframework:spring-web:$springVersion"
    compile "org.springframework:spring-webmvc:$springVersion"
    compile "org.eclipse.jetty:jetty-webapp:$jettyVersion"
    compile 'com.graphql-java:graphql-java:2.1.0'
    compile "commons-fileupload:commons-fileupload:1.3.1"
}
def env = System.getProperty("env") ?: "dev"
def res = env == "dev" ? "resources" : "profile/$env";
sourceSets {
    main {
        resources {
            srcDirs = ["src/main/resources", "src/main/$res"]
        }
    }
}
println "package $env version";
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

我的gradle项目是多模块项目,这里的配置是web相关的配置,core是核心逻辑,通过一个环境变量env打包不同环境的程序 目录结构如下:

project
	- docker
		- build.sh
		- Dockerfile
	- core
		- src/main
			- resources
			- profile
				- test
				- production
		- build.gradle
	- web
	    - src/main
		    - java
		    - resources
		- build.gradle
	- gradle.gradle
	- settings.gradle
	- package.sh
```	
打包命令:

$ package.sh # JAVA打包 $ docker/build.sh # docker打包

运行以上命令之后,会生成一个docker镜像,直接通过docker run命令运行即可,如:

$ docker run -it --rm -p 8080:8080 Image镜像 # Ctrl + C 之后会关掉容器,并自动删除容器,可看容器日志,测试阶段可以这么运行 $ docker run -d --name -p 8080:8080 Image镜像 # 后台运行容器,关掉终端,也不会停止

当然,假如你搭建了docker私有仓库的话,还可以push到仓库中,然后在其他机器直接run就会自动下下来了,主要要加完整的路径,如:https://0.0.0.1/Image镜像 ,否则默认会到Docker中心仓库下载,不想吐槽。如果你的容器是无状态的话,还可以通过 docker swarm 部署一个集群,自动负载多个docker容器,可平滑升级,但是在Aliyun跨主机,哎。。。只能直接来。

build.sh

#!/bin/bash echo $0 basepath=$(cd dirname $0; pwd) cp $basepath/../web/build/distributions/web.tar $basepath/web.tar tag="$1" if [ "$tag" = "" ]; then tag="latest" fi host="" image="api:$tag" sudo docker build -t $host$image $basepath


没什么技术含量,就是把手敲的代码写到一个脚本里面

Dockerfile

FROM anapsix/alpine-java:jre8 ADD web.tar / ENV JAVA_OPTS='-server -Duser.timezone=Asia/Shanghai' EXPOSE 8080 ENTRYPOINT ["/web/bin/web"]

这里一定要加上-Duser.timezone=Asia/Shanghai,不然时区会不对,不是我大天朝的时间,打包完140M,我的程序不到20M,应该包含了一个jre,所以没办法,对java应用来说已经很小了。

package.sh

#!/bin/bash basepath=$(cd dirname $0; pwd) cd $basepath git pull gradle build -x test


总结一下,通过jetty可以很方便的进行java 纯api的项目开发,直接内嵌,部署简答,打包到docker之后,服务端部署就更简单了,不用装jdk,特别是需要配置多个实例的时候,直接通过docker swarm启动一个Service设置一下启动多少个实例就OK了,简单快捷

下次介绍一下怎么基于nginx + lua结合后端的jetty,打造一个前后端分离的应用。

© 著作权归作者所有

共有 人打赏支持
-外星人-
粉丝 49
博文 48
码字总数 22995
作品 0
深圳
程序员
私信 提问
Google 正式开源 Jib ,帮助 Java 应用快速容器化

Google 本周宣布开源一款新的 Java 工具 Jib ,旨在让开发者使用他们熟悉的工具更轻松地将 Java 应用程序容器化。 在7月9日发布的博客文章中,Google 软件工程师 Appu Goundan 和 Qingyang C...

王练
07/11
11.7K
27
为 Java 应用构建容器镜像 - Jib

Jib 是 Google 开发的可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库,以 Maven 和 Gradle 插件形式提供。 通过 Jib,Java 开发者可以使用他们熟悉的 Java 工具来构建容器。Jib 是一个快...

匿名
07/10
0
0
Android Gradle(一)为什么现在要用Gradle?

前言 又要开启一个新系列了,这个系列我们来学习Gradle,它是一个基于JVM的新一代构建工具,关于Gradle完全可以写一本书,这个系列会针对Android开发来对Gradle的知识进行精简讲解。Gradle目...

刘望舒
08/21
0
0
构建Gradle范例项目之构建web项目

Gradle提供了开箱即用的插件,用来组装WAR文件和将web应用部署到本地Servlet容器中。Gradle对构建和运行web应用都提供了扩展性支持。这里我们学习使用两个web应用程序部署插件:War和Jetty。...

柳哥
2015/10/26
0
0
gradle 集成 dockerFile

gradle 集成 dockerFile gradle 是一个新兴的jvm编译工具,docker也是最流行的容器部署方案,docker传统通过Dockerfile进行image的打包,这时候我们想要比较方便的结合docker和gradle 就是在...

来福马斯特
2017/11/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 有一天考拉麻麻拉肚子了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @瘟神灬念 :分享周汇洋的单曲《Man Srae(曼斯拉之舞)》:美滋滋。。。。 手机党少年们想听歌,请使劲儿戳(这里) 我听了一下 赶紧关了, ...

小小编辑
今天
68
5
oh-my-zsh 自定义

GitHub 地址 基于 oh-my-zsh 的自定义配置,增加了一些个人常用插件与皮肤。 采用的是 git submodule 来维护,包括 oh-my-zsh,之所以这么搞,主要是手头有多台 linux 需要维护, 每台机器、...

郁也风
今天
7
0
Docker安装踩坑:E_FAIL 0x80004005的解决

参考 菜鸟教程--Windows Docker 安装 http://www.runoob.com/docker/windows-docker-install.html 官方文档-Install Docker Toolbox on Windows https://docs.docker.com/toolbox/toolbox_in......

karma123
今天
6
0
js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
18
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
昨天
27
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部