SpringCloud入门

Spring Boot和Spring Cloud

SpringCloud
Spring Cloud是-个分布式的整体解决方案。Spring Cloud为开发者提供了在分布式系统(配
置管理,服务发现,熔断,路由,微代理,控制总线,- -次性token,全局琐,leader选举, 分
布式session,集群状态)中快速构建的工具,使用Spring Cloud的开发者可以快速的启动服务
或构建应用、同时能够快速和云平台资源进行对接。
●SpringCloud分布式开发五大常用组件
●服务发现一 Netflix Eureka
●客服端负载均衡一Netflix Ribbon
●断路器一 Netflix Hystrix
●服务网关一-Netlix Zuul
●分布式配置一 -Spring Cloud Config

快速开始Cloud

注册中心

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGNq6ueY-1603278766654)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1584929037174.png)]

配置文件

server:
  port: 8761
eureka:
  instance:
    hostname: eureka-server  #eureka实例的主机名字
  client:
    register-with-eureka: false #不把自己注册到 eureka
    fetch-registry: false   #不从eureka上获取服务的注册信息
    service-url:
      defaultZone: http://localhost:8761/eureka/

在启动类上添加注解

@EnableEurekaServer  //启动注册中心

服务提供者

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qilRvHXc-1603278766658)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1584929138810.png)]

配置文件

server:
  port: 8002
spring:
  application:
    name: provider-ticket

eureka:
  instance:
    prefer-ip-address: true #注册服务时使用ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

服务消费者

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HhK6zVEo-1603278766661)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1584929282691.png)]

配置文件

spring:
	application:
 	 name: consumer-user
server:
  port: 8200
eureka:
  instance:
    prefer-ip-address: true #注册服务时使用ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

启动类添加 获取服务注解 开启负载均衡

@EnableDiscoveryClient    //开启获取服务
@SpringBootApplication
public class ConsumerUserApplication {

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

    @LoadBalanced     //使用负载均衡
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

开始获取服务

@RestController
public class UserController {

    @Autowired
    RestTemplate template;

    @GetMapping("/buy")
    public String buyTicket(String name){
        //第一个参数为注册中心的服务名 , 第二个参数返回值类型;
       String s = template.getForObject("http://PROVIDER-TICKET/ticket",String.class);
        return name+"购买了"+s;
    }
}

SpringBoot

Spring --> SpringMvc --> Tomcat
简化配置值

舍弃笨重的xml 改用 yml 或properties

产品独立运行

产品可独立运行,打成jar包,内置了tomcat 或其他servlet容器,契合微服务的理念;

强大的场景启动器

每一个特定场景需求都封装成了有个starter,只需要导入这个启动器就有了这个场景所需的一切,其中包括针对这个场景的自动化配置,依赖信息;

重要的组成部分

