Dubbo的学习

目录

01【掌握】分布式基础理论

1.1,什么是分布式系统?

1.2发展演变

1.2.1单一应用架构 

 1.2.2垂直应用架构

 1.2.3分布式服务架构

1.2.4流动计算架构 

1.3RPC 

1.3.1什么叫RPC

1.3.2RPC基本原理 

02【了解】taobao网的技术演变 

03【掌握】dubbo核心概念

3.1,简介

3.2,基本概念

04【掌握】dubbo环境搭建windows 

        前提:配置JAVA的环境变量

4.1下载并且安装zookeeper

4.2安装dubbo的服务治理

4.2.1下载 

 4.2.2、加压包说明dubbo-admin  

4.3、进入dubbo-admin修改配置 

​4.4、进入dubbo-admin目录打包

4.5运行dubbo-admin 

 4.6测试

 05【掌握】dubbo环境搭建linux

5.1.在阿里云上启动zookeeper

5.2.上传dobbo-admin.jar

测试

06【掌握】dubbo-spring的集成XML

6.1,提出需求

6.2,创建项目

6.3创建ego_interface 

6.3.1创建项目

6.3.2修改pom.xml

6.3.3创建UserAddress

6.3.4.创建UserService

6.3.5.创建OrderService

6.4.创建ego_user_service_provider【提供者】

6.4.1.创建项目

6.4.2.修改pom.xml加入对ego_interface的依赖 

6.4.3.创建UserServiceImpl

6.4.4.修改pom.xml加入dubbo和zk以及netty的依赖

6.4.5.创建applicationContext.xml的配置文件

6.4.6.启动程序向注册中心注册

6.5.创建ego_order_service_consumer【消费者】

6.5.1.创建项目

6.5.3.创建OrderServiceImpl

6.5.4.修改pom.xml加入dubbo和zk以及netty的依赖

6.5.5.创建applicationContext.xml

6.5.6.测试

7.注解的配置方法

7.1.修改ego_user_service_provider

7.1.1.applicationContext.xml

7.1.2.UserServiceImpl 

7.2.修改ego_order_service_consumer

7.2.1.applicationContext.xml

7.2.2.OrderServiceImpl

8.【掌握】监控中心 8.1.dubbo-monitor-simple

9.【掌握】dubbo整合SpringBoot方式

9.1.概述

9.2.创建boot-ego-user-service-provider 

9.2.1.创建项目

9.2.2.修改pom.xml加入依赖

9.2.3.复制UserServiceImpl

9.2.4.修改application.properties 或yml文件

9.2.5.修改启动类并启动

9.3.创建boot-ego-order-service-comsumer

9.3.1.创建项目

9.3.2.修改pom.xml

9.3.3.复制OrderServiceImpl

9.3.4.修改启动类启动

9.3.5.修改yml文件

9.3.6.测试

10.使用dubbo完成service和web的解耦合 

10.1.项目的创建 

10.1.1.创建项目user-center

10.1.2.创建user-domain

10.1.3.创建user-mapper

10.1.4.创建user-api 

10.1.5.创建user-service 

10.1.6.创建user-web 

10.1.7.项目的内部依赖关系 

10.1.8代码生成 

10.2. 解决外部的依赖关系

10.2.1.user-domain

domain 里面报错,因为没有lombok,在domain 里面依赖lombok

10.2.2.user-mapper

10.2.3.user-api

10.2.4.user-service

10.2.5.user-center的父项目

10.2.6.user-web

10.3.添加配置文件

10.4.在user-web中添加springboot的启动类

10.5.创建UserController 

10.6.启动测试访问

10.7.完成解耦合 

10.7.1修改user-service

 10.7.2修改user-web

11.【掌握】dubbo配置文件加载顺序

1,-Ddubbo.protocol.port=20881

2,-XML

3,-dubbo.properties文件

12.【掌握】dubbo的超时处理

        修改UserServiceImpl

12.1.Xml的配置方法超时

12.1.1.提供者(优先配置) 

12.1.2.消费者 

12.2.注解析配置方法超时

提供者

13【掌握】配置覆盖原则 

阶段总结

覆盖总结

14【掌握】dubbo的启动时检查

14.1什么是启动时检查?

14.2XML的配置

14.3注解的配置 

接口级别的配置

15【掌握】dubbo的重试原则 

为什么要重试

15.1XML的配置 

提供者的配置

15.2注解的配置 

提供者的配置

15.3 如何设置不重试 

 15.4什么时使用重试,什么时候不使用

16.【掌握】dubbo的灰度发布 

16.1.什么是灰度发布

16.2.配置测试逻辑

16.3.创建UserService2Impl

16.5.具体配置[注解]

17.【掌握】dubbo的本地存根

17.1.概述

17.2,XML的配置 

本地存根是针对消费者的

在消费者创建StubUserServiceImpl

17.3,注解的配置 

18【掌握】zookeeper宕机与dubbo直连

18.1.宕机直连1

18.2.宕机直连2

19【掌握】集群下dubbo负载均衡配置 

19.1.概述

19.2.Random LoadBalance【默认的】

 19.3.RoundRobin LoadBalance

19.4.LeastActive LoadBalance 

19.5.ConsistentHash LoadBalance

19.6.测试思路

19.7.动态权重修改

19.7.1.写死[通过dubbo-admin的界面不能修改了]

19.7.2.动态

19.7.3.精确调整

19.8.动态负载策略

