Spring Cloud

Spring Cloud是基于Spring构建分布式系统的工具集。

Spring Cloud通过Spring Cloud Common项目定义统一抽象API,不同厂商结合各自的中间件提供自己的Spring套件

软件架构演化

接口调用模式

主要通讯协议

单体

垂直

SOA

RPC

TCP

微服务

REST

HTTP

概念解释

集群:通过多台计算机完成同一个工作,多机内容、工作过程等完全一样,从而达到更高的效率和防止单点故障。

分布式:distributed system。一个业务分拆多个子业务,部署在不同的服务器上。不同的服务器运行不同的代码,分工协作完成系统功能。

SOA:Service-Oriented Architecture(面向服务的架构),使用RPC进行远程接口调用,使用XML为主要数据传输格式的粗粒度分布式框架(早期)。

微服务:Microservice。使用REST接口进行远程接口调用,使用JSON为主要数据传输格式的细粒度分布式框架(流行)。

RPC:Remote Procedure Call(远程过程调用)

REST:Representational State Transfer(表现层状态转化),如果一个架构符合REST原则,就称它为RESTful架构。

REST原则:

每一个URI代表一种资源;

客户端和服务器之间,传递这种资源的某种表现层;

客户端通过四个HTTP动词(GET、POST、PUT、DELETE,查增改删),对服务器端资源进行操作,实现"表现层状态转化"。

微服务引发的问题:

运维难度增加

服务间通信成本增加

数据一致性问题

沟通成本增加

链路追踪复杂

Spring Cloud技术栈

框架

作用

说明

Eureka(Netflix)

Zookeeper(Apache)

Consul(HashiCorp)

Nacos Discovery(Alibaba)

服务注册和发现

服务注册是一个记录当前可用的微服务实例的网络信息数据库,服务调用方从服务注册中心找到自己需要调用的服务的地址。

Config(Pivotal)

Nacos Config(Alibaba)

分布式配置中心

Feign(Netflix)

声明式服务调用

Ribbon(Netflix)

客户端负载均衡

和Nginx的区别:

Hystrix(Netflix)

Sentinel(Alibaba)

断路器

负责监控服务之间的调用情况,连续多次失败进行熔断保护。

Zuul(Netflix)

Gateway(Pivotal)

API网关服务

负责转发所有对外的请求和服务。

如果让客户端直接与各个微服务通信可能出现:

客户端需要调用不同的url地址,增加难度

在一定的场景下,存在跨域请求的问题

每个微服务都需要进行单独的身份认证

API网关的基本功能有:统一接入、用户鉴权、动态路由、灰度发布、A/B测试、安全防护、协议适配、负载限流、长短链接支持、容错能力。(安全、流量、路由)

将本地化的配置信息(Properties、XML、YAML等)注册到配置中心,实现程序包在开发、测试、生产环境的无差别性,方便程序包的迁移。配置部分可以单独使用高可用的分布式配置中心,确保一个配置服务出现问题时,其他服务也能够提供配置服务。

Bus

消息总线

Stream

消息驱动的微服务

Sleuth(Pivotal)

Zipkin(Pivotal)

链路追踪

记录完成一个业务逻辑时调用到的微服务,并将这种串行或并行的调用关系展示出来,方便我们进行错误追踪、性能监控、给热点服务分配更多资源。

分布式事务

对于重要的业务,需要通过分布式事务技术(TCC、高可用消息服务、最大努力通知〉保证数据的一致性。根据业务的不同,适当地牺牲一些数据的一致性要求,确保数据的最终一致性。

SpringCloud体系结构

    1. 服务注册和发现

服务治理框架比较

组件名

供应商

语言

CAP

一致性算法

服务健康检查

对外暴露接口

Eureka

Netflix

Java

AP

可配支持

HTTP

Consul

HashiCorp

Go

CP

Raft

支持

HTTP/DNS

Zookeeper

Apache

Java

CP

Paxos

支持

客户端

Nacos

Alibaba

Java

AP

Raft

支持

HTTP

Eureka的治理机制

Eureka专门用于给其他服务注册的称为Eureka Server(服务注册中心),其余注册到Eureka Server的服务称为Eureka Client。

Eureka Client分为服务提供者和服务消费者。一个系统模块既可以是服务提供者又可以是服务消费者。

服务提供者

服务注册:启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息。

服务续约:在注册完服务之后,服务提供者会每隔30秒向Eureka Server发送心跳用来持续告诉Eureka Server: "我还活着”

服务下线:当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。

服务消费者

服务发现:当我们启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。

服务调用:服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。调用服务时优先访问同处一个Zone中的服务提供方。

服务注册中心Eureka Server

失效剔除:每隔一段时间(默认为60秒)将当前清单中超时(默认为90秒)没有续约的服务剔除出去。

自我保护:Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%(通常由于网络不稳定导致)。Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。

Eureka使用步骤

搭建Eureka Server(服务注册中心)

1)创建maven模块

