springcloud

springCloud:

  1.bootstrap.yml(bootstrap.properties)与application.yml(application.properties)执行顺序

      ### bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等

      ### application.yml(application.properties) 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。

      ### bootstrap.yml 先于 application.yml 加载

      应用场景 :

        1.当使用 Spring Cloud Config Server的时候,你应该在 bootstrap.yml里面指定 spring.application.name和 spring.cloud.config.server.git.uri

        2.一些加密/解密的信息

  ribbon:

    调用链路选择服务器逻辑

      LoadBalancerClient(RibbonLoadBalancerClient) -> ILoadBalancer(ZoneAwareLoadBalancer) -> IRule (ZoneAvoidanceRule)

      LoadBalancerClient:

        转化URI,将含应用名称URI转化成具体主机+端口形式

        选择服务实例,通过负载算法,选择指定服务中的一台机器实例

        请求执行回调,针对选择后的服务实例,执行具体的请求回调操作

        默认实现:RibbonLoadBalancerClient

      LoadBalancerContext:

        转化URI,将含应用名称URI转化成具体主机+端口形式

        组件关联,关联RetryHandler、ILoadBalancer等

        记录服务统计信息,记录请求时间、错误数量等

        默认实现:RibbonLoadBalancerContext

      ILoadBalancer:

        增加服务器

        获取服务器:通过关联Key获取、获取所有服务列表、获取可用服务器列表

        服务器状态:标记服务器宕机

        默认实现:ZoneAwareLoadBalancer

      IRule

        选择服务器,根据负载均衡器以及关联Key获取候选的服务器

        默认实现:ZoneAvoidanceRule

      IPing:

        活动检测,根据指定的服务器,检测其是否活动

        默认实现:DummyPing

      ServerList:

        获取初始化服务器列表

        获取更新服务器列表

        默认实现:ConfigurationBasedServerList或DiscoveryEnabledNIWSServerList

    负载均衡器:

      ILoadBalancer

        BaseLoadBalancer

        DynamicServerListLoadBalancer

        ZoneAwareLoadBalancer

        NoOpLoadBalancer

    负载均衡规则接口

      IRule:

        随机规则:RandomRule

        最可用规则:BestAvailableRule

        轮训规则:RoundRobinRule

        重试实现:RetryRule

        客户端配置:ClientConfigEnabledRoundRobinRule

        可用性过滤规则:AvailabilityFilteringRule

        RT权重规则:WeightedResponseTimeRule

        规避区域规则:ZoneAvoidanceRule

    ping策略

      IPingStrategy

        NoOpPing

        DummyPing

        PingConstant

        PingUrl

        NIWSDiscoveryPing

  Hystrix:

      Hystrix能做什么

通过hystrix可以解决雪崩效应问题,它提供了资源隔离、降级机制、融断、缓存等功能。

资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。

融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。

缓存:返回结果缓存,后续请求可以直接走缓存。