  starter 启动器
  @Enablexxx 注解      功能启用
  yml 或 propertires   配置文件
  主启动类

相关注解

@Configuration 注解标记一个类后,该类成为配置类,加载这个类中的配置可以取代以前的xml 配置文件

@Bean 注解把一个类的对象加入IOC容器
@Import 相对于@Bean,能更便捷的将已给类jiaruIOC容器

@Conditional注解 一个类满足特定条件时才加如IOC容器

@ComponentScan 指定IOC容器扫描的包,自动扫描指定的包下的注解 等同于 xml context:component-scan;
@ComponentScan({"全限定包名1","全限定包名2"}) 可以扫描多个包

@SpringBootConfiguration @Configuration注解的 SpringBoot版
@Targer(ElementType.Type)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@COnfiguration
public @interface SpringBootConfiguration{

}

@EnableAutoConfigurtion 启动自动化配置

@AutoConfigurationPackage 指定自动配置的包

@SpringBootAppliction 注解相当于 ssm中的总配置文件,包含了  @SpringBootConfiguration  @ComponentScan @EnableAutoConfigurtion ...

SpringBoot 工作原理

读取spring.factories文件

SpringBoot启动时会读取spring-boot-autoconfigure-2.2.5.RELEASE.jar包下的ME TA-INF/spring.factories文件。读取
org.springframework.boot.autoconfigure.EnableAutoConfiguration属性的值加载自动配置类。

加载XxxProperties类

根据自动配置类中指定的XxxPropertes类设置自动配置的属性值,开发者也可以根据XxxProperties类中指定的属性在yml 
配置文件中修改自动配置。.

根据@ConditionalXxx注解决定加载哪些组件

SpringBoot通过@ConditionalXxx注解指定特定组件加入IOC容器时所需要具备的特定条件。这个组件会在满足条件时加入
I0C容器。

整合bootRedis

导入依赖

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

boot 无法连接redis

解决办法:
查看有没有启动Redis服务器。

redis的配置application.yml(或application.properties)中
spring.redis.timeout连接超时时间(毫秒)中设置不能为0,
一般修改如下:spring.redis.timeout=5000。

找到redis的配置文件 redis.conf : 执行 vim redis.conf
3.1 protected-mode yes 改为 protected-mode no (即该配置项表示是否开启保护模式,默认是开启,开启后Redis只会本地进行访问,拒绝外部访问)。
3.2 注释掉 bin127.0.0.1 即 #bin 127.0.0.1 (ps: 不注释掉,表示指定 redis 只接收来自于该 IP 地址的请求,注释掉后,则表示将处理所有请求)。

如果在Redis中没有配置requirepass ,那么在application.properties(或application.yaml)中就不要写spring.redis.password。

Redis (error) NOAUTH Authentication required.解决方法

出现认证问题,应该是设置了认证密码,输入密码既可以啦

注意密码是字符串形式!

cdm 命令

//密码
auth "yourpassword"
//查询所有的 keys
keys *
//查询指定 key的值
get key

SpringCloud 的组件

注册中心:Eureka

客户端负载均衡:Ribbon

声明式远程方法调用:Feign

服务降级 熔断 :Hystrix;

网关:Zuul

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ka3ibEb2-1603278766665)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1585097293833.png)]

创建 Cloud项目

1.创建注册中心

创建boot 项目

导入依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

启动类 添加注解

@EnableEurekaServer //启用Eurek服务器功能

yml 配置文件

server:
  port: 5000
eureka:
  instance:
    hostname: localhost           #注册中心的地址
  client:
    register-with-eureka: false  #不把自己注册到注册中心,自己本身就是
    fetch-registry: false        #不需要从注册中行取回信息
    service-url:                  #注册中心地址 , 客户端访问注册中心时使用
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

2.Feign (提供业务接口)

建议使用boot 项目

openfeign 提供远程业务接口

导入依赖

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

编写远程业务接口

调用者:

//远程调用的接口方法
//要求 方法完全一致  (修饰符,参数,方法名,返回值)
//请求方式 ,请求路径完全一致
//使用的注解完全一致
import com.sl.commons.pojo.Employee;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

// 表示当前接口和一个 provider的服务对应
@FeignClient("provider")
public interface EmployeeRemoteService {

    //远程调用的接口方法
    //要求 方法完全一致  (修饰符,参数,方法名,返回值)
    //请求方式 ,请求路径完全一致
    //使用的注解完全一致
    @RequestMapping("/provider/get/employee/remote")
    public Employee getEmployeeRemote();

}

3.服务提供者

创建boot 项目 (web)

1.导入依赖

 <!--依赖接口提供者工程-->
        <dependency>
            <groupId>com.sl</groupId>
            <artifactId>commons</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
         <!--客户端依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency> 

yml配置

server:
  port: 1000

eureka:
  client:
    service-url:
      defaultZone: http://localhost:5000/eureka/
spring:
  application:
    name: provider

启动类 2.0版本之下的需要添加注解 其下任意一个即可

@EnableEurekaClient

只能是获取 Eureka注册中心提供的服务;

@EnableDiscoveryClient

可以获取任意注册中写 的服务

实现Feign提供的业务接口

注意点:

//远程调用的接口方法
//要求 方法完全一致 (修饰符,参数,方法名,返回值)
//请求方式 ,请求路径完全一致
//使用的注解完全一致

@RestController
public class EmployeeController {

    @RequestMapping("/provider/get/employee/remote")
    public Employee getEmployeeRemote(){
        System.out.println("1000");
        return new Employee(555,"provider:",555.55);
    }

4.服务消费者

创建 boot项目 (web)

导入依赖

