Spring Cloud与SpringCloud Alibaba

Spring Cloud与SpringCloud Alibaba_第1张图片
配置中心(SpringCloud config)
注册中心(SpringCloud netflix eurka)
API网关(SpringCloud netflix zuul)

1、SpringCloud Alibaba简介

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
SpringCloud Alibaba Github地址

  • SpringCloud的几大缺点
    1.部分组件停止维护和更新给开发带来不便(eurka)
    2.部分环境搭建复杂,没有完善的可视化界面,需要大量的二次开发
    3.配置复杂难上手部分配置差别较细

  • SpringCloud Alibaba的优点
    阿里使用的组件经过实际考验,性能强悍,设计合理,开源成套的产品搭配完善的可视化界面给开发和运维带来极大便利,且搭建简单,学习难度低。

  • 结合SpringCloud Alibaba项目的最终的技术搭配方案
    Spring Cloud与SpringCloud Alibaba_第2张图片

  • spring-cloud-alibaba版本的选择,见
    SpringCloud Alibaba Github地址

  • 在父项目pom文件中引入一

<!--   dependencyManagement实际不引用依赖只提供版本号与scope信息 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

1.1.spring Cloud Alibaba Nacos

  • 安装 Alibaba Nacos server
    下载Nacous Server并解压(这里为了方便我们放到本地window系统),运行bin/startup.cmd即可启动Nacous Server服务
    http://127.0.0.1:8848/nacos访问服务

1.1.1 discovery(注册中心)

  • common模块引入依赖
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
  • 在应用的配置文件中配置服务名和Nacos Server 地址,
spring:
  application:
    name: wwmall-product
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  • 启动类标注@EnableDiscoveryClient即可将服务注册到nacous注册中心

1.1.2Config(配置中心)

1.1.2.1简单示例

  • common模块导入依赖,引入 Nacos Config Starter
<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>
  • 在应用的 /src/main/resources/bootstrap.properties 配置文件中配置 Nacos Config 元数据
#该文件会优先于application.yml/application.properties加载
spring.application.name=wwmall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
  • 给配置中心默认添加一个数据集(Data Id的规则为:应用名.properties。例如wwmall-coupon.properties)
    Spring Cloud与SpringCloud Alibaba_第3张图片
  • 将需要的配置文件写在数据集中并发布,即可动态获取
    Spring Cloud与SpringCloud Alibaba_第4张图片
  • 动态获取:使用@RefreshScope(动态获取或刷新配置)和@Value("${配置项的名}")(获取配置)
@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;
/*---------------------测试代码start----------------------------------------------*/
    @Value("${coupon.user.name}")
    private String username;

    @Value("${coupon.user.age}")
    private Integer age;

    @RequestMapping("/test")
    public R test(){
       return R.ok().put("username",username).put("age",age);
    }

注:如果配置中心和当前应用的配置文件中由相同的项,则优先使用配置中心中的配置信息

1.1.2.2 命名空间与配置分组

Spring Cloud与SpringCloud Alibaba_第5张图片

  • 命名空间(Namespace):可用于进行不同环境的配置隔离。一般一个环境划分到一个命名空间
    默认的public为保留空间,默认新增的所有配置都在public空间
    1.在不同的环境(开发、测试、生产)利用命名空间来做环境隔离可以在bootstrap.properties配置需要使用哪个命名空间下的配置
    2.每一个微服务之间互相隔离,每个微服务创建自己的命名空间,只加载自己命名空间下的所有配置
#指定使用的命名空间
spring.cloud.nacos.config.namespace=ad0d2241-8cfc-4c30-a83f-1bd2c72eb62d
  • 配置分组(Group):配置分组用于将不同的服务可以归类到同一分组。一般将一个项目的配置分到一组
    默认所有的配置集都属于DEFAULT_GRUOP
    在bootstrap.properties中使用指定命名空间下的指定配置分组:
#指定使用的命名空间
spring.cloud.nacos.config.namespace=ad0d2241-8cfc-4c30-a83f-1bd2c72eb62d
#指定使用的分组
spring.cloud.nacos.config.group=dev
  • 配置集(Data ID):在系统中,一个配置文件通常就是一个配置集。一般微服务的配置就是一个配置集
    Spring Cloud与SpringCloud Alibaba_第6张图片

本项目采用:每个微服务创建自己的命名空间,使用配置分组区分环境(desv,test,prod)
Spring Cloud与SpringCloud Alibaba_第7张图片

1.1.2.3加载多配置文件

配置文件不会全写在application.yml中会根据配置项分出多个配置集,我们关心在nacos中如何加载多个配置集
将配置文件拆分成多个datasource.yml,mybatis.yml,other.yml并在配置中心创建对应的配置集
在这里插入图片描述

  • 在bootstrap.properties说明加载配置中心中指定的配置集组
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
spring.cloud.nacos.config.extension-configs[0].group=dev
#开启动态刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true

spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml
spring.cloud.nacos.config.extension-configs[1].group=dev
spring.cloud.nacos.config.extension-configs[1].refresh=true

spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true

  • @value @configrationProperties等以前在springboot中能从配置文件中获取值的现在也可以使用。
    注:配置中心有的优先从配置中心取,没有的话就去项目的application.properties文件中取

1.1.3Nacos持久化

https://www.cnblogs.com/larscheng/p/11422909.html

1.2spring Cloud Alibaba sentinel

1.2.1什么是熔断降级限流

熔断
在这里插入图片描述
降级
在这里插入图片描述
两者相同点
在这里插入图片描述
两者不同点
在这里插入图片描述
限流
对打入服务的请求流量进行控制,使服务能承担不超过自己的流量压力

1.2.2sentinel简介

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
官方文档 https://github.com/alibaba/spring-cloud-alibaba/wiki
整合springboot/springcolud https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
控制台
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。

1.2.3spring boot 整合sentinel

引入依赖

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

下载,启动,配置控制台
下载地址 https://github.com/alibaba/Sentinel/releases 命令java -jar 启动
配置控制台

spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

在控制台设置流控设置即可,设置的留空规则是保存在内存中的,重启就会失效

两个问题

  • 控制台的实时监控没有数据(使用endpoint支持)?
    1.在服务中导入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

2.修改springboot配置

#允许 Endpoints 的访问。
management.endpoints.web.exposure.include=*
  • 请求限流的自定义提示,资源控制
@RestController
public class TestController {
    // blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
    @SentinelResource(blockHandler = "blockHandlerForGetUser", fallback = "blockHandlerForGetUser")
    @RequestMapping("/hello")
    public String hello(String id) {
        return "Hello Sentinel";
    }

    public String blockHandlerForGetUser(String id,BlockException exception) {
        System.out.println(id+"--------------------");
        return id+"访问频繁...";
    }
}

1.2.4流控规则

流控模式:链路 假设现在需要流控的资源名C,设置A为请求入口,有一个请求A调用了B调用了C,那么只有请求只有入口为A落到C的请求才被流控,从其他入口调用C都不会被流控
流控模式:关联 当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。流控资源为C 关联资源为A,当C被流控时也流控A

1.2.5熔断降级

使用sentinel来保护feign远程调用,熔断
调用方的熔断保护
引入依赖spring-cloud-starter-alibaba-sentinel,spring-cloud-starter-openfeign
配置文件配置:feign.sentinel.enabled=true

@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    String echo(@PathVariable("str") String str);
}

class FeignConfiguration {
    @Bean
    public EchoServiceFallback echoServiceFallback() {
        return new EchoServiceFallback();
    }
}

class EchoServiceFallback implements EchoService {
    @Override
    public String echo(@PathVariable("str") String str) {
        return "echo fallback";
    }
}

调用方控制台手动指定远程服务的降级策略,远程服务被降级处理会触发我们的熔断回掉方法
超大流量的时候必须牺牲一下远程服务,在服务的提供方指定降级策略.提供方是在执行方法,但是执行自己的业务逻辑,返回的是默认的降级数据(限流的数据)

1.2.6自定义受保护资源

1.抛出异常的方式定义资源

// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
  // 被保护的业务逻辑
  // do something here...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 在此处进行相应的处理操作
}

2.注解方式定义资源
注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。请注意 blockHandler 和 fallback 函数的形式要求,https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

// 原本的业务方法.
@SentinelResource(blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
    throw new RuntimeException("getUserById command failed");
}

// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(String id, BlockException ex) {
    return new User("admin");
}

1.2.7网关层控制-不进入服务

引入依赖(sentinel与网关的整合版本与cloud alibaba吻合)-提供了自动配置,官方文档给的依赖还需要编写配置类

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

可以在配置文件中配置被限流降级的回调信息
Spring Cloud与SpringCloud Alibaba_第8张图片
使用代码方式编写回调操作

@Configuration
public class SentinelGatewayConfig {
    public SentinelGatewayConfig(){
        GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Mono<ServerResponse> mono = ServerResponse.ok().body(Mono.just("网关限流降级"), String.class);
                return mono;
            }
        });
    }
}

1.2.8sentinel持久化

https://www.jianshu.com/p/609961eb6a6e

2.Spring cloud组件

2.1Feign(声明式远程调用)

Feign是声明式的Http客户端,它让微服务之间的调用变得更简单了,Fegin提供了Http请求的模板,通过编写简单的接口和插入注解,就可以定义好Http请求的参数、格式、地址等信息。
Spring Cloud Fegin集成了Ribbon(负载均衡),可在让我们不在显式的使用这个组件。
Spring Cloud openFegin在NetfilxFeign基础上扩展了对SpringMVC注解的支持,在其实现下我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了Spring Cloud Ribbon自行封装服务调用客户端的开发量。

  • 引入依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

