一、 Spring Cloud Alibaba简介

1 简介

Spring Cloud Alibaba 是Spring 公司下顶级项目Spring Cloud 的二级子项目。
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。该项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
2018年10月31日,Spring Cloud Alibaba正式入驻Spring Cloud 官方孵化器,并在Maven中央仓库中发布第一个版本:Spring Cloud for Alibaba 0.2.0 released版本。目前可以在https://mvnrepository.com/查找到的最老版本1.5.0.RELEASE版本。最早时间为2019年8月。

https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies

Spring Cloud Alibaba Dubbo服务调用 - 图1

2 依赖管理

Spring Cloud Alibaba 软件环境分为两大类:

2.1 自己部署服务器

所有软件及服务器自己进行管理提供,可以直接在项目中添加Spring Cloud依赖。推荐




com.alibaba.cloud
spring-cloud-alibaba-dependencies
{project-version}
pom
import


2.2 使用阿里云

如果希望使用阿里云服务。则需要导入阿里云对应的依赖。 不推荐,早期使用




com.alibaba.cloud
aliyun-spring-boot-dependencies
{project-version}
pom
import


3 核心组件

Spring Cloud Alibaba和 Spring Cloud Netflix 同属于Spring Cloud 下三大阵营产品之一。内部提供了一系列组件。

3.1 Spring Cloud Alibaba Nacos Discovery

Nacos是由阿里巴巴推出的用于构建云本机应用程序的易于使用的动态服务发现,配置和服务管理平台。
Nacos Discovery 是使用Nacos的服务注册与发现功能。在Spring Cloud Alibaba中常使用Nacos作为注册中心。

3.2 Spring Cloud Alibaba Nacos Config

Nacos Config 是利用Nacos作为分布式配置中心使用。

3.3 Spring Cloud Alibaba Sentinel

Sentinel是Spring Cloud Alibaba体系中提供服务限流,断路和负载保护的解决方案。已经成功的在阿里巴巴双十一活动中运行10余年。可靠性非常高。

3.4 Spring Cloud Alibaba Dubbo

Dubbo 是阿里巴巴于2011年对外提供使用的RPC框架。使用他可以实现接口发布和接口调用功能,内部还提供了负载均衡等策略。是国内使用较多的服务调用框架。
从2.7版本开始阿里巴巴把Dubbo贡献给Apache。
Spring Cloud Alibaba Dubbo是基于Dubbo-spring-boot-starter 2.7的封装,可以让Dubbo程序员几乎零成本的学习。

3.5 Spring Cloud Alibaba Cloud ANS

ANS(应用程序命名服务)是EDAS(企业级分布式应用服务,平时所说的阿里云)的组件。使用ANS可以使用直接在阿里云部署好的Nacos Discover应用。

3.6 Spring Cloud Alibaba Cloud ACM

Spring Cloud AliCloud ACM是Spring Cloud客户端上商业产品应用程序配置管理(ACM)的实现,并且是免费的。
使用Spring Cloud AliCloud ACM可基于Spring Cloud的编程模型快速访问ACM配置管理功能。
ACM就是阿里云中Nacos Config的实现。

3.7 Spring Cloud Alibaba Cloud OSS

OSS(对象存储服务)是阿里云上的存储产品。Spring Cloud阿里云OSS提供符合Spring Cloud规范的商业化存储服务。我们提供易于使用的API,并支持将Resource集成到Spring框架中。
OSS其实就是阿里云中类似FastDFS的实现。

3.8 Spring Cloud Alibaba Cloud SchedulerX

SchedulerX(分布式作业调度)是阿里云产品EDAS的组件。Spring Cloud Alibaba Cloud SchedulerX提供符合Spring Cloud规范的分布式作业调度。SchedulerX提供具有几秒钟的高精度,高稳定性和高可用性的定时作业调度服务,并支持多种作业类型,例如简单的单服务器作业,简单的多主机作业,脚本作业和网格作业。

3.9 Spring Cloud Alibaba Cloud SMS

SMS(短消息服务)是一种覆盖全球的消息服务,阿里巴巴SMS提供便捷,高效和智能的通信功能,可帮助企业快速联系其客户。
Spring Cloud Alibaba Cloud SMS提供了易于使用的API,可基于Spring Cloud Alibaba SMS快速访问Alibaba Cloud的SMS服务。

4 总体布局

Spring Cloud Alibaba Dubbo服务调用 - 图2

二、 RPC简介

1 RFC

