9、Spring技术栈-整合dubbo、zookeeper

来源:互联网 发布:数据库工程师做什么 编辑:程序博客网 时间:2024/05/21 21:47

在我们的Spring Web开发实战的前8篇文章中,我们详细介绍了使用Spring从0开始搭建一个项目并整合log4j2、整合MyBatis,使用hibernate-validator进行服务端数据验证、使用Spring Session管理服务端会话以及过滤器、拦截器的使用。通过前面的文章我们大致可以完成一个简单系统的实现。但是出于学习的目的,我们需要不停的完善系统,不停的学习新的东西以充实自己。此文我们将介绍如何整合Spring、dubbo、zookeeper进行分布式系统的开发。

关于分布式系统的设计概念,可参考分布式系统设计理念。

1、zookeeper的安装与介绍

关于zookeeper,我们已经有一些列的文章对其进行介绍,zookeeper请直接参考Zookeeper系列,但是在我们的开发环境中(windows),我们需要下载zookeeper包,解压并点击bin目录下的zkServer.cmd即可在本地windows环境运行。

这里写图片描述

zookeeper默认端口号为2181,但是读者可以自行进行个性化配置,配置文件在conf目录下,具体参数的解释以及如何配置,也可参考Zookeeper系列。

2、Spring整合dubbo、zookeeper

首先我们现在父级项目的pom.xml文件中先定义我们需要整合的dubbo、zookeeper的版本(可直接到GitHub下载源码)。

<dubbo_version>2.5.5</dubbo_version><zkclient_version>0.10</zkclient_version>

2.1. 开发服务提供方

我们以用户服务为例来阐述服务提供方的开发过程。

首先,使用dubbo,我们需要为每一个服务提供一个接口,服务的消费方通过该接口调用服务。以用户服务为例,我们需要新建一个UserBaseFacade接口,这个接口服务的消费方和服务的提供方公用。

public interface UserBaseFacade {    /**     * @Comment 检查邮箱是否存在     * @Author Ron     * @Date 2017年8月31日 下午5:18:09     * @return     */    boolean checkEmail(String email);}

1、新建一个blog_user_service模块,新建方式请参考Spring技术栈-博客系统基础架构。

2、该模块依赖blog_dao(数据库交互)、blog_facade(接口模块)、dubbo、zkclient;

pom.xml配置如下:

<!--依赖blog-dao模块 --><dependency>    <groupId>ron.blog</groupId>    <artifactId>blog_dao</artifactId>    <version>${project.version}</version></dependency><!--依赖blog-facade模块 --><dependency>    <groupId>ron.blog</groupId>    <artifactId>blog_facade</artifactId>    <version>${project.version}</version></dependency><!-- dubbo --><dependency>    <groupId>com.alibaba</groupId>    <artifactId>dubbo</artifactId>    <version>${dubbo_version}</version></dependency><!-- zookeeper --><dependency>    <groupId>com.101tec</groupId>    <artifactId>zkclient</artifactId>    <version>${zkclient_version}</version></dependency>

3、开发并配置服务

新建服务实现类UserBaseService并实现UserBaseFacade接口;

/** * @Comment 用户服务,必须指定服务名称 * @Author Ron * @Date 2017年9月26日 下午3:45:54 * @return */@Component("userService")public class UserBaseService implements UserBaseFacade {    private Logger logger = LogManager.getLogger(this.getClass());    @Autowired    BlogUserBaseDao blogUserBaseDao;    /**     * @Comment 检查邮箱是否存在     * @Author Ron     * @Date 2017年8月31日 下午5:18:28     * @return     */    @Override    public boolean checkEmail(String email) {        if (blogUserBaseDao.checkEmail(email) > 0) {            return true;        }        return false;    }}

在config.properties文件中增加zookeeper地址的配置:

#zookeeper配置registry.address=127.0.0.1:2181

在resources目录新建dubbo/dubbo.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"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">    <dubbo:application name="blog-user-service" logger="log4j"/>    <dubbo:registry protocol="zookeeper" address="${registry.address}"/>       <dubbo:monitor protocol="registry"></dubbo:monitor>    <dubbo:protocol name="dubbo" port="20881" />    <dubbo:provider timeout="30000" loadbalance="random" >        <dubbo:parameter key="shutdown.timeout" value="60000" />        <dubbo:parameter key="shutdown.hook"    value="true" />        <dubbo:parameter key="retries"          value="0" />    </dubbo:provider>    <!-- 声明需要暴露的服务 -->    <dubbo:service interface="ron.blog.blog_facade.user.UserBaseFacade" ref="userService"/></beans>

在spring-context.xml文件中导入dubbo.xml配置

<import resource="classpath:dubbo/dubbo.xml" />

4、启动服务

新建一个服务启动器,我们这里新建一个类UserServiceProvider,通过这个类加载Spring配置文件并启动服务:

public class UserServiceProvider{    private static final Logger LOG = LogManager.getLogger(UserServiceProvider.class);    public static final String DUBBO_PROVIDER = "classpath:spring-context.xml";    private static void init() {        LOG.info("开始启动dubo服务,载入的配置服务提供文件为[" + DUBBO_PROVIDER + "]");        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(DUBBO_PROVIDER);        context.registerShutdownHook();        context.start();        LOG.info("【tfs-service-user】启动完毕!");    }    public static void main(String[] args) {        init();        while (true) {            try {                Thread.currentThread();                Thread.sleep(3L);            } catch (Exception e) {                e.printStackTrace();            }        }    }}

至此,服务提供方开发完毕。

2.2. 修改blog_pc作为服务消费方

服务消费方,需要配置blog_facade、dubbo和zookeeper的依赖

<!-- 添加对Facade的依赖 --><dependency>    <groupId>ron.blog</groupId>    <artifactId>blog_facade</artifactId>    <version>${project.version}</version></dependency> <!-- dubbo --><dependency>    <groupId>com.alibaba</groupId>    <artifactId>dubbo</artifactId>    <version>${dubbo_version}</version></dependency><!-- zookeeper --><dependency>    <groupId>com.101tec</groupId>    <artifactId>zkclient</artifactId>    <version>${zkclient_version}</version></dependency>

依赖配置完成之后,在resources目录下新建dubbo目录,在dubbo目录下新建dubbo_consumer.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"    xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"    xsi:schemaLocation="     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd     http://code.alibabatech.com/schema/dubbo     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->    <dubbo:application name="ron_blog_consumer" />    <context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties" />    <!-- 使用zookeeper注册中心暴露服务地址 -->    <dubbo:registry protocol="zookeeper" address="${registry.address}" />    <!-- 用户相关服务 -->    <dubbo:reference id="userService"  interface="ron.blog.blog_facade.user.UserBaseFacade" /></beans>

在spring-context.xml文件中导入服务消费配置文件:

<!-- 导入dubbo消费者配置 --><import resource="classpath:dubbo/dubbo_consumer.xml" />

Ok,所有准备工作已经完成,如何运行该应用呢?

  1. 启动zookeeper
  2. 启动Redis(我们使用了Spring Session with Redis,Session都保存在了Redis中)
  3. 运行UserServiceProvider启动服务
  4. 运行blog_pc启动网站

如果运行成功,那么祝贺您,您已经启动了您的第一个分布式应用。

项目源码:https://github.com/Ron-Zheng/blog-system-distribute