springcloud 入门2

Feign声明式服务调用

Feign概述
Feign 是一个声明式的 REST 客户端,它用了基于接口的注解方式,很方便实现客户端配置。
Feign 最初由 Netflix 公司提供,但不支持SpringMVC注解,后由 SpringCloud 对其封装,支持了SpringMVC注解,让使用者更易于接受。

使用Feign进行远程调用,比使用Ribbon进行调用更加灵活/方便,是以后开发的主流方案。

Feign远程调用快速入门

  1. 在消费端引入 open-feign 依赖
  2. 编写Feign调用接口
  3. 在启动类 添加 @EnableFeignClients 注解,开启Feign功能

1.在消费端引入 open-feign 依赖

<!--1.在消费端引入 openfeign 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.编写Feign调用接口

import com.itheima.comsumer.config.FeignLogConfig;
import com.itheima.comsumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author CZM
 * @date 2021 04 04 18:47
 *  2.编写Feign调用接口.发起远程调用用的
 *
 *  2.1 定义接口
 *  2.2 接口上添加注解@FeignClient,设置value属性为 服务提供者的 应用名称
 *  2.3 编写调用接口,接口的声明规则 和 提供方接口保持一致(方法名不用一致)
 *  2.4 注入该接口对象,调用该接口方法完成远程调用
 */
@FeignClient(value = "FEIGN-PROVIDER") 
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);
}

3.在启动类 添加 @EnableFeignClients 注解,开启Feign功能

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author CZM
 * @date 2021 04 03 23:20
 */
@SpringBootApplication
@EnableEurekaClient
//3.在启动类 添加 @EnableFeignClients 注解,开启Feign功能
@EnableFeignClients
public class ConsumerApp {
    public static void main(String[] args){
        SpringApplication.run(ConsumerApp.class,args);
    }
}

通过Feign进行调用

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    //注入该接口对象,调用该接口方法完成远程调用
    @Autowired
    private GoodsFeignClient goodsFeignClient;

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){

        //通过feign远程调用接口
        Goods goods = goodsFeignClient.findGoodsById(id);
        return goods;
    }

}

Feign 其他功能 – 超时设置
Feign 底层依赖于 Ribbon 实现负载均衡和远程调用。
Ribbon默认1秒超时。
超时配置(application.yml配置文件中设置):

#设置ribbon的超时时间
ribbon:
  ConnectTimeout: 1000 # 连接超时时间 默认1s
  ReadTimeout: 3000 # 逻辑处理超时时间 默认1s

Feign 其他功能 – 日志记录
Feign 只能记录 debug 级别的日志信息。
步骤:
1.设置debug 级别的日志信息配置(application.yml配置文件中设置):

# 1.设置当前的日志级别 debug,feign只支持记录debug级别的日志
logging:
  level:
    com.itheima: debug

2.定义Feign日志级别Bean

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author CZM
 * @date 2021 04 03 23:56
 * 2.定义Feign日志级别Bean
 */
@Configuration
public class FeignLogConfig {
    /*
        NONE,不记录
        BASIC,记录基本的请求行,响应状态码数据
        HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
        FULL,记录完成的请求 响应数据
     */

    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}

3.启用该Bean,在feign的调用接口中的@FeignClient注解中添加configuration = XxxConfig.class(Xxx:bean所在的类)

@FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)  //3.使用configuration = FeignLogConfig.class 启动该bean
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);
}

Hystrix 熔断器

Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。
雪崩:一个服务失败,导致整条链路的服务都失败的情形。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
Hystix 主要功能:隔离、降级、熔断、限流

一、Hystrix隔离:
-----1.线程池隔离(Hystrix默认,无需配置)

在这里插入图片描述
线程池为每个服务分配一定的线程数,当某个服务出现异常时,在其分配的线程数用完之后不会再分配线程,防止出现雪崩现象。
-----2.信号量隔离
在这里插入图片描述