RFC(Request For Comments) 是由互联网工程任务组(IETF)发布的文件集。文件集中每个文件都有自己唯一编号,例如:rfc1831。目前RFC文件由互联网协会(Internet Society,ISOC)赞助发行。
RPC就收集到了rfc 1831中。可以通过下面网址查看:
https://datatracker.ietf.org/doc/rfc1831/

2 RPC

RPC在rfc 1831中收录 ,RPC(Remote Procedure Call) 远程过程调用协议
Spring Cloud Alibaba Dubbo服务调用 - 图3
RPC协议规定允许互联网中一台主机程序调用另一台主机程序,而程序员无需对这个交互过程进行编程。在RPC协议中强调当A程序调用B程序中功能或方法时,A是不知道B中方法具体实现的。
RPC是上层协议,底层可以基于TCP协议,也可以基于HTTP协议。一般我们说RPC都是基于RPC的具体实现,如:Dubbo框架。从广义上讲只要是满足网络中进行通讯调用都统称为RPC,甚至HTTP协议都可以说是RPC的具体实现,但是具体分析看来RPC协议要比HTTP协议更加高效,基于RPC的框架功能更多。
RPC协议是基于分布式架构而出现的,所以RPC在分布式项目中有着得天独厚的优势。基于RPC协议推出了一些框架(Dubbo),慢慢发展甚至出现了一种架构方式叫做RPC架构。RPC架构特点:一定是A项目调用B项目,调用过程中使用RPC协议。

3 RPC和HTTP对比

3.1 具体实现

RPC:可以基于TCP协议,也可以基于HTTP协议。
HTTP:基于HTTP协议

3.2 效率

RPC:自定义具体实现可以减少很多无用的报文内容,使得报文体积更小。
HTTP:如果是HTTP 1.1 报文中很多内容都是无用的。如果是HTTP2.0以后和RPC相差不大,比RPC少的可能就是一些服务治理等功能。

3.3 连接方式

RPC:长连接、短链接都支持。阻塞连接、非阻塞连接都支持。
HTTP:每次连接都是3次握手。Http2.0开始支持长连接。

3.4 序列化性能

RPC可以基于很多序列化方式。如:thrift
HTTP 主要是通过JSON,序列化和反序列效率更低。

3.5 注册中心

RPC :一般RPC框架都支持注册中心。
HTTP:都是直连。

3.6 负载均衡

RPC:绝大多数RPC框架都带有负载均衡工具。
HTTP:一般都需要借助第三方工具。如:nginx

3.7 综合结论

RPC框架一般都带有丰富的服务治理等功能,更适合企业内部接口调用。而HTTP更适合多平台之间相互调用。

三、 Dubbo简介

1 官方说明

Spring Cloud Alibaba Dubbo服务调用 - 图4
Apache Dubbo 是一个高可用的,基于Java的开源RPC框架。
Dubbo框架不仅仅是具备RPC访问功能,还包含服务治理功能(注册中心,负载均衡、容灾等)。

2 发展历史

Dubbo是最开始是阿里巴巴内部使用的RPC框架。
2011年对外提供。
2012年停止更新。
2017年开始继续更新。
2019年捐献给Apache,由Apache维护2.7以上版本。

四、 Dubbo架构讲解(面试题)

1 架构图

Spring Cloud Alibaba Dubbo服务调用 - 图5

2 架构说明

2.1 虚线

虚线表示异步,实线表示同步。异步不阻塞线程性能高,同步阻塞线程必须等待响应结果才能继续执行,相对性能低。

2.2 Provider

提供者。编写持久层和事务代码。

2.3 Container

容器(Spring容器),Dubbo完全基于Spring实现的。

2.4 Registry

注册中心。放置所有Provider对外提供的信息。包含Provider的IP,访问端口,访问遵守的协议,对外提供的接口,接口中有哪些方法等相关信息。

2.5 Consumer

消费者(RPC调用者,SOA调用服务的项目)开发中也是一个项目,编写service和controller(还可以报页面等)。调用XXXXServiceImpl中的方法。

2.6 Monitor

监控中心。监控Provider的压力情况等。每隔2分钟Consumer和Provider会把调用次数发送给Monitor,由Monitor进行统计。

