dubbo的学习笔记

一、初识Dubbo

1.1为什么Dubbo性能高

  • 高性能要从底层的原理说起,既然是-一个RPC框架,主要干的就是远程过程(方法)调用,那么提升性能就要从最关键、最耗时的两个方面入手:序列化和网络通信。
  • 序列化:我们学习Java网络开发的时候知道,本地的对象要在网络上传输,必须要实现Serializable接口,也就是必须序列化。我们序列化的方案很多: xml、 json、 二进制流…其中效率最高的就是二进制流(因为计算机就是二进制的)。然而Dubbo采用的就是效率最高的二进制。
  • 网络通信:不同于HTTP需要进行7步走(三次握手和四次挥手),Dubbo 采用Socket通信机制,一步到位,提升了通信效率,并且可以建立长连接,不用反复连接,直接传输数据

1.2别的RPC框架

  • gRPC
  • Thrift
  • HSF

1.3dubbo的前世今生

dubbo之前一直都作为Alibaba公司内部使用的框架

  • 2011年,dubbo被托管到了GitHub上(开源)
  • 2014年11月发布2.4.11版本后宣布停止更新。此后–段时间很多公司开源了自己基于Dubbo.的变种版本(例如当当网的Dubbo x,网易考拉的Dubbo K)
  • 2017年SpringCloud横空出世,Dubbo感觉到压力后连续更新了几个版本.
  • 2018年1月,阿里公司联合当当网将Dubbo和DubboX合并,发布了2.6版本
  • 2018年除夕夜阿里将Dubbo贡献给了Apache 基金会
  • 2018除夕夜至今,Apache维护和更新Dubbo

二、Dubbo框架

2.1概述

Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案、服务治理方案

官网:https://dubbo.apache.org/zh/

2.2基本架构

Dubbo架构学习整理

2.2.1简单说明

(1)Provider暴露服务方称之为“服务提供者”。
服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
(2)Consumer调用远程服务方称之为“服务消费者”。
服务消费者向注册中心获取服务提供者地址列表 , 并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
(3)Registry服务注册与发现的中心目录服务称之为“服务注册中心”
注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
(4)Monitor统计服务的调用次调和调用时间的日志服务称之为“服务监控中心”
监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示

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

2.3支持的协议

​ 支持多种协议: dubbo,hessian , rmi , http, webservice , thrift , memcached , redis。dubbo官方推荐使用dubbo协议。dubbo协议默认端口20880

使用dubbo协议,spring 配置文件加入:

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

2.4 dubbo健壮性

(1)监控中心宕掉不影响使用,只是丢失部分采样数据
(2)数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
(3)注册中心对等集群,任意一台宕掉后,将自动切换到另一台
(4)注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
(5)服务提供者无状态,任意一台宕掉后,不影响使用
(6)服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

2.5 dubbo伸缩性

(1)注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
(2)服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者

三、ssm简单实现dubbo

Dubbo采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载.

下列实现方式使用官方推荐的项目结构实现:

  • 接口独立工程(entity、service)
  • 服务提供者工程(serviceImpl),实现接口工程中的业务接口
  • 服务消费者工程(controller),实现消费服务提供者提供的业务接口

3.1接口项目

  1. 创建一个普通maven项目

  2. 新建service包和entity包

  3. 编写entity层

    public class User implements Serializable {
        private Integer id;
        private String name;
    
        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;
        }
    }
    
  4. 编写service层

    public interface SomeService{
        /**
         *
         * @param msg
         * @return
         */
        String hello(String msg);
    
        /**
         *
         * @param id
         * @return
         */
        User queryUser(Integer id);
    
    }
    
  5. 项目架构

    image-20220506192106222

