美文网首页
springcloud

springcloud

作者: 流萤飘枫 | 来源:发表于2019-07-23 11:20 被阅读0次

    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框架处理

    相关文章

      网友评论

          本文标题:springcloud

          本文链接:https://www.haomeiwen.com/subject/dekolctx.html