2)pom.xml导入坐标

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

3)application.properties配置服务

server:

port: 8761

eureka:

instance:

 hostname: localhost

client:

 registerWithEureka: false #false自己就是注册中心,无需注册自己。#配置项名驼峰、横杠皆可

 fetchRegistry: false #false自己就是注册中心,无需检索服务。#配置项名驼峰、横杠皆可

 serviceUrl:

  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4)启动类配置服务

服务消费者的配置举例:

eureka:

  client:

    register-with-eureka: false  # 当前微服务不注册到eureka中(消费端)

    service-url:

      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

不再通过RestTemplate

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。

服务绑定:

// value --->指定调用哪个服务

// fallbackFactory--->熔断器的降级提示

@FeignClient(value = "MICROSERVICECLOUD-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)

public interface DeptClientService {

    // 采用Feign我们可以使用SpringMVC的注解来对服务进行绑定!

    @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)

    public Dept get(@PathVariable("id") long id);

    @RequestMapping(value = "/dept/list", method = RequestMethod.GET)

    public List<Dept> list();

    @RequestMapping(value = "/dept/add", method = RequestMethod.POST)

    public boolean add(Dept dept);

}

Feign中使用熔断器:

/**

 * Feign中使用断路器

 * 这里主要是处理异常出错的情况(降级/熔断时服务不可用,fallback就会找到这里来)

 */

@Component // 不要忘记添加,不要忘记添加

public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {

    @Override

    public DeptClientService create(Throwable throwable) {

        return new DeptClientService() {

            @Override

            public Dept get(long id) {

                return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")

                        .setDb_source("no this database in MySQL");

            }

            @Override

            public List<Dept> list() {

                return null;

            }

            @Override

            public boolean add(Dept dept) {

                return false;

            }

        };

    }

}

调用:

    1. 远程调用

Dubbo是阿里巴巴公司开源的远程服务调用的分布式框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。

Dubbo架构

注册中心(Regist):接收服务提供者的注册和服务消费者的订阅,服务地址更新时向消费者推送地址列表。

服务提供者(Provider):启动时向注册中心注册服务地址。

服务消费者(Consumer):启动时向注册中心订阅服务地址,请求时随机调用一个服务地址,失败重试另一地址。

监控中心(Monitor):后台采集服务的调用次数和调用时间,以及配置客户端的负载均衡。

Dubbo和Spring Cloud比较

分布式框架

架构类型

通信协议

服务调用方式

访问速度

生态环境

Dubbo

SOA(粗粒度)

Dubbo

RPC

较快

较差

Spring Cloud

微服务(细粒度)

HTTP

REST

较慢

较好

SpringBoot整合Dubbo

要诀:在pom.xml中引入starter-dubbo依赖,在application.properties中配置属性,使用@Service暴露服务,使用@Reference引用服务

  1. 下载安装zookeeper并启动:
  1. 创建服务提供者模块和服务消费者模块,都导入以下包:

下载地址:Apache ZooKeeper

    <!-- dubbo启动器 -->

    <dependency>

        <groupId>io.dubbo.springboot</groupId>

        <artifactId>spring-boot-starter-dubbo</artifactId>

        <version>${dubbo-spring-boot}</version>

    </dependency>

    <!-- zookeeper客户端 -->

     <dependency>

        <groupId>com.101tec</groupId>

        <artifactId>zkclient</artifactId>

        <version>0.7</version>

    </dependency>

  1. 创建服务提供者接口并在实现类中使用Dubbo提供的注解@Service注解该实现类:
  1. 服务提供者模块核心配置文件添加配置如:

import com.alibaba.dubbo.config.annotation.Service;

import com.springboot.dubbo.service.TestService;

@Service(version = "1.0.0",timeout = 3000)

public class TestServiceImpl implements TestService{

    @Override

    public void testDubbo() {

    }

}

server:

  port: 8080 #Tomcat端口

spring:

  dubbo:

    application:

      name: springboot-dubbo-demo #应用名

    registry:

      address: zookeeper://localhost #zookeeper地址

      port: 2181 #zookeeper端口

    protocol:

      name: dubbo

      port: 20890 #Dubbo服务暴露的端口

    scan: com.springboot.dubbo.service.impl #扫描的服务类包名

  1. 创建服务消费者接口并在实现类中使用Dubbo提供的注解@Reference注入服务提供者:
  1. 服务消费者模块核心配置文件添加配置如:

