SpringCloud的学习笔记(Eureka、Ribbon、Feign、Hystrix、Zuul)

在这里插入图片描述

1. 微服务

集中式架构
垂直拆分
分布式服务
SOA面向服务架构
微服务架构

微服务架构:是一套使用小服务或者单一业务来开发单个应用的方式或途径。

微服务架构特点:

  • 单一职责
  • 服务粒度小
  • 面向服务(对外暴露REST api)
  • 服务之间相互独立

与使用ESB的SOA架构的区别:微服务架构没有使用ESB,有服务治理注册中心;业务粒度小。

2. Spring Cloud概述

目标:Spring Cloud整合的组件和版本特征

小结

  • 整合的组件可以有很多组件;常见的组件有:eureka注册中心,Gateway网关,Ribbon负载均衡,Feign服务调用,Hystrix熔断器。在有需要的时候项目添加对于的启动器依赖即可。
  • 版本特征:以英文单词命名(伦敦地铁站名)

2.1 初识Spring Cloud

微服务是一种架构方式,最终肯定需要技术架构去实施。
微服务的实现方式很多,但是最火的莫过于Spring Cloud了。为什么?

  • 后台硬:作为Spring家族的一员,有整个Spring全家桶靠山,背景十分强大。
  • 技术强:Spring作为Java领域的前辈,可以说是功力深厚。有强力的技术团队支撑,一般人还真比不了
  • 群众基础好:可以说大多数程序员的成长都伴随着Spring框架,试问:现在有几家公司开发不用Spring?
  • Spring Cloud与Spring的各个框架无缝整合,对大家来说一切都是熟悉的配方,熟悉的味道。
  • 使用方便:相信大家都体会到了SpringBoot给我们开发带来的便利,而Spring Cloud完全支持Spring Boot的开发,用很少的配置就能完成微服务框架的搭建

2.2 简介

 Spring Cloud是Spring旗下的项目之一,官网地址:http://projects.spring.io/spring-cloud/ Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。
 Spring Cloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等功能;协调分布式环境中各个系统,为各类服务提供模板性配置。其主要
涉及的组件包括:

  • Eureka:注册中心
  • Zuul、Gateway:服务网关
  • Ribbon:负载均衡
  • Feign:服务调用
  • Hystrix或Resilience4j:熔断器

以上只是其中一部分,架构图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可见SpringCloud不单单只是一个框架,而是一个生态,里面包含了各种各样的技术栈。 是将目前各家公司开发比较成熟的服务框架组合起来,通过SpringBoot风格再进行封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂,易部署和易维护的分布式系统开发工具包

扫描二维码关注公众号,回复: 14227262 查看本文章

2.3 Eureka

Eureka的主要功能是进行服务管理,定期检查服务状态,返回服务地址列表。是一个服务的注册中心,用户可以按需将微服务注册到EurekaServer中。
server↓

server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false  # 不注册自己
    fetch-registry: false # false则自己是注册中心
    service-url:
      defaultZone: http://${
    
    eureka.instance.hostname}:${
    
    server.port}/eureka/

运行后,可以看到的是服务注册中心注册的一些实例
在这里插入图片描述

  • 自我保护机制:某时刻一个微服务如果不可用,eureka不会立刻清理,依旧会对该微服务的信息进行保存。

2.3.1 简单的集群搭建

在这里插入图片描述

搭建了三个EurekaServer,然后像另外两个服务结点挂载自己,由于没有多个机器,所以只能采用localhost,下方是其中一个服务结点的配置,然后client结点的话则要发布到三个服务结点(7001、7002、7003)

server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false  # 不注册自己
    fetch-registry: false # false则自己是注册中心
    service-url:
      defaultZone: http://${
    
    eureka.instance.hostname}:7002/eureka/,http://${
    
    eureka.instance.hostname}:7003/eureka/

server:
  port: 8001
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/db1?userUnicode=true&characterEncoding=utf-8
    username: root
    password: 123456
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept8001
mybatis-plus:
  type-aliases-package: pers.fjl.springcloud.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

2.3.2 Eureka与Zookeeper

CAP理论

  • C:强一致性
  • A:可用性
  • P:分区容错性(必须的)
  • Zookeeper保证的是CP,可以容忍注册中心返回的是几分钟前的注册信息,但不能接收服务直接挂掉,主节点挂了以后其余节点要重新选取主节点,此时服务就不可用。
  • Eureka保证的是AP,每个节点都是平等的,几个点挂掉不会影响正常节点的工作,剩余节点依然提供注册和查询服务,只不过查到的数据可能并不是最新的。

