乐趣区

关于dubbo:Dubbo学习记录

RPC 基础知识

软件架构

繁多利用架构

当网站流量很小时,利用规模小时,只需一个利用,将所有的性能都部署在一起,以缩小部署服务数量和老本。此时,用于简化增删改查工作量的数据拜访框架 (ORM) 是要害。数据库的解决工夫影响利用的性能。

这种后果的利用适宜小型零碎、小型网站、或者企业的外部零碎,用户较少,申请量不大,对申请的解决工夫没有太高的要求。将所有性能都部署到一个服务器,简略易用。开发我的项目的难度低。

但毛病也不言而喻:

  1. 性能扩大比拟艰难
  2. 不利于多人同时开发
  3. 不利于降级保护
  4. 整个零碎的空间占用比拟大

分布式服务架构

当利用越来越多,利用之间交互不可避免,将外围业务抽取进去,作为独立的服务,逐步造成稳固的服务中心,是前段利用能更疾速的响应多变的市场需求。此时用于进步业务服用及整合的 分布式服务框架(RPC)是要害。分布式系统将服务作为独立的利用,实现服务共享和重用。

分布式系统

什么是分布式系统

分布式系统是若干独立计算机(服务器)的汇合,这些计算机对于用户来说就像单个相干零碎,分布式系统(distributed system) 是建设在网络之上的服务器端的一种构造。

分布式系统中的计算机能够应用不同的操作系统,能够运行不同应用程序提供服务,将服务扩散部署到多个计算机服务器上。

什么是 RPC

RPC(Remote Procedure Call)是指近程过程调用,是一种过程间通信形式,是一种技术思维,而不是标准。它容许程序调用另一个地址空间(网络的另一台机器上)的过程或函数,而不必开发人员显示编码这个调用的细节。调用本地办法和调用近程办法一样。

RPC 的实现办法能够不同,例如 Java 的 rmispring 近程调用等。

RPC 概念是在上世纪 80 年代由Brue Jay Nelson(布鲁·杰伊·纳尔逊)提出,应用 RPC 能够将本地的调用扩大到近程调用(分布式系统的其余服务器)

RPC 的特点:

  1. 简略:应用简略,建设分布式应用更容易
  2. 高效:调用过程看起来非常清晰,效率高
  3. 通用:过程间通信的形式,有通用的规定

RPC 基本原理

图解
RPC 调用过程
  1. 调用方 client 要应用右侧 server 的性能(办法),发动对办法的调用
  2. client stub 是 RPC 中定义的存根,看做是 client 的助手。stub 把要调用的办法参数进行序列化、办法名称和其余数据包装起来
  3. 通过网络 socket(网络通信的技术),把办法调用的细节内容发送给右侧的 server
  4. server 端通过 socket 承受申请的办法名称、参数等数据,传给 stub.
  5. server 端接到的数据由 server stub(server 的助手)解决,来调用 server 的真正办法、解决业务
  6. server 办法解决完业务,把解决的后果对象(Object)交给了助手,助手把 Object 进行序列化,对象转为二进制数据
  7. server 助手二进制数据交给网络处理程序
  8. 通过网络将二进制数据,发送给 client
  9. client 接到数据,交给 client 助手
  10. client 助手,接管到数据通过反序列化为 Java 对象(Object),作为近程办法调用后果

RPC 通信是基于 tcp 或 udp 协定

序列化办法(xml/json/ 二进制)

Dubbo 框架

Dubbo 概述

Apache Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大外围能力:

  1. 面向接口的近程办法调用
  2. 只能容错和负载平衡
  3. 服务主动注册和发现

Dubbo 是一个车分布式服务框架,致力于提供高性能和透明化的 RPC 近程服务调用计划及服务治理计划

面向接口代理:

调用接口的办法,在 A 服务器调用 B 服务器的办法,由 Dubbo 实现对 B 的调用,无需关怀实现的细节。

就像 Mybatis 拜访 Dao 接口能够操作数据库一样,不要管线 Dao 接口办法的实现。简化了开发流程和难度。

根本架构

图解

对象角色阐明

  • 服务提供者(provider):裸露服务的提供方,服务提供者在启动时,向注册核心注册本人提供的服务。
  • 服务消费者(Consumer):调用近程服务的生产方,服务消费者在启动时,向注册核心订阅本人所需的服务。服务消费者从提供者地址列表中,基于软负载平衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 注册核心(Registry):注册核心返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长连贯推送变更数据给消费者
  • 监控核心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心

调用关系阐明

  • 服务容器 负责启动、加载、运行服务提供者
  • 服务提供者在启动时,向注册核心注册本人提供的服务
  • 服务消费者在启动时,向注册核心订阅本人所需的服务
  • 注册核心返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长链接推送变更数据给消费者
  • 服务消费者从提供者地址列表中,基于软负载平衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
  • 服务消费者和提供者,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心

Dubbo 反对的协定

Dubbo 反对多种协定,如:dubbohessianrmihttpwebservicethriftmemcachedredis

Dubbo 官网举荐应用 dubbo 协定,dubbo 协定默认端口 20880.

