dubbo+zookeeper+springmvc

一、Dubbo是一个分布式服务框架,解决了上面的所面对的问题,Dubbo的架构如图所示:


节点角色说明:

Provider: 暴露服务的服务提供方。

Consumer: 调用远程服务的服务消费方。

Registry: 服务注册与发现的注册中心。

Monitor: 统计服务的调用次调和调用时间的监控中心。

Container: 服务运行容器。

二、调用关系说明:

0. 服务容器负责启动,加载,运行服务提供者。

1. 服务提供者在启动时,向注册中心注册自己提供的服务。

2. 服务消费者在启动时,向注册中心订阅自己所需的服务。

3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

三、Dubbo与Zookeeper、SpringMVC整合使用

第一步:在Linux上安装Zookeeper
       Zookeeper作为Dubbo服务的注册中心,Dubbo原先基于数据库的注册中心,没采用Zookeeper,Zookeeper一个分布式的服务框架,是树型的目录服务的数据存储,能做到集群管理数据 ,这里能很好的作为Dubbo服务的注册中心,Dubbo能与Zookeeper做到集群部署,当提供者出现断电等异常停机时,Zookeeper注册中心能自动删除提供者信息,当提供者重启时,能自动恢复注册数据,以及订阅请求。

       1)下载Zookeeper-3.4.6.tar.gz  地址http://www.apache.org/dist/zookeeper/

    (2)我们放到Linux下的一个文件夹,然后解压: 
             #tar zxvf zookeeper-3.4.6.tar.gz

    (3)然后在对应的zookeeper-3.4.6/conf 下有一个文件zoo_sample.cfg的这个文件里面配置了监听客户端连接的端口等一些信息,Zookeeper 在启动时会找zoo.cfg这个文件作为默认配置文件,所以我们复制一个名称为zoo.cfg的文件,如图所示:


 

说明:

 clientPort:监听客户端连接的端口。

 tickTime:基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime。

 我们可以对配置文件的端口等或者进行高级配置和集群配置例如:maxClientCnxns:限制连接到 ZooKeeper 的客户端的数量等

 (4)启动Zookeeper 的服务

     

Zookeeper的安装和配置完成

第二步:配置dubbo-admin的管理页面,方便我们管理页面

    (1)下载dubbo-admin-2.4.1.war包,在Linux的tomcat部署,先把dubbo-admin-2.4.1放在tomcat的webapps/ROOT下,然后进行解压:

        #jar -xvf dubbo-admin-2.4.1.war

    (2)然后到webapps/ROOT/WEB-INF下,有一个dubbo.properties文件,里面指向Zookeeper ,使用的是Zookeeper 的注册中心
 

(3)然后启动tomcat服务,用户名和密码:root,并访问服务,显示登陆页面,说明dubbo-admin部署成功,如图所示:

第三步、创建提供者provider工程(使用maven构建)

dubbo.provider项目结构如下图: 
项目构建

导入依赖,pom.xml如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
             http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.soecode</groupId>
    <artifactId>dubbo.provider</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>dubbo.provider Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <!-- Logger日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.4.10</version> 
        </dependency> 

        <!-- zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.3.4</version>
        </dependency>

        <!-- zkclient 用于访问zookeeper -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.3</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>dubbo.provider</finalName>
    </build>
</project>

在service包下创建接口HelloService.java

public interface HelloService {

    /**
     * say hello
     * @param name
     * @return
     */
    public String sayHello(String name);
}

在Service.impl下实现接口HelloServiceImpl.java

@Service("helloServiceImpl")
public class HelloServiceImpl implements HelloService {

    public String sayHello(String name) {
        return "hello,"+name+"!";
    }

}

接下来填写dubbo-provider.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:context="http://www.springframework.org/schema/context"
    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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 注解包扫描位置: 因为这里的实现类使用注解的方式 -->
    <context:component-scan base-package="com.soecode.dubbo.*" />

    <!-- 接入dubbo的应用程序名称 -->
    <dubbo:application name="demo-provider" />

    <!-- 注册仓库地址:zookeeper组件,192.168.61.128:2181 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 用dubbo协议在20880端口暴露服务 -->  
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 
            声明需要暴露的服务接口,
            请注意ref属性中指定的HelloService接口实现类,它并没有在xml文件中定义,而是使用注解的方式在class中定义
     -->
    <dubbo:service interface="com.soecode.dubbo.service.HelloService" ref="helloServiceImpl"/>  
</beans>

到此服务接口已经定义好,接下来要通过main方法读取配置文件,来达到zookeeper服务注册的效果。