3.Ribbon

3.1 Ribbon简介

目标:描述负载均衡和ribbon的作用

分析

负载均衡是一个算法,可以通过该算法实现从地址列表中获取一个地址进行服务调用。

在Spring Cloud中提供了负载均衡器:Ribbon

小结

Ribbon提供了轮询、随机两种负载均衡算法(默认是轮询)可以实现从地址列表中使用负载均衡算法获取地址进行服务调用。

直白地讲就是将用户请求平摊的分配到多个服务上,从而达到系统高可用。

3.2 实战使用Ribbon轮询调度服务

在这里插入图片描述

  • 7001-7003是三个eureka的服务端结点做的集群
  • 9001是服务的消费方,只有控制层
  • 8001-8002是服务的提供方,负责提供服务,查询数据库返回数据给9001的接口

可以知道的是,8001-8002作为服务的提供方,连接着不同的数据库,当客户调度9001消费方时,此时ribbon就起了作用,因为是其决定是由端口8001的模块还是端口为8002的模块提供服务。
在这里插入图片描述

package pers.fjl.springcloud;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class TestController {
    
    	//9001消费方控制器
    @Resource
    private RestTemplate restTemplate;

    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

    @GetMapping("/consumer/test1")
    public Object test1() {
    
    
        return restTemplate.getForObject(REST_URL_PREFIX + "/test1", Object.class);
    }
}

此时因为不确定提供服务模块的端口,所以url路径也不能写死,应该写成是其在eureka中注册的实例名称
在这里插入图片描述
然后,再将注册的Bean上面加上一个@LoadBalanced注解即可

package pers.fjl.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {
    
    
    // 配置负载均衡实现RestTemplate
    //
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
    
    
        return new RestTemplate();
    }
}

在这里插入图片描述

  • 两个数据库中存着同样的表,不同的是,db_source存放着的是当前数据的名称(更直观的看Ribbon的调度方式)

此时我们向消费方的控制层发送请求,http://localhost:9001/consumer/test1,发现Ribbon默认的是轮询方式, 即轮流调度服务提供方。
在这里插入图片描述
在这里插入图片描述

3.3 重写Ribbon负载均衡算法

点进去RandomRule算法查看源码,发现也是从或者的结点列表中,通过随机数来取出list中的结点,然后再对其判断是否存活后返回结点,此时我们就可以根据这一点来配置我们自己的负载均衡算法。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.netflix.loadbalancer;