20.【掌握】整合hystrix,服务熔断与降级处理 

20.1.服务降级

20.2.集群容错 

20.3整合hystrix  --spring clould 里面的非常核心的技术

20.3.1.配置spring-cloud-starter-netflix-hystrix

  然后在Application类上增加@EnableHystrix来启用hystrix starter:

20.3.2.配置Consumer端 

21.【熟悉】RPC原理和通信原理 

21.1.rpc原理

21.2.netty通信原理 

22.【面试】相关面试题的处理

22.1.Dubbo是什么?

22.2.为什么要用Dubbo? 

22.3.Dubbo 和 Spring Cloud 有什么区别? 

22.4.dubbo都支持什么协议,推荐用哪种? 

22.5.Dubbo需要 Web 容器吗?

22.6.Dubbo内置了哪几种服务容器? 

22.7.Dubbo里面有哪几种节点角色? 

22.8.画一画服务注册与发现的流程图 

22.9.Dubbo默认使用什么注册中心,还有别的选择吗?

22.10.Dubbo有哪几种配置方式?

22.11.Dubbo 核心的配置有哪些?  

22.12.在 Provider 上可以配置的 Consumer 端的属性有哪些?

 22.13.Dubbo启动时如果依赖的服务不可用会怎样?

22.14.Dubbo推荐使用什么序列化框架,你知道的还有哪些?

22.15.Dubbo默认使用的是什么通信框架,还有别的选择吗?

22.16.Dubbo有哪几种集群容错方案,默认是哪种? 

22.17.Dubbo有哪几种负载均衡策略,默认是哪种? 

22.18.注册了多个同一样的服务,如果测试指定的某一个服务呢? 

22.19.Dubbo支持服务多协议吗?

22.20.当一个服务接口有多种实现时怎么做?

22.21.服务上线怎么兼容旧版本?

22.22.Dubbo可以对结果进行缓存吗?

22.23.Dubbo服务之间的调用是阻塞的吗? 

 22.24.Dubbo支持分布式事务吗?

22.25.服务提供者能实现失效踢出是什么原理?

22.26.如何解决服务调用链过长的问题?

22.27.服务读写推荐的容错策略是怎样的?

22.28.Dubbo必须依赖的包有哪些?

22.29.Dubbo的管理控制台能做什么?

22.30.说说 Dubbo 服务暴露的过程。

 22.31.你还了解别的分布式框架吗?

22.32.Dubbo 能集成 Spring Boot 吗?

22.33.在使用过程中都遇到了些什么问题?

22.34.你觉得用 Dubbo 好还是 Spring Cloud 好? 


01【掌握】分布式基础理论

1.1,什么是分布式系统?

《分布式系统原理与范型》定义:

“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”

分布式系统(distributed system)是建立在网络之上的软件系统。

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

1.2发展演变

1.2.1单一应用架构 

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。

适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。

缺点: 1、性能扩展比较难 

       2、协同开发问题

       3、不利于升级维护

 1.2.2垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键

通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展也更方便,更有针对性。

缺点: 公用模块无法重复利用,开发性的浪费

 1.2.3分布式服务架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

1.2.4,流动计算架构 

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)[ Service Oriented Architecture]是关键。

1.3RPC 

1.3.1什么叫RPC

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。

1.3.2RPC基本原理 

 RPC两个核心模块:通讯,序列化

要拍照(题目--->照片) 序列化

要发短信(建立socket)

要接受短信(serverSocket)

图片->文本(图片-->题目) 反序列化

要计算题目 (调用方法计算题目)

要发送答案  (使用socket发送完成)

02【了解taobao网的技术演变 

https://www.cnblogs.com/52czm/p/11097156.html

03【掌握】dubbo核心概念

3.1,简介

Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用智能容错和负载均衡,以及服务自动注册和发现

官网:http://dubbo.apache.org/

3.2,基本概念

 服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。

服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

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

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

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

04【掌握】dubbo环境搭建windows 

前提:配置JAVA的环境变量

4.1下载并且安装zookeeper

网址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/ 

解压zookeeper

解压运行zkServer.cmd ,初次运行会报错,没有zoo.cfg配置文件 

修改conf/zoo_sample.cfg----》zoo.cfg 

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

注意几个重要位置:

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

clientPort=2181 zookeeper的端口号

修改完成后再次启动zookeeper

启动

4.2安装dubbo的服务治理

4.2.1下载 

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

 4.2.2、加压包说明dubbo-admin  

Dubbo-admin dubbo的服务治理项目

Dubbo-monitor 这个监控项目

Dubbo-registry 自己的注册中心,一般我们使用zk

4.3、进入dubbo-admin修改配置 

 4.4、进入dubbo-admin目录打包

 mvn  package 

4.5运行dubbo-admin 

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

 4.6测试

http://127.0.0.1:7001/
默认使用root/root 登陆

 05【掌握】dubbo环境搭建linux

前提:配置JAVA的环境变量

5.1.在阿里云上启动zookeeper

 5.2.上传dobbo-admin.jar

mkdir /usr/local/dubbo-admin

启动

 放行阿里云7001的端口

测试

06【掌握】dubbo-spring的集成XML

6.1,提出需求

某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;

我们现在 需要创建两个服务模块进行测试 

模块

功能

订单服务web模块

创建订单等

用户服务service模块

查询用户地址等

测试预期结果:

 订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。 

6.2,创建项目

6.3创建ego_interface 

6.3.1创建项目

