你可以从http://www.eclipse.org/jetty/download.html下载最新的Jetty发布包,本书基于最新的9.3.x(9.3.11.v20160721)讲解,你可以根据需要下载zip或者tgz格式的压缩包。
Jetty是免安装的,直接将其解压到指定目录即可使用。
进入Jetty目录,我们会发现Jetty主要包含了以下目录和文件,针对这些目录和文件我们做一个简单的介绍,以便我们后续章节的讲解:
目录及文件 | 说明 |
---|---|
bin/ | 用于存放Jetty启动脚本,当前Jetty仅提供了Linux/Unix系统下的启动脚本。 |
demo-base/ | 用于存放Jetty演示示例配置及应用。我们可以通过命令以该目录作为基础目录启动Jetty,从而运行一个演示示例环境。 |
etc/ | Jetty XML配置文件目录。 |
lib/ | Jetty运行依赖的JAR文件目录。 |
logs/ | 请求日志目录。 |
modules/ | Jetty模块定义目录,存放了Jetty模块定义文件(*.mod) |
resources/ | 类路径下的附加资源文件目录,如log4j的配置文件。 |
start.ini | 该文件包含了命令行启动Jetty时一系列执行参数。 |
start.jar | Jetty启动JAR。 |
webapps/ | 运行于Jetty默认配置下(不指定JETTY_BASE目录)的Web应用部署目录。 |
通常情况下,我们可以通过运行start.jar来启动Jetty,除此之外,在Linux/Unix下,还可以通过bin/jetty.sh脚本启动,下面我们分别介绍一下这两种启动方式。
注意:在启动Jetty之前,首先需要确保当前操作系统已经安装了JDK1.8,同时配置了JAVA_HOME环境变量。
这是通用的也是最灵活的Jetty启动方式。无论Windows还是Linux,均可以执行以下命令启动Jetty:
cd $JETTY_HOME
java -jar start.jar
注意:与Tomcat类似,在Jetty中也存在两个常用目录变量:1、安装目录,可通过系统属性jetty.home获取该路径,本书由JETTY_HOME表示;2、Jetty实例的基础路径,该路径保存了Jetty实例的配置以及部署目录等,可通过系统属性jetty.base获取该路径,本书由JETTY_BASE表示。通过这种机制,可以将Jetty实例的配置以及Web应用与Jetty安装目录分离,从而最小化升级Jetty造成的中断。
运行命令后,将看到控制台输出以下信息,即表示Jetty启动成功:
2016-09-18 17:54:01.807:INFO::main: Logging initialized @1246ms
2016-09-18 17:54:02.009:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at http://www.eclipse.org/jetty/documentation/current/startup.html
2016-09-18 17:54:02.477:INFO:oejs.Server:main: jetty-9.3.11.v20160721
2016-09-18 17:54:02.509:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///C:/jetty/webapps/] at interval 1
2016-09-18 17:54:02.649:INFO:oejs.AbstractConnector:main: Started ServerConnect-or@5f375618{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-09-18 17:54:02.665:INFO:oejs.Server:main: Started @2097ms
由于我们是在Jetty安装目录下启动Jetty,因此Web应用的部署目录为$JETTY_HOME/webapps。当我们不指定端口时,Jetty的默认启动端口为8080。
我们在浏览器中输入http://127.0.0.1:8080,可以看到如下界面:
这是因为我们没有部署任何应用,所以请求处理失败。
Jetty并不推荐我们在JETTY_HOME目录下启动服务器,而是从JETTY_BASE目录启动。为了贯彻这一理念,Jetty在发布包中提供了一个用于演示的BASE目录:JETTY_HOME/demo-base,通过它可以演示Jetty推荐的启动方式。
执行以下命令,将JETTY_HOME/demo-base/作为JETTY_BASE启动Jetty:
cd $JETTY_HOME/demo-base/
java -jar $JETTY_HOME/start.jar
从启动日志,我们可以发现如下信息:
对WAR包的处理与Tomcat不同。Jetty并未将WAR直接解压到部署目录,而是在临时目录下生成了相关的解压文件,这种方式使得部署目录更清晰和易于维护。
demo-base默认部署了六个应用(除ROOT),用于演示不同的功能特性,部署目录中除了包含相关的WAR包外还有各个应用的配置文件(Jetty应用部署形式见本书第2章)。
在浏览器中输入http://127.0.0.1:8080,可以看到如下界面:
注意:demo-base下的Web应用仅用于演示,当生产环境部署Jetty时,务必将其删除。
start.jar的基本命令格式如下:
java -jar start.jar [选项...] [属性...] [配置...]
它支持多个选项用于完成不同的操作,主要如下:
选项 | 说明 |
---|---|
–help | 输出start.jar的使用说明。 |
–version | 输出Jetty以及依赖JAR的版本信息,并退出。 |
–list-classpath | 输出用于启动Jetty的类路径信息(包括JAR以及版本信息),然后退出。 |
–list-config | 输出用于启动Jetty的配置信息,包括JVM环境、Jetty环境、JVM参数、属性、服务器类路径、服务器XML配置,然后退出。 |
–dry-run | 输出start.jar生成的完整命令行信息,然后退出。 |
–exec | 在子进程中执行生成的命令行(–dry-run输出)。 |
–exec-properties= |
在子进程中执行生成的命令行(–dry-run输出)。 |
–debug | 启用Jetty启动过程的debug输出。添加该选项后,Jetty启动过程中将会详细输出debug级别的日志。 |
–start-log-file= |
在子进程中执行生成的命令行(–dry-run输出)。 |
–list-modules | 列出系统定义的所有模块(查找jetty.base/modules/和jetty.home/modules/目录下的.mod文件),并且显示模块的启用状态(依据命令行、jetty.base/start.ini和jetty.base/start.d/.ini)。 |
–module= |
通过命令行临时启用一个或者多个模块。 |
–add-to-start= |
通过在jetty.base/start.ini追加配置行来启动一个或多个模块,添加的配置来自于模块自己包含的ini模板。Jetty自动解析模块依赖,当前启动模块依赖的所有模块也会添加到start.ini并启动。 |
–add-to-startd= |
通过在${jetty.base}/start.d/目录创建ini文件来启动一个或者多个模块。Jetty自动解析模块依赖,当前启动模块依赖的所有模块也会在同目录下创建ini文件并启动。 |
–write-module-graph= |
为Jetty生成模块图文件(Graphviz的*.dot格式) |
–create-files | 创建模块初始化所需要的任何缺失的文件,如果模块提供了相应的URL,该选项会通过网络下载文件。 |
–skip-file-validation= |
对于指定的模块,跳过[files]阶段的内容验证,该选项主要用于那些存在可下载内容的模块。 |
–stop | 向运行的Jetty实例发送一个停止信号。需要确保Jetty实例启动时添加了STOP.PORT= |
STOP.HOST=[string] | 用于停止Jetty服务器的主机(默认为127.0.0.1),如果使用—stop选项,需要一并指定STOP.PORT。 |
STOP.PORT=[number] | 用于停止Jetty服务器的端口,如果使用—stop选项,需要一并指定STOP.KEY。 |
STOP.KEY=[alphanumeric] | 用于停止服务器的密码,如果使用—stop选项,需要一并指定STOP.PORT。 |
STOP.WAIT=[number] | Jetty服务器停止时等待确认的时间(秒),如果不指定,将无限期等待。 |
–lib= |
将任意目录(文件)添加到服务器类路径。 |
–include-jetty-dir= |
包含一个额外的目录用作配置信息源,该目录类似于jetty.base。通过这种方式,可以实现配置信息的某些复杂的层次化。 |
–download= |
如果文件在指定的位置不存在,则从指定的HTTP URI下载。 |
除了以上选项,start.jar还支持设置属性(格式如“name=value”),这些属性会影响Jetty的启动机制。常见的属性如:jetty.home、jetty.base、jetty.http.host、jetty.http.port等,其它属性我们在后续章节相关部分会进行说明。
既然已经了解start.jar,那么我们如何手动创建一个新的Jetty基础目录并启动?这对于Jetty来说非常简单。
首先,创建一个空目录:
mkdir /opt/jetty/new_base
接下来,进入目录并启动:
cd /opt/jetty/new_base
java -jar $JETTY_HOME/start.jar
我们会看到如下提示:
WARNING: Nothing to start, exiting ...
Usage: java -jar start.jar [options] [properties] [configs]
java -jar start.jar --help # for more information
这是因为当前目录没有初始化任何配置。我们可以执行以下命令来添加默认启动模块:
java -jar $JETTY_HOME/start.jar --add-to-startd=http,deploy
或者
java -jar $JETTY_HOME/start.jar --add-to-start=http,deploy
再次启动Jetty,我们会看到如下日志:
2016-10-08 17:30:50.839:INFO::main: Logging initialized @387ms
2016-10-08 17:30:51.010:INFO:oejs.Server:main: jetty-9.3.11.v20160721
2016-10-08 17:30:51.027:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///opt/jetty/new_base/webapps/] at interval 1
2016-10-08 17:30:51.045:INFO:oejs.AbstractConnector:main: Started ServerConnector@56cbfb61{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-10-08 17:30:51.046:INFO:oejs.Server:main: Started @594ms
我们可以将Web应用拷贝到/opt/jetty/new_base/webapps/目录下进行部署。
通过以上过程可以知道,Jetty通过命令行可以很容易的完成基础目录的初始化(模块按需指定)以及Web应用部署,这给Jetty服务器实例的维护带来了极大的便利。结合动态的端口分配(由jetty.http.port属性指定),我们可以非常方便的在一台物理机上批量初始化和运行Jetty实例。
在Linux/Unix系统下,Jetty提供了一个Shell脚本文件(JETTY_HOME/bin/jetty.sh)用来启动/停止Jetty服务器(类似于Tomcat),因此我们还可以通过以下命令启动Jetty:
.$JETTY_HOME/bin/jetty.sh start
$JETTY_HOME替换为Jetty的安装目录,当然,你也可以直接进到bin目录下执行。
jetty.sh脚本支持以下选项以完成不同操作:
选项 | 说明 |
---|---|
start | 开启一个daemon进程以运行Jetty服务器。 |
stop | 停止Jetty服务器。 |
restart | 重启Jetty服务器。 |
supervise | 在当前终端运行Jetty服务器。 |
run、demo | 在当前终端运行Jetty服务器。 |
check、status | 输出Jetty服务器的状态以及相关参数值。 |
默认情况下,jetty.sh方式启动时,JETTY_BASE为Jetty服务器的安装目录,我们可以通过编辑jetty.sh文件,在顶部添加如“JETTY_BASE=/opt/jetty-base”,将JETTY_BASE变更为自己希望的目录(当然在这之前,我们需要确保已对该目录进行了初始化)。
使用过Nginx服务器的人都知道,在Linux系统下,我们可以直接通过系统服务来启动和停止Nginx,这种操作方式更加简便和快捷。通过jetty.sh,我们也可以将Jetty设置为Linux系统服务。只需要以root权限执行以下命令即可(假设Jetty安装目录为“/opt/jetty”):
cp /opt/jetty/bin/jetty.sh /etc/init.d/jetty
echo JETTY_HOME=`pwd` > /etc/default/jetty
添加成功后,执行以下命令查看效果:
service jetty start
如1.2.3所述,大多数情况下,Jetty推荐单独设置JETTY_BASE用作实例的配置和部署目录,此时,我们只需要在/etc/default/jetty添加对应参数即可(假设Jetty实例基础目录为“/opt/jetty-base”,注意需要确保该目录已经进行了Jetty配置初始化):
cp /opt/jetty/bin/jetty.sh /etc/init.d/jetty
echo JETTY_HOME=`pwd` > /etc/default/jetty
echo "JETTY_BASE=/opt/jetty-base" >> /etc/default/jetty
当然,我们还可以用同样的方式添加其它初始变量,如临时目录变量TMPDIR。
与Tomcat提供了Windows可执行文件以及service.bat(添加Tomcat为系统服务的脚本)不同,Jetty要添加为Windows系统服务相对比较复杂。
首先,由于Jetty并未提供可执行文件,因此需要依赖第三方程序进行封装,官方推荐的是Apache ProcRun 。
其次,我们需要像Tomcat一样编写一个bat脚本来添加系统服务,幸运的是我们不需要从零开始,只需要基于官方文档提供的示例脚本稍加修改即可:
@echo off
set SERVICE_NAME=JettyService
set JETTY_HOME=C:\opt\jetty
set JETTY_BASE=C:\opt\jetty-base
set STOPKEY=secret
set STOPPORT=50001
set PR_INSTALL=C:\opt\prunsrv.exe
@REM Service Log Configuration
set PR_LOGPREFIX=%SERVICE_NAME%
set PR_LOGPATH=C:\opt\jetty-logs
set PR_STDOUTPUT=auto
set PR_STDERROR=auto
set PR_LOGLEVEL=Debug
@REM Path to Java Installation
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0
set PR_JVM=%JAVA_HOME%\jre\bin\server\jvm.dll
set PR_CLASSPATH=%JETTY_HOME%\start.jar;%JAVA_HOME%\lib\tools.jar
@REM JVM Configuration
set PR_JVMMS=128
set PR_JVMMX=512
set PR_JVMSS=4000
set PR_JVMOPTIONS=-Duser.dir="%JETTY_BASE%";-Djava.io.tmpdir="C:\opt\jetty-temp";-Djetty.home="%JETTY_HOME%";-Djetty.base="%JETTY_BASE%"
@REM Startup Configuration
set JETTY_START_CLASS=org.eclipse.jetty.start.Main
set PR_STARTUP=auto
set PR_STARTMODE=java
set PR_STARTCLASS=%JETTY_START_CLASS%
set PR_STARTPARAMS=STOP.KEY="%STOPKEY%";STOP.PORT=%STOPPORT%
@REM Shutdown Configuration
set PR_STOPMODE=java
set PR_STOPCLASS=%JETTY_START_CLASS%
set PR_STOPPARAMS=--stop;STOP.KEY="%STOPKEY%";STOP.PORT=%STOPPORT%;STOP.WAIT=10
"%PR_INSTALL%" //IS/%SERVICE_NAME% ^
--DisplayName="%SERVICE_NAME%" ^
--Install="%PR_INSTALL%" ^
--Startup="%PR_STARTUP%" ^
--LogPath="%PR_LOGPATH%" ^
--LogPrefix="%PR_LOGPREFIX%" ^
--LogLevel="%PR_LOGLEVEL%" ^
--StdOutput="%PR_STDOUTPUT%" ^
--StdError="%PR_STDERROR%" ^
--JavaHome="%JAVA_HOME%" ^
--Jvm="%PR_JVM%" ^
--JvmMs="%PR_JVMMS%" ^
--JvmMx="%PR_JVMMX%" ^
--JvmSs="%PR_JVMSS%" ^
--JvmOptions="%PR_JVMOPTIONS%" ^
--Classpath="%PR_CLASSPATH%" ^
--StartMode="%PR_STARTMODE%" ^
--StartClass="%JETTY_START_CLASS%" ^
--StartParams="%PR_STARTPARAMS%" ^
--StopMode="%PR_STOPMODE%" ^
--StopClass="%PR_STOPCLASS%" ^
--StopParams="%PR_STOPPARAMS%"
if not errorlevel 1 goto installed
echo Failed to install "%SERVICE_NAME%" service. Refer to log in %PR_LOGPATH%
goto end
:installed
echo The Service "%SERVICE_NAME%" has been installed
:end
注意加粗部分,我们需要指定Jetty、Apache ProcRun、Java的安装目录,Jetty实例的基础目录、临时目录、日志目录等。
该脚本执行成功后,我们可以在Windows系统服务界面看到名为“JettyService”服务,并在该界面启动/停止Jetty。
虽然采用系统服务的方式启动Jetty比较便捷,而且也便于那些不熟悉Java的运维人员使用,但是它的缺点也非常明显,由于$JETTY_BASE是固定的,因此我们无法像start.jar一样灵活启动多个实例。