应用 dubbo 协定,须要在 spring 配置文件中退出下列标签注解:

<dubbo:protocol name="dubbo" port="20880"/>

Dubbo 直连实现

  1. 首先创立一个空的一般 Java 工程
  2. 创立一个子 maven web 工程001-link-userService-provider,最终我的项目目录构造如图所示

  3. 新建 readme.md 文件,编写我的项目思路

    1. 创立一个 maven web 工程——服务的提供者
    2. 配置 pom.xml 文件——增加须要的依赖
    3. 创立一个实体 bean——User
    4. 提供一个服务接口——UserService
    5. 实现这个服务接口——UserServiceImpl
    6. 配置 dubbo 服务提供者的外围配置文件
        + 申明 dubbo 服务提供者的名称(保障唯一性)+ 申明 dubbo 应用的协定和端口号
        + 裸露服务,应用直连形式
    7. 增加监听器
  4. 编写 pom.xml 文件,增加依赖

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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>xyz.rtx3090</groupId>
      <artifactId>001-link-userService-provider</artifactId>
      <version>1.0-SNAPSHOT</version>
      <!--packaging 值默认为 jar-->
      <packaging>war</packaging>
    
      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbo 依赖 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
        <resources>
          <!-- 解决 Maven 动态资源过滤问题 -->
          <resource>
            <directory>src/main/java</directory>
            <includes>
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
          </resource>
          <resource>
            <directory>src/main/resources</directory>
            <includes>
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
      </build>
    
    </project>
  5. 新建包 xyz.rtx3090.dubbo.model,并在其下创立User 实体类

    package xyz.rtx3090.dubbo.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private Integer id;
        private String name;
        private Integer age;
    
        //setter and getter
        public Integer getId() {return id;}
    
        public void setId(Integer id) {this.id = id;}
    
        public String getName() {return name;}
    
        public void setName(String name) {this.name = name;}
    
        public Integer getAge() {return age;}
    
        public void setAge(Integer age) {this.age = age;}
    }
  6. 新建包 xyz.rtx3090.dubbo.service,并在其下创立UserService 接口类

    package xyz.rtx3090.dubbo.service;
    
    import xyz.rtx3090.dubbo.model.User;
    
    public interface UserService {
        // 依据 id 查问用户信息
        User queryUserById(Integer id);
    }
  7. 新建包 xyz.rtx3090.dubbo.service.impl,并在其下创立UserServiceImpl 接口类

    package xyz.rtx3090.dubbo.service.impl;
    
    import xyz.rtx3090.dubbo.model.User;
    import xyz.rtx3090.dubbo.service.UserService;
    
    public class UserServiceImpl implements UserService {
        @Override
        public User queryUserById(Integer id) {
            // 模仿获取长久层中的数据
            User user = new User();
            user.setId(001);
            user.setName("Json");
            user.setAge(22);
    
            return user;
        }
    }
  8. resources 目录创立dubbo-userService-provider.xmlspring 配置文件

    <?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://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
        <!-- 服务提供者申明名称:必须保障服务名称的唯一性,它的名称是 dubbo 外部应用的惟一标示 -->
        <dubbo:application name="001-link-userService-provider"/>
    
        <!-- 拜访服务协定的名称及端口号,dubbo 官网举荐应用的是 dubbo 协定,端口号默认为 20880
            属性:name: 执行协定的名称
                port: 执行协定的端口号(默认为 20880)-->
        <dubbo:protocol name="dubbo"/>
    
        <!-- 裸露服务接口
            属性:interface: 裸露服务接口的权限定类名
                ref: 接口援用的实现类的 spring 容器中的标示
                registry: 如果不应用注册核心,则值为 N /A-->
    
        <dubbo:service interface="xyz.rtx3090.dubbo.service.UserService" ref="userService" registry="N/A"/>
    
        <!-- 将接口的实现类加载到 spring 容器中 -->
        <bean id="userService" class="xyz.rtx3090.dubbo.service.impl.UserServiceImpl"/>
    </beans>
  9. 编写 web.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
      
        <!-- 注册监听器 -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userService-provider.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    </web-app>
  10. 正文 pom.xml 文件中的 <packaging>war</packaging> 标签,是我的项目打包形式变为默认的 jar,而后在右侧的Maven->Lifecyde->install 把我的项目打包为 Jar 包,最初再勾销 <packaging>war</packaging> 标签的注解
  11. 再创立一个新的 maven web 子工程002-link-consumer,最终我的项目目录构造如图所示

  12. 新建 readme.md 文件,编写我的项目思路

    1. 创立一个 maven web 工程——服务的消费者
    2. 配置 pom 文件——增加须要的依赖
    3. 设置 dubbo 的外围配置文件
    4. 编写 controller 类
    5. 配置 DispatcherServlet 地方调度器
  13. 编写 pom.xml 文件,增加依赖

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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>xyz.rtx3090</groupId>
      <artifactId>002-link-consumer</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbo 依赖 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
        <!-- 依赖服务提供者 -->
        <dependency>
          <groupId>xyz.rtx3090</groupId>
          <artifactId>001-link-userService-provider</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
        <resources>
          <!-- 解决 Maven 动态资源过滤问题 -->
          <resource>
            <directory>src/main/java</directory>
            <includes>
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
          </resource>
          <resource>
            <directory>src/main/resources</directory>
            <includes>
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
      </build>
    </project>
  14. 新建包xyz.rtx3090.dubbo.web,并在其下新建类UserController

    package xyz.rtx3090.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 xyz.rtx3090.dubbo.model.User;
    import xyz.rtx3090.dubbo.service.UserService;
    
    @Controller
    public class UserController {
        @Autowired
        private UserService userService;
    
        @RequestMapping(value = "/user")
        public String userDetail(Model model,Integer id) {User user = userService.queryUserById(id);
            model.addAttribute("user",user);
            return "userDetail";
        }
    }
  15. webapp 目录下新建 userDetail.jsp 页面

    <%--
      Created by IntelliJ IDEA.
      User: bernardo
      Date: 2021/8/16
      Time: 03:16
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title> 用户详情 </title>
    </head>
    <body>
    <h1> 用户详情 </h1>
    <div> 用户标识: ${user.getId()}</div>
    <div> 用户名称:${user.getName()}</div>
    </body>
    </html>
  16. resources 目录下,新建 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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明服务消费者的名称——保障唯一性 -->
        <dubbo:application name="002-link-consumer"/>
    
        <!-- 援用近程服务接口:id——近程服务接口对象的名称
            interface——调用近程接口的全限定类名称
            url——拜访服务接口的地址
            registry——不应用注册核心,值为:N/A-->
        <dubbo:reference
                id="userService"
                interface="xyz.rtx3090.dubbo.service.UserService"
                url="dubbo://localhost:20880" registry="N/A"/>
    </beans>
  17. resources 目录下,新建application.xmlspring 外围配置文件

    <?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: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/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">
        <!-- 扫描组件 -->
        <context:component-scan base-package="xyz.rtx3090.dubbo.web"/>
    
        <!-- 配置注解驱动 -->
        <mvc:annotation-driven/>
    
        <!-- 配置视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
  18. 批改 web.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        
      <!-- 注册 DispatcherServlet 地方调度器 -->
      <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:application.xml,classpath:dubbo-consumer.xml</param-value>
        </init-param>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
  19. 配置 001-link-userService-provider 我的项目的 Tomcat 服务器,重点批改 Http port 端口和 JMX port 端口

  20. 配置 002-link-consumer 我的项目的 Tomcat 服务器

  21. 先启动 001-link-userService-provider 我的项目的 Tomcat 服务器,再启动 002-link-consumer 我的项目的 Tomcat 服务器,并在浏览器地址栏中输出http://localhost:8080/user?001,查看页面后果

