zoukankan      html  css  js  c++  java
  • [Java复习] Spring Cloud

    Spring Cloud Netflix常用组件

    服务注册与发现:Eureka

    服务负载均衡:Ribbon

    服务声明式客户端:Feign

    服务熔断:Hystrix

    服务网关: Zuul

    Eureka:

    Eureka分客户端client和服务端server。各微服务为client,将自己的信息注册到server。

    微服务启动后(默认每隔30秒),client做2件事:1. 拉取最新注册服务信息。2. 向server发送心跳,告诉server自己没有挂。

    如果server在一定时间(默认90秒)内没有收到某个微服务节点的心跳,server将会注销该微服务节点。

    每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册表的同步。

    server存储客户端端口号,IP地址等。

    Q:作为服务中心Eureka比ZooKeeper好在哪里?

    参考《阿里巴巴为什么不用 ZooKeeper 做服务发现?》

    在分布式的CAP理论中,ZK保证CP, Eureka保证AP。向服务中心查询服务时,可以容忍返回的时几分钟之前的注册信息,但不能接收服务挂掉不可用。

    ZK多机房会出现网络孤岛,导致本机房的服务B不能新部署,重启,扩容或缩容。本机房的服务A则不能调用服务B。破坏服务之间本身的可连通性,违反注册中心的原则!

    ZK更适用于分布式协调。

    Eureka优先保证可用性,各节点平等,某节点连接失败,自动切换其他节点,只要一台Eureka Server还在,就能保证服务可用,只不过查到的信息可能不是最新。

    Eureka源码分析:

    图中的这个名字叫做registry的CocurrentHashMap,就是注册表的核心结构。Eureka Server的注册表直接基于纯内存,即在内存里维护了一个数据结构。

    ConcurrentHashMap的key就是服务名称,比如“inventory-service”,就是一个服务名称。value则代表了一个服务的多个服务实例。

    再看作为value的Map:Map<String, Lease<InstanceInfo>>.Map的key就是服务实例的id,value是一个叫做Lease的类,它的泛型是一个叫做InstanceInfo的类。

    InstanceInfo就代表了服务实例的具体信息,比如机器的ip地址、hostname以及端口号。这个Lease,里面则会维护每个服务最近一次发送心跳的时间。

    Eureka Server为了避免同时读写内存数据结构造成的并发冲突问题,还采用了多级缓存机制来进一步提升服务请求的响应速度。

    总结:Eureka通过设置适当的请求频率(拉取注册表30秒间隔,发送心跳30秒间隔),可以保证一个大规模的系统每秒请求Eureka Server的次数在几百次。同时通过纯内存的注册表,保证了所有的请求都可以在内存处理,确保了极高的性能。另外,多级缓存机制,确保了不会针对内存数据结构发生频繁的读写并发冲突操作,进一步提升性能。

    Ribbon:

    Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

    用法:只需要在RestTemplate的Bean上加上@LoadBalanced注解即可。

    实现原理:Ribbon的负载均衡,主要通过LoadBalancerClient来实现的,而LoadBalancerClient具体交给了ILoadBalancer来处理,ILoadBalancer通过配置IRule、IPing等信息,并向EurekaClient获取注册列表的信息,并默认10秒一次向EurekaClient发送“ping”,进而检查是否更新服务列表,最后,得到注册列表后,ILoadBalancer根据IRule的策略进行负载均衡。IRule有轮询,最小请求数,随机,权重等算法。

    而RestTemplate 被@LoadBalanced注解后,能够用负载均衡,主要是维护了一个被@LoadBalanced注解的RestTemplate列表,并给列表中的RestTemplate添加拦截器,进而交给负载均衡器去处理。

    Feign:

    Feign是一个声明式的伪HttpClient。它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。

    Feign Client会在底层根据注解,和指定的服务建立连接、构造请求、发起请求、获取响应,解析响应。关键机制时使用动态代理。

    • 首先,如果你对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理
    • 接着你要是调用那个接口,本质就是会调用Feign创建的动态代理,这是核心中的核心

    Feign的动态代理会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址.

    Hystrix:

    用法:引入spring-cloud-starter-netflix-hystrix依赖。

    启动app类上加:@EnableCircuitBreaker。

    具体方法上加:@HystrixCommand(fallbackMethod = "fallbackCreateOrder")

    断路器工作原理:当Hystrix Command请求后端服务失败数量超过一定比例(默认50%),断路器切换到开路状态(OPEN),请求会直接失败。断路器保持在开路一段时间后(默认5s),自动切换到半开路状态(HALF-OPEN),会判断下一次请求的返回情况,如果成功,切回闭路(CLOSED),否则重新切换为开路(OPEN)。

     Fall back:

          降级操作。对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存。

    Zuul:

    Zuul的主要功能是路由和过滤器。

    路由功能是微服务的一部分,比如/api/a映射到a服务,/api/b映射到b服务。zuul实现了负载均衡。

    用法:

    1.dependency引入spring-cloud-starter-zuul

    2.在其入口applicaton类加上注解@EnableZuulProxy,开启zuul

    3. 加上配置文件:

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8769
    spring:
      application:
        name: service-zuul
    zuul:
      routes:
        api-a:
          path: /api-a/**
          serviceId: service-a
        api-b:
          path: /api-b/**
          serviceId: service-b

    首先向eureka注册自己,端口为8769,服务名为service-zuul;以/api-a/ 开头的请求都指向service-a;以/api-b/开头的请求都指向service-b。

    Zuul不仅可以路由,还可以做过滤器:

    @Component
    public class MyFilter extends ZuulFilter{
        @Override
        public String filterType() {
            return "pre";
        }
        @Override
        public int filterOrder() {
            return 0;
        }
        @Override
        public boolean shouldFilter() {
            return true;
        }
        @Override
        public Object run() {
         // filter logic ...
        }
    }

      filterType():返回一个字符串代表过滤器的类型

    • pre:路由之前
    • routing:路由之时
    • post: 路由之后
    • error:发送错误调用

      filterOrder():过滤的顺序

      shouldFilter():这里可以写逻辑判断,是否要过滤,true:过滤

      run():过滤器的具体逻辑

  • 相关阅读:
    hdu 4027 Can you answer these queries? 线段树
    ZOJ1610 Count the Colors 线段树
    poj 2528 Mayor's posters 离散化 线段树
    hdu 1599 find the mincost route floyd求最小环
    POJ 2686 Traveling by Stagecoach 状压DP
    POJ 1990 MooFest 树状数组
    POJ 2955 Brackets 区间DP
    lightoj 1422 Halloween Costumes 区间DP
    模板 有源汇上下界最小流 loj117
    模板 有源汇上下界最大流 loj116
  • 原文地址:https://www.cnblogs.com/fyql/p/11739147.html
Copyright © 2011-2022 走看看