Spring Cloud全家桶主要组件及简要介绍

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud全家桶主要组件及简要介绍相关的知识,希望对你有一定的参考价值。

参考技术A 一、微服务简介

微服务是最近的一两年的时间里是很火的一个概念。感觉不学习一下都快跟不上时代的步伐了,下边做一下简单的总结和介绍。

何为微服务?简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。

一个微服务一般完成某个特定的功能,比如下单管理、客户管理等等。每一个微服务都是微型六角形应用,都有自己的业务逻辑和适配器。一些微服务还会发布API给其它微服务和应用客户端使用。其它微服务完成一个Web UI,运行时,每一个实例可能是一个云VM或者是Docker容器。

比如,一个前面描述系统可能的分解如下:

总的来说,微服务的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作,并且每个服务都维护着自身的数据存储、业务开发、自动化测试以及独立部署机制。

二、微服务的特征

1、每个微服务可独立运行在自己的进程里;

2、一系列独立运行的微服务共同构建起了整个系统;

3、每个服务为独立的业务开发,一个微服务一般完成某个特定的功能,比如:订单管理、用户管理等;

4、微服务之间通过一些轻量的通信机制进行通信,例如通过REST API或者RPC的方式进行调用。

三、微服务的优缺点

1、易于开发和维护

2、启动较快

3、局部修改容易部署

4、技术栈不受限

5、按需伸缩

6、DevOps

四、常见微服务框架

1、服务治理框架

(1)Dubbo、Dubbox(当当网对Dubbo的扩展)

最近的好消息是Dubbo已近重新开始进行运维啦!

(2)Netflix的Eureka、Apache的Consul等。

Spring Cloud Eureka是对Netflix的Eureka的进一步封装。

2、分布式配置管理

(1)百度的Disconf

(2)360的QConf

(3)Spring Cloud组件中的Config

(3)淘宝的Diamond

3、批量任务框架

(1)Spring Cloud组件中的Task

(2)LTS

4、服务追踪框架

。。。

五、Spring Cloud全家桶组件

在介绍Spring Cloud 全家桶之前,首先要介绍一下Netflix ,Netflix 是一个很伟大的公司,在Spring Cloud项目中占着重要的作用,Netflix 公司提供了包括Eureka、Hystrix、Zuul、Archaius等在内的很多组件,在微服务架构中至关重要,Spring在Netflix 的基础上,封装了一系列的组件,命名为:Spring Cloud Eureka、Spring Cloud Hystrix、Spring Cloud Zuul等,下边对各个组件进行分别得介绍:

(1)Spring Cloud Eureka

我们使用微服务,微服务的本质还是各种API接口的调用,那么我们怎么产生这些接口、产生了这些接口之后如何进行调用那?如何进行管理哪?

答案就是Spring Cloud Eureka,我们可以将自己定义的API 接口注册到Spring Cloud Eureka上,Eureka负责服务的注册于发现,如果学习过Zookeeper的话,就可以很好的理解,Eureka的角色和 Zookeeper的角色差不多,都是服务的注册和发现,构成Eureka体系的包括:服务注册中心、服务提供者、服务消费者。

1、两台Eureka服务注册中心构成的服务注册中心的主从复制集群;

2、然后服务提供者向注册中心进行注册、续约、下线服务等;

3、服务消费者向Eureka注册中心拉去服务列表并维护在本地(这也是客户端发现模式的机制体现!);

4、然后服务消费者根据从Eureka服务注册中心获取的服务列表选取一个服务提供者进行消费服务。

(2)Spring Cloud Ribbon

在上Spring Cloud Eureka描述了服务如何进行注册,注册到哪里,服务消费者如何获取服务生产者的服务信息,但是Eureka只是维护了服务生产者、注册中心、服务消费者三者之间的关系,真正的服务消费者调用服务生产者提供的数据是通过Spring Cloud Ribbon来实现的。

在(1)中提到了服务消费者是将服务从注册中心获取服务生产者的服务列表并维护在本地的,这种客户端发现模式的方式是服务消费者选择合适的节点进行访问服务生产者提供的数据,这种选择合适节点的过程就是Spring Cloud Ribbon完成的。

Spring Cloud Ribbon客户端负载均衡器由此而来。

(3)Spring Cloud Feign

上述(1)、(2)中我们已经使用最简单的方式实现了服务的注册发现和服务的调用操作,如果具体的使用Ribbon调用服务的话,你就可以感受到使用Ribbon的方式还是有一些复杂,因此Spring Cloud Feign应运而生。

简单的可以理解为:Spring Cloud Feign 的出现使得Eureka和Ribbon的使用更为简单。

(4)Spring Cloud Hystrix