Dubbo 服务化最佳实际

分包

倡议将服务接口、服务模型等均放在公共包中

粒度

  • 服务接口尽可能大粒度,每个服务办法应代表一个性能,而不是某性能的一个步骤
  • 服务接口倡议以业务场景为单位划分,并对相近业务做形象,避免接口数量暴涨
  • 不倡议应用过于形象的通用接口,如Map query(Map),这样的接口没有明确语义,会给前期保护带来不便

版本

每个接口都应定义版本号,辨别同一个接口的不同实现

如:<dubbo:service interface="com.xxx.XxxService" version="1.0"

Dubbo 罕用标签

Dubbo 中罕用标签分为三个类别:

  1. 共用标签
  2. 服务提供者标签
  3. 服务消费者标签
共用标签
  1. 配置利用信息

    <dubbo:appliation name="服务的名称"/>

  2. 配置注册核心

    <dubbo:registry address="ip:port" protocol="协定"/>

服务提供者标签
  1. 配置裸露的服务

    <dubbo:service interface="服务接口名" ref="服务实现对象 bean"/>

服务消费者标签
  1. 配置服务消费者援用近程服务

    <dubbo:reference id="服务援用 bean 的 id" interface="服务接口名"/>

Dubbo 直连 - 革新案例

为了解决 Dubbo 直连实现 中的问题,咱们须要引入一个 接口工程 ,将 bean 实体类和公共接口放入到这个 接口工程

  1. 新建一般 maven 工程(不带 web 模版)003-link-interface,最终我的项目目录构造如图所示:

  2. 创立 readme.md 文件,书写我的项目思路

    link-interface 是一个 maven java 工程
    dubbo 官网举荐应用的一个模式,将实体 bean 和业务接口寄存到接口工程中
  3. 批改 pom.xml 配置文件,去除不须要的内容

    <?xml version="1.0" encoding="UTF-8"?>
    <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>xyz.rtx3090</groupId>
        <artifactId>003-link-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    
    
    </project>
  4. java 目录下创立包 xyz.rtx3090.model,并新建User 实体类

    package xyz.rtx3090.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
    
        private Integer id;
        private String username;
    
        //setter and getter
        public Integer getId() {return id;}
    
        public void setId(Integer id) {this.id = id;}
    
        public String getUsername() {return username;}
    
        public void setUsername(String username) {this.username = username;}
    }
  5. java 目录下创立包 xyz.rtx3090.service,并新建UserService 接口

    package xyz.rtx3090.service;
    
    import xyz.rtx3090.model.User;
    
    public interface UserService {
    
        /**
         * 通过 id 查问用户信息
         * @param id 用户 id 号
         * @return 用户对象
         */
        User queryUserById(Integer id);
    
        /**
         * 查问用户总人数
         * @return 用户总人数
         */
        Integer queryAllUserCount();}
  6. 新建 maven web 工程004-link-userService-provider,最终我的项目目录构造如图所示:

  7. 批改 pom.xml 文件,增加所须要的依赖

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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>xyz.rtx3090</groupId>
      <artifactId>004-link-userService-provider</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbo 依赖 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
    
        <!-- 接口工程 -->
        <dependency>
          <groupId>xyz.rtx3090</groupId>
          <artifactId>003-link-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
    
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
  8. java 目录下新建包 xyz.rtx3090.service.impl,并在其包下新建UserServiceImpl 实现类

    package xyz.rtx3090.service.impl;
    
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    public class UserServiceImpl implements UserService {
        @Override
        public User queryUserById(Integer id) {User user = new User();
            user.setId(id);
            user.setUsername("Jason");
            return user;
        }
    
        @Override
        public Integer queryAllUserCount() {return 52;}
    }
  9. resources 目录下新建 dubbo-userService-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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明 dubbo 服务提供者名称——保障唯一性 -->
        <dubbo:application name="004-link-userService-provider"/>
    
        <!-- 设置 dubbo 应用协定和端口号
            name:协定名称
            port:端口号 -->
        <dubbo:protocol name="dubbo" port="20880"/>
    
        <!-- 裸露服务接口 -->
        <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userServiceImpl" registry="N/A"/>
    
        <!-- 加载业务接口的实现类到 spring 容器中 -->
        <bean id="userServiceImpl" class="xyz.rtx3090.service.impl.UserServiceImpl"/>
    </beans>
  10. 批改 web.xml 配置文件,注册监听器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
      <!-- 注册监听器 -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userService-provider.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
    </web-app>
  11. 新建 maven web 工程005-link-consumer,最终我的项目目录构造如图所示:

  12. 批改 pom.xml 文件,增加所须要的依赖

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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>xyz.rtx3090</groupId>
      <artifactId>005-link-consumer</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbok 依赖 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
        <!-- 接口工程 -->
        <dependency>
          <groupId>xyz.rtx3090</groupId>
          <artifactId>003-link-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
  13. java 目录下新建包 xyz.rtx3090.web,并在其包下新建UserController

    package xyz.rtx3090.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    import javax.annotation.Resource;
    
    @Controller
    public class UserController {
        @Resource
        private UserService userService;
    
        @RequestMapping(value = "/userDetail")
        public String userDetail(Model model, Integer id) {
            // 依据用户标示获取用户详情
            User user = userService.queryUserById(id);
            // 获取用户总人数
            Integer count = userService.queryAllUserCount();
    
            model.addAttribute("user",user);
            model.addAttribute("allUserCount",count);
            return "userDetail";
        }
    }
  14. webapp 目录下新建 userDetail.jsp 页面

    <%--
      Created by IntelliJ IDEA.
      User: bernardo
      Date: 2021/8/17
      Time: 12:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title> 用户详情 </title>
    </head>
    <body>
    <h2> 用户详情页面 </h2>
    <div> 用户标示:${user.id}</div>
    <div> 用户姓名:${user.username}</div>
    <div> 用户人数:${allUserCount}</div>
    </body>
    </html>
  15. resources 目录下新建 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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明服务消费者名称——保障唯一性 -->
        <dubbo:application name="005-link-consumer"/>
    
        <!-- 援用近程接口服务 -->
        <dubbo:reference
                id="userService"
                interface="xyz.rtx3090.service.UserService"
                url="dubbo://localhost:20880"
                registry="N/A"/>
    </beans>
  16. resources 目录下新建 applicationContext.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: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/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">
    
        <!-- 扫描组件 -->
        <context:component-scan base-package="xyz.rtx3090.web"/>
    
        <!-- 配置注解驱动 -->
        <mvc:annotation-driven/>
    
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
  17. 批改 web.xml 配置文件,注册地方调度器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!-- 注册地方调度器 -->
        <servlet>
          <servlet-name>dispatcherServlet</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value>
          </init-param>
        </servlet>
        <servlet-mapping>
          <servlet-name>dispatcherServlet</servlet-name>
          <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
  18. 配置并启动 004-link-userService-provider 的 tomcat 服务器

  19. 配置并启动 005-link-consumer 的 tomcat 服务器

  20. 在浏览器地址栏输出http://localhost:8080/005/userDetail?id=1,查看测试后果

