gradle + Jetty + docker 实现Java自动化打包
来源:互联网 发布:手机淘宝历史版本大全 编辑:程序博客网 时间:2024/05/10 08:39
从去年开始,构建工具就从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.8repositories { 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/bashecho $0basepath=$(cd `dirname $0`; pwd)cp $basepath/../web/build/distributions/web.tar $basepath/web.tartag="$1"if [ "$tag" = "" ]; then tag="latest"fihost=""image="api:$tag"sudo docker build -t $host$image $basepath
没什么技术含量,就是把手敲的代码写到一个脚本里面
Dockerfile
FROM anapsix/alpine-java:jre8ADD web.tar /ENV JAVA_OPTS='-server -Duser.timezone=Asia/Shanghai'EXPOSE 8080ENTRYPOINT ["/web/bin/web"]
这里一定要加上-Duser.timezone=Asia/Shanghai,不然时区会不对,不是我大天朝的时间,打包完140M,我的程序不到20M,应该包含了一个jre,所以没办法,对java应用来说已经很小了。
package.sh
#!/bin/bashbasepath=$(cd `dirname $0`; pwd)cd $basepathgit pullgradle build -x test
总结一下,通过jetty可以很方便的进行java 纯api的项目开发,直接内嵌,部署简答,打包到docker之后,服务端部署就更简单了,不用装jdk,特别是需要配置多个实例的时候,直接通过docker swarm启动一个Service设置一下启动多少个实例就OK了,简单快捷
下次介绍一下怎么基于nginx + lua结合后端的jetty,打造一个前后端分离的应用。
- gradle + Jetty + docker 实现Java自动化打包
- Android使用Gradle自动化打包
- gradle实现多渠道打包
- Gradle实现多渠道打包
- Gradle多渠道自动化打包(基础篇)
- Android Gradle JenKins SVN 自动化打包
- gradle 区分debug和realse自动化打包
- Jenkins+Gradle实现自动化Android打包、输出APK到指定路径
- Jenkins+Gradle实现自动化Android打包、输出APK到指定路径
- 一.jenkins+github+gradle 实现android自动化打包全攻略(MAC版)
- 通过Gradle实现多渠道打包
- 利用Gradle实现多包名打包
- Gradle实现多渠道OEM打包
- Jenkins实现Android自动化打包
- 使用gradle打包java项目
- Gradle多渠道和自动化打包(深入篇)
- Android Studio Gradle实践之多渠道自动化打包+版本号管理
- Android Gradle多渠道和自动化打包(深入篇)
- ORACLE数据库的索引类型及其适用场景
- Spring-JdbcTemplate-春天的故事5
- python眼中的tkinter
- ListView使用自定义框架mylibrary的基本理解
- 去除数组中重复的元素,高效率
- gradle + Jetty + docker 实现Java自动化打包
- 常用adb命令
- mybatis入门篇
- 两列布局——左侧宽度固定,右侧宽度自适应的两种方法
- sqlite3的添加,删除,查看
- java.lang.IllegalArgumentException: The class class ** is not found in EntityFactory.
- RxJava之map源码解析
- 自定义控件中onMeasure,onLayout,onDraw的使用
- java语言 三目运算符