请求合并:可以实现将一段时间内的请求(一般是对同一个接口的请求)合并,然后只对服务提供者发送一次请求。

    初始化顺序: @EnableCiruitBreaker -> EnableCircuitBreakerImportSelector -> HystrixCircuitBreakerConfiguration

    HystrixCircuitBreakerConfiguration

      自动装配Hystrix组件:

          Hystrix命令切面: HystrixCommandAspect

          Hystrix Endpoint: HystrixStreamEndpoint

          Hystrix指标: HystrixMetricsPollerConfiguration

    HystrixCommandAspect

      拦截标注@HystrixCommand或@HystrixCollapser的方法(@Aroud)

      生成拦截方法原信息(MetaHolderFactory)

      生成HystrixInvokable(HystrixCommandFactory)

      选择执行模式(Observable或非Observable)

    SpringFactoryImportSelector

      选择/META-INF/spring.factories中注解类型(泛型),所配置的SpringConfiguration类

        EnableCircuitBreakerImportSelector、EnableDiscoveryClientImportSelector

    1.使用@EnableHystrix 实现服务提供方短路

      @HystrixCommand(

          //Command 配置

            commandProperties = {

                    // 设置操作时间为 100 毫秒

                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")

            },fallbackMethod = "fallbackForGetUsers" //设置 fallback 方法

    )

    @GetMapping("/user/list")

    public Collection<User> getUsers() throws InterruptedException {

        long executeTime = random.nextInt(200);

        // 通过休眠来模拟执行时间

        System.out.println("Execute Time : " + executeTime + " ms");

        Thread.sleep(executeTime);

        return userService.findAll();

    }

    /**

    * {@link #getUsers()} 的 fallback 方法

    */

    public Collection<User> fallbackForGetUsers() {

        return Collections.emptyList();

    }

    2.使用@EnableCircuitBreaker 实现服务调用方短路

    /**

    * 申明 具有负载均衡能力 {@link RestTemplate}

    * @return

    */

    @Bean

    @LoadBalanced

    public RestTemplate restTemplate() {

        return new RestTemplate();

    }

  3.增加编程方式的短路实现

    public class UserRibbonClientHystrixCommand extends HystrixCommand<Collection> {

    private final String providerServiceName;

    private final RestTemplate restTemplate;

    public UserRibbonClientHystrixCommand(String providerServiceName, RestTemplate restTemplate) {

        super(HystrixCommandGroupKey.Factory.asKey(

                "User-Ribbon-Client"),

                100);

        this.providerServiceName = providerServiceName;

        this.restTemplate = restTemplate;

    }

    /**

    * 主逻辑实现

    *

    * @return

    * @throws Exception

    */

    @Override

    protected Collection run() throws Exception {

        return restTemplate.getForObject("http://" + providerServiceName + "/user/list", Collection.class);

    }

    /**

    * Fallback 实现

    *

    * @return 空集合

    */

    protected Collection getFallback() {

        return Collections.emptyList();

    }

}

  zuull:

  两种启动方式:

    @EnableZuulServer

      DispatcherServlet

        ZuulHandlerMapping

          ZuulController

            ZuulServlet

              ZuulFilter

    @EnableZuulProxy

      DispatcherServlet

        ZuulHandlerMapping

          ZuulController

            ZuulServlet

              RibbonRoutingFilter

    eureka-server:

    1. 错误:  Instances currently registered with Eureka

      解决问题:

        ## Spring Cloud Eureka 服务器作为注册中心,通常情况下,不需要再注册到其他注册中心去,同时,它也不需要获取客户端信息

        ### 取消向注册中心注册

        eureka.client.register-with-eureka = false

        ### 取消向注册中心获取注册信息(服务、实例信息)

        eureka.client.fetch-registry = false

        ## 解决 Peer / 集群 连接问题

        eureka.instance.hostname = localhost

        eureka.client.serviceUrl.defaultZone = http://${eureka.instance.hostname}:${server.port}/eureka

    1. @EnableDiscoveryClient与@EnableEurekaClient区别

      注解@EnableEurekaClient上有@EnableDiscoveryClient注解,可以说基本就是@EnableEurekaClient有@EnableDiscoveryClient的功能,其实@EnableEurekaClientz注解就是一种方便使用eureka的注解而已,可以说使用其他的注册中心后,都可以使用@EnableDiscoveryClient注解,但是使用@EnableEurekaClient的情景,就是在服务采用eureka作为注册中心的时候,使用场景较为单一。

    服务注册流程:

      Eureka Client 的注册是由 Spring Cloud 的 AutoServiceRegistration 自动注册发起, 在设置应用实例 Instance 初始状态为 UP 时, 触发了 InstanceInfoReplicator#onDemandUpdate()按需更新方法, 将实例 Instance 信息通过 DiscoveryClient 注册到 Eureka Server, 期间经过了一些 EurekaHttpClient 的装饰类, 实现了诸如定期重连, 失败重试, 注册重定向, 统计收集 Metrics 信息等功能, 最后由 JerseryClient 发送 POST 请求调用 Eureka Server 的[/eureka/apps / 应用名] 端点, 请求体携带 InstanceInfo实例信息, 完成注册。在服务注册后,Eureka Client会维护一个心跳来持续通知Eureka Server,说明服务一直处于可用状态,防止被剔除。Eureka Client在默认的情况下会每隔30秒(eureka.instance.leaseRenewallIntervalInSeconds)发送一次心跳来进行服务续约。 Eureka Server之间会互相进行注册,构建Eureka Server集群,不同Eureka Server之间会进行服务同步,用来保证服务信息的一致性。

    服务调用流程:

      Eureka Client在刚启动的时候会从Eureka Server全量获取一次注册信息,同时初始化Eureka Client本地实例信息缓存定时更新任务,默认30s一次 registryFetchIntervalSeconds = 30。同时,为了性能考虑,Eureka Server也会维护一份只读的服务清单缓存,该缓存每隔30秒更新一次。 服务消费者在获取到服务清单后,就可以根据清单中的服务列表信息,查找到其他服务的地址,从而进行远程调用。Eureka有Region和Zone的概念,一个Region可以包含多个Zone,在进行服务调用时,优先访问处于同一个Zone中的服务提供者。

    服务下线流程:

      当Eureka Client需要关闭或重启时,就不希望在这个时间段内再有请求进来,所以,就需要提前先发送REST请求给Eureka Server,告诉Eureka Server自己要下线了,Eureka Server在收到请求后,就会把该服务状态置为下线(DOWN),并把该下线事件传播出去。

    服务剔除:

      有时候,服务实例可能会因为网络故障等原因导致不能提供服务,而此时该实例也没有发送请求给Eureka Server来进行服务下线,所以,还需要有服务剔除的机制。Eureka Server在启动的时候会创建一个定时任务,每隔一段时间(默认60秒),从当前服务清单中把超时没有续约(默认90秒,eureka.instance.leaseExpirationDurationInSeconds)的服务剔除。

    自我保护:

      既然Eureka Server会定时剔除超时没有续约的服务,那就有可能出现一种场景,网络一段时间内发生了异常,所有的服务都没能够进行续约,Eureka Server就把所有的服务都剔除了,这样显然不太合理。所以,就有了自我保护机制,当短时间内,统计续约失败的比例,如果达到一定阈值,则会触发自我保护的机制,在该机制下,Eureka Server不会剔除任何的微服务,等到正常后,再退出自我保护机制。自我保护开关(eureka.server.enable-self-preservation: false)