注册核心

概述

对于服务提供方它须要公布服务,而且因为利用零碎的复杂性——服务的数量、类型也一直收缩;

对于服务消费者,它最关怀如何获取到它所需的服务,而面对简单的利用零碎,须要治理大量的服务调用。

而且,对于服务提供方和服务生产方来说,他们还有可能兼具这两种角色,即须要提供服务,又须要生产服务。

通过将服务对立治理起来,能够无效地优化外部利用对服务公布 / 应用的流程和治理。

服务注册核心能够通过特定协定来实现服务对外的对立,Dubbo 提供的注册核心有如下几种类型可供选择:

  1. Multicast注册核心:组播形式
  2. Redis注册核心:应用 Redis 作为注册核心
  3. Simple注册核心:就是一个 dubbo 服务,作为注册核心,提供查找服务的性能
  4. Zookeeper注册核心:应用 Zookeeper 作为注册核心(举荐)

注册核心工作形式

Zookeeper 注册核心

Zookeeper 是一个高性能的、开源的分布式应用程序协调服务,简称 ZK。Zookeeper 直译为 动物园管理员,能够了解为 windows 中的资源管理器或者注册表。他是一个树形构造,这种树形构造和规范文件系统类似。Zookeeper 数中的每个节点能够领有子节点,每个节点示意一个惟一服务资源,Zookeeper 运行须要 Java 环境。

