一、背景
假如当前有一个系统,里面包含了用户模块、积分模块、商城模块...等等等,非分布式的做法是开一个web工程,把所有的模块放到同一个系统中,前端web页面也放其中,称为单体工程。很明显,这种做法会产生很多问题,臃肿、扩展延伸性差、性能瓶颈低、不利研发分组等。在分布式下则不同,每个模块都成为独立的一个系统,各个系统之间相互调用,加上前后端分离,让服务器端只提供接口,供pcweb、移动web、微信公众号等调用。
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。当前很多公司首选Dubbo作为RPC框架,本人之前也有接触并使用,下面就使用一套ssm系统简单的介绍下Dubbo的使用。
二、功能简单介绍
系统介绍:两个系统,会员系统和商城系统,都是ssm搭建,会员系统中包含了商城的web页面,商城系统只暴露接口没有web页面。商城功能包含显示所有商品、个人购物车、下单等。
功能截图
三、引入dubbo+zookeeper
会员系统作为dubbo角色中的consumer,商城系统作为provider,另外再下载zookeeper、监控中心dubbo-admin-2.5.4。
1、服务提供者商城系统配置dubbbo
引入dubbo和zookeeper依赖包,在pom.xml中加入依赖:
<!-- Dubbo 依赖 start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Dubbo 依赖 end -->
<!-- Zookeeper 依赖 start -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- Zookeeper 依赖 end -->
新建dubbo配置文件,spring-dubbo.xml,作为dubbo服务提供者配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo_provider" />
<!-- 使用zookeeper注册中心暴露服务地址-->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 areaService 使用注解已经声明 -->
<dubbo:service interface="com.tshop.service.ShopCarIService" ref="shopCarIService" />
<bean id="shopCarIService" class="com.tshop.service.impl.ShopCarServiceImpl" />
<dubbo:service interface="com.tshop.service.ShopOrderIService" ref="shopOrderIService" />
<bean id="shopOrderIService" class="com.tshop.service.impl.ShopOrderServiceImpl" />
<dubbo:service interface="com.tshop.service.ShopProductIService" ref="shopProductIService" />
<bean id="shopProductIService" class="com.tshop.service.impl.ShopProductServiceImpl" />
<!-- 使用注解方式暴露接口 -->
<dubbo:annotation package="com.tshop.service" />
</beans>
这里的sevice实现类使用@Service注解修饰,注意是com.alibaba.dubbo.config.annotation.Service注解。
并在web.xml中加入启动:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-mybatis.xml,
classpath:spring-dubbo.xml
</param-value>
</context-param>
下载注册中心zookeeper,进入Apache ZooKeeper官方网站进行下载,https://zookeeper.apache.org/releases.html,此时还是在windows操作系统上,linux后续再使用:
下载完成解压,复制conf文件夹下zoo_sample.cfg并命名为zoo.cfg,就可以启动,双击bin目录下zkServer.cmd启动zookeeper,启动成功后入下图:
下载dubbo管理控制台dubbo-admin,这里使用的是dubbo-admin-2.5.4,为一个web项目,下载后放入tomcat,启动后有登录页面,默认root/root。
tomcat容器启动商城项目,启动成功后在dubbo-admin中查看服务提供者和服务接口:
可以看到在dubbo-privoder中配置的三个服务接口,代表配置成功。
2、服务消费者会员系统配置dubbbo
消费端同样需要导入maven依赖包,与提供者一样。
新建dubbo配置文件,spring-dubbo.xml,作为dubbo服务消费者配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubbo_consumer" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:reference interface="com.tshop.service.ShopCarIService" id="shopCarIService" check="false" />
<dubbo:reference id="shopOrderIService" interface="com.tshop.service.ShopOrderIService" check="false" />
<dubbo:reference id="shopProductIService" interface="com.tshop.service.ShopProductIService" check="false" />
</beans>
在消费者配置文件中,dubbo:reference总的id属性代表bean的id值,interface的值必须与提供者中的值一致,所以在消费者工程中需要建立相应的包以及相应的接口类,在接口类中注入上述bean即可调用。如在controller中使用如下注入方式:
@Resource
private ShopCarIService shopCarIService;
就可以完成注入,进行远程方法调用。
dubbo配置文件同样需要在web.xml中加入启动设置,也可以讲spring-dubbo配置文件import进spring-mybatis.xml配置文件中。
<import resource="classpath:spring-dubbo.xml" />
配置完后启动消费者,查看dubbo-admin中消费者:
可以看到消费者三个消费接口。
上述服务提供者和消费者都是部署在各自的tomcat容器当中,依托tomcat才能运行对外提供服务,如果服务有很多,将有同样多的tomcat,将占用更多的端口,tomcat更多的是一个servlet容器,比较适合web项目。
另外两种启动服务方式为使用main方法启动和使用Dubbo框架提供的main方法来启动。
四、dubbo服务启动运行方式
这里提供三种方式,一是作为web项目放在tomcat中启动,二是使用main方法启动spring容器,从而启动dubbo服务,三是使用maven构建可执行jar包,直接启动jar方式。
dubbo启动方式 | 优缺点描述 | 场景 |
---|---|---|
使用servlet容器运行(tomcat、jetty) | 借助tomcat添加了复杂性,占用更多的端口、内存 | 不建议使用 |
自建Main方法类运行spring容器 | 稳定性差,手动编写启动类存缺陷,dubbo高级特性未使用(优雅关机) | 不建议使用,可作为本地研发调试 |
使用dubbo框架提供的Main方法类运行(spring) | dubbo容器本身提供启动类,可实现优雅关机 | 建议使用,线上线下都可使用 |
自建Main方法类运行spring容器,即为手动编写启动类:
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-mybatis.xml");
ctx.start();
synchronized (test.class) {
while(true) {
try {
test.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
需要在spring配置文件中加载dubbo配置文件:
<import resource="classpath:spring-dubbo.xml" />
启动成功后,在dubbo-admin中可看到启动的服务。
五、使用maven生成可执行的dubbo服务jar包
上述,项目能放在tomcat中运行,成功发布服务并成功的在dubbo监控平台能看到,接下来使用maven打包jar包,直接运行jar包方式发布dubbo服务。
只需在上述的基础上稍作修改,添加maven build插件,正确的引入相关配置即可。
1、把打包方式改为jar包方式,修改packaging的值。
<packaging>jar</packaging>
2、添加build标签。
<build>
<finalName>tlshop</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>
</resource>
<!-- 结合com.alibaba.dubbo.container.Main -->
<resource>
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<!-- <directory>src/main/resources/spring</directory> -->
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>spring-mvc.xml</include>
</includes>
</resource>
</resources>
<!-- <pluginManagement>
<plugins>
解决Maven插件在Eclipse内执行了一系列的生命周期引起冲突
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement> -->
<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>
<useUniqueVersions>false</useUniqueVersions>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3、注意加载配置文件方式,修改spring配置文件。
<import resource="classpath:spring-mybatis.xml" />
<import resource="classpath:spring-dubbo.xml" />
配置完,先在pom.xml中右键run as→maven clear,清理完成,再run as → maven install,即可在target下看到构建的jar包和其他文件。
如果install报jdk版本问题,见关于Maven项目build时出现No compiler is provided in this environment的处理。
如下图:
进target本地文件夹,删除其他文件,只保留jar包和lib文件夹,如下图:
使用windows窗口命令类启动运行这个jar包,cmd进target目录,运行
java -jar tlshop.jar &
需本地java环境,运行如下图:
运行成功,再次进入到dubbo-admin监控平台,可以看到成功发布的服务:
上述是在windows环境下,接下来,使用linux运行maven构建的可执行jar包,先安装虚拟机,配置好网络,可见本人博客vmware虚拟机安装和配置网络。
现在linux下安装好一个tomcat,方法可见这里,用于运行dubbo-admin监控平台。把tomcat和dubbo-admin拷贝至linux中,并且在linux中安装好zookeeper。
安装zookeeper只需要把zookeeper包拷贝进linux,如图:
拷贝zoo.cfg文件,修改值:
创建文件夹:
mkdir /tmp/zookeeper
mkdir /tmp/zookeeper/data
mkdir /tmp/zookeeper/log
配置环境变量:
export ZOOKEEPER_INSTALL=/root/zookeeper/zookeeper-3.3.6/
export PATH=$PATH:$ZOOKEEPER_INSTALL/bin
启动zookeeper,进入zookeeper的bin目录,运行启动脚本:
运行zookeeper成功之后,再来启动tomcat,跑dubbo-admin,把dubbo-admin拷贝进tomcat的webapps目录下,直接启动tomcat:
启动tomcat成功。
在浏览器中查看dubbo-admin运行效果:
运行成功,可以看到暂时没有任何服务。
接下来在linux中运行maven构建的可执行jar包,把maven构建好的tlshop.jar包和lib目录拷贝进linux中:
启动操作与windows下一致,使用java -jar tlshop.jar &就可以启动,启动成功后可以在dubbo-admin中看到发布的服务,也可以使用脚本来一键启动。