我们在(1)、(2)、(3)中知道了使用Eureka进行服务的注册和发现,使用Ribbon实现服务的负载均衡调用,还知道了使用Feign可以简化我们的编码。但是,这些还不足以实现一个高可用的微服务架构。

例如:当有一个服务出现了故障,而服务的调用方不知道服务出现故障,若此时调用放的请求不断的增加,最后就会等待出现故障的依赖方 相应形成任务的积压,最终导致自身服务的瘫痪。

Spring Cloud Hystrix正是为了解决这种情况的,防止对某一故障服务持续进行访问。Hystrix的含义是:断路器,断路器本身是一种开关装置,用于我们家庭的电路保护,防止电流的过载,当线路中有电器发生短路的时候,断路器能够及时切换故障的电器,防止发生过载、发热甚至起火等严重后果。

(5)Spring Cloud Config

对于微服务还不是很多的时候,各种服务的配置管理起来还相对简单,但是当成百上千的微服务节点起来的时候,服务配置的管理变得会复杂起来。

分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件Spring Cloud Config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在Cpring Cloud Config 组件中,分两个角色,一是Config Server,二是Config Client。

Config Server用于配置属性的存储,存储的位置可以为Git仓库、SVN仓库、本地文件等,Config Client用于服务属性的读取。

(6)Spring Cloud Zuul

我们使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载;通过Spring Cloud Config实现了应用多环境的外部化配置以及版本管理。为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。

先来说说这样架构需要做的一些事儿以及存在的不足:

1、首先,破坏了服务无状态特点。为了保证对外服务的安全性,我们需要实现对服务访问的权限控制,而开放服务的权限控制机制将会贯穿并污染整个开放服务的业务逻辑,这会带来的最直接问题是,破坏了服务集群中REST API无状态的特点。从具体开发和测试的角度来说,在工作中除了要考虑实际的业务逻辑之外,还需要额外可续对接口访问的控制处理。

2、其次,无法直接复用既有接口。当我们需要对一个即有的集群内访问接口,实现外部服务访问时,我们不得不通过在原有接口上增加校验逻辑,或增加一个代理调用来实现权限控制,无法直接复用原有的接口。

面对类似上面的问题,我们要如何解决呢?下面进入本文的正题:服务网关!

为了解决上面这些问题,我们需要将权限控制这样的东西从我们的服务单元中抽离出去,而最适合这些逻辑的地方就是处于对外访问最前端的地方,我们需要一个更强大一些的均衡负载器,它就是本文将来介绍的:服务网关。

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

(7)Spring Cloud Bus

在(5)Spring Cloud Config中,我们知道的配置文件可以通过Config Server存储到Git等地方,通过Config Client进行读取,但是我们的配置文件不可能是一直不变的,当我们的配置文件放生变化的时候如何进行更新哪?

一种最简单的方式重新一下Config Client进行重新获取,但Spring Cloud绝对不会让你这样做的,Spring Cloud Bus正是提供一种操作使得我们在不关闭服务的情况下更新我们的配置。

Spring Cloud Bus官方意义:消息总线。

当然动态更新服务配置只是消息总线的一个用处,还有很多其他用处。

六、总结

Spring Cloud 的组件还不止这些,通过上边的口水话的介绍,应该可以大致有一定的了解,但是每一个组件的功能远不止上述介绍的那些,每一个组件还有很多其他的功能点,这里的介绍希望能够带大家入个门,不要对微服务这个这么大的概念有所畏惧。

Spring Cloud Alibaba全家桶——微服务组件Sentinel介绍与使用

前言

本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括分布式系统存在的问题分布式系统问题的解决方案Sentinel介绍Sentinel快速开始(包括:API实现Sentinel资源保护@SentinelResource注解实现资源保护),Sentinel控制台Spring Cloud Alibaba整合Sentinel 等进行详尽介绍~

不积跬步,无以至千里;不积小流,无以成江海。每天进步一点点,在成为强者的路上,小新与大家共同成长!

📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

↩️本文上接:Spring Cloud Alibaba全家桶(五)——微服务组件Nacos配置中心


目录

微服务组件Sentinel介绍与使用

一、分布式系统存在的问题

分布式系统可能会遇到的问题:服务的可用性问题

服务的可用性场景:在一个高度服务化的系统中,我们实现的一个业务逻辑通常会依赖多个服务, 如图所示:

如果其中的下单服务不可用,就会出现线程池里所有线程都因等待响应而被阻塞,从而造成整个服务链路不可用,进而导致整个系统的服务雪崩,如图所示:

服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应导致服务不可用的原因:

在服务提供者不可用的时候,会出现大量重试的情况:用户重试、代码逻辑重试,这些重试 终导致:进一步加大请求流量。所以归根结底导致雪崩效应的 根本原因是:大量请求线程同步等待造成的资源耗尽。当服务调用者使用同步调用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。