创建ProviderApp.java

package com.soecode.dubbo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 服务提供者示例
 * @author antgan
 * @date 2017/1/12
 *
 */
public class ProviderApp {

    public static void main(String[] args) throws Exception {
        //读取配置文件
        new ClassPathXmlApplicationContext(new String[]{"dubbo-provider.xml"});
        System.out.println("provider服务已注册");
        //使线程阻塞
        System.in.read();
    }

}

运行ProviderApp,即可。

如何校验是否成功注册?进入dubbo-admin,点菜单栏上的提供者,如下图就注册成功了,成功暴露接口。 
提供者

第四步、

创建消费者consumer项目

dubbo.consumer项目结构 
项目构建

引入依赖,pom.xml如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.soecode</groupId>
    <artifactId>dubbo.consumer</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>dubbo.consumer Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.4.10</version>
        </dependency>

        <!-- zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.3.4</version>
        </dependency>

        <!-- zkclient -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.3</version>
        </dependency>

        <!-- 引用dubbo.provider -->
        <dependency>
            <groupId>com.soecode</groupId>
            <artifactId>dubbo.provider</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>


        <!-- SpringMVC -->
        <!-- spring web依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!--3: Servlet web 相关依赖 -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>dubbo.consumer</finalName>
    </build>
</project>

配置dubbo-consumer.xml,向zookeeper注册接口

<?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="demo-consumer" />

    <!-- 注册仓库地址:zookeeper组件,192.168.61.128:2181 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 引用的服务,那个interface一定是一个被引入到DUBBO仓库的接口定义 -->
    <dubbo:reference id="helloService" interface="com.soecode.dubbo.service.HelloService"/>  
</beans>

创建ConsumerApp.java,运行测试

package com.soecode.dubbo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.soecode.dubbo.service.HelloService;

/**
 * 消费者示例
 * @author antgan
 * @date 2017/1/12
 *
 */
public class ConsumerApp {
    public static void main(String[] args) throws Exception {
        //读取配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-consumer.xml"});
        //获取在zookeeper注册的服务接口
        HelloService helloService = (HelloService)context.getBean("helloService");
        //调用接口
        System.out.println("HelloService = " + helloService.sayHello("ant"));
        //不让控制台消失,按任意键结束
        System.in.read();
    }
}

运行结果: 
运行结果

我们也可以在dubbo-admin上看一下,如下 
消费者

至此,已经完成了第一部分在main方法模拟调用远程接口

第五步、

consumer引入SpringMVC

dubbo.consumer引入springMVC,pom.xml 添加以下jar包:

<!-- SpringMVC -->
        <!-- spring web依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!--3: Servlet web 相关依赖 -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>

在resource文件夹下创建spring-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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation=" 
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置SpringMVC -->
    <!-- 1:开启SpringMVC注解模式 -->
    <!-- 简化配置:
    1)自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter 
    2) 提供一系列:数据绑定,数字和日期的format等功能,支持xml,json读写-->
    <mvc:annotation-driven/>

    <!--2: 静态资源配置 
    1) 加入静态资源的处理,如js,gif,png
    2)允许使用"/"处理
    -->
    <mvc:default-servlet-handler/>

    <!-- 3: 配置jsp 显示ViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />  <!-- 前缀 -->
        <property name="suffix" value=".jsp" />   <!-- 后缀 -->
    </bean>

    <!-- 4: 扫描web相关的bean -->
    <context:component-scan base-package="com.soecode.dubbo.web"/>

</beans>

修改web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>dubbo.consumer</display-name>

    <!-- 加载dubbo-consumer.xml -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/dubbo-consumer.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <!-- 配置DispatcherServlet -->
    <servlet>
        <servlet-name>dubbo.consumer-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载spring-web.xml -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-web.xml</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dubbo.consumer-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

dubbo.web包下创建HelloController.java

package com.soecode.dubbo.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.soecode.dubbo.service.HelloService;

@Controller
@RequestMapping("hello")
public class HelloController {

    /**
     * 注入远程接口
     */
    @Autowired
    private HelloService helloService;

    /**
     * 调用远程接口,返回index.jsp页面
     * @param model
     * @return
     */
    @RequestMapping("index")
    public String index(Model model){
        model.addAttribute("str", helloService.sayHello("ant"));
        return "index";
    }
}

运行,地址栏输入:http://localhost:8080/dubbo.consumer/hello/index 
运行结果

猜你喜欢

转载自blog.csdn.net/qq_35414397/article/details/84585051
今日推荐