6.3.2修改pom.xml

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
</dependencies>

 6.3.3创建UserAddress

package com.wxz.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;

public class UserAddress implements Serializable {
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress {
    private Integer id;
    private String userAddress;
    private String userId;
}

6.3.4.创建UserService

package com.wxz.service;
import com.wxz.domain.UserAddress;
import java.util.List;


public interface UserService {
    /**
     * 根据用户ID查询用户地址列表
     * @param userId
     * @return
     */
    List<UserAddress> getUserAddressList(String userId);
}

6.3.5.创建OrderService

package com.wxz.service;

import com.wxz.domain.UserAddress;
import java.util.List;


public interface OrderService {

    /**
     * 初始化订单
     * @param userId
     * @return
     */
    List<UserAddress> initOrder(String userId);
}

6.4.创建ego_user_service_provider【提供者】

6.4.1.创建项目

6.4.2.修改pom.xml加入对ego_interface的依赖 

<!--加入对ego_interface依赖-->
<dependency>
  <groupId>com.wxz</groupId>
  <artifactId>ego_interface</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

6.4.3.创建UserServiceImpl

package com.wxz.service.impl;

import com.wxz.domain.UserAddress;
import com.wxz.service.UserService;

import java.util.ArrayList;
import java.util.List;


public class UserServiceImpl implements UserService {
    public static List<UserAddress> address=new ArrayList<>();

    static {
        address.add(new UserAddress(1, "湖北省武汉市东湖高新区金融港B22栋11楼", "wxz"));
        address.add(new UserAddress(2, "北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层尚学堂", "bjsxt"));
    }
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("提供者被调用,返回地址数据");
        return address;
    }
}

6.4.4.修改pom.xml加入dubbo和zk以及netty的依赖

<?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>com.wxz</groupId>
    <artifactId>ego_user_service_provider</artifactId>
    <version>1.0</version>
    <dependencies>
        <!--引入公共接口-->
        <dependency>
            <groupId>com.wxz</groupId>
            <artifactId>ego_interface</artifactId>
            <version>1.0</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.9</version>
        </dependency>

        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
        </dependency>
        <!-- curator-framework -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
    </dependencies>
</project>

6.4.5.创建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: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="ego_user_service_provider"></dubbo:application>
    <!--指定注册中心的地址-->
    <dubbo:registry address="zookeeper://47.105.128.151:2181"></dubbo:registry>
    <!--使用dubbo协议,将服务暴露在20880端口  -1代表自增的端口 从20880开始搜索-->
    <dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
    <!--创建UserServiceImpl-->
    <bean name="userServiceImpl" class="com.wxz.service.impl.UserServiceImpl"></bean>
    <!--使用dubbo把userServiceImpl这个对象暴露出去-->
    <dubbo:service interface="com.wxz.service.UserService" ref="userServiceImpl"></dubbo:service>
</beans>

 6.4.6.启动程序向注册中心注册


public class AppProvider
{
    public static void main( String[] args ) throws IOException {
        //加载applicationContext.xml
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        context.start();
        System.out.println("服务提供者启动成功");
        System.in.read();//阻止程序结束

    }
}

6.5.创建ego_order_service_consumer【消费者】

6.5.1.创建项目

6.5.2.修改pom.xml加入ego_interface的依赖

<!--加入对ego_interface依赖-->
<dependency>
  <groupId>com.wxz</groupId>
  <artifactId>ego_interface</artifactId>
  <version>1.0</version>
</dependency>

6.5.3.创建OrderServiceImpl


public class OrderServiceImpl implements OrderService {


    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public List<UserAddress> initOrder(String userId) {
        return userService.getUserAddressList(userId);
    }
}

6.5.4.修改pom.xml加入dubbo和zk以及netty的依赖

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.9</version>
</dependency>

<dependency>
  <groupId>com.101tec</groupId>
  <artifactId>zkclient</artifactId>
  <version>0.11</version>
</dependency>
<!-- curator-framework -->
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-framework</artifactId>
  <version>4.1.0</version>
</dependency>
<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>4.1.32.Final</version>
</dependency>

6.5.5.创建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: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
      http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--声明当前用户程序名称-->
    <dubbo:application name="ego_order_service_consumer"></dubbo:application>
    <!--指定注册中心的地址 -->
    <dubbo:registry address="zookeeper://47.105.128.151:2181" />

    <!--引入远程服务-->
    <dubbo:reference id="userService" interface="com.wxz.service.UserService" ></dubbo:reference>

    <!--创建对象-->
    <bean id="orderServiceImpl" class="com.wxz.service.impl.OrderServiceImpl">
        <property name="userService" ref="userService"></property>
    </bean>
</beans>

6.5.6.测试

public class AppConsumer
{
    public static void main( String[] args ) throws IOException {
        //加载applicationContext.xml
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        context.start();
        OrderService orderService = context.getBean(OrderService.class);

        List<UserAddress> userAddresses = orderService.initOrder("wxz");
        for (UserAddress userAddress : userAddresses) {
            System.out.println(userAddress.getId()+"  "+userAddress.getUserAddress());
        }
        System.out.println("服务消费者启动成功");
        System.in.read();
    }
}

 

7.注解的配置方法

7.1.修改ego_user_service_provider

7.1.1.applicationContext.xml

7.1.2.UserServiceImpl 

必须选dubbo 的

7.2.修改ego_order_service_consumer

