#1 引言 众所周知,不管是dubbo服务的提供方还是服务的消费方,我们都可以把工程打包成war包放到web容器(servlet容器)中启动,但这种方式是否合理呢?在dubbo的 官方文档 中,介绍了dubbo的服务提供方其实是不需要web容器单独运行的,也就是本文将要介绍的通过java命令 ** java -jar dubbo服务.jar ** 这个命令运行服务,为了运行这个jar包,我们必须把服务打包成可运行jar包,并把所依赖的jar放在约定的目录下。

如果不了解可执行jar的打包方法,请参考文章:

为什么对于服务提供方的工程,dubbo官方推荐使用可执行jar的方式运行呢,下面对三种启动方式进行比较:

  1. ** 使用web容器(Tomcat、Jetty等)启动dubbo服务 ** : 增加端口管理复杂性, tomcat/jetty等都需要占用端口,dubbo服务也需要端口;浪费资源(内存),单独启动 tomcat,jetty占用内存大
  2. ** 使用自建Main方法类运行spring容器启动dubbo服务**:Dobbo提供的优雅停机高级特性没用上,并且自已编写启动类可能会有缺陷
  3. ** 使用Dubbo框架提供的Main方法类运行Spring容器启动服务**:官方建议使用,dubbo框架本身提供启动类(com.alibaba.dubbo.container.Main),可实现优雅关机

对于优雅停机的概念和原理,请参考文档: http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E4%BC%98%E9%9B%85%E5%81%9C%E6%9C%BA

那么,下面我们来研究怎么使用java命令启动dubbo服务吧。

#2 命令行运行dubbo服务

相对于使用web容器启动的方式,该方式除了需要修改maven配置外,不需要修改原有的配置。

2.1 打包可运行jar的maven配置

主要利用maven的maven-jar-plugin和maven-dependency-plugin插件,前一个插件是配置可运行jar的manifest清单文件,该清单文件主要配置主程序main所在的位置还有依赖的jar包的位置。由于dubbo启动类 com.alibaba.dubbo.container.Main 默认自动加载META-INF/spring目录下的所有Spring配置,所以我们还需要把spring的配置文件通过maven拷贝到指定目录。除此之外,packaging的构建包类型修改为jar。完整的pom文件如下:

<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>
	<parent>
		<groupId>com.github.thinwonton.dubbo.sample</groupId>
		<artifactId>dubbo-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<relativePath>../dubbo-parent</relativePath>
	</parent>
	<groupId>com.github.thinwonton.dubbo.sample</groupId>
	<artifactId>container-provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>dubbo-container-提供者</name>

	<build>
		<!-- 输出文件名 -->
		<finalName>dubbo-container-provider</finalName>

		<resources>
			<resource>
				<targetPath>${project.build.directory}/classes</targetPath>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
				<includes>
					<include>**/*.xml</include>
					<include>**/*.properties</include>
				</includes>
				<excludes>
					<!-- spring配置文件由下面的配置:拷贝到META-INF/spring中 -->
					<exclude>spring/*.xml</exclude>
				</excludes>
			</resource>
			<!-- com.alibaba.dubbo.container.Main加载spring配置文件的路径 META-INF/spring -->
			<resource>
				<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
				<directory>src/main/resources/spring</directory>
				<filtering>true</filtering>
				<includes>
					<include>*.xml</include>
				</includes>
			</resource>
		</resources>

		<plugins>
			<!-- 资源文件拷贝插件 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<version>2.7</version>
				<configuration>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>

			<!-- java编译插件 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.2</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>

			<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<classesDirectory>target/classes/</classesDirectory>
					<archive>
						<manifest>
							<!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
							<useUniqueVersions>false</useUniqueVersions>
							<!-- 添加Class-Path -->
							<addClasspath>true</addClasspath>
							<!-- Class-Path添加前缀 -->
							<classpathPrefix>lib/</classpathPrefix>
							<!-- 指定Main-Class -->
							<mainClass>com.alibaba.dubbo.container.Main</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>

			<!-- 拷贝依赖的jar包到lib目录 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<version>2.10</version>
				<executions>
					<execution>
						<id>copy</id>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>
								<!-- 拷贝依赖到lib文件夹 -->
								${project.build.directory}/lib
							</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

2.2 运行

(1)到工程目录的根目录,运行 mvn clean package ,由maven在target目录构建jar包和拷贝依赖包到target/lib目录

(2)自建一个文件夹,把构建出来的jar和lib目录拷贝到新建文件夹中,然后使用java -jar命令运行服务

java -jar dubbo-container-provider.jar