[開發背景]
tomcat啓動之後佔用三個端口。我對此非常不理解,我決定在tomcat基礎之上,開發一個新的tomcat,僅僅佔用一個端口。
gitee地址:https://gitee.com/litongjava_admin/bill-tomcat
bill-tomcat開發
創建工程
pom.xml中添加依賴
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.6</jdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!-- java編譯插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
在src/main/resources創建webapps目錄
在src/main/resources創建tomcat.properties
內容如下
tomcat.port=8080
進行編碼
ConfigUtil.java
package com.litong.utils.file;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
/**
* @author litong 讀取config.properties
*/
public class ConfigUtil {
private static String configFilePath = "tomcat.properties";
private static Properties prop = null;
private static InputStream ins = null;
static {
ins = ConfigUtil.class.getClassLoader().getResourceAsStream(configFilePath);
// 防止讀取亂碼
InputStreamReader insReader = null;
try {
insReader = new InputStreamReader(ins, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
prop = new Properties();
try {
prop.load(insReader);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* get value of key
*/
public static String getValue(String key) {
return prop.getProperty(key);
}
public static int getIntValue(String key) {
return Integer.parseInt(prop.getProperty(key));
}
/**
* 設置值,設置值後存盤
* @param key
* @param value
*/
public static void put(String key, String value) {
prop.put(key, value);
ConfigUtil.save();
}
public static void save() {
URL url = ConfigUtil.class.getClassLoader().getResource(configFilePath);
File file = new File(url.getFile());
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
prop.store(fileOutputStream, null);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* get properties
*/
public static Properties getProperties() {
return prop;
}
/**
*
* @return 配置文件名稱
*/
public static String getConfigFile() {
return configFilePath;
}
public static void main(String[] args) {
// String value = ConfigUtil.getValue("prorject_id");
// System.out.println(value);
Properties prop = ConfigUtil.getProperties();
Set<Entry<Object, Object>> entrySet = prop.entrySet();
for (Entry<Object, Object> entry : entrySet) {
System.out.println("" + entry.getKey() + "=" + entry.getValue());
}
}
}
Constants.java
package com.uairobot.bill.tomcat;
public class Constants {
public static final String tomcatPort = "tomcat.port";
}
TomcatUtil.java
package com.uairobot.bill.tomcat;
import java.io.File;
import java.net.URL;
import com.litong.utils.file.ConfigUtil;
public class TomcatUtil {
private static URL webappsPath;
private static File webappFile;
private static ClassLoader classLoader;
public static URL getWebappsPath() {
if (webappsPath == null) {
webappsPath = getClassLoader().getResource("webapps");
}
return webappsPath;
}
public static File getWebappsFile() {
if (webappFile == null) {
URL webappPath = getWebappsPath();
if (webappPath == null) {
String file = getClassLoader().getResource("").getFile();
System.out.println("webappPath is null,auto create webapps in " + file);
webappFile = new File(file + "webapps");
if (!webappFile.exists()) {
webappFile.mkdirs();
}
} else {
webappFile = new File(webappPath.getFile());
}
}
return webappFile;
}
public static ClassLoader getClassLoader() {
if (classLoader == null) {
classLoader = TomcatUtil.class.getClassLoader();
}
return classLoader;
}
public static int getPort() {
return ConfigUtil.getIntValue(Constants.tomcatPort);
}
}
TomcatServer.java
package com.uairobot.bill.tomcat;
import java.io.File;
import javax.servlet.ServletException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
public class TomcatServer {
public static Tomcat tomcat = null;
public static void main(String[] args) {
long start = System.currentTimeMillis();
File webappsFile = TomcatUtil.getWebappsFile();
File[] listFiles = webappsFile.listFiles();
// 創建root目錄
String rootPath = webappsFile.getAbsoluteFile() + File.separator + "ROOT";
File rootFile = new File(rootPath);
if (!rootFile.exists()) {
rootFile.mkdirs();
}
tomcat = new Tomcat();
// 添加webapp
try {
tomcat.addWebapp("/", rootPath);
System.out.println("add webapp " + "/" + "=>" + rootPath);
for (File file : listFiles) {
String contextPath = "/" + file.getName();
String baseDir = file.getAbsolutePath();
tomcat.addWebapp(contextPath, baseDir);
System.out.println("add webapp " + contextPath + "=>" + baseDir);
}
} catch (ServletException e1) {
e1.printStackTrace();
}
// 設置tomcat端口
tomcat.setPort(TomcatUtil.getPort());
// 啓動tomcat
try {
tomcat.start();
} catch (LifecycleException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("啓動完成,共使用了:" + (end - start) + "ms");
// 等待接收關閉指令
tomcat.getServer().await();
}
}
執行TomcatServer就可以啓動項目
bill-tomcat打包
打包概述和啓動命令
what is 打包
打包:將程序打包成tar.gz文件,可以放到服務器上運行
[總體概述]
將依賴包和項目包放到lib目錄下
將配置文件放到config目錄下載
將webapps,放到webapps目錄下
[啓動命令]
因爲要在classpath下載尋找webapps所以需要將當前目錄,config目錄和lib目錄添加到到classpath下
在linux上前臺啓動
java -Xverify:none -cp .:./config:./lib/*: com.uairobot.bill.tomcat.TomcatServer
maven-jar-plugin
maven-jar-plugin排除配置文件和webapps目錄不添加到jar包中
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<excludes>
<exclude>*.txt</exclude>
<exclude>*.xml</exclude>
<exclude>*.properties</exclude>
<exclude>webapps</exclude>
<exclude>webapps/*</exclude>
<exclude>sql</exclude>
<exclude>sql/*</exclude>
</excludes>
</configuration>
</plugin>
maven-assembly-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!-- jar 等壓縮文件在被打包進入 zip、tar.gz 時是否壓縮,設置爲 false 可加快打包速度 -->
<recompressZippedFiles>false</recompressZippedFiles>
<!-- 打包生成的文件是否要追加 release.xml 中定義的 id 值 -->
<appendAssemblyId>true</appendAssemblyId>
<!-- 指向打包描述文件 package.xml -->
<descriptors>
<descriptor>src/main/assembly/package.xml</descriptor>
</descriptors>
<!-- 打包結果輸出的基礎目錄 -->
<outputDirectory>${project.build.directory}/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
src\main\assembly\package.xml內容如下
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<!-- assembly 打包配置更多配置可參考官司方文檔: http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html -->
<id>release</id>
<!-- 設置打包格式,可同時設置多種格式,常用格式有:dir、zip、tar、tar.gz dir 格式便於在本地測試打包結果 zip 格式便於 windows 系統下解壓運行 tar、tar.gz 格式便於 linux 系統下解壓運行 -->
<formats>
<!-- <format>dir</format> <format>zip</format> -->
<format>tar.gz</format>
</formats>
<!-- 打 zip 設置爲 true 時,會在 zip 包中生成一個根目錄,打 dir 時設置爲 false 少層目錄 -->
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<!-- src/main/resources 配置文件 copy 到 config 目錄下 -->
<fileSet>
<directory>${basedir}/src/main/resources</directory>
<outputDirectory>config</outputDirectory>
<includes>
<include>*.xml</include>
<include>*.properties</include>
<include>*.txt</include>
</includes>
</fileSet>
<!-- 複製sql文件到config目錄下 -->
<fileSet>
<directory>${basedir}/src/main/resources/sql</directory>
<outputDirectory>config/sql</outputDirectory>
</fileSet>
<!--複製靜態文件 -->
<fileSet>
<directory>${basedir}/src/main/resources/webapps</directory>
<outputDirectory>webapps</outputDirectory>
</fileSet>
<!-- 複製service文件 -->
<fileSet>
<directory>${basedir}/src/main/bin</directory>
<lineEnding>unix</lineEnding>
<outputDirectory>service</outputDirectory>
<!-- 腳本文件在 linux 下的權限設爲 755,無需 chmod 可直接運行 -->
<fileMode>755</fileMode>
<includes>
<include>*.service</include>
</includes>
</fileSet>
<!-- 項目根下面的腳本文件 copy 到根目錄下 -->
<fileSet>
<directory>${basedir}/src/main/bin</directory>
<lineEnding>unix</lineEnding>
<outputDirectory></outputDirectory>
<!-- 腳本文件在 linux 下的權限設爲 755,無需 chmod 可直接運行 -->
<fileMode>755</fileMode>
<includes>
<include>*.sh</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/src/main/bin</directory>
<lineEnding>windows</lineEnding>
<outputDirectory></outputDirectory>
<!-- 腳本文件在 linux 下的權限設爲 755,無需 chmod 可直接運行 -->
<fileMode>755</fileMode>
<includes>
<include>*.bat</include>
</includes>
</fileSet>
</fileSets>
<!-- 依賴的 jar 包 copy 到 lib 目錄下 -->
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
啓動腳本
src\main\bin\bill-tomcat.sh內容如下
#!/bin/sh
# chkconfig: 345 99 01
# description:bill-tomcat
##########################
# get app home start
###########################
PRG="$0"
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
##########################
# get app home end
###########################
##########################
# custom variables start
###########################
JAVA_HOME=/usr/java/jdk1.8.0_211
APP_HOME=`dirname "$PRG"`
APP_NAME=`basename "$PRG"`
PID_FILE=$APP_HOME/$APP_NAME.pid
CP=$APP_HOME:$APP_HOME/config:$APP_HOME/lib/*
# 啓動入口類,該腳本文件用於別的項目時要改這裏
MAIN_CLASS=com.uairobot.bill.tomcat.TomcatServer
# Java 命令行參數,根據需要開啓下面的配置,改成自己需要的,注意等號前後不能有空格
# JAVA_OPTS="-Xms256m -Xmx1024m -Dundertow.port=80 -Dundertow.host=0.0.0.0"
# JAVA_OPTS="-Dundertow.port=80 -Dundertow.host=0.0.0.0"
CMD="$JAVA_HOME/bin/java -Xverify:none ${JAVA_OPTS} -cp ${CP} ${MAIN_CLASS}"
###########################
# custom variables end
###########################
source /etc/init.d/functions
#########################
# define funcation start
##########################
if [[ "$MAIN_CLASS" == "com.yourpackage.YourMainClass" ]]; then
echo "請先修改 MAIN_CLASS 的值爲你自己項目啓動Class,然後再執行此腳本。"
exit 0
fi
lock_dir=/var/lock/subsys
lock_file=$lock_dir/$APP_NAME
createLockFile(){
[ -w $lock_dir ] && touch $lock_file
}
start(){
[ -e $APP_HOME/logs ] || mkdir $APP_HOME/logs -p
if [ -f $PID_FILE ]
then
echo 'alread running...'
else
echo $CMD
nohup $CMD >> $APP_HOME/logs/$APP_NAME.log 2>&1 &
echo $! > $PID_FILE
createLockFile
echo_success
fi
}
stop(){
if [ -f $PID_FILE ]
then
killproc -p $PID_FILE
rm -f $PID_FILE
echo_success
else
echo 'not running...'
fi
}
restart(){
stop
start
}
status(){
cat $PID_FILE
}
##########################
# define function end
##########################
ACTION=$1
case $ACTION in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo usage "{start|stop|restart|status}"
;;
esac
打包
使用clean package -DskipTests在Eclipse會出現中會出現MANIFEST.MF (系統找不到指定的路徑。)所以執行install
clean install -DskipTests
打包完成後生成文件名bill-tomcat-1.0-release.tar.gz,文件大小是13.3 MB
解壓後的目錄結果如下
bill-tomcat-1.0
├── bill-tomcat.sh
├── config
│ ├── tomcat.properties
├── lib
│ ├── backport-util-concurrent-3.1.jar
│ ├── bill-tomcat-1.0.jar
│ ├── classworlds-1.1-alpha-2.jar
│ ├── commons-cli-1.2.jar
│ ├── commons-codec-1.6.jar
│ ├── commons-compress-1.4.1.jar
│ ├── commons-io-2.2.jar
│ ├── commons-lang-2.6.jar
│ ├── commons-logging-1.1.3.jar
│ ├── common-tomcat-maven-plugin-2.2.jar
│ ├── doxia-sink-api-1.0-alpha-7.jar
│ ├── ecj-4.2.2.jar
│ ├── guava-10.0.1.jar
│ ├── httpclient-4.3.1.jar
│ ├── httpcore-4.3.jar
│ ├── jcl-over-slf4j-1.7.5.jar
│ ├── jsch-0.1.27.jar
│ ├── jsr305-1.3.9.jar
│ ├── jtidy-4aug2000r7-dev.jar
│ ├── maven-archiver-2.4.2.jar
│ ├── maven-artifact-2.0.6.jar
│ ├── maven-artifact-manager-2.2.1.jar
│ ├── maven-core-2.0.6.jar
│ ├── maven-error-diagnostics-2.0.6.jar
│ ├── maven-filtering-1.0.jar
│ ├── maven-model-2.0.6.jar
│ ├── maven-monitor-2.0.6.jar
│ ├── maven-plugin-api-2.2.1.jar
│ ├── maven-plugin-descriptor-2.0.6.jar
│ ├── maven-plugin-parameter-documenter-2.0.6.jar
│ ├── maven-plugin-registry-2.2.1.jar
│ ├── maven-profile-2.2.1.jar
│ ├── maven-project-2.2.1.jar
│ ├── maven-reporting-api-2.0.6.jar
│ ├── maven-repository-metadata-2.0.6.jar
│ ├── maven-settings-2.0.6.jar
│ ├── plexus-archiver-2.1.1.jar
│ ├── plexus-build-api-0.0.4.jar
│ ├── plexus-classworlds-2.2.2.jar
│ ├── plexus-component-annotations-1.5.5.jar
│ ├── plexus-container-default-1.0-alpha-9-stable-1.jar
│ ├── plexus-interactivity-api-1.0-alpha-4.jar
│ ├── plexus-interpolation-1.13.jar
│ ├── plexus-io-2.0.3.jar
│ ├── plexus-utils-3.0.15.jar
│ ├── slf4j-api-1.7.5.jar
│ ├── tomcat7-maven-plugin-2.2.jar
│ ├── tomcat7-war-runner-2.2.jar
│ ├── tomcat-annotations-api-7.0.47.jar
│ ├── tomcat-api-7.0.47.jar
│ ├── tomcat-catalina-7.0.47.jar
│ ├── tomcat-catalina-ha-7.0.47.jar
│ ├── tomcat-coyote-7.0.47.jar
│ ├── tomcat-dbcp-7.0.47.jar
│ ├── tomcat-el-api-7.0.47.jar
│ ├── tomcat-embed-core-7.0.47.jar
│ ├── tomcat-embed-logging-juli-7.0.47.jar
│ ├── tomcat-embed-logging-log4j-7.0.47.jar
│ ├── tomcat-jasper-7.0.47.jar
│ ├── tomcat-jasper-el-7.0.47.jar
│ ├── tomcat-jdbc-7.0.47.jar
│ ├── tomcat-jsp-api-7.0.47.jar
│ ├── tomcat-juli-7.0.47.jar
│ ├── tomcat-servlet-api-7.0.47.jar
│ ├── tomcat-tribes-7.0.47.jar
│ ├── tomcat-util-7.0.47.jar
│ ├── wagon-file-1.0-beta-2.jar
│ ├── wagon-http-lightweight-1.0-beta-2.jar
│ ├── wagon-http-shared-1.0-beta-2.jar
│ ├── wagon-provider-api-1.0-beta-2.jar
│ ├── wagon-ssh-1.0-beta-2.jar
│ ├── wagon-ssh-common-1.0-beta-2.jar
│ ├── wagon-ssh-external-1.0-beta-2.jar
│ ├── xml-apis-1.0.b2.jar
│ └── xz-1.0.jar
└── webapps
└── ROOT
└── index.html
bill-tomcat安裝
[下載]
https://gitee.com/litongjava_admin/bill-tomcat/releases/v1.0
下載bill-tomcat-1.0-release.tar.gz
[bill-tomcat安裝]
mkdir /opt/package/bill-tomcat
cd /opt/package/bill-tomcat
#上傳bill-tomcat-1.0-release.tar.gz到此目錄下
tar -xf bill-tomcat-1.0-release.tar.gz -C /usr/local/
cd /opt/package/bill-tomcat
#在linux上後臺啓動
./bill-tomcat.sh start
在linux上前臺啓動
cd /opt/package/bill-tomcat
/usr/java/jdk1.8.0_211/bin/java -Xverify:none -cp ./config:./lib/*: com.uairobot.bill.tomcat.TomcatServer
[向bill-tomcat安裝部署項目]
#進入webapps目錄
cd /usr/local/bill-tomcat-1.0/webapps
#本tomcat不會自動解壓war包,需要手動下載war並解壓到此目錄下
wget http://xxx.com/bill-websocket-web-chat-1.0.war
mkdir bill-websocket-web-chat
unzip bill-websocket-web-chat-1.0.war -d bill-websocket-web-chat
#重啓讓部署的項目生效
/usr/local/bill-tomcat-1.0/bill-tomcat.sh restart
#訪問
http://192.168.78.131:8080/bill-websocket-web-chat/
基於bill-tomcat進行開發
其實很簡單,在pom.xml中添加omcat7-maven-plugin的依賴即可,這樣我們就不需要向項目中添加重複的依賴了
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
依賴圖