@Reference(version = "1.0.0",timeout = 300)

private TestService testService;

server:

  port: 8081 #Tomcat端口

spring:

  dubbo:

    application:

      name: springboot-dubbo-demo

    registry:

      address: zookeeper://localhost

      port: 2181

    scan: com.springboot.dubbo.test.controller

7种负载均衡策略

策略

配置

轮询RoundRobinRule

默认策略。按照一定的顺序依次调用服务实例。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

权重WeightedResponseTimeRule

根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

随机RandomRule

从服务提供者的列表中随机选择一个服务实例。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

最小连接数BestAvailableRule

也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule

重试策略(RetryRule)

按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。

ribbon:

  ConnectTimeout: 2000 # 请求连接的超时时间

  ReadTimeout: 5000 # 请求处理的超时时间

springcloud-nacos-provider: # nacos 中的服务 id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

可用性敏感策略(AvailabilityFilteringRule)

先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule

区域敏感策略(ZoneAvoidanceRule)

根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。

springcloud-nacos-provider: # nacos中的服务id

  ribbon:

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule

自定义负载均衡策略

实现方法:继承AbstractLoadBalancerRule类,重写public Server choose(ILoadBalancer lb, Object key)

Fallback(失败快速返回):当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

资源/依赖隔离(线程池隔离):它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响, 而不会拖慢其他的依赖服务。

Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)

每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。

直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

Hystrix仪表盘:它主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题,从而及时地采取应对措施。除了可以开启单个实例的监控页面之外,还有一个监控端点 /turbine.stream是对集群使用的。 从端点的命名中,可以引入Turbine, 通过它来汇集监控信息,并将聚合后的信息提供给 HystrixDashboard 来集中展示和监控。

Gateway网关

应用场景

  1. 请求过滤(令牌桶限流)
  2. 容错(Hystrix)

基本使用

和nginx的区别,为什么不用nginx代替Gateway

nginx是用C语言写的,自定义扩展的话,要么写C要么写lua

gateway是java语言的一个框架,可以在框架上进行代码的扩展与控制,例如:安全控制,统一异常处理,XXS,SQL注入等;权限控制,黑白名单,性能监控,日志打印等;

gateway的主要功能有,路由,断言,过滤器,利用它的这些特性,可以做流控。

nginx做网关,更多的是做总流量入口,反向代理,负载均衡等,还可以用来做web服务器。

nginx做网关,更多的是做总流量入口,反向代理,负载均衡等,还可以用来做web服务器。

SpringCloud Zuul通过与SpringCloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息。外层调用都必须通过API网关,使得将维护服务实例的工作交给了服务治理框架自动完成。

在API网关服务上进行统一调用来对微服务接口做前置过滤,以实现对微服务接口的拦截和校验。

Zuul天生就拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。也就是说:Zuul也是支持Hystrix和Ribbon。

zuul是对外暴露的唯一接口相当于路由的是controller的请求,而Ribbonhe和Fegin路由了service的请求

zuul做最外层请求的负载均衡 ,而Ribbon和Fegin做的是系统内部各个微服务的service的调用的负载均衡

    1. Cloud Config分布式系统的配置管理方案

随着业务的扩展,我们的服务会越来越多,越来越多。每个服务都有自己的配置文件。

既然是配置文件,给我们配置的东西,那难免会有些改动的。

比如我们的Demo中,每个服务都写上相同的配置文件。万一我们有一天,配置文件中的密码需要更换了,那就得三个都要重新更改。

在分布式系统中,某一个基础服务信息变更,都很可能会引起一系列的更新和重启

Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

简单来说,使用Spring Cloud Config就是将配置文件放到统一的位置管理(比如GitHub),客户端通过接口去获取这些配置文件。

在GitHub上修改了某个配置文件,应用加载的就是修改后的配置文件。

通过BeanDefinitionReader接口读取配置文件到BeanDefinition

通过BeanFactoryPostProcessor修改BeanDefinition

如PlaceHolderConfigurerSupport读取properties文件信息来替换掉bean配置中的变量表达式${}

实例化和初始化的区别:

实例化:在堆中开辟一块空间,属性都是默认值

初始化:1)给属性赋值;2)调用具体的初始化方法;

详见 Spring循环依赖及解决方式_Java_张sir_InfoQ写作社区