7.2.1.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:dubbo="http://dubbo.apache.org/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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
      http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--声明当前用户程序名称-->
    <dubbo:application name="ego_order_service_consumer"></dubbo:application>
    <!--指定注册中心的地址 -->
    <dubbo:registry address="zookeeper://47.105.128.151:2181" />

    <!--引入远程服务-->
    <!--<dubbo:reference id="userService" interface="com.wxz.service.UserService" ></dubbo:reference>-->

    <!--创建对象-->
    <!--<bean id="orderServiceImpl" class="com.wxz.service.impl.OrderServiceImpl">-->
        <!--<property name="userService" ref="userService"></property>-->
    <!--</bean>-->
     <!--扫描dubbo的注解-->
    <dubbo:annotation package="com.wxz.service.impl"/>
     <!--扫描spring的注解-->
    <context:component-scan base-package="com.wxz.service.impl"></context:component-scan>
</beans>

7.2.2.OrderServiceImpl

 注解版本的总结:

1 添加在服务提供者Service上面的注解是:@Service(dubbo)

2 添加在服务的消费者上的属性的注解是:@Reference(dubbo)

3 在服务提供者里面的包扫描:<dubbo:annotation package=“dubbo注解所在的包”>

4 dubbo的包扫描只能扫描dubbo的注解,spring的注解需要你使用:<context:comp-scan>

8.【掌握】监控中心 
8.1.dubbo-monitor-simple

1、找到之前下载好的dubbo-admin里面的dubbo-monitor-simple项目

2、修改配置指定注册中心地址

进入 dubbo-monitor-simple\src\main\resources\conf

修改 dubbo.properties文件

3、打包dubbo-monitor-simple

mvn  package

4.解压dubbo-monitor-simple-2.0.0-assembly.tar.gz 

 

运行start.bat

启动之前,必须保证windows的zookeeker的运行

5,启动访问8080

9.【掌握】dubbo整合SpringBoot方式

9.1.概述

dubbo整合springboot和三种方式

  • 方式1:引入dubbo-starter,在application.properties配置属性,使用@Service【暴露服务】使用@Reference【引用服务】
  • 方式2:保留dubbo xml配置文件; 导入dubbo-starter,使用@ImportResource导入dubbo的配置文件即可
  • 方式3:使用注解API的方式, 将每一个组件手动创建到容器中,让dubbo来扫描其他的组件
可以查看githubhttps://github.com/apache/dubbo

9.2.创建boot-ego-user-service-provider 

9.2.1.创建项目

9.2.2.修改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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxz</groupId>
    <artifactId>boot-ego-user-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-ego-user-service-provider</name>
    <description>springboot整合dubbo的提供者</description>

    <properties>
        <java.version>1.8</java.version>
        <dubbo.version>2.7.7</dubbo.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--引入公共接口-->
        <dependency>
            <groupId>com.sxt</groupId>
            <artifactId>ego_interface</artifactId>
            <version>1.0</version>
        </dependency>

        <!--引入dubbo的相关依赖-->
        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- 使用zk 做注册中心,Dubbo 需要的依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

9.2.3.复制UserServiceImpl

package com.wxz.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.wxz.domain.UserAddress;
import com.wxz.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;

import java.util.ArrayList;
import java.util.List;


//@Service  //使用dubbo的Service的注解
//@org.apache.dubbo.config.annotation.Service
@DubboService  //2.7.7的版本开始使用这个 之前的版本使用@Service
public class UserServiceImpl implements UserService {
    public static List<UserAddress> address=new ArrayList<>();

    static {
        address.add(new UserAddress(1, "湖北省武汉市东湖高新区金融港B22栋11楼", "wxz"));
        address.add(new UserAddress(2, "北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层尚学堂", "bjsxt"));
    }
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("提供者被调用,返回地址数据");
        return address;
    }
}

9.2.4.修改application.properties 或yml文件

#application-name
dubbo.application.name=boot-ego-user-service-provider
#registry
dubbo.registry.address=zookeeper://47.105.128.151:2181
#dubbo protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

dubbo:
  application:
    name: boot-ego-user-service-provider
  registry:
    address: zookeeper://47.105.128.151:2181
  protocol:
    name: dubbo
    port: -1  #-1代表从20880开始先搜索没有没有使用,如果有就自增

9.2.5.修改启动类并启动

9.3.创建boot-ego-order-service-comsumer

9.3.1.创建项目

 9.3.2.修改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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wxz</groupId>
    <artifactId>boot-ego-order-service-comsumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-ego-order-service-comsumer</name>
    <description>springboot整合dubbo的消费者</description>

    <properties>
        <java.version>1.8</java.version>
        <dubbo.version>2.7.7</dubbo.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--引入公共接口-->
        <dependency>
            <groupId>com.wxz</groupId>
            <artifactId>ego_interface</artifactId>
            <version>1.0</version>
        </dependency>

        <!--引入dubbo的相关依赖-->
        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- 使用zk 做注册中心,Dubbo 需要的依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

9.3.3.复制OrderServiceImpl

package com.wxz.service.impl;
import com.wxz.domain.UserAddress;
import com.wxz.service.OrderService;
import com.wxz.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import java.util.List;

@Service  //使用的spring里面的注解
public class OrderServiceImpl implements OrderService {
    @DubboReference  //引用
    private UserService userService;

    @Override
    public List<UserAddress> initOrder(String userId) {
        return userService.getUserAddressList(userId);
    }
}