3.2提供者项目

  1. 新建一个web的maven项目

  2. 引入依赖

    这里需要引入接口的依赖

    建议spring的依赖版本与我的一致,否则可能会出现错误

    <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
    <!--    dubbo-->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.0</version>
        </dependency>
    <!--    spring-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
    <!--    接口-->
        <dependency>
          <groupId>com.lzj.dubbo</groupId>
          <artifactId>001-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
    
  3. 编写serviceimpl层

    @Component
    public class SomeServiceImpl implements SomeService {
        @Override
        public String hello(String msg) {
            return "hello"+msg;
        }
    
        @Override
        public User queryUser(Integer id) {
            User user = new User();
            user.setId(id);
            user.setName("lzj-"+id);
            return user;
        }
    }
    
  4. 编写dubbo配置文件

    dubbo-link-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://code.alibabatech.com/schema/dubbo"
           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://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">
    <!--    扫描包的注解-->
        <context:component-scan base-package="com.lzj.service.impl"/>
    <!--    声明服务提供者名称,保证它的唯一性,它是dubbo内部使用的唯一标识-->
        <dubbo:application name="002-link-provider"/>
    <!--    指定dubbo的协议名称和端口号
            name 指定协议名称,官方推荐dubbo
            port 协议的端口号,默认为20880
    -->
        <dubbo:protocol name="dubbo" port="20880"/>
    
    <!--    暴露服务:dubbo:service
            interface 暴露服务的接口全限定名
            ref 引用接口在spring容器中的标识名称
            registry 使用直连方式,不适用组成,值:N/A
    -->
        <dubbo:service interface="com.lzj.service.SomeService"
                       ref="someServiceImpl"
                       registry="N/A"/>
    <!--    加载接口实现类-->
    <!--    <bean id="someServiceImpl" class="com.lzj.service.impl.SomeServiceImpl"/>-->
    </beans>
    
  5. 编写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-link-provider.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>
    
  6. 项目架构

    image-20220506192904171

3.3消费者项目

  1. 新建一个web的maven项目

  2. 引入依赖

    也需要加入接口的依赖

    <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.0</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>com.lzj.dubbo</groupId>
          <artifactId>001-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>4.3.19.RELEASE</version>
          <scope>test</scope>
        </dependency>
    
  3. 编写controller层

    @Controller
    public class SomeController {
        @Autowired
        private SomeService someService;
    
        @RequestMapping("/hello")
        public String hello(Model model){
            //调用远程接口服务
            String lzj = someService.hello("lzj");
            model.addAttribute("hello",lzj);
            return "hello";
        }
    
        @RequestMapping("/detail")
        public String user(Model model,Integer id){
            User user = someService.queryUser(1);
            model.addAttribute("user",user);
            return "detail";
        }
    }
    
    
  4. 编写dubbo配置文件

    dubbo-link-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://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内部服务名称的唯一标识-->
        <dubbo:application name="003-link-consumer"/>
    <!--引用远程接口
        id 远程接口服务的代理对象名称
        interface 接口的全限定类名
        url 调用远程接口服务的url地址
        registry 直连方式,不使用注册中心,值:N/A
    -->
        <dubbo:reference id="someService"
                         interface="com.lzj.service.SomeService"
                         url="dubbo://localhost:20880"
                         registry="N/A"/>
    
    </beans>
    
  5. 编写springmvc配置文件

    springmvc.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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
        <!--    注解驱动  mvc-->
        <mvc:annotation-driven/>
        <!--    扫描包-->
        <context:component-scan base-package="com.lzj.controller"/>
    
        <!--    视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--        前缀-->
            <property name="prefix" value="/"/>
            <!--        后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
    </beans>
    
  6. 编写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-link-consumer.xml,classpath:springmvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  7. webapp目录下新建两个jsp文件

    hello.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>${hello}</h1>
    
    </body>
    </html>
    

    detail.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>${user.id}</h1>
    <h1>${user.name}</h1>
    
    </body>
    </html>
    
  8. 项目架构

    image-20220506192842762

3.4测试

  1. 给提供者和消费者两个web项目配置tomcat(注:两个项目的以下两个端口号需要不同)

    提供者:

    image-20220506193021246

    消费者

    image-20220506193102290

  2. 两个项目的tomcat配置完成后,按照顺序执行tomcat(提供者->消费者)

  3. 进行测试访问

    测试一:

    image-20220506193211986

    测试二:

    image-20220506193233983

四、注册中心-Zookeeper

4.1 概述

官方文档:https://dubbo.apache.org/zh/docs/references/registry/zookeeper/

Zookeeper是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用

image-20220507001330641

流程说明:

  • 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  • 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  • 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

