百战商城(十六)-SpringCloud

一.Hystrix

1.Hystrix介绍
  Hystrix是一个延迟和容错库,旨在隔离远程系统、服务和第三方库的访问点,停止级联故障,并在不可避免的复杂分布式系统中启用弹性。
在这里插入图片描述
2.Hystrix解决的问题
2.1正常情况下
当一切正常时,请求流可能是这样的:
在这里插入图片描述
2.2发生故障时
当后端系统之一发生故障时,它可以阻止整个用户请求:
在这里插入图片描述
2.3Hystrix解决方案

  • 线程隔离, Hystrix给每个服务设置独立的线程池, 和主应用服务器的线程池进行隔离, 同时, 多个服务之间的线程池进行隔离;
  • 服务的降级和熔断, 服务降级是指当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个友好的结果; 熔断是服务调用失败次数达到阈值时, Hystrix会主动将服务熔断, 停止服务, 而当情况好转之后, 可以自动重连(弹性).
    在这里插入图片描述

3.服务降级
应该在服务消费者方使用(demo-consumer), 服务降级发生的情况:
 1.超时, 默认是1秒,
 2.抛出异常
3.1添加依赖

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

3.2配置启动类注解

//@SpringBootApplication
//@EnableDiscoveryClient
//@EnableCircuitBreaker

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
    }
}

3.3代码

@Service
@DefaultProperties(defaultFallback = "fallback")
public class DemoService {
    @Autowired
    private RestTemplate restTemplate; 

    @HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public ResponseEntity userList(List<Integer> ids) {
        List<User> list = new ArrayList<>();
        for (Integer id : ids) {
            // 直接将服务名写入路径, Ribbon会通过拦截器解析
            String url = "http://demo-provider/user/" + id;
            User user = restTemplate.getForObject(url, User.class);
            list.add(user);
        }
        return ResponseEntity.ok(list);
    }

    // 如果单独指定(fallbackMethod), fallback方法和目标方法的要求:
    //  返回值类型一致
    //  参数列表一致
    // 如果是默认的fallback, 要求没有参数列表
    public ResponseEntity fallback() {
        // ResponseEntity.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
        return ResponseEntity.ok("服务器繁忙, 请稍后重试...");
    }
}

3.4全局配置超时时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000 # 配置Hystrix的全局超时时间

Hystrix的超时时间应该大于重试的超时时间, 否则重试无效.
4.服务熔断
当确定服务无效时, 需要快速失败, 将服务暂时停止. 同时, 要在指定的时间后继续尝试重新访问, 如果故障解决, 服务继续生效.
4.1 熔断器的工作流程
在这里插入图片描述

4.2熔断器的状态
在这里插入图片描述
4.3Hystrix的熔断机制
Hystrix默认请求阈值为20, 如果20次请求的50%失败, 服务熔断. 服务的默认熔断休眠期为5秒, 5秒后进入半开模式, 如果请求成功, 熔断器关闭
在这里插入图片描述
可以通过如下方式进行修改:

@HystrixCommand(commandProperties = {
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),
    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
})
public ResponseEntity userList(List<Integer> ids) {
    List<User> list = new ArrayList<>();
    for (Integer id : ids) {
        // 直接将服务名写入路径, Ribbon会通过拦截器解析
        String url = "http://demo-provider/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        list.add(user);
    }
    return ResponseEntity.ok(list);
}

二.Feign
在这里插入图片描述
Feign是netflix开发的一款声明式web客户端, 可以简化基于REST的远程调用.
1.添加依赖

<!--Feign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.启动类上开启

@SpringCloudApplication
@EnableFeignClients
public class ConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class, args);
    }
}

3.提供feign客户端接口

@FeignClient("demo-provider")
public interface UserClient {

    @GetMapping("/user/{id}")
    User userInfo(@PathVariable("id") Integer id);

}

4.修改调用代码

@Service
public class DemoService {
    @Autowired
    private UserClient userClient;

    public ResponseEntity userList(List<Integer> ids) {
        List<User> list = new ArrayList<>();
        for (Integer id : ids) {
            list.add(userClient.userInfo(id));
        }
        return ResponseEntity.ok(list);
    }
}

5.Feign集成Hystrix配置

@Component
public class UserClientFallback implements UserClient {
    @Override
    public User userInfo(Integer id) {
        User user = new User();
        user.setId(id);
        user.setRealname("查无此人...");
        return user;
    }
}
feign:
  hystrix:
    enabled: true # 开启hystrix

三.Zuul

网关, 整个微服务系统的统一入口. 作用:

  • 分发请求
  • 鉴权(过滤)
    在这里插入图片描述

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

1.创建网关工程
添加zuul启动器依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
</dependencies>

2.配置路由规则

server:
  port: 10000
# 配置路由规格
zuul:
  routes:
    demo-provider: 
      path: /demo-provider/** # 映射的访问路径
      url: http://127.0.0.1:8080/  # 路由的地址

3.面向服务的配置
需要添加eureka-client的启动器, 由zuul从eureka拉取服务列表, 实现动态路由并进行负载均衡

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

修改yml配置

server:
  port: 10000
# 配置路由规格
zuul:
  routes:
    demo-provider: # /demo-provider/** # 简化配置
      path: /user/** # 映射的访问路径
      serviceId: demo-provider # 要调用的服务id, 底层使用ribbon进行负载均衡
      strip-prefix: false # 不要忽略前缀
  ignored-services:
    - demo-consumer # 忽略哪些服务
spring:
  application:
    name: demo-gateway
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka/
    registry-fetch-interval-seconds: 10
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值