9.3.4.修改启动类启动

9.3.5.修改yml文件

dubbo:
  application:
    name: boot-ego-order-service-comsumer
  registry:
    address: zookeeper://47.105.128.151:2181
    timeout: 10000
  config-center:
    timeout: 10000 #解决zookeeper有时候超时的问题

9.3.6.测试

10.使用dubbo完成service和web的解耦合 

10.1.项目的创建 

项目都是简单的maven项目

10.1.1.创建项目user-center

10.1.2.创建user-domain

 10.1.3.创建user-mapper

10.1.4.创建user-api 

10.1.5.创建user-service 

10.1.6.创建user-web 

最后的项目结构效果: 

10.1.7.项目的内部依赖关系 

10.1.8代码生成 

10.2. 解决外部的依赖关系

10.2.1.user-domain

domain 里面报错,因为没有lombok,在domain 里面依赖lombok

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
    </dependency>
</dependencies>

10.2.2.user-mapper

mapper 里面暂时不需要添加额外依赖

<dependencies>
    <dependency>
        <groupId>com.bjsxt</groupId>
        <artifactId>user-domain</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

10.2.3.user-api

api 里面也不需要添加额外的依赖

<dependencies>
    <dependency>
        <groupId>com.bjsxt</groupId>
        <artifactId>user-domain</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

10.2.4.user-service

service 里面需要添加spring-context 依赖

<dependencies>
    <dependency>
        <groupId>com.bjsxt</groupId>
        <artifactId>user-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>com.bjsxt</groupId>
        <artifactId>user-mapper</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.2</version>
    </dependency>
</dependencies>

10.2.5.user-center的父项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.1</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

我们的项目瞬间变成了spring boot 项目

10.2.6.user-web

需要添加 web ,mybaits,mysql 驱动的依赖

<dependencies>
    <dependency>
        <groupId>com.bjsxt</groupId>
        <artifactId>user-service</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

10.3.添加配置文件

server:
  port: 8001
spring:
  application:
    name: user-center
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123456