下载

留神咱们这里要下载 3.5.6 版本的,不然可能会呈现不兼容的状况

装置

将下载的 apache-zookeeper-3.5.6-bin.tar.gz 文件,解压到指定目录地位即可

tar -zxvf apache-zookeeper-3.5.9-bin.tar.gz -C /usr/local/

配置文件

配置文件详解
  1. tickTime:间接翻译为心跳工夫,单位毫秒。Zookeeper 服务器之间或客户端与服务器之间维持心跳的工夫距离,也就是每个 tickTime 工夫就会发送一个心跳,表明存活状态
  2. dataDir:数据目录,能够是任意目录。存错 zookeeper 的快照文件、pid 文件,默认为 /tmp/zookeeper,倡议在zookeeper 装置目录下创立 data 目录,将 dataDir 配置改为/usr/local/zookeeper-3.5.9/data
自定义配置文件内容
  1. 复制 conf/zoo_sample.cfg 文件到同级目录中改名为zoo.cfg
  2. apache-zookeeper-3.5.9-bin 根目录下创立 data 文件夹
  3. 批改配置文件 conf/zoo.cfg 中的dataDir=/Users/bernardo/JavaDoc/apache-zookeeper-3.5.9-bin/data(即上述创立的文件夹门路)
  4. 批改配置文件 conf/zoo.cfg,在 clientPort=2181 上面退出admin.serverPort=8888

conf/zoo.cfg最终内容:

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/Users/bernardo/JavaDoc/zookeeper-3.5.9/data
# the port at which the clients will connect
clientPort=2181
admin.serverPort=8888
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

启动

切换到 bin 目录下,执行命令./zkServer.sh start

敞开

切换到 bin 目录下,执行命令./zkServer.sh stop

