Dubbo 采用全 Spring 配置方式,透明化接入应用,对应用没有任何 API 侵入,只需用 Spring 加载 Dubbo 的配置即可,Dubbo 基于 Spring 的 Schema 扩展 进行加载。
如果不想使用 Spring 配置,可以通过 API 的方式 进行调用。
dubbo官方提供了三种启动注册方式。分别是:
1、利用main方法进行服务启动
2、利用tomcat容器
3、利用dubbo官方提供的com.alibaba.dubbo.container.Main方法
三种方式各有利弊。这篇文章以一个简单的例子来简单的介绍一下这三种启动注册方式,在看这篇博客前,相信已经熟悉dubbo+zk的架构和项目中成员的组成了。
- Provider: 暴露服务的服务提供方。
- Consumer: 调用远程服务的服务消费方。
- Registry: 服务注册与发现的注册中心。
- Monitor: 统计服务的调用次数和调用时间的监控中心。
- Container: 服务运行容器。
注:Dubbo的Container详解模块,是一个独立的容器,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。可参考:http://www.ccblog.cn/75.htm
一、main方法
这种方式需要在项目中新建一个类来专门执行main方法,去加载配置文件。所以这种方式更加适合开发阶段的使用,方便开发人员进行单元测试。
官网:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
public class ProviderApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
context.start();
System.out.println("启动成功");
System.in.read(); // 按任意键退出。为保证服务一直开着,利用输入流的阻塞来模拟
}
}
或者使用CountDownLatch让主线程阻塞
如果主线程不等待,那么监听的容器也会随之停止,无法监听请求。
这段代码的作用就是让主线程等待,让监听的Spring容器可以不断监听请求。
也可以用其他的方式等待,都可以,不一定要用CountDownLatch。
public class ProviderApplication {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
/**
* 如果没有web容器,需要hold住服务,否则进程会退出,参考以下代码:
* @param args
*/
public static void main(String[] args) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{
"classpath:spring/applicationContext.xml",
"classpath:spring/spring-dubbo-provider.xml",
"classpath:spring/spring-dubbo-consumer.xml"});
System.out.println("-------------------------->启动成功-------------------------->");
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
二、web容器
这种方式不需要添加任何多余的类或方法,只需要将provider注册服务的配置文件放在web.xml中加载到web容器中即可。
- 这种方式服务注册的配置文件是支持中文格式的。
- 但是这种方式增加了tomcat的耦合性,web容器是用来运行web程序的,还需要分出额外的精力去管理dubbo服务注册,造成管理压力。
- 同时对内存的占用也会加大,影响程序性能。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="appication" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
三、利用dubbo官方提提供的com.alibaba.dubbo.container.Main方法
引用:https://www.iteye.com/blog/zhaoshijie-2214753
服务容器是一个standalone的启动程序,因为后台服务不需要Tomcat或JBoss等Web容器的功能,如果硬要用Web容器去加载服务提供方,增加复杂性,也浪费资源。
服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。
服务容器的加载内容可以扩展,内置了spring, jetty, log4j等加载,可通过Container扩展点进行扩展,参见:Container
Spring Container
自动加载META-INF/spring目录下的所有Spring配置。
配置:(配在java命令-D参数或者dubbo.properties中)
dubbo.spring.config=classpath*:META-INF/spring/*.xml ----配置spring配置加载位置
Jetty Container
启动一个内嵌Jetty,用于汇报状态。
配置:(配在java命令-D参数或者dubbo.properties中)
dubbo.jetty.port=8080 ----配置jetty启动端口
dubbo.jetty.directory=/foo/bar ----配置可通过jetty直接访问的目录,用于存放静态文件
dubbo.jetty.page=log,status,system ----配置显示的页面,缺省加载所有页面
Log4j Container
自动配置log4j的配置,在多进程启动时,自动给日志文件按进程分目录。
配置:(配在java命令-D参数或者dubbo.properties中)
dubbo.log4j.file=/foo/bar.log ----配置日志文件路径
dubbo.log4j.level=WARN ----配置日志级别
dubbo.log4j.subdirectory=20880 ----配置日志子目录,用于多进程启动,避免冲突
容器启动
如:(缺省只加载spring)
java com.alibaba.dubbo.container.Main
或:(通过main函数参数传入要加载的容器)
java com.alibaba.dubbo.container.Main spring jetty log4j
或:(通过JVM启动参数传入要加载的容器)
java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
或:(通过classpath下的dubbo.properties配置传入要加载的容器)
dubbo.properties
dubbo.container=spring,jetty,log4j
1、配置spring.xml的位置
第一种方法(采用dubbo默认配置的位置)
将spring.xml放进src/main/resources下的META-INF/spring/目录下
第二种方法(自定义spring.xml位置)
在src/main/resources目录下新建文件dubbo.properties配置文件,内容为
dubbo.spring.config=classpath:spring.xml
=后面的就是spring.xml路径
2、调用dubbo的main函数
package com.dubbo.start;
import com.alibaba.dubbo.container.Main;
public class ProviderApplication {
public static void main(String[] args) {
Main.main(args);
//Main.main(new String[]{"spring","jetty","log4j"});
}
}
启动即可。具体可调试查看com.alibaba.dubbo.container.Main.main()
利用maven生成jar包通过Java-jar命令注册服务
这种方式可以将需要注册的服务单独放在服务器上进行管理。方便,有利于分布式应用的管理。利于分布式应用服务的扩展。
1、pom文件的配置
<build>
<resources>
<resource>
<!--生成的classes文件的路径,此文件夹中包含运行时的所有文件,可以不配置--> <targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.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>applicationContext.xml</include>
</includes>
</resource>
</resources>
<!--下面的必须配置-->
<plugins>
<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
<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>
<!-- 打包时 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>
2、创建服务注册时相应的文件夹
这个是必须要建的,可能是默认生成的路径,如果配置resource后,targetPath也是这个
3、利用maven进行打包
install到本地后,会在target中生成:lib和你要打的jar包
生成的target目录下的情况:
classes是在直接执行com.alibaba.dubbo.container.Main方法时运行时所需要的所有文件.class文件和xml.
4、错误
在target目录下,通过java -jar 命令执行时报错:
原因:在配置文件中存在中文导致的。注释中的中文也是不可以的。将中文注释删掉后,执行成功!
查看效果:
最后,利用这三种注册方式的就都完成了。
还想让大家看的一个效果:
发现同一个ip的同一个端口注册一次就不允许二次注册服务了。这个端口号也是我们自定义的来管理我们的分布式服务的!
————————————————
原文链接:https://blog.csdn.net/wangyy130/article/details/51741431
●阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路
●SpringCloud电商秒杀微服务-Redisson分布式锁方案
查看更多好文,进入公众号--撩我--往期精彩
一只 有深度 有灵魂 的公众号0.0