#配置mybatis-plus
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #输出sql
  mapper-locations:
    - classpath:mapper/*Mapper.xml

10.4.在user-web中添加springboot的启动类

10.5.创建UserController 

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService ;

    @GetMapping("/{id}")
    public User selectUser(@PathVariable("id") Integer id){
        User user = userService.selectByPrimaryKey(id);
        return user ;
    }
}

10.6.启动测试访问

10.7.完成解耦合 

之前user-web依赖的是user-service,在userController里面进行本地调用

现在修改,user-web里面只依赖user-api,不依赖user-service,使用rpc进行远程调用

10.7.1修改user-service

pom.xml,引入dubbo,暴露服务,user-service作为服务的提供者

 <properties>

        <dubbo.version>2.7.7</dubbo.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.bjsxt</groupId>
            <artifactId>user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.bjsxt</groupId>
            <artifactId>user-mapper</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


        <!--<dependency>-->
            <!--<groupId>org.springframework</groupId>-->
            <!--<artifactId>spring-context</artifactId>-->
            <!--<version>5.3.2</version>-->
        <!--</dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>


        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>

        <!-- 使用zk 做注册中心,Dubbo 需要的依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

    </dependencies>

创建启动类,开启dubbo,mapper的包扫描

@SpringBootApplication
@EnableDubbo
@MapperScan("com.bjsxt.mapper")
public class UserServiceApp {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApp.class,args) ;
        System.out.println("user-service启动成功");
    }
}

创建application.xml

spring:
  application:
    name: user-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123456

#配置mybatis-plus
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #输出sql
  mapper-locations:
    - classpath:mapper/*Mapper.xml


#dubbo的服务提供者的配置
dubbo:
  application:
    id: ${spring.application.name}
    name: ${spring.application.name}
  registry:
    address: zookeeper://81.68.123.67:2181
    timeout: 20000
  protocol:
    port: 20880
    name: dubbo
  scan:
    base-packages: com.bjsxt.service.impl

修改userServiceImpl

 10.7.2修改user-web

修改pom.xml

 <properties>
        <dubbo.version>2.7.7</dubbo.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.bjsxt</groupId>
            <artifactId>user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- 使用zk 做注册中心,Dubbo 需要的依赖 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

修改application.yml  加入dubbo的配置,去掉mybatis的配置和数据库的连接

server:
  port: 8001
spring:
  application:
    name: user-web
#dubbo消费者的配置
dubbo:
  application:
    name: ${spring.application.name}
    id: ${spring.application.name}
  registry:
    address: zookeeper://81.68.123.67:2181
    timeout: 20000
  scan:
    base-packages: com.bjsxt.controller

修改userController

修改启动类

测试

启动服务提供者

 启动服务消费者: 

启动dubbo观察服务的提供者和消费者

测试:远程调用

11.【掌握】dubbo配置文件加载顺序

以提供者为例说明 

1,-Ddubbo.protocol.port=20881

2-XML

3-dubbo.properties文件

 启动测试发现注册的是20881

JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。

XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。

Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。

12.【掌握】dubbo的超时处理

为什么会有超时处理??

当消费者调用提供时,提供者执行的时间过长,会超时,消费者会认为服务调用失败

调用失败之后就会进行重试默认会重试二次

修改UserServiceImpl

注册启动消费者报错(timeout超时)

 并会重试【默认二次】

12.1.Xml的配置方法超时

12.1.1.提供者(优先配置) 

全局超时配置

超时的优先级:提供者全局的<提供者接口级别<提供方法级别 

12.1.2.消费者 

清除提供者里面所有超时的配置

配置消费者

 超时级别:消费者全局的<消费者接口级别< 消费方法级别

12.2.注解析配置方法超时

提供者

消费者

13【掌握】配置覆盖原则 

什么是覆盖???

因为配置可以提供者和消费者配置

问题1:如果在同一个位置都配置了,那么谁的优先级高

问题2:实际开发中配置哪一个

提供者全局给3秒提供者方法睡2秒消费者全局给1秒

问题:是否超时间?    超时

说明

在全局级别 消费者的优先级大于提供者

提供者接口3秒提供者方法睡2秒消费者接口给1秒

问题:是否超时间?    超时

说明

在接口级别 消费者的优先级大于提供者

提供者方法3秒提供者方法睡2秒消费者方法给1秒

问题:是否超时间?    超时

说明
在方法级别 消费者的优先级大于提供者

阶段总结

同一个级别,消费者的优先级大于提供者

提供者接口3秒提供者方法睡2秒消费者全局给1秒

是否超时  :不超时

说明
提供者的接口级别>消费者的全局级别

提供者方法3秒提供者方法睡2秒消费者接口给1秒

是否超时  :不超时

说明
提供者的方法级别>消费者的接口级别

覆盖总结

消费者方法>提供者方法>消费者接口级别>提供者接口级别>消费者全局级别>提供者全局

1) 方法级配置别优于接口级别,即小Scope优先 

2) Consumer端配置 优于 Provider配置 优于 全局配置,

实际开发中是配置提供者还是消费者??

实际开发中配置提供者

没有人比自己更了解自己

服务器最了解我自己

14【掌握】dubbo的启动时检查

14.1什么是启动时检查?

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"。

可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。

说白就是 如果提供者没有上线,启动消费者默认会报错 ,关闭检查之后只要不使用远程引用户对象,就不会报错

启动检查配置在消费者方

14.2XML的配置

消费者

14.3注解的配置 

接口级别的配置

 全局配置

15【掌握】dubbo的重试原则 

为什么要重试

15.1XML的配置 

提供者的配置

消费者的配置

15.2注解的配置 

提供者的配置

 消费者的配置

15.3 如何设置不重试 

在xml里面设置   0  提供者和消费者只设置一个

注解的设置  -1

 15.4什么时使用重试,什么时候不使用

针对于幂等性操作  ==无论方法执行多少次,结果一样 查询  修改  删除

针对于非幂等性操作 ==方法每次执行结果不一样   添加

|--在实际开发中,非幂等性操作一定要设置重试次数为0 == 要么新增一个,要么不新增

16.【掌握】dubbo的灰度发布 

16.1.什么是灰度发布

当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。

可以按照以下的步骤进行版本迁移:

低压力时间段,先升级一半提供者为新版本

然后将剩下的一半提供者升级为新版本

16.2.配置测试逻辑

现在情况  有一个UserServiceImpl ---提供者  1.0.0

再创建一个 UserService2Impl的实现类  ---提供者  2.0.0

修改消费者指定版本号

16.3.创建UserService2Impl

package com.wxz.service.impl;

import com.wxz.domain.UserAddress;
import com.wxz.service.UserService;

import java.util.ArrayList;
import java.util.List;


//@Service  //使用dubbo的Service的注解
public class UserService2Impl implements UserService {
    public static List<UserAddress> address=new ArrayList<>();

    static {
        address.add(new UserAddress(1, "湖北省武汉市东湖高新区金融港B22栋11楼", "whsxt"));
        address.add(new UserAddress(2, "北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层", "bjsxt"));
    }
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("UserService2Impl--提供者被调用,返回地址数据");
        return address;
    }
}
老版本服务提供者配置:
<dubbo:service interface="com.wxz.service.impl.UserServiceImpl" version="1.0.0" />

新版本服务提供者配置:
<dubbo:service interface="com.wxz.service.impl.UserServiceImpl2" version="2.0.0" />

老版本服务消费者配置:
<dubbo:reference id="userService" interface="com.wxz.service.UserService" version="1.0.0" />

新版本服务消费者配置:
<dubbo:reference id="userService" interface="com.wxz.service.UserService" version="2.0.0" />

如果不需要区分版本,可以按照以下的方式配置:
<dubbo:reference id="userService" interface="com.wxz.service.UserService" version="*" />

16.5.具体配置[注解]

17.【掌握】dubbo的本地存根

17.1.概述

远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub [1],然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。

17.2,XML的配置 

本地存根是针对消费者的

在消费者创建StubUserServiceImpl


public class StubUserServiceImpl implements UserService {

    private UserService userService;

    public StubUserServiceImpl(UserService userService) {
        this.userService=userService;
    }

    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("本地存根执行=---开始");
        //做远程调用
        List<UserAddress> addressList=null;
       try {
           addressList = userService.getUserAddressList(userId);
       }catch (Exception e){
           e.printStackTrace();
           addressList= Arrays.asList(new UserAddress(1,"地址获取出错",""));
       }
        System.out.println("本地存根执行----结束");
        return addressList;
    }
}

    }

    private void before() {
        System.out.println("before");
    }
}

 配置XML

17.3,注解的配置 

18【掌握】zookeeper宕机与dubbo直连

18.1.宕机直连1

1 注册中心和dubbo-admin正常   当提供者启动后注册成功。

2 手动停掉zk  

问题1:启动消费者时默认能不能调用 ?

|-- 不能启动(不注释zk的配置文件),因为消费者启动要连接zk ,zk 挂了,它无法启动了

|--不能调用 因为默认的消费者会从ZK里面拉取服务地址,因为zk挂了,所以无法调用

问题2:启动消费者使用dubbo直连的形式能不能调?

|--可以调用的

修改配置文件 

消费者上的注解的配置

 XML配置 

18.2.宕机直连2

1 启动zk

2 启动服务的提供者

3 启动服务的消费者(打开zk配置,删除url的配置)

4 测试调用一次

5 停止zk

 6 在测试调用一次

消费者调用成功后,会将服务提供者的url 地址缓存起来,就算zk 挂了,我也可以从缓存里面得到一个url值。 

7 若我再启动一个服务的提供者呢?

  | 提供者无法上线:因为无法连接zk

8.若zk 是因为网络和消费者无法连接,但是zk 和提供者能连接,现在我启动提供者能成功?

     zk 可以调用缓存的服务提供者的值,但是以后新上线机器,它无法调用

19【掌握】集群下dubbo负载均衡配置 

19.1.概述

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。

负载均衡策略

19.2.Random LoadBalance【默认的】

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

测试时:启动多个服务的提供者:

让他们有查询的打印:

启动3 个,成功后:

测试:

 19.3.RoundRobin LoadBalance

轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

19.4.LeastActive LoadBalance 

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

19.5.ConsistentHash LoadBalance

一致性 Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />
缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />

19.6.测试思路

1,启动3个提供者20880   20881    20882 

2,启动提供者不加可以看出默认的是random

3,修改成randomrobin的方式再来测试

19.7.动态权重修改

19.7.1.写死[通过dubbo-admin的界面不能修改了]

19.7.2.动态

19.7.3.精确调整

19.8.动态负载策略

20.【掌握】整合hystrix,服务熔断与降级处理 

20.1.服务降级

什么是服务降级?

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。

演示屏蔽  在消费者端把A服务器屏蔽。再去请求,发现没有提供者可用

20.2.集群容错 

演示容错  在消费者端把A服务的超时时间设置成1000  把对应调用了提供者睡眠2000,再来调用测试

屏蔽容错有什么区别

容错和降级(屏蔽)都是返回了一个null 的值。

思考:容错和降级后,是否去调用了服务的提供者?不会调用,消费端直接返回了null的处理

1 容错,到底能解决什么问题呢?

我们远程服务不可用的最重要的原因可能是线程池满了,不可用,此时,我们通过容错的机制,让我们当前服务,不受远程服务的影响,继续能对外提供服务,而不是一直等待远程直到超时,这样的话,可以避免我们自己受到影响。(服务的雪崩现象)

 2 我们是否可以不返回null的处理?

 我们可以不去调用远程服务,而直接返回null,可以解决这个问题,但是最好的方式,是有一个人能自动的感知远程服务的状态,能动态的决定,我是否要求远程调用。

 3 降级它可以把自己禁用掉,不占用系统的资源,把资源留给重要的人

20.3整合hystrix  --spring clould 里面的非常核心的技术

Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能

20.3.1.配置spring-cloud-starter-netflix-hystrix

spring boot官方提供了对hystrix的集成,直接在消费者的:pom.xml里加入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>

  然后在Application类上增加@EnableHystrix来启用hystrix starter:

20.3.2.配置Consumer端 

对于Consumer端,则可以增加一层method调用,并在method上配置@HystrixCommand。当调用出错时,会走到fallbackMethod = "reliable"的调用里。

20.3.2.1.创建UserServiceFallback

20.3.2.2.让远程调用者OrderServiceImpl继承该Fallback

20.3.2.3.在远程调用的方法上面必须添加HystrixCommand 

20.3.2.4.测试的步骤

先正常调用服务的提供者,调用一会后,突然停止服务的提供者,就会发现下面的情况

21.【熟悉】RPC原理和通信原理 

学习地址

https://www.bilibili.com/video/av73964204

21.1.rpc原理

 一次完整的RPC调用流程(同步调用,异步另说)如下: 

1)服务消费方(client)调用以本地调用方式调用服务; 

2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体; 

3)client stub找到服务地址,并将消息发送到服务端; 

4)server stub收到消息后进行解码;   

5)server stub根据解码结果调用本地的服务; 

6)本地服务执行并将结果返回给server stub; 

7)server stub将返回结果打包成消息并发送至消费方; 

8)client stub接收到消息,并进行解码; 

9)服务消费方得到最终结果。

RPC框架的目标就是要2~8这些步骤都封装起来,这些细节对用户来说是透明的,不可见的。 

21.2.netty通信原理 

1 Dubbo 使用的是单一的长连接(对应高并发),对应的tomcat 就是短连接。

2 dubbo 里面使用的是NIO 。底层实现比较难,但是有个框架(netty)完美的封装了它。

在dubbo 里面,并没有使用ServerSocket,ServerSocket是BIO ,ServerSocket 换成Netty就可以了

Netty是一个异步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务器和客户端。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。

Sockt    ---->SocketServer

BIO:(Blocking IO)

Netty 就是一个好用(简单的NIO的模型)的Socket;

BIO: 阻塞的IO ,accept 阻塞,read 阻塞,write阻塞,既然阻塞了,线程不往下走了,若我们要实现高并发,就要使用线程池。 使用BIO的模型,特别浪费线程。

NIO : 非阻塞的IO ,read ,write 不阻塞。因从,我们不需要多个线程来完成,需要一个轮询就可以了。我们的线程就不会浪费。

bio 和nio的对比:

bio: 阻塞的,浪费线程的IO

nio: 非阻塞的,节约线程的io

读写非常密集时?BIO 要优与NIO, 因为线程在一个IO 上会占用非常多的时间。

 bio和nio的学习

https://zhuanlan.zhihu.com/p/23488863

22.【面试】相关面试题的处理

22.1.Dubbo是什么?

Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。

22.2.为什么要用Dubbo? 

因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、Zookeeper,保证了高性能高可用性。
使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
最重要的一点是,分布式架构可以承受更大规模的并发流量。

22.3.Dubbo 和 Spring Cloud 有什么区别? 

两个没关联,如果硬要说区别,有以下几点。

1)通信方式不同

Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。

2)组成部分不同

22.4.dubbo都支持什么协议,推荐用哪种? 

dubbo://(推荐)

rmi://

hessian://

http://  DUBBO

webservice://

thrift://

memcached://

redis://

rest://

22.5.Dubbo需要 Web 容器吗?

不需要,如果硬要用 Web 容器,只会增加复杂性,也浪费资源。

22.6.Dubbo内置了哪几种服务容器? 

Spring Container

Jetty Container

Log4j Container

Dubbo 的服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。

22.7.Dubbo里面有哪几种节点角色? 

22.8.画一画服务注册与发现的流程图 

22.9.Dubbo默认使用什么注册中心,还有别的选择吗?

推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。

22.10.Dubbo有哪几种配置方式?

1)Spring 或springboot配置方式
2)Java API 配置方式

22.11.Dubbo 核心的配置有哪些?  

22.12.在 Provider 上可以配置的 Consumer 端的属性有哪些?

1)timeout:方法调用超时
2)retries:失败重试次数,默认重试 2 次
3)loadbalance:负载均衡算法,默认随机
4)actives 消费者端,最大并发调用限制

 22.13.Dubbo启动时如果依赖的服务不可用会怎样?

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check="true",可以通过 check="false" 关闭检查。

22.14.Dubbo推荐使用什么序列化框架,你知道的还有哪些?

推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。

22.15.Dubbo默认使用的是什么通信框架,还有别的选择吗?

Dubbo 默认使用 Netty 框架,也是推荐的选择,另外内容还集成有Mina、Grizzly。

22.16.Dubbo有哪几种集群容错方案,默认是哪种? 

22.17.Dubbo有哪几种负载均衡策略,默认是哪种? 

22.18.注册了多个同一样的服务,如果测试指定的某一个服务呢? 

可以配置环境点对点直连,绕过注册中心,将以服务接口为单位,忽略注册中心的提供者列表。

22.19.Dubbo支持服务多协议吗?

Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。

22.20.当一个服务接口有多种实现时怎么做?

当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group 即可。

22.21.服务上线怎么兼容旧版本?

可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。

22.22.Dubbo可以对结果进行缓存吗?

可以,Dubbo 提供了声明式缓存,用于加速热门数据的访问速度,以减少用户加缓存的工作量。

22.23.Dubbo服务之间的调用是阻塞的吗? 

默认是同步等待结果阻塞的,支持异步调用。

Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。

异步调用流程图如下。

 22.24.Dubbo支持分布式事务吗?

目前暂时不支持,后续可能采用基于 JTA/XA 规范实现

22.25.服务提供者能实现失效踢出是什么原理?

服务失效踢出基于 Zookeeper 的临时节点原理。

22.26.如何解决服务调用链过长的问题?

Dubbo 可以使用 Pinpoint 和 Apache Skywalking(Incubator) 实现分布式服务追踪,当然还有其他很多方案。

22.27.服务读写推荐的容错策略是怎样的?

读操作建议使用 Failover 失败自动切换,默认重试两次其他服务器。
写操作建议使用 Failfast 快速失败,发一次调用失败就立即报错。

22.28.Dubbo必须依赖的包有哪些?

Dubbo 必须依赖 JDK,其他为可选。

22.29.Dubbo的管理控制台能做什么?

管理控制台主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。

22.30.说说 Dubbo 服务暴露的过程。

Dubbo 会在 Spring 实例化完 bean 之后,在刷新容器最后一步发布 ContextRefreshEvent 事件的时候,通知实现了 ApplicationListener 的 ServiceBean 类进行回调 onApplicationEvent 事件方法,Dubbo 会在这个方法中调用 ServiceBean 父类 ServiceConfig 的 export 方法,而该方法真正实现了服务的(异步或者非异步)发布。   

 22.31.你还了解别的分布式框架吗?

别的还有 Spring cloud。

22.32.Dubbo 能集成 Spring Boot 吗?

可以的,

22.33.在使用过程中都遇到了些什么问题?

Dubbo 的设计目的是为了满足高并发小数据量的 rpc 调用,在大数据量下的性能表现并不好,建议使用 rmi 或 http 协议。

22.34.你觉得用 Dubbo 好还是 Spring Cloud 好? 

扩展性的问题,没有好坏,只有适合不适合,不过我好像更倾向于使用 Dubbo, Spring Cloud 版本升级太快,组件更新替换太频繁,配置太繁琐,还有很多我觉得是没有 Dubbo 顺手的地方…… 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值