springcloud学习

1.1 简介

  SpringCloud是Spring旗下的项目之一,[官网地址:http://projects.spring.io/spring-cloud/](http://projects.spring.io/spring-cloud/)
  Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。
  SpringCloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:  
  netflix
    - Eureka:注册中心
    - Zuul:服务网关
    - Ribbon:负载均衡
    - Feign:服务调用
    - Hystix:熔断器
 1.2 简单的restTemplate远程调用
   新建maven pom父工程,再新建两个子工程
   - use-service-demo:一个提供根据id查询用户的微服务
   - consumer-demo:一个服务调用者,通过RestTemplate远程调用user-service-demo 
  存在什么问题?
    - 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护
    - consumer需要记忆user-service的地址,如果出现变更,可能得不到通知,地址将失效
    - consumer不清楚user-service的状态,服务宕机也不知道
    - user-service只有1台服务,不具备高可用性
    - 即便user-service形成集群,consumer还需自己实现负载均衡
  其实上面说的问题,概括一下就是分布式服务必然要面临的问题:
    - 服务管理
      - 如何自动注册和发现
      - 如何实现状态监管
      - 如何实现动态路由
    - 服务如何实现负载均衡
    - 服务如何解决容灾问题
    - 服务如何实现统一配置
1.3 Eureka注册中心
  实现了服务的自动注册、发现、状态监控
  
      

 

  - Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
  - 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)
  - 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
  - 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

  导入pom依赖,设置@EnableEurekaServer,调整配置文件
 其它工程 @EnableDiscoveryClient
 
1.4 负载均衡的调用
  ribbon  
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate(){
   return new RestTemplate();
  }
  feign 
  @EnableFeignClients(basePackages = "com.example.consumer")
  @FeignClient("user-service")
  public interface UserService {
   @GetMapping("/user/{id}")
   User queryById(@PathVariable("id") Long id);
  }
 1.5 hystrix保护机制
  雪崩问题:所依赖的服务挂掉导致自己也不能使用
  线程隔离,服务降级,服务熔断
  @SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker
1.5.1为单个方法降级
@GetMapping("/ribbon/{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallback")
public User queryById(@PathVariable("id") Long id){
String url = "http://user-service/user/"+id;
User user = restTemplate.getForObject(url, User.class);
return user;
}

public User queryByIdFallback(Long id){
User user = new User();
user.setName("调用超时,服务降级");
return user;
}
1.5.2为整个类中的方法降级
在类上加注解 @DefaultProperties(defaultFallback = "consumerDefault")
@GetMapping("/feign/{id}")
@HystrixCommand
public User queryById2(@PathVariable("id") Long id){
User user = userService.queryById(id);
return user;
}

public User consumerDefault(){
User user = new User();
user.setName("调用超时,类服务降级");
return user;
}
1.5.3为单个方法指定超时时间
@HystrixCommand(fallbackMethod = "queryByIdFallback",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})

1.5.4为整个工程设置超时时间
  在配置文件中设置  
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 # 设置hystrix的超时时间为6000ms

1.5.5 熔断机制
  在最近的20次请求中,超过50%失败,就会认为服务有问题,开启熔断,5秒休眠时间窗后开启部分熔断,放入少部分请求判断是否成功,若都成功则关闭熔断,否则重新进入休眠期
feign的熔断比较特别,需要为接口配置类,再配置fallback方法,需要在配置文件中开启

1.6 Zuul网关
  为了保证对外服务的安全性,我们需要实现对服务访问的权限控制,而开放服务的权限控制机制将会贯穿并污染整个开放服务的业务逻辑,这会带来的最直接问题是,破坏了服务集群中REST API无状态的特点。
  从具体开发和测试的角度来说,在工作中除了要考虑实际的业务逻辑之外,还需要额外考虑对接口访问的控制处理。
  当我们需要对一个即有的集群内访问接口,实现外部服务访问时,我们不得不通过在原有接口上增加校验逻辑,或增加一个代理调用来实现权限控制,无法直接复用原有的接口

面对类似上面的问题,我们要如何解决呢?答案是:服务网关!

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


  标准url拦截配置 url,标准服务拦截配置 serverId,
  简化服务拦截配置,默认的服务拦截
  关闭默认拦截配置
ignored-services
    单个前缀路径 strip-prefix:true默认是去除,自己改为false即可,就可以省略一次路径匹配 /user/user/1 -->/user/1(不过这样就不能用简化的服务拦截配置了)
  全局配置前缀 prefix: /api
  总之反向代理和负载均衡都已完成

  权限过滤器
  ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:
  ```java
  public abstract ZuulFilter implements IZuulFilter{
      abstract public String filterType();
      abstract public int filterOrder();
   
      boolean shouldFilter();// 来自IZuulFilter
      Object run() throws ZuulException;// IZuulFilter
  }
  ```
  - `shouldFilter`:返回一个`Boolean`值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
  - `run`:过滤器的具体业务逻辑。
  - `filterType`:返回字符串,代表过滤器的类型。包含以下4种:
    - `pre`:请求在被路由之前执行
    - `routing`:在路由请求时调用
    - `post`:在routing和errror过滤器之后调用
    - `error`:处理请求时发生错误调用
  - `filterOrder`:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高
- 正常流程:
  - 请求到达首先会经过pre类型过滤器,而后到达routing类型进行路由,请求就到达真正的服务提供者,执行请求,返回结果后会到达post过滤器而后返回响应
- 异常流程:
  - 整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户
  - 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。
  - 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了

  
  应用场景非常多:
  - 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了
  - 异常处理:一般会在error类型和post类型过滤器中结合来处理。
  - 服务调用时长统计:pre和post结合使用。
zuul高可用

 

 



posted @ 2019-10-07 02:03  helloworldmybokeyuan  阅读(511)  评论(0编辑  收藏  举报