支持以下功能:

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置 <dubbo:registry check="false" /> 时,记录失败注册和订阅请求,后台定时重试
  • 可通过 <dubbo:registry username="admin" password="1234" /> 设置 zookeeper 登录信息
  • 可通过 <dubbo:registry group="dubbo" /> 设置 zookeeper 的根节点,不配置将使用默认的根节点。
  • 支持 * 号通配符 <dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者

注册中心工作方式

image-20220507001727155

4.2 下载Zookeeper

linux和windows的压缩包是同一个

版本选择下载地址:https://archive.apache.org/dist/zookeeper/

4.2.1 下载zookeeper
  1. 进入官网:https://zookeeper.apache.org/

    image-20220507100517608

  2. 按照以下操作点击

    image-20220507100601649

    image-20220507100632251

  3. 我选择下载的版本是3.5.9

    image-20220507100715837

    image-20220507100804181

  4. 如果需要下下载其它版本(就是我前面提到的版本选择下载地址)

    image-20220507100906457

    image-20220507100920510

  5. linux和window是是同一个压缩包,下载后解压即可

4.3 安装配置zookeeper

4.3.1 windows下

运行zookeeper需要java环境

  1. 解压压缩包,打开下载的文件(管理员模式打开),运行/bin/zkServer.cmd,初次运行时可能会报错,因为没有zoo.cfg

    也有可能遇到闪退的问题!

    闪退的解决方案:右键编辑zkServer.cmd文件,在末尾添加pauser(如果右键不能点击编辑,可以将文件的后缀名改为txt,然后修改完后再改回cmd)

    image-20220315195317861

  2. 修改zoo.cfg配置文件

    将conf文件夹下面的zoo_sample.cfg复制一份改名为zoo.cfg即可。

    需要添加admin.serverPort=9001(也可以设置成其它端口号),避免启动时占用tomcat的端口号8080

    image-20220507111127125

    注意几个重要位置:

    dataDir=./ 临时数据存储的目录(可写相对路径)

    clientPort=2181 zookeeper的端口号

    修改完成后再次启动zookeeper

  3. 打开zkCli.cmd进行测试(在打开zkCli.cmd前,要先将zkServer.cmd打开)

    ls /:列出zookeeper根下保存的所有节点

    create –e /lzj123:创建一个lzj节点,值为123

    get /lzj:获取/lzj节点的值

4.3.2 Linux下

需要java环境

基本操作操作与windows下一致,只是需要使用命令行进行操作

  1. 将压缩包放到对应位置
  2. 解压文件
    • tar zxvf FileName.tar.gz
  3. 修改zoo.zfg配置文件
    • cp zoo_sample.cfg zoo.cfg
    • vim zoo.cfg
    • 添加admin.serverPort=9001
  4. 进行测试启动
    • ./zkServer.sh start
  5. 检查是否启动成功
    • pe -ef | grep zook

五、ssm简单实现dubbo+zookeeer

5.1 接口工程

  1. 创建一个普通maven项目

  2. 新建service包和entity包

  3. 编写entity层

    public class User implements Serializable {
        private Integer id;
        private String name;
    
        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;
        }
    }
    
  4. 编写service层

    public interface SomeService{
        /**
         *
         * @param msg
         * @return
         */
        String hello(String msg);
    
        /**
         *
         * @param id
         * @return
         */
        User queryUser(Integer id);
    
    }
    
  5. 项目架构

    image-20220506192106222