模仿会员(wwmall-member)模块调用优惠券(wwmall-coupon)模块

  • 想要远程调用coupon模块的getCouponListByMemberId方法
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @RequestMapping("/member-coupon/couponList")
    public R getCouponListByMemberId(String memberName){
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("五折优惠.....");
    return R.ok().put("memberName",memberName).put("couponEntity",Arrays.asList(couponEntity));
    }
  • 在会员模块编写一个接口,使用@FeignClient注解告诉springcloud这个接口需要调用哪个远程服务,声明接口内的每一个方法是调用哪个远程服务的哪个请求
package com.walkwind.wwmall.member.feign;
@FeignClient("wwmall-coupon")
public interface CouponFeignService {

    @RequestMapping("/coupon/coupon/member-coupon/couponList")
    public R getCouponListByMemberId(String memberName);
}
  • 测试调用远程接口业务代码
@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Autowired
    CouponFeignService couponFeignService;

    @RequestMapping("/getCouponList")
     public R getCouponList(){
        R coupon = couponFeignService.getCouponListByMemberId("张三");
        return coupon;
    }
  • 使用@EnableFeignClients在启动类上注解开启远程调用功能
@SpringBootApplication
@EnableDiscoveryClient
//明确告诉fegin远程调用接口处在哪个包下,不配置的话会自动扫描所有标注了@FeignClient("wwmall-coupon")的接口
@EnableFeignClients(basePackages="com.walkwind.wwmall.member.feign")
public class WwmallMemberApplication {

    public static void main(String[] args) {
        SpringApplication.run(WwmallMemberApplication.class, args);
    }

}

  • 运行项目测试远程调用功能(需开启Nacos服务)
    注:feign远程调用传递参数是以json数据传输,只要属性名对应就可以封装到任意引用类型中,上例的张三传递失败没有实际业务意义,实际应用会创建一个to对象(从业务中抽取的实体类中的某些属性组合成的对象,没有实际意义只用于远程调用接口数据传输的载体)

Fegin请求头丢失问题

登录后远程调用请求头数据cookie丢失
Spring Cloud与SpringCloud Alibaba_第9张图片
解决方法:fegin在调用之前要构造请求,调用很多的拦截器,我们可以加上fegin远程调用的拦截器在请求进入后,获取请求头数据,将请求头放入新的requestTemplate中。RequestContextHolder使用ThreadLocal去获取原请求上下文信息
Spring Cloud与SpringCloud Alibaba_第10张图片
fegin异步情况丢失上下文问题
Spring Cloud与SpringCloud Alibaba_第11张图片
解决方法
在主方法中获取老请求的请求头数据,在创建的每个子线程类中为请求头放入数据
Spring Cloud与SpringCloud Alibaba_第12张图片

2.2gateway网关

1.简介
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制。springcloud gateway作为springcloud官方推出的第二代网关框架,取代了zuul网关。
2.概念
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。

Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。

Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

3.工作原理
Spring Cloud与SpringCloud Alibaba_第13张图片
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

4.使用gateway

  • 使用spring初始化向导创建wwmall-gateway模块引入gateway组件
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  • 在pom文件中引入common模块
    注这里应排除common工程中的mybatis依赖不然会报错
 <dependency>
            <groupId>com.walkwind.wwmall</groupId>
            <artifactId>wwmall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
  • 将wwmall-gateway注册到nacos中
    1.开启注册发现服务功能
    @EnableDiscoveryClient
    2.配置文件中配置,服务注册/发现中心地址
spring:
  application:
    name: wwmall-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

3.在nacos中配置命名空间与配置集
Spring Cloud与SpringCloud Alibaba_第14张图片

4.配置文件中配置,配置中心信息及使用的命名空间信息
bootstrap.properties

spring.application.name=wwmall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=ac252e0f-5dc4-4a9c-9175-08937b6ddcd9
spring.cloud.nacos.config.name=wwmall-gateway.yml
spring.cloud.nacos.config.group=dev

5.配置网关路由信息

spring:
  cloud:
    nacos:
    gateway:
      routes:
        - id: baidu_route
          uri: https://www.baidu.com/
          predicates:
            - Path=/baidu
        - id: qq_route
          uri: https://www.qq.com
          predicates:
            - Path=/qq

更多路由配置参考说明文档

2.3sleuth+zipkin服务链路追踪

2.3.1.为什么用

Spring Cloud与SpringCloud Alibaba_第15张图片

2.3.2.基本术语

官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.2.2.RELEASE/reference/html/#introduction
Spring Cloud与SpringCloud Alibaba_第16张图片

2.3.3流程图

服务调用业务
Spring Cloud与SpringCloud Alibaba_第17张图片
对应的流程
Spring Cloud与SpringCloud Alibaba_第18张图片
span之间的父子关系
Spring Cloud与SpringCloud Alibaba_第19张图片

2.3.4整合sleuth

Spring Cloud与SpringCloud Alibaba_第20张图片

2.3.5整合zipkin可视化观察链路

在这里插入图片描述
Spring Cloud与SpringCloud Alibaba_第21张图片
界面分析

Spring Cloud与SpringCloud Alibaba_第22张图片

你可能感兴趣的:(Spring,Cloud,Alibaba)