二、Hystrix降级:
Hystix 降级:当服务发生异常或调用超时,返回默认数据
在这里插入图片描述
Hystrix 降级 – 服务提供方

  1. 在服务提供方,引入 hystrix 依赖
  2. 定义降级方法
  3. 在原方法上使用 @HystrixCommand 注解配置降级方法
  4. 在启动类上开启Hystrix功能:使用注解@EnableCircuitBreaker

1.在服务提供方,引入 hystrix 依赖

<!-- 1.在服务提供方,引入 hystrix 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

2.定义降级方法
3.在原方法上使用 @HystrixCommand 注解配置降级方法

import com.itheima.provider.domain.Goods;
import com.itheima.provider.service.GoodsService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * Goods Controller 服务提供方
 */

@RestController
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    /**
     * 降级:
     *  1.出现异常
     *  2.服务调用超时
     *
     *  @HystrixCommand(fallbackMethod = "")
     *      fallbackMethod:指定降级后调用方法的名称
     */
    @GetMapping("/findOne/{id}")
    //3.使用 @HystrixCommand 注解配置降级方法
    @HystrixCommand(fallbackMethod = "findOne_fallbacl",commandProperties = {
            //设置Hystrix的超时时间,默认1s
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000"),
    })
    public Goods findOne(@PathVariable("id") int id){
    
        Goods goods = goodsService.findOne(id);
        return goods;
    }

    /**
     * 2.定义降级方法:
     *  2.1 方法的返回值需要和原方法一样
     *  2.2 方法的参数需要和原方法一样
     */
    public Goods findOne_fallbacl(int id){

        Goods goods = new Goods();
        goods.setTitle("降级了:" + id);

        return goods;
    }
}

4.在启动类上开启Hystrix功能:使用注解@EnableCircuitBreaker

@EnableEurekaClient //该注解 在新版本中可以省略
@SpringBootApplication
//4.在启动类上开启Hystrix功能:@EnableCircuitBreaker
@EnableCircuitBreaker
public class ProviderApp {

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

Hystrix 降级 – 服务消费方

  1. feign 组件已经集成了 hystrix 组件,无需再导坐标。
  2. 定义feign 调用接口实现类,复写方法,即 降级方法
  3. 在Feign调用接口的 @FeignClient 注解中使用 fallback 属性设置降级处理类。
  4. 配置开启 feign.hystrix.enabled = true

2.定义feign调用接口实现类,复写方法,即降级方法

import com.itheima.consumer.domain.Goods;
import org.springframework.stereotype.Component;

/**
 * @author CZM
 * @date 2021 04 04 21:05
 */
/**
 * Feign 客户端的降级处理类
 * 1. 定义类 实现 Feign 客户端接口
 * 2. 使用@Component注解将该类的Bean加入SpringIOC容器
 */
@Component  //注册为bean 才能被发现
public class GoodsFeignClientFallback implements GoodsFeignClient {

    @Override
    public Goods findGoodsById(int id) {
        Goods goods = new Goods();
        goods.setTitle("又被降级了:" + id);
        return goods;
    }
}

3.在 Feign调用接口的@FeignClient 注解中使用 fallback 属性设置降级处理类。

import com.itheima.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

//3.在 @FeignClient 注解中使用 fallback 属性设置降级处理类。
@FeignClient(value = "HYSTRIX-PROVIDER",fallback = GoodsFeignClientFallback.class)
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);

}

4.配置开启 feign.hystrix.enabled = true(application.yml)

#4.开启feign对hystrix的支持
feign:
  hystrix:
    enabled: true

三、Hystrix熔断
Hystrix 熔断机制,用于监控微服务调用情况,当失败的情况达到预定的阈值(5秒失败20次),会打开断路器,拒绝所有请求。断路器开启时间5秒(默认)后,会进入半开状态,此时若调用服务仍然失败,断路器再次进入全开状态,拒绝所有请求。若调用成功次数达到阈值,则关闭断路器,服务恢复正常。
在这里插入图片描述
Hystrix断路器设置:在服务提供方 接口 上添加@HystrixCommand注解