二、分布式系统问题的解决方案

解决问题的关键就是提高系统的稳定性、恢复性。

常见的容错机制:

  • 超时机制
    在不做任何处理的情况下,服务提供者不可用会导致消费者请求线程强制等待,而造成系统资源耗尽。加入超时机制,一旦超时,就释放资源。由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题。

  • 服务限流

  • 隔离

原理:用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,则会进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。

隔离前:


隔离后:

信号隔离:信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离 大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请, 如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。信号量的大小可以动态调整, 线程池大小不可以。

  • 服务熔断

远程服务不稳定或网络抖动时暂时关闭,就叫服务熔断。

现实世界的断路器大家肯定都很了解,断路器实时监控电路的情况,如果发现电路电流异常,就会跳闸,从而防止电路被烧毁。

软件世界的断路器可以这样理解:实时监测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。跳闸一段时间后(例如10秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。

所以,同样的道理,当依赖的服务有大量超时时,在让新的请求去访问根本没有意义,只会无畏的消耗现有资源。比如我们设置了超时时间为1s,如果短时间内有大量请求在1s内都得不到响应,就意味着这个服务出现了异常,此时就没有必要再让其他的请求去访问这个依赖了,这个时候就应该使用断路器避免资源浪费。

服务降级有服务熔断,必然要有服务降级。

所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。 例如:(备用接口/缓存/mock数据) 。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。

三、Sentinel介绍

Sentinel:——分布式系统的流量防卫兵。

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

源码地址:https://github.com/alibaba/Sentinel

官方文档:https://github.com/alibaba/Sentinel/wiki

Sentinel具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500台以下规模的集群的汇总运行情况。
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、 gRPC的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

阿里云提供了 企业级的 Sentinel 服务,应用高可用服务 AHAS。

Sentinel和Hystrix对比:

四、Sentinel快速开始

https://github.com/alibaba/Sentinel/wiki/如何使用

使用 Sentinel 来进行资源保护,主要分为几个步骤:

  • 定义资源
  • 定义规则
  • 检验规则是否生效
Entry entry = null;
// 务必保证 finally 会被执行
try 
  // 资源名可使用任意有业务语义的字符串,注意数目不能太多(超过 1K),超出几千请作为参数传入而不要直接作为资源名
  // EntryType 代表流量类型(inbound/outbound),其中系统规则只对 IN 类型的埋点生效
  entry = SphU.entry("自定义资源名");
  // 被保护的业务逻辑
  // do something...
 catch (BlockException ex) 
  // 资源访问阻止,被限流或被降级
  // 进行相应的处理操作
 catch (Exception ex) 
  // 若需要配置降级规则,需要通过这种方式记录业务异常
  Tracer.traceEntry(ex, entry);
 finally 
  // 务必保证 exit,务必保证每个 entry 与 exit 配对
  if (entry != null) 
    entry.exit();
  

1️⃣API实现Sentinel资源保护

🍀(1)引入依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel‐core</artifactId>
  <version>1.8.0</version>
</dependency>

🍀(2)编写测试逻辑

@RestController 
@slf4j
public class Hellocontroller 
  private static final String RESOURCE_NAAE = "hello" ;
  
  RequestMapping(walue = "/hello")
  public String hello() 
    Entry entry = null;
    try 
      //资源名可使用任意有业务语义的字符中,比如方法名、接口名或其它可唯一标识的字符串。
      entry = SphU.entry(RESOURCE_NAME);
      //被保护的业务逻辑
      String str = "hello world";
      log .info("====="+str);
      return str;
     catch (BlockException e1)
      // 资源访问阻止,被限流或被降级
      // 进行相应的处理操作
      log.info("block!");
     catch (Exception ex) 
      // 若需要配置降级规则,需要通过这种方式记录业务异常
      Tracer.traceEntry(ex, entry);
     finally 
      if(entry != null)
        entry.exit();
      
    
    return null;
  
  /**
  * 定义流程规则
  */  
  @PostConstruct
  private static void initFlowRules() 
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowaRule();
    // 设置受保护的资源
    rule.setResource(RESOURCE_NAME);
  

🍀(3)测试效果

🍀(4)缺点

  • 业务侵入性很强,需要在controller中写入非业务代码;
  • 配置不灵活,若需要添加新的受保护资源,需要手动添加init方法来添加流控规则。

2️⃣@SentinelResource注解实现资源保护

@SentinelResource 注解用来标识资源是否被限流、降级。

blockHandler: 定义当资源内部发生了BlockException应该进入的方法(捕获的是Sentinel定义的异常)。

fallback: 定义的是资源内部发生了Throwable应该进入的方法。

exceptionsToIgnore:配置fallback可以忽略的异常。

源码入口:com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect。

🍀(1)引入依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel‐annotation‐aspectj</artifactId>
  <version>1.8.0</version>
</dependency>

🍀(2)配置切面支持

@Configuration
public class SentinelAspectConfiguration 

  @Bean
  public SentinelResourceAspect sentinelResourceAspect() 
    return new SentinelResourceAspect();
  

🍀(3)UserController中编写测试逻辑,添加@SentinelResource,并配置blockHandler和fallback

@RequestMapping(value = "/findOrderByUserId/id")
@SentinelResource(value = "findOrderByUserId",fallback = "fallback",fallbackClass = ExceptionUtil.class,blockHandler = "handleException",blockHandlerClass = ExceptionUtil.class)
public R findOrderByUserId(@PathVariable("id") Integer id) 
  //ribbon实现
  String url = "http://mall‐order/order/findOrderByUserId/"+id;
  R result = restTemplate.getForObject(url,R.class);

  if(id==4)
    throw new IllegalArgumentException("非法参数异常");
  

  return result;

🍀(4)编写ExceptionUtil,注意如果指定了class,方法必须是static方法

public class ExceptionUtil 

  public static R fallback(Integer id,Throwable e)
    return R.error(2,"===被异常降级啦===");
  

  public static R handleException(Integer id, BlockException e)
    return R.error(2,"===被限流啦===");
  

🍀(5)流控规则设置可以通过Sentinel dashboard配置

客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel‐transport‐simple‐http</artifactId>
  <version>1.8.0</version>
</dependency>
 ‐Dcsp.sentinel.dashboard.server=consoleIp:port

五、Sentinel控制台

下载控制台 jar 包并在本地启动:可以参见此处文档https://github.com/alibaba/Sentinel/releases

#启动控制台命令
java ‐jar sentinel‐dashboard‐1.8.0.jar

用户可以通过如下参数进行配置:

  • -Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;
  • -Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为sentinel;
  • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;
java ­Dserver.port=8858 ­Dsentinel.dashboard.auth.username=xushu ­Dsentinel.dashboard.auth.password=123456 ­jar sentineldashboard­1.8.0.jar

为了方便快捷启动可以在桌面创建.bat文件:

java ‐Dserver.port=8858 ‐Dsentinel.dashboard.auth.username=xushu ‐Dsentinel.dashboard.auth.password=123456 ‐jar D:\\server\\sentinel‐dashboard‐1.8.0.jar
pause

访问http://localhost:8080/#/login ,默认用户名密码: sentinel/sentinel

Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包,所以要确保客户端有访问量;

六、Spring Cloud Alibaba整合Sentinel

🍀(1)引入依赖

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring‐cloud‐starter‐alibaba‐sentinel</artifactId>
</dependency>

🍀(2)添加yml配置,为微服务设置sentinel控制台地址添加Sentinel后,需要暴露/actuator/sentinel端点,而Springboot默认是没有暴露该端点的,所以需要设置,测试
http://localhost:8800/actuator/sentinel

server:
  port: 8800

spring:
  application:
    name: mall‐user‐sentinel‐demo
  cloud:
    nacos:
      discovery:
        server‐addr: 127.0.0.1:8848

  sentinel:
    transport:
      # 添加sentinel的控制台地址
      dashboard: 127.0.0.1:8080
      # 指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
      # port: 8719

🍀(3)在sentinel控制台中设置流控规则

  • 资源名: 接口的API
  • 针对来源: 默认是default,当多个微服务都调用这个资源时,可以配置微服务名来对指定的微服务设置阈值
  • 阈值类型: 分为QPS和线程数 假设阈值为10
  • QPS类型: 只得是每秒访问接口的次数>10就进行限流
  • 线程数: 为接受请求该资源分配的线程数>10就进行限流

🍀(4)测试

因为QPS是1,所以1秒内多次访问会出现如下情形:


访问http://localhost:8800/actuator/sentinel, 可以查看flowRules。

🍀(5)微服务和Sentinel Dashboard通信原理

Sentinel控制台与微服务端之间,实现了一套服务发现机制,集成了Sentinel的微服务都会将元数据传递给Sentinel控制台,架构图如下所示:

流控针对privoder 熔断降级,针对consumer。


后记

👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~

以上是关于Spring Cloud全家桶主要组件及简要介绍的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Alibaba全家桶——微服务调用组件Feign

Spring Cloud Alibaba全家桶——微服务组件Nacos配置中心

Spring Cloud Alibaba全家桶——Spring Cloud Alibaba介绍

Spring Cloud Alibaba全家桶——微服务网关Gateway组件

Spring Cloud全家桶介绍

Spring Cloud Alibaba全家桶——微服务组件Nacos注册中心