 <!--依赖接口提供者工程-->
        <dependency>
            <groupId>com.sl</groupId>
            <artifactId>commons</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        
            <!--服务消费者依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
          <!--客户端依赖-->
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

yml配置

server:
  port: 4000
spring:
  application:
    name: cosumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5000/eureka/

启动类添加注解

扫描Feign提供的远程接口

 @EnableFeignClients("com.sl.commons") 

远程调用微服务接口

@RestController
public class HumanResourcrHandler {
    //准备 远程调用微服务的接口
    @Autowired
    private EmployeeRemoteService employeeRemoteService;

    @RequestMapping("/feign/get/employee")
    public Employee getEmployee() {
       return employeeRemoteService.getEmployeeRemote();
    }

    @RequestMapping("/s")
    public String s() {
        return "ssss";
    }
}

小拓展

ribbon

负载均衡:的实现过程被隐藏 在远程调用微服务是开启;

spring-cloud-starter-netflix-ribbon

集群:一模一样的业务的集合,来自于同一个注册中兴,端口不一样,服务名一样;

参数的传递

基本类型

@RequestParam(“id”) String id

复杂类型

@RequestBody Student stu

服务雪崩

在微服务架构体系下,服务间的调用错综复杂,交织成一张大网。 如果其中某个节点突然无法正常工作,则访问它的众多服务都会被卡住,进而有更多服务被卡住,系统中的线程、CPU、内存等资源有可能被迅速耗尽,最终整个服务体系崩溃。
我们管这样的现象叫服务雪崩。

Hytrix介绍

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里, 许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix 能够保正在个依 赖出问题的情况下,不会导致整体服务失败,避免级联故险,以提商分布式系统的弹性。

“断路器”本身是种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),面不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用用方的线程不会被长时间、不必要地占用,从而避见了故障在分布式系统中的蔓延。乃至雪崩:
Hytrix能够提供眼务降级、服务熔断、服务用流、按近实时的监控等方面的功能。

服务熔断机制

[熔断机制]是应对雪蹦效应的一种微服务链路保护机制。

当扇出链路的某个微服务不可用或者响应时何太长时。会进行服务的[降级]:近而熔断该节点服务的调用,快速响应错误信息:当检测到该节点微服务调用响施正常后恢复调用链路,在SpringCloud框架里熔断机制通过Hystrix 实现。Hystrix 会监控微厦务间调用的状况,当失败的调用到一定阀值,缺省是5秒内20次调用夫败就会启动熔断机制。熔断机制的注解是@HystrixCommand.

服务消费者 备用方案 : 降级

服务降级 处理是在 客户端(Consumer) 实现完成的 , 于服务端(Provider)没有关系,当某个Consumer访问Provider却迟迟得不到响应时执行预先设定好的一个解决方案; 而不是一直等待
  
      Consumer   ------->
             正常方案 : XXX     -------------->     provider
                                                      |
                                                     异常
                                                      ↓  
             备用方案 : XXX     <--------------    启用备选方案
                  |
                  ↓ 
              返回相同类型的数据
            让整个系统可以据需运行
                                                                                                                                                  

在 业务接口 导入依赖

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

自定义返回值类

作为项目的统一返回值

ResultEntity

package com.sl.commons.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


/**
 * 项目统一使用 这个类型作为Ajax 请求 或远程
 * 方法条用返回响应的数据格式
 * @param <T>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultEntity<T> {
    public static final String SUCCESS = "SUCCESS"; //成功
    public static final String FAILED = "FAILED";   //失败
    public static final String NO_MESSAGE = "NO_MESSAGE";  //无消息
    public static final String NO_DATA = "NO_DATA";  //无数据


    private String resulr;
    private String message;
    private T data;

    /**
     * 操作成功,无需返回数据
     * @return
     */
    public static ResultEntity<String> successWithoutData(){
        return  new ResultEntity<String>(SUCCESS,NO_MESSAGE,NO_DATA);
    }

    /**
     * 操作成功 ,需要返回数据
     * @param data
     * @param <E>
     * @return
     */
    public static <E> ResultEntity<E> successWithoutData(E data){
        return new ResultEntity<>(SUCCESS,NO_MESSAGE,data);
    }

    /**
     * 操作失败 ,返回错误信息
     * @param message
     * @param <E>
     * @return
     */
    public static <E> ResultEntity<E> failed(String message){
        return new ResultEntity<>(SUCCESS,message,null);
    }
}

