13、Spring技术栈-整合dubbo、zookeeper实现高可用分布式微服务实战

在Spring技术栈-整合dubbo、zookeeper一文中我们已经讲述了如何整合Spring、dubbo、zookeeper来开发一个分布式的应用。本文在上文的基础上来描述如何打包部署dubbo微服务,实现一个高可用的微服务集群,如果不知道如何整合Spring、dubbo、zookeeper,请读者先阅读上文,然后再阅读此文进行微服务的打包和部署操作。

准备工作

我们假设读者已经在自己的环境中安装了maven,java jdk等必须的基础软件,本文不会讲述如何安装这些基础构件,只描述部署dubbo微服务的打包、部署、运行测试方案。

安装虚拟机3台,笔者安装虚拟机使用的是VirtualBox,读者可根据自己的环境具体分析,安装完成虚拟机之后,要确保虚拟机和宿主机之间能够进行网络通讯。

IP 备注 开放端口
192.168.199.177(宿主机) MySQL是安装在宿主机 3306(需要添加入站规则,将3306端口开放,否则虚拟机无法链接MySQL)
192.168.199.161(虚拟机) zookeeper注册中心 2181
192.168.199.249(虚拟机) 服务主机 20882
192.168.199.126(虚拟机) 服务主机 20882

以上是笔者机器上所安装的虚拟机信息,仅供参考,读者可根据自己的具体环境具体安装。

实例介绍

我们以开发一个博客服务为例,用户在访问博客列表时,我们一开始启动两个服务实例注册到Zookeeper,然后让其中一个服务宕机,然后测试博客列表是否能够正常访问。

服务接口

public interface BlogFacade {
    /**
     * @Comment 获取博客列表
     * @Author Ron
     * @Date 2017年10月25日 下午2:53:39
     * @return
     */
    List findBlogList(BlogContent blogContent);

    /**
     * @Comment 获取博客内容
     * @Author Ron
     * @Date 2017年10月25日 下午3:04:57
     * @return
     */
    BlogContent getBlog(String bid);
}

服务实现

新建一个blog_service项目,新建BlogService实现以上接口

@Component("blogService")
public class BlogService implements BlogFacade{

    private Logger logger = LogManager.getLogger(this.getClass());

    @Autowired 
    private BlogContentMapper blogContentMapper;

    @Autowired  
    RedisUtils redisUtils;  

    /**
     * @Comment 获得博客列表
     * @Author Ron
     * @Date 2017年10月25日 下午3:04:01
     * @return
     */
    @Override
    public List findBlogList(BlogContent blogContent) {
        logger.info("进入博客查询列表");
        try {
            return blogContentMapper.selectList(blogContent);
        } catch (Exception e) {
            logger.error("访问博客列表失败"+e);
            return null;
        }
    }

    /**
     * @Comment 获取博客内容
     * @Author Ron
     * @Date 2017年10月25日 下午3:05:27
     * @return
     */
    @Override
    public BlogContent getBlog(String bid) {
        if(redisUtils.exists(bid)){
            logger.info("缓存命中博客"+bid);
            return (BlogContent) redisUtils.get(bid);
        }else{
            logger.info("缓存尚未命中博客"+bid);
            BlogContent blogContent = blogContentMapper.selectByPrimaryKey(bid);
            redisUtils.set(bid, blogContent);
            return blogContent;
        }
    }
}

在服务实例中我们用到了Redis做缓存,读者可参考12、Spring技术栈-Redis Sentinel实战一文了解如何使用Redis实现缓存集群。

其中blogContentMapper是通过整合Mybatis访问MySQL的映射类,关于如何整合Mybatis,读者可参考2、Spring技术栈-整合Mybatis

Dubbo 服务提供方配置

在resources目录增加dubbo目录,新建dubbo.xml,写入如下内容


<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="ron-service-blog" logger="log4j"/>

    <dubbo:registry protocol="zookeeper" address="${registry.address}"/>   

    <dubbo:monitor protocol="registry"/>

    <dubbo:protocol name="dubbo" port="${service.port}" serialization="java" />

    <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.blog.BlogFacade" ref="blogService" />
beans>

config.properties配置

在配置文件中,增加zookeeper地址和端口以及服务端口的配置。

#zookeeper配置
registry.address=192.168.199.161:2181
service.port=20882

微服务项目pom.xml配置

在服务的pom.xml文件中除了添加dubbo和zookeeper客户端的依赖之外,我们还需要添加一些maven插件,帮助我们在使用maven打包项目时能够拷贝依赖的jar包和相关的资源文件到指定的目录。同时因为我们开发的微服务一般情况家都是一个jar包,所以我们需要这个jar包能够单据运行,所以我们也需要在pom文件中指定main函数(程序入口)的位置。具体的配置如下:

