jetty 必知必会
导语
如果是开发老鸟,请阅读快速入门,这已经足够。如果是新手,请阅读全文,这里有你想要的热部署,debug 配置等内容,能够提高开发效率,避免浪费时间。
简介
jetty 是一个应用服务器,类似于 tomcat、resin,但是更轻量,尤其在开发时更为适合。项目地址:http://www.eclipse.org/jetty/
快速入门
在我们的 maven 项目中,引入 jetty 插件,就可以简单的以一行命令启动服务,命令如下
mvn clean package -Djetty.port=8100 jetty:run
一目了然,监听服务端口是 8100。使用 jetty 插件启动我们的服务,需要如下配置。
- 在 web 项目的 pom.xml 中加入 jetty 的 plugin。
<plugins> ..... <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>[latest stable version]</version> </plugin> </plugins>
-
在项目类路径下加入 jetty-contexts.xml。加入这个文件是为了使 jetty 启动变快,过滤掉不必要的扫描。因为在 jetty8 后启动时会扫描所有的 jar 包,来查找符合 Servlet3 特征的文件。
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> <Arg>.*/.*jsp-api-[^/]\.jar$|./.*jsp-[^/]\.jar$|./.*taglibs[^/]*\.jar$ </Arg> </Call> </Configure>
- 在 jetty plugin 中加入 jetty-contexts.xml。最终配置如下
<plugins> ..... <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>[latest stable version]</version> <configuration> <contextXml>src/main/resources/jetty-contexts.xml</contextXml> </configuration> </plugin> </plugins>
热部署
当上面配置完成后,尚未配置动态部署,具体实现操作如下
- 设置 IDE,将其设置为自动编译。eclipse 默认即是自动编译,idea 需要设置,如下
- 将启动命令增加设置,如下
mvn clean package -Djetty.port=8100 -Djetty.reload=automatic -Djetty.scanIntervalSeconds=2 jetty:run
- 设置 JVM 参数,增大 max perm size。在重新加载时,使用默认 JVM 设置会出现方法区出现 out of memory error, perm size 字样。
-XX:PermSize=512M -XX:MaxPermSize=512M
现在,使用步骤2 的 mvn 命令,即可实现热部署,便利的进行开发了。
断点调试
这里以 idea 为例介绍,eclipse 下使用类似,使用 idea 的好处请自行 google。
- 新建启动配置。在菜单栏 -> RUN -> edit configurations... 下,点击左上角的 “+” 符号,添加 maven configuration。这里起名 crm。
- 设置 run debug。在菜单栏 -> RUN -> edit configurations... 下,将热部署 2 中的命令粘贴到 command line 中(注:去掉 maven),如下
- 同样设置 JVM 参数,打开 Runner 页签,设置 VM OPTIONS,如下
至此,既可以断点调试设置完毕,进入菜单栏 -> Run -> Debug ‘crm’,点击即启动断点调试。
示例
请参考 crm 项目的 run.sh 脚本,如下
1 #!/bin/bash 2 # 1. `sh run.sh all dev` 拉取 fe 的 dev 分支代码,启动项目. 3 # 2. `sh run.sh all` 拉取 fe 的默认分支 `master`,启动项目. 4 # 3. `sh run.sh` 保持原 fe 分支代码,启动项目. 5 6 pullFeCode(){ 7 # pull newest fe code 8 echo "lianjia-fe/crm newest code pulled to fe/ directory" 9 10 if [ ! -d fe ];then 11 mkdir fe 12 fi 13 14 cd fe 15 16 if [ ! -d crm ];then 17 git clone git@git.lianjia.com:lianjia-fe/crm.git 18 fi 19 20 cd crm && git pull && git checkout $FE_CRM_BRANCH && git pull origin $FE_CRM_BRANCH 21 22 # remove old files 23 cd ../../src/main/webapp && rm -rf asset deps template index.html 24 25 # build new files 26 cd ../../../fe/crm && sh build.sh "./" "../../src/main/webapp/" 27 } 28 29 startJetty(){ 30 cd $PROJECT_BASE; 31 export MAVEN_OPTS="-Xms2048m -Xmx2048m -XX:PermSize=512M -XX:MaxPermSize=512M -Dfile.encoding=UTF-8" 32 mvn clean package -Djetty.port=8100 jetty:run 33 } 34 35 printUsage(){ 36 echo "USAGE: sh run.sh [all] [branch]"; 37 echo "-- all 表示拉取分支, branch 表示前端分支, 使用示例:"; 38 echo " 1. 'sh run.sh all dev' 拉取 fe 的 dev 分支代码,启动项目."; 39 echo " 2. 'sh run.sh all' 拉取 fe 的默认分支 'master',启动项目."; 40 echo " 3. 'sh run.sh' 保持原 fe 分支代码,启动项目."; 41 } 42 43 Main(){ 44 45 PROJECT_BASE=`pwd`; 46 47 #当前的前端分支 48 FE_CRM_BRANCH="master"; 49 50 # 强制杀死所有已经启动的 Jetty 51 jps|grep Launcher|awk '{system("kill -9 "$1)}' 52 53 # 参数不能多于两个 54 if [ $# -gt 2 ]; then 55 echo "ERROR: 参数不能超过两个 !"; 56 printUsage 57 exit; 58 fi 59 60 # 有参数则第一个参数必须为 all 61 if ([ $# -ne 0 ] && [ $1 != "all" ]); then 62 echo "ERROR: 第一个参数必须为 'all' !"; 63 printUsage 64 exit; 65 fi 66 67 # 当没有参数时,直接编译 Java 代码,启动 Jetty 68 if [ $# -eq 0 ]; then 69 startJetty; 70 exit; 71 fi 72 73 FE_CRM_BRANCH=$2; 74 echo "前端分支切换到 $FE_CRM_BRANCH"; 75 76 # 当参数为 all 时,拉取最新前端分支代码,编译 Java 代码,启动 jetty 77 pullFeCode && startJetty; 78 } 79 80 Main $@