Dubbo 案例革新—本地应用 zookeeper

  1. 新建一般 maven java 子工程001-zk-interface,最终我的项目目录如图所示:

  2. java 目录下新建包 xyz.rtx3090.model,并在其下新建User 实体类

    package xyz.rtx3090.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private Integer id;
        private String username;
    
        //setter and getter
    
        public Integer getId() {return id;}
    
        public void setId(Integer id) {this.id = id;}
    
        public String getUsername() {return username;}
    
        public void setUsername(String username) {this.username = username;}
    }
  3. java 目录下新建包 xyz.rtx3090.service,并在其下新建UserService 接口

    package xyz.rtx3090.service;
    
    import xyz.rtx3090.model.User;
    
    public interface UserService {
        /**
         * 依据用户 id 查问用户信息
         * @param id 用户 id
         * @return 用户信息
         */
        User queryUserById(Integer id);
    }
  4. 新建 maven web 子工程002-zk-userService-provider,最终目录构造如图所示:

  5. 批改 pom.xml 文件,增加所需的依赖

    <dependencies>
            <!--spring 依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.16.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.3.16.RELEASE</version>
            </dependency>
            <!--dubbo 依赖 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.2</version>
            </dependency>
            <!-- 接口工程依赖 -->
            <dependency>
                <groupId>xyz.rtx3090</groupId>
                <artifactId>001-zk-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!-- 注册核心依赖 -->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.1.0</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <!-- 规定我的项目 JDK 版本 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
  6. java 目录下新建包 xyz.rtx3090.service.impl,并在其下新建UserServiceImpl

    package xyz.rtx3090.service.impl;
    
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    public class UserServiceImpl implements UserService {
        /**
         * 依据用户 id 获取用户信息
         * @param id 用户 id
         * @return 用户对象
         */
        @Override
        public User queryUserById(Integer id) {User user = new User();
            user.setId(id);
            user.setUsername("Jason" + id);
            return user;
        }
    }
  7. resources 目录下创立 dubbo-userService-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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明 dubbo 服务提供者名称——保障唯一性 -->
        <dubbo:application name="002-zk-userService-provider"/>
    
        <!-- 注册核心 zookeeper-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
    
        <!-- 设置 dubbo 应用的协定和端口号 -->
        <dubbo:protocol name="dubbo" port="20880"/>
    
        <!-- 裸露服务接口 -->
        <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userServiceImpl"/>
    
        <!-- 加载业务接口的实现类到 spring 容器中 -->
        <bean id="userServiceImpl" class="xyz.rtx3090.service.impl.UserServiceImpl"/>
    </beans>
  8. 批改 web.xml 配置文件,注册监听器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
      <!-- 注册监听器 -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userService-provider.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
    </web-app>
  9. 新建 maven web 子工程003-zk-consumer,最终目录构造如图所示:

  10. 批改 pom.xml 配置文件,增加所需的依赖

        <dependencies>
            <!--spring 依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.16.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.3.16.RELEASE</version>
            </dependency>
            <!--dubbo 依赖 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.6.2</version>
            </dependency>
            <!-- 接口工程依赖 -->
            <dependency>
                <groupId>xyz.rtx3090</groupId>
                <artifactId>001-zk-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!-- 注册核心依赖 -->
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.1.0</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <!-- 规定我的项目 JDK 版本 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
  11. java 目录下新建包 xyz.rtx3090.web,并在其下新建UserController

    package xyz.rtx3090.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    import javax.annotation.Resource;
    
    @Controller
    public class UserController {
        @Resource
        private UserService userService;
    
        @RequestMapping(value = "/userDetail")
        public String userDetail(Model model, Integer id) {User user = userService.queryUserById(id);
            model.addAttribute("user",user);
            return "userDetail";
        }
    }
  12. webapp 目录下新建 userDetail.jsp 页面

    <%--
      Created by IntelliJ IDEA.
      User: bernardo
      Date: 2021/8/18
      Time: 15:04
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title> 用户信息 </title>
    </head>
    <body>
    <h2> 用户详情信息页面 </h2>
    <div> 用户编号:${user.id}</div>
    <div> 用户姓名:${user.username}</div>
    </body>
    </html>
  13. resources 目录下新建 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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明服务消费者名称——保障唯一性 -->
        <dubbo:application name="003-zk-consumer"/>
    
        <!-- 注册核心 zookeeper-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
    
        <!-- 援用近程接口服务 -->
        <dubbo:reference id="userServiceImpl" interface="xyz.rtx3090.service.UserService"/>
    </beans>
  14. resources 目录下新建applicationContext.xmlspring 配置文件

    <?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: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/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">
    
        <!-- 扫描组件 -->
        <context:component-scan base-package="xyz.rtx3090.web"/>
    
        <!-- 配置注解驱动 -->
        <mvc:annotation-driven/>
    
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
  15. 批改 web.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!-- 配置地方调度器 -->
        <servlet>
            <servlet-name>dispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
  16. 切换到 zookeeper-3.5.6/bin/ 目录,执行 ./zkServer.sh start 来启动 zookeeper 注册核心

  17. 配置并启动 002-zk-userService-provider 我的项目的 tomcat 服务器

  18. 配置并启动 003-zk-consumer 我的项目的 tomcat 服务器

  19. 在浏览器地址栏输出http://localhost:8080/003/userDetail?id=1,查看页面测试后果

Dubbo 案例革新—近程主机应用 zookeeper

Dubbo 案例革新—本地应用 zookeeper 的代码根底上进行批改

  1. 在近程主机上 下载 配置 启动 zookeeper,步骤和在本地主机上的一样(记得凋谢端口21818888)
  2. 批改 002-zk-userService-providerdubbo-userService-provider配置文件

    <!-- 批改注册核心 zookeeper,将 localhost 换成近程主机的 ip-->
    <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
  3. 批改 003-zk-consumerdubbo-consumer配置文件

    <!-- 批改注册核心 zookeeper,将 localhost 换成近程主机的 ip-->
    <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
  4. 配置并启动 002003 我的项目的 tomcat 服务器,在浏览器地址栏输出http://localhost:8080/003/userDetail?id=2,查看页面测试后果

Dubbo 配置

敞开查看

dubbo 缺省会在启动时查看依赖的服务是否可用,不可用时会抛出异样,阻止 Spring 初始化实现,以便上线时能及时发现问题,默认 check=true。通过check=false 敞开查看。比方测试时,有些服务不关怀,或者呈现了循环依赖,必须有一方先启动。

  1. 例一:敞开某人服务的启动时查看

    <dubbo:reference interface="xyz.rtx3090.BarService" check="false"/>
  2. 例二:敞开注册核心启动时查看

    <dubbo:registry check="false"/>

    默认启动服务时,查看核心存在并已运行,注册核心不启动会报错

重试次数

消费者拜访提供者,如果拜访失败,则切换重试拜访其余服务器,但重试会带来更长提早。拜访工夫变长,用户的体验较差。屡次从新拜访服务器有可能拜访胜利。可通过 retries="2"来设置重试次数(不含第一次)

  1. <dubbo:service retries="2"/>
  2. <dubbo:reference retries="2"/>

超时工夫

因为网络或服务端不牢靠,会导致调用呈现一种不确定的中间状态(超时)。为了防止超时导致客户端资源(线程)挂起耗尽,必须设置超时工夫。

通过设置 timeout 来调整近程服务超时工夫(毫秒)

  1. 调整生产端服务超时工夫

    <dubbo:reference interface="xyz.rtx3090.BerServicee" timeout="2000"/>
  2. 调整服务端超时工夫

    <dubbo:server interface="xyz.rtx3090.BarService" timeout="2000"/>

