结合本人不成熟的实际应用简单分析一下几种Dubbo服务运行的方式
使用Servlet容器
运行在Tomcat、Jetty等容器中,不需要做很多额外的处理,比较方便,但是比较浪费资源,本身容器的很多功能都是浪费,而且容器需要额外占用端口。
自建Main方法、Test方法
直接启动Spring容器,一般在测试环境下进行,结合Junit、Spring-test可以在开发的时候比较快速地把服务跑起来,启动也比较快,但是比较丑陋,不适用于实际应用环境。启动测试示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-dao.xml", "classpath:spring-trans.xml", "classpath:spring-service.xml", "classpath:spring-redis.xml"}) @WebAppConfiguration public class ServiceTest { @Autowired WebApplicationContext context; @Test public void RunService() throws IOException { System.out.println("服务已启动..."); Scanner sc = new Scanner(System.in); sc.next(); System.out.println("服务已关闭..."); } }
|
Dubbo提供的Main方法
Dubbo本身提供了一个启动的Main方法,比较突出的优点是使用ShutdownHook实现了优雅关机,而且加载内容可以扩展。
如果要使用这种方法需要对项目的打包做一些处理,打成jar包部署运行。以Maven为例,需要在POM文件中添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <build> <finalName>mydubbo-server</finalName> <resources> <resource> <targetPath>${project.build.directory}/classes</targetPath> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>others/*.xml</include> <include>**/*.properties</include> </includes> </resource> <resource> <targetPath>${project.build.directory}/classes/META-INF/spring</targetPath> <directory>src/main/resources/spring</directory> <filtering>true</filtering> <includes> <include>spring-*.xml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <classesDirectory>target/classes/</classesDirectory> <archive> <manifest> <mainClass>com.alibaba.dubbo.container.Main</mainClass> <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>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <type>jar</type> <includeTypes>jar</includeTypes> <outputDirectory>${project.build.directory}/lib </outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> <includeScope>compile</includeScope> </configuration> </execution> </executions> </plugin> </plugins> </build>
|
然后运行maven命令打出jar包,成功后可以在模块或者工程的target目录下看到生成的lib文件夹和生成的jar包。
如果是在windows下,可以在该目录下运行命令行,然后输入java -jar jar包名
,回车可以看到服务开始启动,也可以在监控中心看到服务已经部署。如果是Linux可以写一个简单的启动脚本java -jar XXX.jar > "log.log" 2>&1
来运行。
其实框架jar包里面的META-INF/assembly.bin目录下有已经写好的批处理和Bash文件可以直接拿来用。
最后是服务的停止,windows下看了看就是直接关闭命令窗口吧。Linux下使用Kill PID即可正常结束容器运行,注意不要使用kill -9 PID强制关闭,这样不会执行优雅停机。
总结
总的来说和网上大部分内容比较相似,做的时候也是一步一步查过来的。想看看为什么默认采用Spring的Container来运行容器,简单看了一下main方法,比较明显的是定义的CONTAINER_KEY(dubbo.container),但是包里并没有任何相关文件,尝试debug了一把流程,粗略看下来应该是从dubbo.internal目录下的com.alibaba.dubbo.common.extension.ExtensionFactory这个文件里读的内容最后得到了这个”spring”,不过没有继续深究下去。
至于其他的Jetty、log容器目前没有进一步尝试。