本文使用的是dubbo提供的主类com.alibaba.dubbo.container.Main启动容器。
主要区别是提供不同插件的的启动方式。
目录
一、项目内容
1.1、目录结构图
1.2、相关文件配置
二、运行容器方式
2.1 使用Java命令启动(手动)
2.1.1 使用maven-shade-plugin 插件打包运行
2.1.2 使用 maven-jar-plugin 插件和 maven-dependency-plugin 插件打包运行
2.2 使用脚本启动
2.2.1 windows启动脚本start.bat
2.2.2 linux启动脚本start.sh
2.2.3 linux停止脚本stop.sh
2.2.4 linux重启脚本restart.sh
一、项目内容
1.1 目录结构如图:
1.2 相关文件的配置
- DemoService
package com.test.provider;
/**
* Created by Administrator on 2018/2/1.
*/
public interface DemoService {
String sayHello(String word);
}
- DemoServiceImpl
package com.test.provider;
import org.springframework.stereotype.Service;
/**
* Created by Administrator on 2018/2/1.
*/
@Service("demoService")
public class DemoServiceImpl implements DemoService {
public String sayHello(String word) {
return "hello " + word + ",I'm provider \r\n";
}
}
- assemble-descriptor.xml
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>bin</id>
<formats>
<format>tar.gz</format>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/resources/bin</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>*</include>
</includes>
<fileMode>0755</fileMode>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>src/main/resources/cconf</directory>
<outputDirectory>cconf</outputDirectory>
<includes>
<include>*</include>
</includes>
<fileMode>0755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
- application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="classpath:cconf/dubbo-provider.xml"/>
</beans>
- dubbo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.test.provider"/>
<!--IP 为zookeeper 地址-->
<dubbo:registry protocol="zookeeper" address="47.93.200.10:2181"/>
<dubbo:service interface="com.test.provider.DemoService" ref="demoService" />
</beans>
- dubbo.properties
#把属行放在该文件主要是为了方便使用脚本启动时,获取以下的信息
dubbo.application.name=hello-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jay.test.dubbo-zookeeper</groupId>
<artifactId>hello-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<spring.version>4.3.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.9</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--dubbo注册中心-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<!--zookeeper客户端-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<!--dubbo 容器配置-->
<!-- 把 directory 下的 include 文件 复制到 targetPath-->
<resource>
<!--dubbo 默认指定的容器启动目录-->
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/cconf</directory>
<filtering>true</filtering>
<includes>
<include>application.xml</include>
</includes>
</resource>
</resources>
<plugins>
<!--java命令启动:第一种打包方式-->
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>-->
<!--分————————————割——————————————————线-->
<!--java命令:第二种打包方式-->
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<!– <classesDirectory>target/classes/</classesDirectory>–>
<archive>
<manifest>
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
<!– 打包时 MANIFEST.MF文件不记录的时间戳版本 –>
<useUniqueVersions>false</useUniqueVersions>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>-->
<!--分————————————割——————————————————线-->
<!--脚本启动使用的插件-->
<!--该插件可以做额外的文件打包,比如bin目录,conf配置文件夹。使用java 命令启动可忽略该插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-binary-pacakge</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!--打包后的报名-->
<finalName>deploy-jar</finalName>
<!-- 包名是否追加assemble-descriptor.xml中的id-->
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/assemble/assemble-descriptor.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
二、运行容器方式
2.1、使用java命令启动(手动)
2.1.1 方法一:使用maven-shade-plugin 插件打包运行
pom主要使用如下配置
<build>
<resources>
<!--主要是把src/main/resources下的所有的文件中的变量替换-->
<!--如:dubbo.properties 中的prop.log.dir=${pom.log.dir},pom.log.dir配置在pom.xml文件中-->
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<!--dubbo 容器配置-->
<!-- 把 directory 下的 include 文件 复制到 targetPath-->
<resource>
<!--dubbo 默认指定的容器启动目录-->
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/cconf</directory>
<filtering>true</filtering>
<includes>
<include>application.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
打包完成后target如下
在jar包的目录打开cmd,运行命令 java -jar hello-provider-1.0-SNAPSHOT.jar,如下图即启动成功
在dubbo-ammin 也能看到对应的注册信息
2.1.2 使用 maven-jar-plugin 插件和 maven-dependency-plugin 插件
pom主要使用如下配置
<build>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<!--dubbo 容器配置-->
<!-- 把 directory 下的 include 文件 复制到 targetPath-->
<resource>
<!--dubbo 默认指定的容器启动目录-->
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/cconf</directory>
<filtering>true</filtering>
<includes>
<include>application.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- <classesDirectory>target/classes/</classesDirectory>-->
<archive>
<manifest>
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
<!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
<useUniqueVersions>false</useUniqueVersions>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
打包完成后target如下图
打开target目录,运行 java -jar hello-provider-1.0-SNAPSHOT.jar 即可,是否注册成功参照2.1.1图
注:该方式jar包和lib包必须在同一目录下运行java命令才能启动spring容器
2.2 使用脚本启动
dubbo也提供脚本启动方式,在dubbo-2.5.9.jar中的META-INF/assembly.bin下有提供模板文件。
使用脚本启动容器只需要使用 maven-assembly-plugin 插件即可。主要配置如下:
<build>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<!--dubbo 容器配置-->
<!-- 把 directory 下的 include 文件 复制到 targetPath-->
<resource>
<!--dubbo 默认指定的容器启动目录-->
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/cconf</directory>
<filtering>true</filtering>
<includes>
<include>application.xml</include>
</includes>
</resource>
</resources>
<plugins>
<!--脚本启动使用的插件-->
<!--该插件可以做额外的文件打包,比如bin目录,conf配置文件夹。使用java 命令启动可忽略该插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-binary-pacakge</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!--打包后的报名-->
<finalName>deploy-jar</finalName>
<!-- 包名是否追加assemble-descriptor.xml中的id-->
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/assemble/assemble-descriptor.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
重新编译打包项目,在target下会出现两个文件:deploy-jar.zip和deploy-jar.tar.gz。windows使用deploy-jar.zip,linux使用deploy-jar.tar.gz。再上传到对应服务器上解压内容如下:
进入bin目录,windows启动使用bat,linux使用sh脚本
2.2.1 windows启动脚本start.bat
内容如下,双击start.bat即可运行,验证方式如方法一
@echo off & setlocal enabledelayedexpansion
set LIB_JARS=..\cconf
cd ..\lib
for %%i in (*) do set LIB_JARS=!LIB_JARS!;..\lib\%%i
cd ..\bin
echo Starting the server [服务名] ......
java -classpath %LIB_JARS% com.alibaba.dubbo.container.Main
endlocal
2.2.2 linux启动脚本start.sh
进入bin目录,执行./start.sh,验证方式如方法一
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/cconf
# =======================================================================================
# 检测操作系统类型
# =======================================================================================
OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]`
case "$OS" in
'sunos')
# OS="solaris"
;;
'hp-ux' | 'hp-ux64') # 未经过验证
# OS="linux"
;;
'darwin') # Mac OSX
OS="unix"
;;
'unix_sv')
OS="unix"
;;
esac
# 该脚本目前只支持linux、Mac OSX
if [ "$OS" != "linux" ] && [ "$OS" != "unix" ]; then
echo "Unsupported OS: $OS"
exit 1
fi
# =======================================================================================
# 检测服务是否已经启动,或者端口号是否已经被占用
# Mac OSX支持: ps -e -o 'pid=,command=',但linux必须写成: ps -e -o 'pid=' -o 'command='
# =======================================================================================
PIDS=`ps -e -o 'pid=' -o 'command='|grep java|grep "$CONF_DIR"|awk '{print $1}'`
if [ -n "$PIDS" ]; then
# 服务已经启动
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit 1
fi
if [ -n "$SERVER_PORT" ]; then
# 端口号是否被占用
# netstat的输出格式:
# linux: 192.168.169.1:10050
# Mac OSX: 192.168.169.2.56508
if [ "$OS" == "unix" ]; then
SERVER_PORT_COUNT=`netstat -ant -p tcp|tail -n +3|awk '{print $4}'|grep '[.:]$SERVER_PORT' -c`
else
SERVER_PORT_COUNT=`netstat -ant|tail -n +3|awk '{print $4}'|grep '[.:]$SERVER_PORT' -c`
fi
if [ $SERVER_PORT_COUNT -gt 0 ]; then
echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
exit 1
fi
fi
# =======================================================================================
# 启动服务
# =======================================================================================
# dubbo服务配置参数
SERVER_NAME=`sed '/^#/d;/dubbo.application.name/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`
fi
SERVER_PORT=`sed '/^#/d;/dubbo.protocol.port/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
SERVER_HOST=`sed '/^#/d;/dubbo.protocol.host/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
if [ -z "$SERVER_HOST" ]; then
SERVER_HOST=127.0.0.1
fi
# 日志:log4j.xml文件路径、日志路径、stdout日志文件名
LOG4J_XML=`sed '/^#/d;/prop.log.log4j-xml/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
LOG_DIR=`sed '/^#/d;/prop.log.dir/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
if [ -n "$LOG_DIR" ]; then
LOG_DIR=`dirname $LOG_DIR/stdout.log`
else
LOG_DIR=$DEPLOY_DIR/logs
fi
if [ ! -d $LOG_DIR ]; then
# 日志目录不存在,创建这个目录
mkdir -p $LOG_DIR
fi
LOG_STDOUT=`sed '/^#/d;/prop.log.stdout-file/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
if [ -z "$LOG_STDOUT" ]; then
LOG_STDOUT=$LOG_DIR/stdout.log
else
OG_STDOUT=$LOG_DIR/$LOG_STDOUT
fi
# classpath设置
LIB_DIR=$DEPLOY_DIR/lib
LIB_JARS=`ls $LIB_DIR|grep .jar|awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`
CLASS_PATH=$CONF_DIR:$LIB_JARS
JAVA_OPTS=" -Dfile.encoding=utf-8 -Duser.language=en -Duser.country=US -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dlog4j.configuration=$LOG4J_XML "
echo "Starting the $SERVER_NAME, $SERVER_HOST:$SERVER_PORT"
nohup java $JAVA_OPTS -classpath $CLASS_PATH com.alibaba.dubbo.container.Main > $LOG_STDOUT 2>&1 &
# =======================================================================================
# 检测服务状态,服务启动状态OK之后再退出
# =======================================================================================
echo -e " Waiting for service [$SERVER_HOST $SERVER_PORT] status OK ...\c"
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
# 能够连通服务端口号,则服务启动完成
COUNT=`echo status | nmap $SERVER_HOST -p $SERVER_PORT | grep -c open`
done
echo "OK!"
# 下面ps命令参数兼容linux、Mac OSX(Free BSD)
PIDS=`ps -e -o 'pid=' -o 'command='|grep java|grep "$CONF_DIR"|awk '{print $1}'`
echo " PID: $PIDS"
echo " STDOUT: $LOG_STDOUT"
2.2.3 linux停止脚本stop.sh
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/cconf
SERVER_NAME=`sed '/^#/d;/dubbo.application.name/!d;s/.*=//' cconf/dubbo.properties | tr -d '\r'`
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`
fi
PIDS=`ps -e -o 'pid=' -o 'command='|grep java|grep "$CONF_DIR"|awk '{print $1}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
echo "Stopping the $SERVER_NAME ..."
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
echo " PID: $PID"
done
echo -e " Waiting PIDS to quit ...\c"
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps -p $PID|tail -n +2|wc -l`
if [ "$PID_EXIST" -gt 0 ]; then
COUNT=0
break
fi
done
done
echo "OK!"
2.2.4 linux重启脚本restart.sh
#!/bin/bash
cd `dirname $0`
./stop.sh
./start.sh