创建 MyFallBackFactiry

实现 FallbackFactory

package com.sl.commons.factory;

import com.sl.commons.api.EmployeeRemoteService;
import com.sl.commons.pojo.Employee;
import com.sl.commons.util.ResultEntity;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;


import java.util.List;

/**
 * 实现 Conumer 服务降级的功能
 * 实现 FallbackFactory 这个借口是 要传入 @FeignClient注解标记的接口类型;
 * 实现create 方法  返回 @FeignClient注解标记的接口类型的对象  当 provide调用失败时 会执行这个对象对应的方法
 */
@Component
public class MyFallBackFactiry implements FallbackFactory<EmployeeRemoteService> {
    @Override
    public EmployeeRemoteService create(Throwable throwable) {
        return new EmployeeRemoteService() {
            @Override
            public Employee getEmployeeRemote() {
                return null;
            }

            @Override
            public List<Employee> getEList(String key) {
                return null;
            }

            @Override
            public ResultEntity<Employee> breaker(String signal) {
                return ResultEntity.failed(throwable.getMessage()+"降级使用");
            }
        };
    }
}

接口业务类

注解

@FeignClient(value = “provider”,fallbackFactory = MyFallBackFactiry.class)

package com.sl.commons.api;


import com.sl.commons.factory.MyFallBackFactiry;
import com.sl.commons.pojo.Employee;
import com.sl.commons.util.ResultEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

// 表示当前接口和一个 provider的服务对应
//fallbackFactory 指定  provider 不可使用时 提供备用的 工厂对象
@FeignClient(value = "provider",fallbackFactory = MyFallBackFactiry.class)
public interface EmployeeRemoteService {

    //远程调用的接口方法
    //要求 方法完全一致  (修饰符,参数,方法名,返回值)
    //请求方式 ,请求路径完全一致
    //使用的注解完全一致
    @RequestMapping("/provider/get/employee/remote")
    public Employee getEmployeeRemote();
    @RequestMapping("/provider/get/empList/remote")
    List<Employee> getEList(@RequestParam("key") String key);

    @RequestMapping("/provider/get/emp/circuit/breaker")
     public  ResultEntity<Employee> breaker(@RequestParam("signal") String signal)throws InterruptedException;
}

服务消费者类 扫描接口业务的包;

@EnableFeignClients("com.sl.commons")@SpringBootApplication(scanBasePackages = {"com.sl.commons","com.sl.consumer"})

服务消费者 导入依赖

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

配置文件

feign:
  hystrix:
    enabled: true

服务提供者 备用方案 : 熔断

服务提供者 导入 依赖

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

为指定的方法添加 备用方法

@HystrixCommand 指定方法出现问题时调用备份方法

    // @HystrixCommand 指定方法出现问题时调用备份方法;
    @HystrixCommand(fallbackMethod = "breaker2")
    @RequestMapping("/provider/get/emp/circuit/breaker")
    public ResultEntity<Employee> breaker(@RequestParam("signal") String signal) throws InterruptedException {
        if ("quick-bang".equals(signal)) {
           throw  new RuntimeException();
        }
        if ("slow-bang".equals(signal)) {
            Thread.sleep(5000);
        }
       return ResultEntity.successWithoutData(new Employee(555,"provider3",555.55));
    }

    public ResultEntity<Employee> breaker2(@RequestParam("signal") String signal){
        String message = "方法出现问题"+signal+"/n执行备用方法";
        return ResultEntity.failed(message);
    }

监控 服务

在 服务提供者

provider工程中添加依赖

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

配置yml添加

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

创建一个 监控工程

导入依赖

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

启用仪表盘监控功能

@EnableHystrixDashboard

访问服务监控

http://localhost:9000/hystrix

完成一整套的服务 ;才能有该服务的监控;