import com.netflix.client.config.IClientConfig;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class RandomRule extends AbstractLoadBalancerRule {
    
    
    public RandomRule() {
    
    
    }

    @SuppressWarnings({
    
    "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
    
    
        if (lb == null) {
    
    
            return null;
        } else {
    
    
            Server server = null;

            while(server == null) {
    
    
                if (Thread.interrupted()) {
    
    
                    return null;
                }

                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
    
    
                    return null;
                }

                int index = this.chooseRandomInt(serverCount);
                server = (Server)upList.get(index);
                if (server == null) {
    
    
                    Thread.yield();
                } else {
    
    
                    if (server.isAlive()) {
    
    
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

    protected int chooseRandomInt(int serverCount) {
    
    
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    public Server choose(Object key) {
    
    
        return this.choose(this.getLoadBalancer(), key);
    }

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    
    
    }
}

  • 首先在另外一个包的类中配置bean(不要在springboot启动类同级或者同级的包之下,否则无论自定义是否使用都会被扫描到默认为使用)
  • 其次,配置类中要进行定义。
package pers.fjl.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FRule {
    
    
    @Bean
    public IRule myRule(){
    
    
        return new MyRandomRule();
    }

}

接下来就是重写RandomRule()方法,笔者在两个等号之间重写了方法,即每个结点循环调度五次后,切换到下一个结点,其余内容不变即可。

package pers.fjl.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class MyRandomRule extends AbstractLoadBalancerRule {
    
    

    private int total = 0;  // 被调用的次数
    private int currentIndex = 0;   //当前是谁在提供服务

    @SuppressWarnings({
    
    "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
    
    
        if (lb == null) {
    
    
            return null;
        } else {
    
    
            Server server = null;

            while (server == null) {
    
    
                if (Thread.interrupted()) {
    
    
                    return null;
                }

                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
    
    
                    return null;
                }

//                int index = this.chooseRandomInt(serverCount);  // 生成区间随机数
//                server = (Server)upList.get(index);
                //========================================================
                if (total < 5) {
    
    
                    server = upList.get(currentIndex);
                    total++;
                } else {
    
    
                    total = 0;
                    currentIndex++;
                    if (currentIndex >= upList.size()) {
    
    
                        currentIndex = 0;
                    }
                    server = upList.get(currentIndex);
                }
                //========================================================

                if (server == null) {
    
    
                    Thread.yield();
                } else {
    
    
                    if (server.isAlive()) {
    
    
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

    protected int chooseRandomInt(int serverCount) {
    
    
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    public Server choose(Object key) {
    
    
        return this.choose(this.getLoadBalancer(), key);
    }

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    
    
    }
}

启动测试,发现确实是每个结点调用五次以后才会变换,自此大功告成。

4.Feign:负载均衡(基于服务端)

4.1 Feign简介

  Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端
只需要创建一个接口,然后添加注解即可~
 Feign,主要是社区版,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务访问两种方法

  • 微服务名字 【ribbon】
  • 接口和注解 【feign】

4.2 Feign能干什么?

Feign旨在使编写Java Http客户端变得更容易

  • 前面在使用Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一个客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步的封装,由他来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它 (类似以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon 时,自动封装服务调用客户端的开发量。
    Feign默认集成了Ribbon

利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

使用了Feign以后,代码更面向接口实现,直接加注解来配置对应的服务名,即不用restTemplate,但是缺点是要多写一层来实现。

package pers.fjl.springcloud.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import pers.fjl.springcloud.pojo.Dept;

import java.util.List;

@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {
    
    
	
	// 相当于调用服务提供方的controller接口
    @GetMapping("/test1")
    public List<Dept> queryAll();

}

消费方控制层如下

package pers.fjl.springcloud;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import pers.fjl.springcloud.pojo.Dept;
import pers.fjl.springcloud.service.DeptClientService;

import javax.annotation.Resource;
import java.util.List;

@RestController
public class FeignController {
    
    
//    @Resource
//    private RestTemplate restTemplate;

//    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

    // 用了feign就不用写死的
    @Resource
    public DeptClientService service = null;

    @GetMapping("/consumer/test1")
    public List<Dept> test1() {
    
    
        return this.service.queryAll();
    }
}

5. Hystrix:服务熔断

分布式系统面临的问题:
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免失败!

5.1 服务雪崩

​ 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的“扇出”,如果扇出的链路上某个微服务的调用响应时间过长,或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。
在这里插入图片描述
如果调度顺序是A、P、H、I,如果中间的服务崩了,那整个调度都是失败的。
在这里插入图片描述
 对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几十秒内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以达到单个依赖关系的失败而不影响整个应用程序或系统运行。所以​我们需要,弃车保帅!
在这里插入图片描述

5.2 什么是Hystrix?

​   Hystrix是一个应用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix 能够保证在一个依赖出问题的情况下,不会导致整个体系服务失败,避免级联故障,以提高分布式系统的弹性。

​   ​ “断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控 (类似熔断保险丝) ,向调用方返回一个服务预期的,可处理的备选响应 (FallBack) ,而不是长时间的等待或者抛出调用方法无法处理的异常,这样就可以保证了服务调用方的线程不会被长时间,不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

5.3服务熔断

  • 什么是服务熔断?
    ​ 熔断机制是赌赢雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阀值缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是:@HystrixCommand。

服务熔断解决如下问题:

  • 当所依赖的对象不稳定时,能够起到快速失败的目的;
  • 快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复。

在这里插入图片描述

在这里插入图片描述

5.4 熔断实战

在启动类加上@EnableCircuitBreaker即可启动熔断服务,加了@HystrixCommand注解后,会在服务不可用时回调到你写的备用方法。

package pers.fjl.springcloud;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import pers.fjl.springcloud.pojo.Dept;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@RestController
public class TestController {
    
    
    @Resource
    private TestDao testDao;
    private int total = 0;

    @GetMapping("/test1")
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public List<Dept> test1() {
    
    
        total++;
        if (total % 2 == 0) {
    
    
            throw new RuntimeException("服务熔断");
        } else {
    
    
            return testDao.selectList(null);
        }
    }

    //  备用方法
    public List<Dept> hystrixGet() {
    
    
        List<Dept> deptList = new ArrayList<>();
        deptList.add(new Dept().setDbSource("no this database").setDName("这是一个Hystrix演示!"));
        return deptList;
    }
}

5.5 服务降级

什么是服务降级?
​ 服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理,或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。
 资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。
 服务降级主要用于什么场景呢?当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。
 降级的方式可以根据业务来,可以延迟服务,比如延迟给用户增加积分,只是放到一个缓存中,等服务平稳之后再执行 ;或者在粒度范围内关闭服务,比如关闭相关文章的推荐。

在这里插入图片描述

由上图可得,当某一时间内服务A的访问量暴增,而B和C的访问量较少,为了缓解A服务的压力,这时候需要B和C暂时关闭一些服务功能,去承担A的部分服务,从而为A分担压力,叫做服务降级。这就是为什么双十一淘宝不能退款的缘故?

服务降级需要考虑的问题
1)哪些服务是核心服务,哪些服务是非核心服务
2)哪些服务可以支持降级,哪些服务不能支持降级,降级策略是什么
3)除服务降级之外是否存在更复杂的业务放通场景,策略是什么?
自动降级分类

  • 超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测回复情况
  • 失败次数降级:主要是一些不稳定的api,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测回复情况
  • 故障降级:比如要调用的远程服务挂掉了(网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一些静态页面)、缓存(之前暂存的一些缓存数据)
  • 限流降级:秒杀或者抢购一些限购商品时,此时可能会因为访问量太大而导致系统崩溃,此时会使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级;降级后的处理方案可以是:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)。

5.6 Dashboard监控

在需要添加监控的服务提供者的启动类配置

package pers.fjl.springcloud;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

@EnableEurekaClient
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("pers.fjl.springcloud")
@EnableCircuitBreaker   // 添加对熔断的支持
public class DeptHystrix_8001 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(DeptHystrix_8001.class, args);
    }

    // 增加servlet监控
    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet() {
    
    
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        return registrationBean;
    }
}

在这里插入图片描述

6. Zuul:路由网关

 Zull包含了对请求的路由(用来跳转的)和过滤两个最主要功能:
​  其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。

server:
  port: 9527
spring:
  application:
    name: springcloud-zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
  instance:
    instance-id: springcloud-zuul-9527
    prefer-ip-address: true
info:
  app.name: fjl-spring-cloud
  company.naeme: roses_are_rosie
zuul:
  routes:
    mydept.serviceId: springcloud-provider-dept
    mydept.path: /mydept/**
  ignored-services: springcloud-provider-dept # 不能使用该路径访问 隐藏微服务

7 Spring Cloud Config 分布式配置

 Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。很容易添加替代实现,并使用Spring配置将其插入。

分布式系统面临的–配置文件问题

 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务,由于每个服务都需要必要的配置信息才能运行,所以一套集中式的,动态的配置管理设施是必不可少的。spring cloud提供了configServer来解决这个问题,我们每一个微服务自己带着一个application.yml,那上百个的配置文件修改起来,令人头疼!

什么是SpringCloud config分布式配置中心?

在这里插入图片描述
​ spring cloud config 为微服务架构中的微服务提供集中化的外部支持,配置服务器为各个不同微服务应用的所有环节提供了一个中心化的外部配置。

spring cloud config 分为服务端和客户端两部分。

  • ​服务端也称为 分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密,解密信息等访问接口。
  • 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理。并且可用通过git客户端工具来方便的管理和访问配置内容。

spring cloud config 分布式配置中心能干嘛?

  • 集中式管理配置文件
  • 不同环境,不同配置,动态化的配置更新,分环境部署,比如 /dev /test /prod /beta /release
  • 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
  • 当配置发生变动时,服务不需要重启,即可感知到配置的变化,并应用新的配置
  • 将配置信息以REST接口的形式暴露
    spring cloud config 分布式配置中心与GitHub整合

​ 由于spring cloud config 默认使用git来存储配置文件 (也有其他方式,比如自持SVN 和本地文件),但是最推荐的还是git ,而且使用的是 http / https 访问的形式。

猜你喜欢

转载自blog.csdn.net/Dlihctcefrep/article/details/113933109