zoukankan      html  css  js  c++  java
  • Dubbo 基础教程

    一、Duboo基本概念解释

      Dubbo是一种分布式服务框架。 Webservice也是一种服务框架,但是webservice并不是分布式的服务框架,他需要结合F5实现负载均衡。因此,dubbo除了可以提供服务之外,还可以实现软负载均衡。它还提供了两个功能Monitor 监控中心和调用中心。这两个是可选的,需要单独配置

    Dubbo的计数架构图如下:

    调用关系说明:

    1) 服务容器启动、加载和运行服务提供者;
    2) 服务提供者在启动时,向注册中心注册自己提供的服务;
    3) 服务消费者在启动时,向注册中心订阅自己所需的服务;
    4) 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更给消费者;
    5) 服务消费者从地址列表中,基于软负载均衡算法选一台服务提供者进行调用,如果调用失败再选另一台;
    6) 服务消费者和服务提供者在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

    节点角色说明:

    Dubbo 采用全 Spring 配置方式,透明化接入应用,对应用没有任何 API 入侵,只需用 Spring 加载 Dubbo 配置即可。

    二、dubbo原理

    2.1、初始化过程细节(第一步start,就是将服务装载容器中,然后准备注册服务。和Spring中启动过程类似,spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务)

    解析服务:

    1)、基于dubbo.jar内的Meta-inf/spring.handlers配置,spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler类。 
    2)、所有的dubbo标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。

    说明:在ServiceConfig.export 或者ReferenceConfig.get 初始化时,将Bean对象转会为url格式,将所以Bean属性转成url的参数。 然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露和引用。

    暴露服务:

    a、 只暴露服务端口

    在没有使用注册中心的情况,这种情况一般适用在开发环境下,服务的调用这和提供在同一个IP上,只需要打开服务的端口即可。 
    即,当配置 or 
    ServiceConfig解析出的URL的格式为: 

    Dubbo://service-host/com.xxx.TxxService?version=1.0.0 

    基于扩展点的Adaptiver机制,通过URL的“dubbo://”协议头识别,直接调用DubboProtocol的export()方法,打开服务端口。

    b、向注册中心暴露服务:

    和上一种的区别:需要将服务的IP和端口一同暴露给注册中心。 
    ServiceConfig解析出的url格式为: 

    registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)

    基于扩展点的Adaptive机制,通过URL的“registry://”协议头识别,调用RegistryProtocol的export方法,将export参数中的提供者URL先注册到注册中心,再重新传给Protocol扩展点进行暴露: 

    Dubbo://service-host/com.xxx.TxxService?version=1.0.0

    引用服务:

    a、直接引用服务:

    在没有注册中心的,直连提供者情况下, ReferenceConfig解析出的URL格式为: 

    Dubbo://service-host/com.xxx.TxxService?version=1.0.0

    基于扩展点的Adaptive机制,通过url的“dubbo://”协议头识别,直接调用DubboProtocol的refer方法,返回提供者引用。

    b、从注册中心发现引用服务:

    此时,ReferenceConfig解析出的URL的格式为: 

    registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”)

    基于扩展点的Apaptive机制,通过URL的“registry://”协议头识别,就会调用RegistryProtocol的refer方法,基于refer参数总的条件,查询提供者URL,如: 

    Dubbo://service-host/com.xxx.TxxService?version=1.0.0

    基于扩展点的Adaptive机制,通过提供者URL的“dubbo://”协议头识别,就会调用DubboProtocol的refer()方法,得到提供者引用。 
    然后RegistryProtocol将多个提供者引用,通过Cluster扩展点,伪装成单个提供这引用返回。

    远程调用细节

    1、服务提供者暴露服务的主过程:

    首先ServiceConfig类拿到对外提供服务的实际类ref,然后将ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到invoker的转化。接下来就是Invoker转换到Exporter的过程。 
    Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程,下面我们以Dubbo和rmi这两种典型协议的实现来进行说明: 
    Dubbo的实现: 
    Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由dubbo自己实现。 
    Rmi的实现: 
    RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,他通过Spring或Dubbo或JDK来实现服务,通讯细节由JDK底层来实现

    2、服务消费的主过程:

    ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例。接下来把Invoker转为客户端需要的接口

    三、快速入门

    3.1 安装注册中心

    官方推荐使用 Zookeeper 作为注册中心,因此本次测试使用 Zookeeper,将其放置在 ip 为 192.168.2.14 的虚拟机上

    # 解压和转移目录
    tar -zxvf zookeeper-3.4.8.tar.gz -C /usr/
    cd /usr
    mv zookeeper-3.4.8 zookeeper
    # 设置配置文件
    cd /usr/zookeeper/conf
    cp zoo_sample.cfg zoo.cfg
    # 启动 zookeeper
    /usr/zookeeper/bin/zkServer.sh start
    # 查看 zookeeper 运行状态,如果出现 Mode: standalone 说明运行成功
    /usr/zookeeper/bin/zkServer.sh status

    3.2 服务提供者

    创建一个 Maven 项目(名为 dubbo-service 的 web 项目)。

    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.light</groupId>
      <artifactId>dubbo-service</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      
      <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.9</version>
        </dependency>
      </dependencies>
    </project>

     web.xml 配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">
        <display-name>dubbo-service</display-name>
        
        <!-- spring容器 start -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-dubbo.xml</param-value>
        </context-param>
        <!-- spring容器 end -->
        
    </web-app>

    接口:

    public interface HelloService {
        String sayHello(String name);
    }

     applicationContext-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="hello-demo"/>
           
        <dubbo:registry address="zookeeper://192.168.2.14:2181"/>
        
        <dubbo:protocol name="dubbo" port="20880"/>
        
        <dubbo:service interface="com.light.dubbo.service.HelloService" ref="helloService"/>
        
        <bean id="helloService" class="com.light.dubbo.service.impl.HelloServiceImpl"/>
        
    </beans>

    3.3 服务消费者

     创建一个 Maven 项目(名为 dubbo-consumer 的 web 项目)

     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.light</groupId>
        <artifactId>dubbo-consumer</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.3</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.0</version>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.9</version>
            </dependency>
        </dependencies>
    </project>

     web.xml 配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">
        <display-name>dubbo-consumer</display-name>
        
        <!-- spring容器 start -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-dubbo.xml</param-value>
        </context-param>
        <!-- spring容器 end -->
        
        <!-- springmvc容器 start -->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <!-- springmvc容器 end -->
        
    </web-app>

     将 dubbo-service 项目中的 HelloService 接口复制到该项目(dubbo-consumer)中。

     控制层:

    @Controller
    public class HelloController {
        @Autowired
        private HelloService helloService;
        
        @RequestMapping("hello")
        @ResponseBody
        public String hello(String name) {
            return this.helloService.sayHello(name);
        }
    }

     applicationContext-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="hello-demo"/>
           
        <dubbo:registry address="zookeeper://192.168.2.14:2181"/>
        
        <dubbo:protocol name="dubbo" port="20880"/>
        
        <dubbo:reference interface="com.light.dubbo.service.HelloService"/>
        
    </beans>

    springmvc.xml 配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
                            http://www.springframework.org/schema/context  
                            http://www.springframework.org/schema/context/spring-context-4.0.xsd">
                            
          <!-- 只扫描含有@Controller注解的类 -->                     
          <context:component-scan base-package="com.light.dubbo.controller">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
          </context:component-scan>
          
          <!-- 加载解析 @rquestMapping等注解的解析器 -->
          <mvc:annotation-driven/>
          
    </beans>

    先启动服务提供者的项目(8080),再启动服务消费者的项目(8081)。打开浏览器访问http://localhost:8081/hello?name=jack,结果如下图:

    四、监控

    4.1 获取源码

    git clone --branch dubbo-2.6.0 https://github.com/alibaba/dubbo.git

     下载完成后使用 IDE 工具引入其子项目 dubbo-sample\dubbo-monitor-sample 进行编译和打包。打包后会在项目的 target 目录下生成 dubbo-monitor-simple-2.6.0-assembly.tar.gz 压缩文件。

    4.2 修改配置

    1) 解压 dubbo-monitor-simple-2.6.0-assembly.tar.gz 压缩包,修改 dubbo-monitor-simple-2.6.0\conf\dubbo.properties:

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

     2) 在服务提供者的配置文件中添加:

    <!-- 注册中心自动查找监控服务 -->
    <dubbo:monitor protocol="registry"/>

     最后启动 dubbo-monitor-simple-2.6.0\bin\start.bat。打开浏览器访问http://localhost:8080/,效果图如下:

    五、管理控台

    Dubbo 提供了一套在线管理服务的管理控制台,该管理控制台为阿里巴巴内部裁减版本,开源部分主要包含:路由规则、动态配置、服务降级、访问控制、权重调整和负载均衡。

    5.1 获取运行项目

    在第四节下载的 duboo 源码中,通过 IDE 工具引入其子项目 dubbo-admin 进行编译和打包。
    打包后会在项目的 target 目录下生成 dubbo-admin-2.6.0.war 压缩文件。

    5.2 修改配置

    将 dubbo-admin-2.6.0.war 里边的文件和文件夹复制粘贴到 tomcat 的 ROOT 目录中并修改 webapps\ROOT\WEB-INF\dubbo.properties 文件内容:

    dubbo.registry.address=zookeeper://192.168.2.14:2181
    dubbo.admin.root.password=root
    dubbo.admin.guest.password=guest

    其中,配置中设置 2 个用户:root 和 guest。

    最后启动 tomcat 容器,打开浏览器访问http://localhost:8080/,页面要求输入账号和密码,登录后效果图如下:

    六、参考资料

        http://dubbo.apache.org/

  • 相关阅读:
    8.3.ZooKeeper集群安装配置
    Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)
    Shiro 学习
    JavaWeb项目:Shiro实现简单的权限控制(整合SSM)
    权限管理——权限模型和权限控制
    Java程序员面试题集(151-180)
    Java面试题集(136-150)
    Java面试题集(131-135)
    Java面试题集(116-135)
    Java面试题集(1-50)
  • 原文地址:https://www.cnblogs.com/PollyLuo/p/8612764.html
Copyright © 2011-2022 走看看