版本号

每个接口都应定义版本号,为后续不兼容降级提供可能。当一个接口有不同的实现,我的项目晚期应用的一个实现类,之后创立接口的新实现类。辨别不同接口实现应用 version,特地是我的项目须要把晚期接口的实现全副换位新的实现类,也须要实现 version。

能够用版本号从晚期实现适度到欣的接口实现,版本号不同的服务相互间不援用。

能够依照以下的步骤进行版本迁徙:

  1. 在低压力时间段,先降级一半提供者为新版本
  2. 再将所有消费者降级为新版本
  3. 而后将剩下的一半提供者降级为新版本

Dubbo 案例革新 - 多版本 + 近程 zookeeper

有时候咱们在降级新版本的时候同样须要兼顾旧版本,这个时候咱们就须要【多版本】的计划了

  1. 新建一般 maven java 工程009-zk-multi-interface,最终我的项目目录构造如图所示:

  2. 在 java 目录下新建包 xyz.rtx3090.model,并在其下新建User 实体类

    package xyz.rtx3090.model;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private Integer id;
        private String username;
    
        //setter and getter
    
        public Integer getId() {return id;}
    
        public void setId(Integer id) {this.id = id;}
    
        public String getUsername() {return username;}
    
        public void setUsername(String username) {this.username = username;}
    }
  3. 在 java 目录下新建包 xyz.rtx3090.service,并在其下新建UserService

    package xyz.rtx3090.service;
    
    import xyz.rtx3090.model.User;
    
    public interface UserService {
        /**
         * 依据用户 id 获取用户音讯
         * @param id 用户 id
         * @return 用户对象
         */
        User queryUserById(Integer id);
    }
  4. 新建 maven web 工程,最终我的项目构造如图所示:

  5. 批改 pom.xml 文件,增加所需依赖

      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbo 依赖 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
    
        <!-- 接口工程 -->
        <dependency>
          <groupId>xyz.rtx3090</groupId>
          <artifactId>009-zk-multi-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 注册核心依赖 -->
        <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.1.0</version>
        </dependency>
    
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
  6. 在 java 目录下新建包 xyz.rtx3090.service.impl 包,并在其下新建 UserServiceImpl 类和 UserServiceImpl2

    package xyz.rtx3090.service.impl;
    
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    public class UserServiceImpl implements UserService {
        @Override
        public User queryUserById(Integer id) {User user = new User();
            user.setId(id);
            user.setUsername("Jason" + id);
            return user;
        }
    }
    package xyz.rtx3090.service.impl;
    
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    public class UserServiceImpl2 implements UserService {
        @Override
        public User queryUserById(Integer id) {User user = new User();
            user.setId(id);
            user.setUsername("Bernardo" + id);
            return user;
        }
    }
  7. 在 resources 目录下新建 dubbo-userService-multi-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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xmlns:dubbbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明 dubbo 服务提供者名称:保障唯一性 -->
        <dubbo:application name="010-zk-userService-multi-provider"/>
    
        <!-- 申明 dubbo 协定和端口号 -->
        <dubbbo:protocol name="dubbo" port="20880"/>
    
        <!-- 申明注册核心 -->
        <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
    
    
        <!-- 多版本,裸露服务接口(不论是不是多版本,最好都提供版本号)-->
        <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userService1" version="1.0.0"/>
        <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userService2" version="2.0.0"/>
    
        <bean id="userService1" class="xyz.rtx3090.service.impl.UserServiceImpl"/>
        <bean id="userService2" class="xyz.rtx3090.service.impl.UserServiceImpl2"/>
    </beans>
  8. 批改 web.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!-- 注册监听器 -->
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:dubbo-userService-multi-provider.xml</param-value>
        </context-param>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>
  9. 新建 maven web 工程011-zk-multi-consumer,最终我的项目目录构造如图所示:

  10. 批改 pom.xml 配置文件,增加我的项目所需依赖

      <dependencies>
        <!--spring 依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.16.RELEASE</version>
        </dependency>
        <!--dubbo 依赖 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
    
        <!-- 接口工程 -->
        <dependency>
          <groupId>xyz.rtx3090</groupId>
          <artifactId>009-zk-multi-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- 注册核心依赖 -->
        <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.1.0</version>
        </dependency>
    
      </dependencies>
    
      <build>
        <plugins>
          <!-- 规定我的项目 JDK 版本 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
  11. 在 java 目录下新建包xyz.rtx3090.web,并在其下新建类UserController

    package xyz.rtx3090.web;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import xyz.rtx3090.model.User;
    import xyz.rtx3090.service.UserService;
    
    @Controller
    public class UserController {
        @Autowired
        @Qualifier("userServiceImpl")
        // 这里的 byName 主动注入是根据 `dubbo-multi-consumer` 配置文件中的 `dubbo:reference` 标签属性 `id`
        private UserService userServiceImpl;
    
        @Autowired
        @Qualifier("userServiceImpl2")
        private UserService userServiceImpl2;
    
        @RequestMapping(value = "/userDetail")
        public String userDetail(Model model, Integer id) {User user1 = userServiceImpl.queryUserById(id);
            User user2 = userServiceImpl2.queryUserById(id);
            model.addAttribute("user1",user1);
            model.addAttribute("user2",user2);
            return "userDetail";
        }
    }
  12. 在 resources 目录下新建配置文件dubbo-multi-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:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 申明 dubbo 服务消费者名称:保障服务名称的唯一性 -->
        <dubbo:application name="011-zk-multi-consumer"/>
    
        <!-- 指定注册核心 -->
        <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
    
        <!-- 援用近程接口服务 -->
        <dubbo:reference id="userServiceImpl" interface="xyz.rtx3090.service.UserService" version="1.0.0"/>
        <dubbo:reference id="userServiceImpl2" interface="xyz.rtx3090.service.UserService" version="2.0.0"/>
    </beans>
  13. 在 resources 目录下新建配置文件applicationContext.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: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/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">
    
        <!-- 组件扫描器 -->
        <context:component-scan base-package="xyz.rtx3090.web"/>
    
        <!-- 配置注解驱动 -->
        <mvc:annotation-driven/>
    
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
  14. 批改 web.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!-- 注册地方调度器 -->
        <servlet>
          <servlet-name>dispatcherServlet</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dubbo-multi-consumer.xml,classpath:applicationContext.xml</param-value>
          </init-param>
        </servlet>
        <servlet-mapping>
          <servlet-name>dispatcherServlet</servlet-name>
          <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
  15. 在 webapp 目录下新建 userDetail.jsp 页面

    <%--
      Created by IntelliJ IDEA.
      User: bernardo
      Date: 2021/8/19
      Time: 14:51
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title> 用户信息页面 </title>
    </head>
    <body>
    <h2> 用户一 </h2>
    <div> 用户编号:${user1.id}</div>
    <div> 用户姓名:${user1.username}</div>
    
    <h2> 用户二 </h2>
    <div> 用户编号:${user2.id}</div>
    <div> 用户姓名:${user2.username}</div>
    </body>
    </html>
  16. 启动近程主机的 zookeeper
  17. 配置并启动我的项目 010-zk-userService-multi-provider 的 tomcat 服务器(留神批改端口号,防止两个 tomcat 服务器抵触)

  18. 配置比启动我的项目 011-zk-multi-consumer 的 tomcat 服务器

  19. 在浏览器地址栏中输出http://localhost:8080/011/userDetail?id=1,查看页面测试后果