5.2 服务提供者工程

  1. 新建一个web的maven项目

  2. 引入依赖

    这里需要引入接口的依赖

    dubbo的版本必须为2.6.2不能为低版本,因为低版本dubbo依赖支持的zookeeper依赖名称不是我写的这个

    建议spring的依赖版本与我的一致,否则可能会出现错误

    <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.1</version>
          <scope>test</scope>
        </dependency>
    <!--    dubbo-->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
    <!--    spring-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
    
    <!--    接口工程-->
        <dependency>
          <groupId>com.lzj.dubbo</groupId>
          <artifactId>001-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
    <!--    zookeeper注册中心依赖-->
        <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.1.0</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>4.3.19.RELEASE</version>
          <scope>test</scope>
        </dependency>
    
  3. 编写serviceimpl层

    @Component
    public class SomeServiceImpl implements SomeService {
        public String hello(String msg) {
            return "hello dubbo zookeeper"+msg;
        }
    
        public User queryUser(Integer id) {
            User user = new User();
            user.setId(id);
            user.setName("zk-dubbo-"+id);
            return user;
        }
    }
    
    
  4. 编写dubbo配置文件

    dubbo-zk-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://code.alibabatech.com/schema/dubbo"
           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://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">
    <!--扫描注解-->
        <context:component-scan base-package="com.lzj.service.impl"/>
    <!--    声明服务提供者名称-->
        <dubbo:application name="004-zk-provider"/>
    <!--    指定协议及端口号-->
        <dubbo:protocol name="dubbo" port="20880"/>
    <!--    指定注册中心-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
    <!--    暴露服务-->
        <dubbo:service interface="com.lzj.service.SomeService"
                       ref="someServiceImpl"
                        timeout="3000"/>
    <!--    加载接口实现类-->
    <!--    <bean id="someServiceImpl" class="com.lzj.service.impl.SomeServiceImpl"/>-->
    </beans>
    
    
  5. 编写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-zk-provider.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    </web-app>
    
  6. 项目架构

    image-20220507111929801

5.3 服务消费者工程

  1. 新建一个web的maven项目

  2. 引入依赖

    需要加入接口工程的依赖

    <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <!--    dubbo-->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
        <!--    spring-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>4.3.19.RELEASE</version>
        </dependency>
    
        <!--    接口工程-->
        <dependency>
          <groupId>com.lzj.dubbo</groupId>
          <artifactId>001-interface</artifactId>
          <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--    zookeeper注册中心依赖-->
        <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.1.0</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>4.3.19.RELEASE</version>
          <scope>test</scope>
        </dependency>
    
  3. 编写controller层

    @Controller
    public class SomeController {
        @Autowired
        private SomeService someService;
    
        @RequestMapping("/hello")
        public String hello(Model model){
            //调用远程接口服务
            String lzj = someService.hello("lzj");
            model.addAttribute("hello",lzj);
            return "hello";
        }
    
        @RequestMapping("/detail")
        public String user(Model model,Integer id){
            User user = someService.queryUser(1);
            model.addAttribute("user",user);
            return "detail";
        }
    }
    
  4. 编写dubbo配置文件

    dubbo-zk-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://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="005-zk-consumer"/>
    <!--    指定注册中心-->
        <dubbo:registry address="zookeeper://localhost:2181"/>
    <!--    引用远程接口服务-->
        <dubbo:reference id="someService" interface="com.lzj.service.SomeService"/>
    </beans>
    
    
  5. 编写springmvc配置文件

    springmvc.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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
        <!--    注解驱动  mvc-->
        <mvc:annotation-driven/>
        <!--    扫描包-->
        <context:component-scan base-package="com.lzj.controller"/>
    
        <!--    视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--        前缀-->
            <property name="prefix" value="/"/>
            <!--        后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
    </beans>
    
  6. 编写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-zk-consumer.xml,classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
    
  7. webapp目录下新建两个jsp文件

    hello.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>${hello}</h1>
    
    </body>
    </html>
    

    detail.jsp

    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>${user.id}</h1>
    <h1>${user.name}</h1>
    
    </body>
    </html>
    
  8. 项目架构

    image-20220507112126805

5.4 测试

  1. 给提供者和消费者两个web项目配置tomcat(注:两个项目的以下两个端口号需要不同)

    提供者:

    image-20220507112240035

    消费者

    image-20220507112258399

  2. 启动zookeeper

    image-20220507112541711

  3. 两个项目的tomcat配置完成后,按照顺序执行tomcat(提供者->消费者)

  4. 如果出现8080端口号被占用的情况,就是你的zoo.cfg中没有修改端口,可以往前面翻下我的zookeeper安装配置说明

  5. 进行测试访问

    测试一:

    image-20220507112318203

    测试二:

    image-20220507112333785

六、dubbo的配置

6.1 配置原则

在服务提供者配置访问参数,因为服务提供者更了解服务的各种参数

6.2 关闭检查

​ dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true.通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
​ **例1:**关闭某个服务的启动时检查
<dubbo:reference interface=“com.foo.BarService” check=“false” />
​ **例2:**关闭注册中心启动时检查
<dubbo:registry check=“false” />
默认启动服务时检查注册中心存在并已运行。注册中心不启动会报错。

6.3 重试次数

​ 消费者访问提供者,如果访问失败,则切换重试访问其它服务器,但重试会带来更长延迟。访问时间变长,用户的体验较差。多次重新访问服务器有可能访问成功。可通过retries="2"来设置重试次数(不含第一次)。

​ 重试次数配置如下

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

6.4 超时时间

​ 由于网络或服务端不可靠,会导致调用出现- - 种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。
timeout:调用远程服务超时时间(毫秒)

消费端
<dubbo:consumer timeout="5000" /><dubbo:server interface="com.foo.BarService" timeout="2000" />

服务端
<dubbo:provider timeout="5000" /><dubbo:provider interface="com.foo.BarService" timeout="2000"/>

6.5 版本号

​ 每个接口都应定义版本号,为后续不兼容升级提供可能。当一个接口有不同的实现,项目早期使用的一个实现类,之 后创建接口的新的实现类。区分不同的接口实现使用version。

七、监控中心(dubbo-admin)

​ Dubbo的使用,其实只需要有注册中心,消费者,提供者这三个就可以使用了,但是并不能看到有哪些消费者和提供者,为了更好的调试,发现问题,解决问题,因此引入dubbo-admin。通过dubbo-admin 可以对消费者和提供者进行管理。可以在dubbo应用部署做动态的调整,服务的管理。

7.1 Window下安装Dubbo-admin

注意:dubbo-admin可能会使用20880端口,所以在编写生产者的时候要修改生产者的dubbo的端口号

是一个监控管理后台,查看我们注册了哪些服务,哪些服务被消费了

dubbo本身并不是一个服务软件。它其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。

但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubbo-admin,不过这个监控即使不装也不影响使用。

安装步骤:

  1. 下载dubbo-admin

    https://github.com/apache/dubbo-admin

    左侧选择master后在code中下载zip

    image-20220315201441763

  2. 进入解压后的目录,进入\dubbo-admin-server\src\main\resources

    该目录下有一个application.properties,双击打开该文件

    由于dubbo-admin后台服务端口默认为8080,可能会与tomcat的端口产生冲突,所以我们需要在application.properties中修改默认端口

    修改方法:在文件末尾加入server.port=7001,即将其默认端口修改为7001

    其它需要修改的可以参考如下:(我的话是只修改了端口号就可以了

    server.port=7001
    spring.velocity.cache=false
    spring.velocity.charset=UTF-8
    spring.velocity.layout-url=/templates/default.vm
    spring.messages.fallback-to-system-locale=false
    spring.messages.basename=i18n/message
    spring.root.password=root
    spring.guest.password=guest
    
    dubbo.registry.address=zookeeper://127.0.0.1:2181
    
  3. 项目目录下cmd中打包dubbo-admin(第一次打包过程可能有点慢)

    mvn clean package -Dmaven.test.skip=true
    

    image-20220315201811796

  4. 打包完成后,会生成如图的jar包,可能不是这个名字

    image-20220315204659543

  5. 进入\dubbo-admin-distribution\target\下可以找到这个jar包(应该就在这个位置,如果不在这个位置,可以去其它文件夹的target目录下找一找)

    image-20220315204751378

  6. 执行 \dubbo-admin-distribution\target\ 下的dubbo-admin-0.3.0.jar(前提:zookeeper的服务一定要打开,即运行zkServer.cmd

    打开cmd在该路径下运行:

    java -jar dubbo-admin-0.3.0.jar
    
  7. 执行完毕,我们去访问一下http://localhost:7001/,这时候我们需要输入登录账户和密码,我们都是默认的root,如果需要修改的话,可以在第二步的properties中修改,然后重新打包

    image-20220315205325079

7.2运行dubbo-admin应用

  1. 先启动注册中心
  2. 执行提供者项目
  3. 执行dubbo-admin的jar包
  4. 执行消费者项目
  5. 游览器中输入localhost:7001访问监控中心控制台(默认用户名和密码都是root)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的大雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值