学习日志day75(2021-11-18)(1、feign传递参数 2、fallback机制 3、服务隔离及断路器-hystrix 4、新一代网关-Gateway)

学习内容:学习SpringCloud(Day75)

1、feign传递参数
2、fallback机制
3、服务隔离及断路器-hystrix
4、新一代网关-Gateway


1、feign传递参数

(1)如果是复杂类型参数,默认采用post方式
传递单个参数,推荐使用@PathVariable;多个参数,可以使用@RequestParam,不省略value属性
传递对象信息,统一采用json方式,要添加@RequestBody注解
Client接口要使用@RequestMapping注解

(2)Search模块创建一个pojo

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private Integer id;
    private String name;
    private Integer age;
}

Search模块controller

@GetMapping("/search/{id}")
public Customer findById(@PathVariable Integer id){
    return new Customer(id,"张三",22);
}

@GetMapping("/getCustomer")
public Customer getCustomer(@RequestParam Integer id,@RequestParam String name){
    return new Customer(id,name,22);
}

@PostMapping("/save")        //会自动转为post请求   405
//传递对象信息,统一采用json方式,要添加@RequestBody注解
public Customer save(@RequestBody Customer customer){
    return customer;
}

Customer模块封装client,创建对应Search模块的接口

@GetMapping("/search/{id}")
Customer findById(@PathVariable Integer id);
@GetMapping("/getCustomer")
Customer getCustomer(@RequestParam Integer id, @RequestParam String name);
@RequetMapping("/save") //会自动转为post请求   405
//传递对象信息,统一采用json方式,要添加@RequestBody注解
Customer save(@RequestBody Customer customer);

Customer模块controller

@GetMapping("/search/{id}")
public Customer findById(@PathVariable Integer id){
    return searchClient.findById(id);
}

@GetMapping("/getCustomer")
public Customer getCustomer(@RequestParam Integer id, @RequestParam String name){
    return searchClient.getCustomer(id,name);
}

@RequestMapping("/save")
//传递对象信息,统一采用json方式,要添加@RequestBody注解
public Customer save(@RequestBody Customer customer){
    return searchClient.save(customer);
}

2、fallback机制

(1)Feign提供了fallback机制,也就是当对方服务存在问题,可以返回一些信息供服务进行下去,也就是服务降级。

(2)创建一个类,实现client接口,添加@Component注解成为spring组件

@Component
public class SearchClientFallBack implements SearchClient {
    @Override
    public String search() {
        return "要访问的search模块有异常";
    }
}

修改client接口注解,添加属性

@FeignClient(value = "SEARCH",fallback = SearchClientFallBack.class)

添加一个配置

feign:
  hystrix:
    enabled: true

在search模块中添加一个异常进行测试

@GetMapping("search")
public String search(){
    int i = 1/0;
    return "search" + port;
}

此时Search中有报错信息,Customer没有报错信息,使用FallbackFactory可以实现Customer也出现报错信息
创建类,实现FallbackFactory,加入spring容器管理,引入ClientFallBack对象并返回

@Component
@Slf4j
public class SearchClientFallBackFactory implements FallbackFactory<SearchClient> {
    @Autowired
    private SearchClientFallBack searchClientFallBack;

    @Override
    public SearchClient create(Throwable throwable) {
        throwable.printStackTrace();
        log.error(throwable.getMessage());
        return searchClientFallBack;
    }
}

修改client注解,添加fallbackFactory属性

@FeignClient(value = "SEARCH",fallbackFactory = SearchClientFallBackFactory.class)

测试,调用方Customer也能看到错误信息

3、服务隔离及断路器-hystrix

(1)Hystrix主要是为了解决服务雪崩问题
1.降级机制:当你的某一个服务出现的超时,资源不足,出现了异常时,可以执行一个降级方法,返回一个托底数据。
2.隔离:提供了一个Hystrix线程池,信号量,和Tomcat的线程池相互隔离。
3.熔断:当你的某-个服务的失败率达到- -定的阈值时, 自动触发降级。
4.缓存:请求缓存的功能

(2)降级机制实现
Customer模块导入hystrix依赖

<!--熔断器-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

Customer启动类添加一个注解

@EnableCircuitBreaker//启动降级

在接口上添加@HystrixCommand注解指定降级方法
针对某一个controller编写降级方法,出现异常时执行降级方法

@GetMapping("/search/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public Customer findById(@PathVariable Integer id){
    int i = 1/0;
    return searchClient.findById(id);
}
//降级的方法,方法描述要一模一样
public Customer findByIdFallback(@PathVariable Integer id){
    return new Customer(-1,"",-1);
}