3 执行流程

  1. start:启动Spring容器时会把Provider启动。
    1. register:把Provider相关信息注册到Registry里
    2. subscribe:Consumer从Registry中订阅Provider的信息
    3. notify:通知给Consumer
    4. invoke:Consumer根据Registry通知的信息进行调用Provider中方法。
    5. count:Consumer和Provider把调用次数信息异步发送给Monitor进行统计。

    五、 Dubbo支持的协议

    1 Dubbo协议(官方推荐协议)

    优点:
    采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)
    缺点:
    大文件上传时,可能出现问题(不使用Dubbo文件上传)

    1.1 关于NIO、BIO、AIO的区别(面试题)

    1.1.1 NIO
    JDK 1.4 推出的。同步非阻塞。执行代码时必须等IO操作结束才能执行下一行代码(同步),但是允许并发IO操作(非阻塞)
    1.1.2 BIO
    同步阻塞。执行代码时必须等IO操作结束才能执行下一行代码(同步),不允许并发IO操作(阻塞)
    1.1.3 AIO
    JDK1.7 推出的。异步非阻塞。执行代码时IO操作代码可以相当于忽略直接执行下一行代码(异步),允许并发IO操作(非阻塞)

    2 RMI(Remote Method Invocation)协议

    优点:
    JDK自带的能力。
    缺点:
    偶尔连接失败.

    3 Hessian协议

    优点:
    可与原生Hessian互操作,基于HTTP协议
    缺点:
    需hessian.jar支持,http短连接的开销大

    六、 Dubbo支持的注册中心

    1 Zookeeper

    1) 优点:
    支持分布式.很多周边产品.
    2) 缺点:
    受限于Zookeeper软件的稳定性.Zookeeper专门分布式辅助软件,稳定较优

    2 Nacos

    1) 优点:
    阿里自身注册中心,无缝集成。除此还支持配置中心等。

    3 Multicast

    1) 优点:
    去中心化,不需要单独安装软件.
    2) 缺点:
    2.2.1 Provider和Consumer和Registry不能跨机房(路由)

    4 Redis

    1) 优点:
    支持集群,性能高
    2) 缺点:
    要求服务器时间同步.否则可能出现集群失败问题.

    5 Simple

    1) 优点:
    标准RPC服务.没有兼容问题
    2) 缺点:
    不支持集群.

    七、 Zookeeper安装

    1 Zookeeper简介

    zookeeper分布式管理软件。常用它做注册中心(依赖zookeeper的发布/订阅功能)、配置文件中心、分布式锁配置、集群管理等。
    zookeeper一共就有两个版本。主要使用的是java语言写的。

    2 基于Docker安装Zookeeper

    2.1 拉取镜像

    docker pull zookeeper:3.5.5

    2.2 创建并运行容器

    docker run -d -p 2181:2181 —name zookeeper —restart always zookeeper:3.5.5

    2.3 连接测试

    docker exec -it zookeeper bash
    # zkCli.sh

    或者
    # docker exec -it zookeeper zkCli.sh

    2.4 常用命令

    如果记不住命令,可以输入任意字符,回车,查看zookeeper提供的命令提示。
    Spring Cloud Alibaba Dubbo服务调用 - 图6
    2.4.1 连接

    docker exec -it zookeeper zkCli.sh
    使用Zookeeper提供的客户端脚本,连接服务器。默认连接localhost:2181服务器。
    -server 参数。指定连接的服务器。默认: localhost:2181

    2.4.2 退出

    quit

    2.4.3 查看Zookeeper中的键
    命令格式: ls [args] [path]
    查看根节点下的所有键
    # ls /
    查看Zookeeper中的所有键
    # ls -R /
    2.4.4 查看Zookeeper中的value值
    语法: get /path
    2.4.5 设置Zookeeper中的键值对
    语法: set path value
    2.4.6 创建Zookeeper中的键值对
    语法: create path [value]
    如果不提供value,则是value为null。如果value数据中包含空格,需要使用双引号标记。
    2.4.7 删除Zookeeper中的键值对
    删除某一个指定的节点。此节点下,不能有任何子节点。
    delete path
    删除某一个指定的节点,此节点下,可以有子节点
    deleteall path
    过时命令,功能等同于deleteall。不推荐使用。
    rmr path

    八、 Eureka和Zookeeper对比(面试)

    在Spring Cloud Netfilx中可以使用Eureka作为注册中心,但是也可以通过配置的方式使用Zookeeper作为配置中心,既然都支持,就需要知道两者的区别。

    1 CAP理论(分布式一致性定理)

    著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP
    C(一致性Consistency):在分布式系统中,是否立即达到数据同步的效果(平时多说的强一致性)。在分布式系统一定最终会一致的。如果请求时,整个分布式系统同步后才返回结果,叫做强一致性(满足一致性)。如果先返回结果,在一定时间后才实现一致性就叫做弱一致性。
    A(可用性Availability):在分布式系统中,其中一些节点出现问题,整个整体是否还可用。
    P(分区容错性):在分布式系统中,是否可以在有限的时间内达到数据一致的效果,如果因为网络等问题最终没有达到一致性,这时称为出现分区错误。

    2 Zookeeper 保证 CP

    在Zookeeper集群中,Zookeeper的数据保证的是一致性的。当Leader出现问题时,整个Zookeeper不可用,需要花费30~120s来进行重新选择leader,当leader选举成功以后才能进行访问整个Zookeeper集群。
    通过这点也可以看出Zookeeper是强一致性的,集群所有节点必须能通信,才能用集群。虽然这样集群数据安全了,但是可用性大大降低了。而作为注册中心来说可用性是很重要的。

    3 Eureka保证AP

    Eureka发现了Zookeeper的问题,所以它舍弃了Zookeeper中强一致性,而保证了可用性。
    在Eureka集群中所有的节点都是保存完整的信息的,当Eureka Client向Eureka中注册信息时,如果发现节点不可用,会自动切换到另一台Eureka Server,也就是说整个集群中即使只有一个Eureka可用,那么整个集群也是可用的。同时Eureka的自我保护机制也是实现可用性非常重要的体现。

    4 ZooKeeper和Eureka对比(最完整的对比)