Eureka与Consul对比:

Consul强一致性(C)带来的是:(CA)

服务注册相比Eureka会稍慢一些。因为Consul的raft协议要求必须过半数的节点都写入成功才认为注册成功

Leader挂掉时,重新选举期间整个consul不可用。保证了强一致性但牺牲了可用性。

Eureka保证高可用(A)和最终一致性:(AP)

服务注册相对要快,因为不需要等注册信息replicate到其他节点,也不保证注册信息是否replicate成功

当数据出现不一致时,虽然A, B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如此保证了可用性但牺牲了一致性。

其他方面,eureka就是个servlet程序,跑在servlet容器中; Consul则是go编写而成。

  feign(声明式HTTP客户端调用):

    Decoder/Encoder: ResponseEntityDecoder/SpringEncoder

    Logger: slf4jLogger

    Contract: SpringMvcContract

    Feign.Builder: HystrixFeign.Builder

    client: LoadBalancerFeignClient (Ribbon 激活时)

  处理流程:

    1.基于面向接口的动态代理方式生成实现类

    2.根据接口类的注解声明,解析出底层的methodhandler

    3.基于requestbean动态生成request

    4.encoder将bean包装成请求

    5.拦截器负责对请求和返回进行装饰处理

    6.日志记录

    7.基于重试器发送http请求,可基于不同的http框架处理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351