dubbo_version:2.8.4a
zkclient_version:0.10

    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>dubboartifactId>
        <version>${dubbo_version}version>
    dependency>
    
    <dependency>
        <groupId>com.101tecgroupId>
        <artifactId>zkclientartifactId>
        <version>${zkclient_version}version>
    dependency>
    <build>
        <finalName>ron-service-blogfinalName>
        <resources>
            
            <resource>
                <targetPath>${project.build.directory}/classestargetPath>
                <directory>src/main/javadirectory>
                <filtering>truefiltering>
                <includes>
                    <include>**/*.xmlinclude>
                includes>
            resource>
            <resource>
                
                <targetPath>${project.build.directory}/classestargetPath>
                <directory>src/main/resourcesdirectory>
                <filtering>truefiltering>
                <includes>
                    <include>**/*.xmlinclude>
                    <include>**/*.propertiesinclude>
                includes>
            resource>
            <resource>
                
                <targetPath>${project.build.directory}/classes/META-INF/springtargetPath>
                <directory>src/main/resources/directory>
                <filtering>truefiltering>
                <includes>
                    <include>spring-context.xmlinclude>
                includes>
            resource>
        resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-jar-pluginartifactId>
                <configuration>
                    <classesDirectory>target/classes/classesDirectory>
                    <archive>
                        <manifest>
                            <mainClass>com.alibaba.dubbo.container.MainmainClass>
                            <useUniqueVersions>falseuseUniqueVersions>
                            <addClasspath>trueaddClasspath>
                            <classpathPrefix>lib/classpathPrefix>
                        manifest>
                        <manifestEntries>
                            <Class-Path>.Class-Path>
                        manifestEntries>
                    archive>
                configuration>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-dependency-pluginartifactId>
                <executions>
                    <execution>
                        <id>copy-dependenciesid>
                        <phase>packagephase>
                        <goals>
                            <goal>copy-dependenciesgoal>
                        goals>
                        <configuration>
                            <type>jartype>
                            <includeTypes>jarincludeTypes>
                            <outputDirectory>
                                ${project.build.directory}/lib
                            outputDirectory>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>

Dubbo消费者配置

在web端的resources目录下新建dubbo目录,添加dubbo.xml文件,写入如下内容。


<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="blog-service" />

    <context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties" />

    
    <dubbo:registry protocol="zookeeper" address="${registry.address}" />

    <dubbo:consumer check="false" />

    
    <dubbo:reference id="blogService"  interface="ron.blog.blog_facade.blog.BlogFacade" />
beans>

其中配置参数都添加到config.properties中,内容如下

#zookeeper配置
registry.address=192.168.199.161:2181

打包blog_service微服务

在命令行工具中,进入项目pom.xml文件目录,执行以下命令进行打包

mvn clean
mvn package -Dmaven.test.skip=true

等待打包完成之后,我们在项目的target目录先会看到一个*.jar包和一个lib文件夹,部署时只需要上传jar包和lib文件夹即可。

13、Spring技术栈-整合dubbo、zookeeper实现高可用分布式微服务实战_第1张图片

安装和配置zookeeper

安装zookeeper作为服务的注册中心,本文将zookeeper安装在192.168.199.161这台虚拟机上,zookeeper安装参见Zookeeper精要-standalone模式,本文主要描述的是服务的高可用,注册中心我们采用单点即可。

注意:服务所指定的注册中心的地址和端口必须是您所安装的zookeeper所在的虚拟机地址和端口。

#zookeeper配置
registry.address=192.168.199.161:2181
#服务端口
service.port=20882

部署服务

我们假设读者已经在自己的虚拟机上安装了java环境,所以这里就不说明如何安装java环境。

在服务主机(笔者的服务主机是192.168.199.126、192.168.199.249)新建一个目录,用于存放服务相关文件。

mkdir /data/blogSrv

通过ftp工具将打包好的内容上传到该目录,笔者使用的是filezilla.exe。文件上传完成之后,编写启动脚本。

新建start.sh,文件,写入启动脚本。

cd /data/blogSrv
vi start.sh

在start.sh中写入如下内容

#!/bin/bash
nohup java -jar ron-service-blog.jar > nohup.log 2>&1 &

解释一下启动脚本命令的含义:在后台运行服务并将服务的错误流信息作为标准输出流输出到nohup.log文件中。

赋予start.sh脚本读写权限

chmod 777 start.sh

启动服务

在服务主机上使用如下命令分别执行启动脚本启动服务。

cd /data/blogSrv
./start.sh

服务启动成功后,可通过如下命令查看是否启动成功

ps -ef|grep ron-service-blog(这里是jar包的名称)

如果启动成功,您会看到如下内容

[root@localhost blogSrv]# ps -ef|grep ron-service-blog
root      4193     1  0 14:09 pts/0    00:00:29 java -jar ron-service-blog.jar
root      4348  2316  0 15:25 pts/0    00:00:00 grep --color=auto ron-service-blog

如果启动失败,在服务jar包存放的目录会生成一个nohup.log文件,读者可查看该日志文件中的内容查看错误信息并修复。

服务可用性测试

如果两台机器上的服务都成功启动,我们就可以打开我们的服务消费端,亲测博客页面能访问。
13、Spring技术栈-整合dubbo、zookeeper实现高可用分布式微服务实战_第2张图片

接下来我们去到任意一台部署服务的虚拟机,使用kill命令杀掉服务进程,再次刷新页面,博客列表页面依然可用。

这里写图片描述

重新刷新页面

13、Spring技术栈-整合dubbo、zookeeper实现高可用分布式微服务实战_第3张图片

系统源码:http://download.csdn.net/download/zyhlwzy/10122870

你可能感兴趣的:(Spring,Web开发实战,架构师,Zookeeper,Spring,MVC,Spring,Web开发实战专栏)