@HystrixCommand(commandProperties = {
            //监控时间 默认5000 毫秒
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),
            //失败次数。默认20次
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),
            //失败率 默认50%
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")
    })

Hystrix熔断监控
Hystrix 提供了 Hystrix-dashboard 功能,用于实时监控微服务运行状态。
但是Hystrix-dashboard只能监控一个微服务。
Netflix 还提供了 Turbine ,进行聚合监控。
Turbine聚合监控模块搭建步骤

Gateway网关

网管概述
网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求。
存在的问题:
客户端多次请求不同的微服务,增加客户端的复杂性
认证复杂,每个服务都要进行认证
http请求不同服务次数增加,性能不高
网关就是系统的入口,封装了应用程序的内部结构,为客户端提
供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,
诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等
在目前的网关解决方案里,有Nginx+ Lua、Netflix Zuul 、Spring Cloud Gateway等等
在这里插入图片描述

Spring Cloud Gateway网关快速入门

  1. 搭建网关模块
  2. 引入依赖:starter-gateway
  3. 编写启动类
  4. 编写配置文件
  5. 启动测试

所需依赖

<dependencies>

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

        <!--引入gateway 网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

配置文件(application.yml):

server:
  port: 80

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # Gateway 网关路由配置---静态路由,配置服务的ip和端口号,服务更改,得跟着改,耦合度高,不推荐
        # uri: http://localhost:8001/
        # Gateway 网关路由配置---动态路由(uri: lb://服务名称),配置服务名称,实现解耦合,推荐
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**
        filters:  #配置局部过滤器的
        - AddRequestParameter=username,zhangsan

      - id: gateway-consumer
        # uri: http://localhost:9000
        uri: lb://GATEWAY-CONSUMER
        predicates:
        - Path=/order/**
        #Gateway 网关路由配置 --- 微服务名称配置
      discovery:
        locator:
          enabled: true # 设置为true 请求路径前可以添加微服务名称(也可以不添加),当服务多时可以进行区分
          lower-case-service-id: true # 请求路径上的服务名配置为小写

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

Gateway 网关过滤器
Gateway 支持过滤器功能,对请求或响应进行拦截,完成一些通用操作。
Gateway 提供两种过滤器方式:“pre”和“post”
pre 过滤器,在转发之前执行,可以做参数校验、权限校验、流量监控、日志输出、协议转换等。
post 过滤器,在响应之前执行,可以做响应内容、响应头的修改,日志的输出,流量监控等。
Gateway 还提供了两种类型过滤器
GatewayFilter:局部过滤器,针对单个路由
GlobalFilter :全局过滤器,针对所有路由
在这里插入图片描述
Gateway 过滤器 – 局部过滤器
GatewayFilter 局部过滤器,是针对单个路由的过滤器。
在Spring Cloud Gateway 组件中提供了大量内置的局部过滤器,对请求和响应做过滤操作。
遵循约定大于配置的思想,只需要在配置文件配置局部过滤器名称,并为其指定对应的值,就可以让其生效。

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:   #配置局部过滤器
        - AddRequestParameter=username,zhangsan

在Spring Cloud Gateway 组件中提供了大量内置的局部过滤器,具体请看Spring Cloud Gateway 内置的过滤器工厂(局部过滤器)

Gateway 过滤器 – 全局过滤器
GlobalFilter 全局过滤器,不需要在配置文件中配置,系统初始化时加载,并作用在每个路由上。
Spring Cloud Gateway 核心的功能也是通过内置的全局过滤器来完成。
自定义全局过滤器步骤:

  1. 定义类实现 GlobalFilter 和 Ordered接口
  2. 复写方法
  3. 完成逻辑处理
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author CZM
 * @date 2021 04 05 19:36
 */
@Component   //注册为bean
public class MyFilter implements GlobalFilter,Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //完成逻辑处理
        System.out.println("自定义全局过滤器执行了!!");

        //放行
        return chain.filter(exchange);
    }

    /**
     * 过滤器排序
     * @return 数值越小 越先执行
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenzm666666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值