(3)线程隔离
如果使用Tomcat的线程池去接收用户的请求,使用当前线程去执行其他服务的功能,如果某一个服务出现了故障,导致tomcat的线程大量的堆积, 导致Tomcat无法处理其他业务功能。
1、Hystrix的线程池 (默认),接收用户请求采用tomcat的线程池,执行业务代码,调用其他服务时,采用Hystrix的线程池。
2、信号量, 使用的还是Tomcat的线程池,帮助我们去管理Tomcat的线程池。

Hystrix的线程池的配置 (具体的配置name属性需要去查看HystrixCommandProperties类)
1.线程隔离策略: name= hystrix.command.default.execution.isolation.strateg,value= THREAD, SEMAPHORE
2.指定超时时间: name= hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds,value= 1000
3.是否开启超时时间配置: name= hystrix.command.default.execution.timeout.enabled,value= true
4. 超时之后是否中断线程:
name= hystrix.command.default.execution.isolation.thread.interruptOnTimeout,value= true
5.取消任务后是否中断线程:
name= hystrix.command.default.execution.isolation.thread.interruptOnCancel,value= false

示例

@HystrixCommand(fallbackMethod = "findByIdFallback",commandProperties = {
        @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
        @HystrixProperty(name = "execution.timeout.enabled",value = "true"),
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000"),
        @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout",value = "false")
})

(4)断路器原理
在调用指定服务时,如果失败率达到你输入的一个阈值,断路器会从closed状态转为open状态,此时指定服务是无法访问的,访问就直接走fallback方法。在一定时间内,open状态会再次转为half open状态,允许一个请求发送到指定服务,如果成功,断路器转为closed状态,如果失败,再次转为open状态,过一段时间再次转为half open,循环往复,直到最终回到closed状态。

4、新一代网关-Gateway

(1)关于zuul和Gateway:spring-cloud-Gateway是spring-cloud的一个子项目。而zuul则是netflix公司的项目,只是spring将zuul集成在spring-cloud中使用而已。

Zuul:
使用的是阻塞式的 API,不支持长连接,比如 websockets。
底层是servlet,Zuul处理的是http请求
没有提供异步支持,流控等均由hystrix支持。
依赖包spring-cloud-starter-netflix-zuul。
Gateway:
Spring Boot和Spring Webflux提供的Netty底层环境,不能和传统的Servlet容器一起使用,也不能打包成一个WAR包。
依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter

(2)Gateway基本介绍
Spring Cloud GateWay 是基于WebFlux框架 ,使用Reactor模式, 而WebFlux框架底层使用的Netty
GateWay作用:反向代理、鉴权、流量控制、熔断、日志监控

(3)Gateway配置
新建一个springboot模块:gateway-9527,添加依赖

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

配置application.yml文件
动态路由:Gateway 会根据注册中心注册的服务列表,以注册中心上的微服务名为路径创建动态路由进行转发,从而实现动态路由功能(能负载均衡)。uri的协议为lb,表示启用Gateway的负载均衡功能。discovery.locator.enabled=true表示开启从注册中心动态创建路由的功能。
断言predicates:path路径匹配进行路由、After这个时间之后才能正常访问、Before、Between、Cookie、Header、Host、Method、Query。
路由过滤器filter:路由过滤器可用于修改进入的http请求和返回的http响应,路由过滤器只能指定路由进行使用。Spring cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类产生。路由过滤器只能在业务逻辑之前,和业务逻辑之后。过滤器工厂会在匹配的请求头上加上一对值。

server:
  port: 9527

spring:
  application:
    name: GATEWAY
  cloud:
    gateway:
      routes: #路由集合
        - id: customer                #路由的ID,没有固定规则但要求唯一,建议匹配服务名
          #uri: http://localhost:8080  #匹配后提供路由的地址
          uri: lb://CUSTOMER         #启用Gateway的负载均衡功能
          predicates:
            - Path=/customer          #断言,路径匹配的进行路由
            - After=2021-11-18T11:11:11.111+08:00[Asia/Shanghai]

        - id: search                    #路由的ID,没有固定规则但要求唯一,建议匹配服务名
          #uri: http://localhost:8081  #匹配后提供路由的地址
          uri: lb://SEARCH           #启用Gateway的负载均衡功能
          predicates:
            - Path=/getCustomer          #断言,路径匹配的进行路由
          filters:
            - AddRequestHeader=X-Request-Id,1024  #过滤器工厂会在匹配的请求头上加上一对值,键是:X-Request-Id,值是:1024
      discovery:
        locator:
          enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名进行路由

eureka:
  client:
    serviceUrl:
      defaultZone: http://root:root@localhost:8761/eureka/,http://root:root@localhost:8762/eureka/
    registry-fetch-interval-seconds: 30 #每隔30秒从注册中心更新本地注册表

启动类

@SpringBootApplication
@EnableEurekaClient
public class Gateway9527Applicatiom {
    public static void main(String[] args) {
        SpringApplication.run(Gateway9527Applicatiom.class,args);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值