1、getBean(A) 先去单例池获取,单例池不存在,二级缓存获取,二级缓存不存在且允许提前访问,三级缓存中取,此时返回为空,开始加载 A

2、singletonsCurrentlyInCreation(A) 将 A 放入正在创建的 Map 中

3、new A(); 实例化 A

4、提前暴露 A,将 A 放入三级缓存,addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

5、设置属性 populateBean(beanName, mbd, instanceWrapper);

6、发现 A 依赖 B,需要先创建 B

7、getBean(B)

8、先去单例池获取 B,单例池不存在,二级缓存获取,二级缓存不存在且允许提前访问,三级缓存中取,此时返回为空,开始加载 B

9、将 B 放入 singletonsCurrentlyInCreation() 的 Map 中

10、new B() 实例化 B

11、将 B 放入三级缓存 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

12、设置属性 populateBean(beanName, mbd, instanceWrapper);

13、发现 B 依赖 A

14、getBean(A)

15、发现三级缓存中存在 A,getEarlyBeanReference(A, mbd, bean) 获取 A,同时把 A 放入二级缓存,删除三级缓存

16、执行 B 的 initializeBean 方法,执行 aop,获取增强以后的引用

17、B 创建完了,将 B 放入单例池冲

18、继续执行第 7 步,返回的 getBean(B)就是创建好的 B

19、接下来 A 初始化

20、因为 A 的三级缓存中的 getEarlyBeanReference(beanName, mbd, bean) 被 B 已经执行过了

21、A 就能从二级缓存中获取自己的引用

22、如果发现引用变了,此时 A 就指向二级缓存中的引用

23、将 A 放出单例池中

24、删除二级缓存和三级缓存

Dubbo是一种高性能的Java RPC框架。

Dubbo提供了多种负载均衡策略来实现服务调用的负载均衡:

随机(Random):随机选择一个可用的服务提供者进行调用。

轮询(RoundRobin):轮询选择一个可用的服务提供者进行调用。

最少活跃调用数(LeastActive):选择活跃调用数最小的可用服务提供者进行调用,即处理请求最少的服务提供者优先被调用。

一致性哈希(ConsistentHash):将服务提供者列表映射到一个哈希环上,根据请求的哈希值选择服务提供者。

最近最少使用(LeastRecentlyUsed):根据最近调用的时间选择最少使用的服务提供者进行调用。

权重(WeightedRandom、WeightedRoundRobin):根据服务提供者的权重来进行调用,权重越高的服务提供者被选中的概率越大。

失败自动恢复(Failover):在调用失败的情况下,自动切换到下一个可用的服务提供者进行调用,直到调用成功。

失败安全(FailSafe):在调用失败的情况下,直接忽略错误,不重试,通常用于容错性较高的读操作。

快速失败(FailFast):在调用失败的情况下,立即报错返回,通常用于容错性较低的写操作。

不同的负载均衡策略适用于不同的场景,具体应根据实际情况选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个用于构建分布式系统的开发工具集合。它提供了一些常用的组件和框架,包括服务注册和发现、负载均衡、断路器、分布式配置等等。在使用Spring Cloud时,有一些常见的错误和注意事项需要注意。 首先,关于Spring Boot和Spring Cloud版本对应错误。在使用Spring Cloud时,需要确保Spring Boot和Spring Cloud的版本兼容。不同版本之间可能存在依赖冲突或不兼容的情况,因此需要根据官方文档或者相关文档来选择合适的版本。 另外,Spring Cloud Config是一个用于集中管理和动态获取配置的工具。它支持从Git、SVN或本地文件系统中获取配置文件,并提供了服务器和客户端支持。你可以通过官方使用说明文档了解更多关于Spring Cloud Config的详细信息。 此外,关于选择使用Nacos还是Eureka作为服务注册和发现组件的问题。Nacos是一个功能更强大的服务注册和发现组件,它整合了Spring Cloud Eureka、Spring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的中心动态刷新,而不需要为配置中心新增集群或使用消息队列。另一方面,Eureka是Spring Cloud原生全家桶的一部分,相对来说更加稳定一些。选择使用哪个组件需要根据具体的需求和项目特点来决定。 综上所述,Spring Cloud是一个用于构建分布式系统的开发工具集合,它提供了一些常用的组件和框架。在使用Spring Cloud时,需要注意Spring Boot和Spring Cloud版本的兼容性,并可以使用Spring Cloud Config来动态获取配置。同时,可以选择使用Nacos或Eureka作为服务注册和发现组件,具体选择需要根据项目需求来决定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值