http://localhost:8001/actuator/hystrix.stream

zuul网关

为什么 要 定义统一的入口

不同的微服务有不同的网络地址,而外部的客户端 可能需要调用多个服务的接口才能完成一个业务需求.

会存在一下不利因素

 1.客户端胡多次请求不同的微服务,增加客户端的复杂性;

 2.存在跨域请求,在一定场景下处理相对复杂;

3.认证复杂,每一个服务器都要独立认证;

4.难以重构,随着项目的迭代,可能需要重新划分微服务,如果客户端直接和微服务同行,那么重构会难以实施;

5.某些微服务可能使用了其他的协议,直接访问有一定困难 

Zuul 包含了对请求打的路由和过滤两个最主要的功能;
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,
而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合功能的基础;

Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中或得其他微服务的信息,以及以后的访问微服务都是Zuul跳转后获得;

总的来说, Zuul提供了  代理, 路由 和 过滤 的功能
          
                          (别名)                         
                      (避免暴露微服务的名字)                具体微服务
请求 ---- Zuul ---- 请求特征 --- 微服务名字 --- Eureka ---  具体微服务
                                                        具体微服务
                                                       
                                                       

创建 Zuul网关 代理

创建新的 Sprinboot项目

导入依赖

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

启动Zuul 网关代理功能

@EnableZuulProxy

访问测试

http://localhost:9000/ consumer/feign/get/fallback

​ zuul网关 微服务名字 目标具体的微服务

yml 配置

spring:
  application:
    name: zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5000/eureka/
server:
  port: 9999

#自定义路由
zuul:
  routes:
    employye:     #自定义路由规则名称,在底层的结构式map的键
      service-id: consumer   #目标微服务名称 ,ZuulRoute类型的一个属性
      path: /zuul-emp/**     # 用来代替目标微服务的名称  /**表示多层
  ignored-services: '*'     # 忽略所有的微服务 名称
 # ignored-services:
   # - consumer      # 忽略指定指定微服务名称
  prefix: /sl       #给访问的路径添加统一 的前缀

配置为zuul ,从zuul 进入调用服务 必须按照 zuul 定义的规则来进行访问服务

http://localhost:9000/ sl/zuul-empfeign/get/fallback

Zuul过滤器

MyZuulFilter

package com.sl.zuul.config;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class MyZuulFilter extends ZuulFilter {
    Logger logger = LoggerFactory.getLogger(MyZuulFilter.class);
    @Override
    public String filterType() {
        //返回当前过滤器的类型,并决定当前过滤器在什么时候执行
        //pre 表示 在目标微服务之前执行
        String filterType = "pre";
        return filterType;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    //判断当前请求是否过滤
    //如果过滤 执行 run方法
    //不过滤 直接放行
    //shouldFilter 返回 true 调用 run 方法 false 放行
    @Override
    public boolean shouldFilter() {

        //获取 RequestContext 对象
        //threadLocal; 本地化;
        // 你在上游通过threadLocal.set(T value) 存
        // 你在下游 通过threadLocal.get() 方法取  ,因为是同一条河(同一线程)所以可以取;
        RequestContext currentContext = RequestContext.getCurrentContext();

        //获取 Request 对象
        HttpServletRequest request = currentContext.getRequest();

        String signal = request.getParameter("signal");


        return "hello".equals(signal);
    }

    @Override
    public Object run() throws ZuulException {
        logger.info("当前请求要过滤,执行了 run() 方法");
        //当前实现会忽略这个返回值 , 所以返回null,不做特殊处理;
        return null;
    }
}

SpringCloud小结

SpringBoot 和SpringCloud关系
SpringBoot是基础
SpringCloud要基于SpringBoot开发
SpringCloud 和Dubbo对比
核心:
Dubbo底层基于RPC
SpringCloud底层基于RestFul.也可以说是基于HTTP
其他区别:
SpringCloud相对于Dubbo功能更全面
SpringCloud 是一个一站式解决方案
SpringCloud能够天然的基于Spring全家桶开发



开发业务功能相关程度
Eureka  ★★★★★
Ribbon  ★★★
Feign   ★★★★★
Hystrix ★★★
Zuul    ★★★★★

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页