zoukankan      html  css  js  c++  java
  • Dubbo与Zookeeper开发(Spring版)

    1.Dubbo

    1.1RPC

    RPC全称是remote procedure call,即远程过程调用。比如有两台服务器A和B,它们上面分别部署了一个服务。此时B服务器想调用A服务器上提供的方法,由于不在同一台服务器,就不能直接调用,那就需要通过网络的方式来表达调用的语义和传达调用的数据。需要注意的是它不是一种技术,而是远程过程调用。

    1.2Dubbo基本介绍

    官网:http://dubbo.apache.org
    Dubbo是一个高性能的java RPC框架。它的三大核心能力是:面向接口的远程方法调用、智能容错和负载均衡、服务自动注册与发现。

    SOA(Service-Oriented Architecture)是一种面向服务的架构。它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来.

    Dubbox 是一个分布式服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbox这样的分布式服务框架的需求。

    1.3调用过程

    调用过程图如下:

    调用过程说明:(数字代表调用顺序,与图对应)

    0.服务容器负责启动、加载、运行服务提供者。
    1.服务提供者在启动时,向注册中心注册自己提供的服务。
    2.服务消费者在启动时,向注册中心订阅自己所需的服务。
    3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
    4.服务消费者从提供者地址列表中,基于软负载均衡算法,选一台提供者通过网络进行调用,如果调用失败,再选另一台调用。
    5.在调用过程中,监控中心会时刻监控调用的情况。

    在调用的过程中,可以发现需要一个注册中心,Dubbo官方推荐使用Zookeeper作为注册中心。

    2.Zookeeper

    2.1Zookeeper简介

    Zookeeper是一个基于观察者模式而设计的分布式服务管理框架。它负责存储和管理数据,接受观察者的注册,一旦这些数据发生变化,就通知已经注册的观察者做出相应的操作。
    简单来说,它就是一个注册中心。换句话说,注册中心是负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。

    2.2特点与应用场景

    2.2.1特点

    1)集群中只要有半数以上节点存活,集群就可以正常服务。
    2)全局数据一致。即每个服务器保存一份相同的数据副本。
    3)数据更新原子性。

    2.2.2应用场景

    统一命名服务、统一配置管理、统一集群管理、服务器动态上下线、软负载均衡。

    2.3下载与安装

    2.3.1下载

    官网下载:http://Zookeeper.apache.org/releases.html ,下载需要的版本即可。Windows和Linux都是使用tar.gz类型的压缩包。

    2.3.2在Linux上安装

    在安装之前默认linux中已安装了JDK。

    1)把 zookeeper 的压缩包上传到 linux 系统,这里以3.6.0版本为例。

    2)解压到指定目录

    tar -zxvf zookeeper-3.6.0.tar.gz -C /usr/local

    3)进入 zookeeper-3.4.6 目录,创建 data 文件夹。

    cd zookeeper-3.6.0
    mkdir data

    4)进入conf目录 ,把 zoo_sample.cfg 改名为 zoo.cfg

    cd conf
    mv zoo_sample.cfg zoo.cfg

    5)打开zoo.cfg ,  修改 dataDir路径为data所在路径

    vi zoo.cfg
    #dataDir修改属性如下
    dataDir=/usr/local/zookeeper-3.4.6/data

    6)启动zookeeper服务

    cd ..
    bin/zkServer.sh start

    输出以上内容表示启动成功

    7)关闭服务:

    bin/zkServer.sh stop

    8)查看状态:

    bin/zkServer.sh status

    如果启动状态,提示

    如果未启动状态,提示

    9)启动客户端

    bin/zkCli.sh

    10)查看注册的服务

    ls /

    11)退出客户端

    quit

    2.3.3在Windows上安装

    1)把 zookeeper 的压缩包进行解压

    2)进入 zookeeper-3.4.6 目录,创建 data 文件夹。

    3)进入conf目录 ,把 zoo_sample.cfg复制一份,把复制的文件改名为 zoo.cfg

    4)打开zoo.cfg ,  修改 dataDir路径为data所在路径

    5)进入bin目录,双击zkServer.cmd即可启动服务端

     启动成功如下所示

    6)进入bin目录,双击zkCli.cmd即可启动客户端

     客户端是用来测试服务端启动情况的,一般只开启服务端进行服务的注册和发现。

    2.3.4参数配置解读

    tickTime=5000 通信心跳数,Zookeeper服务器与客户端的心跳时间(ms)
    initLimit=10 LF初始通信时限。即集群中跟随者与领导者服务器之间初始连接时最多能容忍的心跳数。
    syncLimit=5 LF同步通信时限。即集群中跟随者与领导者服务器之间的最大响应时间单位。
    clientPort=2181 客户端端口号
    dataDir 数据文件目录+数据持久化路径
    

    2.4Zookeeper内部原理

    2.4.1选举机制

    1)半数机制:集群中半数以上机器存活,那么集群就可以正常服务(主要是根据myid中尽可能大的进行选举)。故Zookeeper适合安装奇数台服务器。
    2)选举流程
    目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:
    服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking(选举状态)。
    服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
    服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
    服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为小弟。
    服务器5启动,给自己投票,同时与之前启动的服务器1,2,3,4交换信息,尽管服务器5的编号大,但之前服务器3已经胜出,所以服务器5只能成为小弟。

    2.4.2Zookeeper的监听器原理

    1)首先有一个主线程,它会在主线程中创建Zookeeper客户端,那么就会创建两个线程,一个负责网络连接通信(connect),一个负责监听(listener);
    2)通过connect线程把注册的监听事件发送给Zookeeper;
    3)把注册的监听事件添加到Zookeeper的监听器列表中;
    4)Zookeeper监听到有数据或路径变化就会把这个消息发送给listener线程,listener线程内部调用process()方法。

    2.4.3Zookeeper面试题

    Zookeeper的部署方式:单机和集群;
    集群的角色:Loader和Follower;
    集群的最少机器数:3

    3.结合spring开发

    项目地址:https://github.com/zhongyushi-git/dubbo-demo.git

    3.1服务提供者开发

    1)新建一个空项目,名为dubbo-demo,然后在这个空项目中创建一个maven的web工程(名为dubbo-provider)作为服务提供者。

    2)在pom.xml中导入相关的依赖和插件。需要注意的是Zookeeper的版本必须和导入的dubbo依赖的版本一致。(版本不一致,这是一个大坑)。

     <!--指定版本-->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <spring.version>5.0.5.RELEASE</spring.version>
        </properties>
        <dependencies>
            <!-- Spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- dubbo -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.0</version>
            </dependency>
            <!-- zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.7</version>
            </dependency>
            <dependency>
                <groupId>com.github.sgroschupf</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.1</version>
            </dependency>
            <dependency>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.11.0.GA</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <!-- 指定端口 -->
                        <port>8081</port>
                        <!-- 请求路径 -->
                        <path>/</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>

    3)在webapp/WEB-INF/web.xml中配置spring容器

    <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <!-- 加载spring容器 -->
        <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>

    4)在mian目录下新建java和resources的资源目录,然后在java目录成绩包com.zys.dubbo。

    5)创建业务接口

    创建包com.zys.dubbo.service,用于存放业务接口。

    package com.zys.dubbo.service;
    
    public interface UserService {
        public String getName();
    }

    6)创建业务实现类

    创建包com.gh.dubbodemo.service.impl ,用于存放业务实现类。

    package com.zys.dubbo.service.impl;
    
    import com.alibaba.dubbo.config.annotation.Service;
    import com.zys.dubbo.service.UserService;
    
    @Service
    public class UserServiceImpl implements UserService {
        @Override
        public String getName() {
            return "success";
        }
    }

    注意:Service注解与原来不同,需要引入com.alibaba包下的。

    7)创建配置文件applicationContext-service.xml

    在src/main/resources下创建applicationContext-service.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:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--指定dubbo应用的名称-->
        <dubbo:application name="dubbo-provider"/>
        <!--指定服务的注册中心-->
        <dubbo:registry address="zookeeper://192.168.10.128:2181"/>
        <!--配置协议和端口-->
        <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
        <!--指定服务的包扫描-->
        <dubbo:annotation package="com.zys.dubbo.service.impl"/>
    </beans>

    3.2服务消费者开发

    1)在空项目中再创建一个maven的web工程(名为dubbo-consumer)作为服务消费者。

    2)在pom.xml中导入相关的依赖和插件。

    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <spring.version>5.0.5.RELEASE</spring.version>
        </properties>
    
        <dependencies>
            <!-- Spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- dubbo -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.0</version>
            </dependency>
            <!-- zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.7</version>
            </dependency>
            <dependency>
                <groupId>com.github.sgroschupf</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.1</version>
            </dependency>
            <dependency>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.11.0.GA</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <!-- 指定端口 -->
                        <port>8082</port>
                        <!-- 请求路径 -->
                        <path>/</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>

    3)在webapp/WEB-INF/web.xml中配置servlet

    <web-app>
        <display-name>Archetype Created Web Application</display-name>
    
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext-web.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    </web-app>

    4)在mian目录下新建java和resources的资源目录,然后在java目录成绩包com.zys.dubbo。

    5)创建业务接口

    创建包com.zys.dubbo.service,用于存放业务接口。

    package com.zys.dubbo.service;
    
    public interface UserService {
        public String getName();
    }

    6)编写Controller 

    创建包com.zys.dubbo.controller

    package com.zys.dubbo.controller;
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.zys.dubbo.service.UserService;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        //调用远程接口
        @Reference
        private UserService userService;
    
        @RequestMapping("/get")
        @ResponseBody
        public String showName(){
            return userService.getName();
        }
    }

    7)创建配置文件applicationContext-web.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:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <mvc:annotation-driven >
            <mvc:message-converters register-defaults="false">
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <constructor-arg value="UTF-8" />
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        <!-- 引用dubbo 服务 -->
        <dubbo:application name="dubbo-comsumer" />
        <dubbo:registry address="zookeeper://192.168.10.128:2181"/>
        <dubbo:annotation package="com.zys.dubbo.controller" />
    </beans>

    3.3测试运行

    在maven插件中运行tomcat插件。先启动服务提供者,再启动消费者。然后在浏览器输入http://127.0.0.1:8082/user/get.do可访问成功。

    3.4配置参数解读

    3.4.1启动时检查

    在测试运行时,是先启动服务提供者再启动的服务消费者,但是如果先启动服务消费者,就会报错。原因是在启动服务消费者的时候,它会去检查依赖的服务是否可用,由于没有服务提供者,就会抛出异常。如何解决这个 问题呢?只需要在消费者的配置文件(applicationContext-web.xml)中设置check为false即可,默认值是true。

    <dubbo:consumer check="false"/>

    3.4.2负载均衡

    负载均衡:将请求分摊到多个操作单元上执行,共同完成任务。

    在集群中,Dubbo的均衡策略包括随机,轮询、最少活跃调用数和一致性Hash,默认是随机策略。可以在服务提供者设置均衡策略,也可以在服务消费者这是均衡策略。

    1)在服务提供者中设置

    @Service(loadbalance = "random")
    public class UserServiceImpl implements UserService {
        @Override
        public String getName() {
            return "success";
        }
    }

    2)在服务消费者中设置

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        //调用远程接口
        @Reference(loadbalance = "random")
        private UserService userService;
    
        @RequestMapping("/get")
        @ResponseBody
        public String showName(){
            return userService.getName();
        }
    
    }

    4.Dubbo管理控制台安装

    4.1下载

    github:https://github.com/apache/dubbo。在code中下载压缩包

    网盘:链接:https://pan.baidu.com/s/1E7-YZiveKjk1xgDwO5Bp4w   提取码:sdl8 

    4.2打包运行

    1)打包

    如果从github下载,那么下载的是代码,需手动打包。解压后,在根目录里有dubbo-admin目录,进入此目录,执行打包命令

    mvn install -Dmaven.test.skip=true

    会在target目录生成dubbo-admin-2.6.0.war。网盘下载的就是打包后的war文件。

    2)运行

    把war包直接放到tomcat的webapps下,然后启动tomcat即可。这里把它部署到本地的tomcat中。需要注意的是,如果控制台和Zookeeper不是在同一台 服务器上,那么在启动tomcat的过程中会报错。这时需要修改dubbo-admin项目的WEB-INF/dubbo.properties 文件,把下面的ip换成Zookeeper服务器的ip即可。

    dubbo.registry.address=zookeeper://127.0.0.1:2181

    修改之后重启tomcat。

    4.3基本使用

    (1)启动tomcat后在浏览器输入http://localhost:8080/dubbo-admin-2.6.0 ,登录用户名和密码均为root 进入首页。

    (2)启动服务提供者工程,即可在服务治理-提供者查看到该服务。

    (3)启动服务消费者工程,运行页面,观察“消费者”列表

     有多少个服务注册进来就有多少条数据。

    就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
  • 相关阅读:
    canvas+js绘制序列帧动画+面向对象
    canvas+js画饼状图
    CSS3 文本溢出问题
    jquery 实现省市二级联动
    jquery将json数据放入表格当中
    css ie6双倍margin现象
    css margin塌陷问题
    css ie浏览器兼容问题
    css 实现文字图片垂直对齐
    css 清楚浮动三种方法
  • 原文地址:https://www.cnblogs.com/zys2019/p/12623091.html
Copyright © 2011-2022 走看看