对比项 Zookeeper Eureka 备注
CAP CP AP
Dubbo支持 已支持 -
Spring Cloud支持 已支持 已支持
kv服务 支持 - ZK支持数据存储,eureka不支持
使用接口(多语言能力) 提供客户端
(zkClient、Curator)
http协议(跨语言) ZK的跨语言支持比较弱
watch支持 支持 支持 什么是Watch支持?就是客户端
监听服务端的变化情况。zk通过订阅监听来实现eureka通过轮询的方式来实现
集群监控 _ metrics metrics,运维者可以收集并报警这些度量信息达到监控目的

九、 创建Dubbo项目演示

设置需求:
数据库:
学生表:id、name、tid
老师表:id、name
代码实现:
student服务:实现对学生新增。
teacher服务:实现对teacher的新增。
最终:新增学生时同时新增teacher。在student服务调用teacher服务
需要的依赖


<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency>
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-x-discovery</artifactId> <version>5.1.0</version> </dependency>

十、 负载均衡

集群:一个内容,部署多次,形成的整体称为集群。集群中每个个体应该部署到不同的服务器上。
伪集群:集群中内容部署到同一台服务器上,通过不同端口区分不同个体。
负载均衡是在集群前提下,当访问整个集群时,集群中每个节点被访问次数或频率的规则。
Dubbo 内置了四个负载均衡策略。默认为Random

1 内置策略

1.1 Random

随机。随机访问集群中节点。访问概率和权重有关。 默认

1.2 RoundRobin

轮询。访问频率和权重有关。
权重(weight):占有比例。集群中每个项目部署的服务器的性能可能是不同,性能好的服务器权重应该高一些。

1.3 LeastActive

活跃数相同的随机,不同的活跃数高的放前面。

1.4 ConsistentHash

一致性Hash。相同参数请求总是发到一个提供者。

2 Provider集群

新建四个启动类。
每次启动启动类修改配置文件dubbo.protocal.port

3 设置负载均衡

3.1 @DubboReference

调用的服务采用的负载均衡

@DubboReference(loadbalance = “roundrobin”)
private DemoDubboService demoDubboService;

3.2 @DubboService

当前服务采用的负载均衡算法

@DubboService(loadbalance = “random”)
public class DemoDubboServiceImpl implements DemoDubboService {

设置权重

@DubboService(weight = 4)

3.3 配置文件

全局设置所有provider和consumer的负载均衡效果。

dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.32.128:2181
protocol:
port: 20884
provider:
loadbalance: randomweight: 1 consumer:
loadbalance: random

十一、 先启动Consumer解决办法

1 方案一

在配置文件中.全局配置。

dubbo.consumer.check=false

1 方案二

@DubboReference(check = false)

十二、 payload

Dubbo框架在使用dubbo协议实现远程服务调用的时候,默认限制请求和应答数据最大为8M。如果超出范围则抛出异常。可以通过配置设置payload容量。

dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://192.168.137.128:2181
protocol:
payload: 800000000

十三、 group和version(面试常见题)

Dubbo框架支持服务分组注册和服务多版本发布。即相同的接口发布的服务,也可以用组来维护。且可以同时提供若干不同版本的服务提供者实现。
设置方式是:

@DubboService(group = “test”, version = “1.0”)

当Provider注册服务时,约束了分组或版本,Consumer则必须提供相应配置,否则无法发现服务,配置如下:

@DubboReference(group = “test”, version = “1.0”)