监控核心

什么是监控核心

dubbo 的应用其实只须要有注册核心、消费者、提供者三个就能够应用了,然而并不能看到有哪些消费者和提供者。为了更好的调试、发现问题、解决问题,因而引入 dubbo-admin,通过dubbo-admin 能够对消费者和提供者进行治理,能够在 dubbo 援用部署做动静的调整、服务治理。

  1. dubbo-admin

    图形化服务治理页面,装置时须要执行注册核心地址,即可从注册核心中获取到所有的提供这者、消费者进行配置管理

  2. dubbo-monitor-simple

    简略的监控核心

应用监控核心

  1. 进入 https://github.com/apache/dubbo-admin 下载 dubbo-admin 工程

  2. 应用 idea 关上下载的 dubbo-admin 工程
  3. 进入 dubbo-admin-develop/dubbo-admin-server 目录,关上 pom.xml 文件,增加 maven-antrun-plugingrouidorg.apache.maven.plugins,并确定其余内容没有报红

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <version>1.8</version>
                    <executions>
                        <execution>
                            <phase>verify</phase>
                            <configuration>
                                <tasks>
                                    <copy file="target/dubbo-admin-server-${project.version}.jar"
                                          tofile="../dubbo-admin-distribution/target/dubbo-admin-${project.version}.jar"/>
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
  4. 进入 dubbo-admin-develop/dubbo-admin-server/srcd/main/resources 目录,关上 application.properties 配置文件,设置一些 ip 和端口信息

    # ip 地址和端口号改为本人 zookeeper 设置 ip 端口
    admin.registry.address=zookeeper://127.0.0.1:2181
    admin.config-center=zookeeper://127.0.0.1:2181
    admin.metadata-report.address=zookeeper://127.0.0.1:2181
    
    # 前面在浏览器登录 admin 零碎的账号密码
    admin.root.user.name=root
    admin.root.user.password=root
    
    # 新增设置端口号为 7001(默认为 8080,与 tomcat 抵触)server.port=7001
  5. 点击右侧的 maven 工具,进入 dubbo-admin(root)/Lifecyde 先点击 clean 选项,而后点击 package 抉择构建 Jar 包

  6. 启动 zookeeperdubbo我的项目
  7. 等 Jar 包构建实现和下面启动结束,进入 dubbo-admin-develop/dubbo-admin-distribution/target 目录,在此目录下关上终端,执行 java -jar dubbo-admin-0.3.0.jar 命令

  8. 在浏览器地址栏输出http://localhost:7001(7001 是下面我本人设置的端口号),即可对 dubbo 我的项目进行监控


END

退出移动版