SpringCloud中部分组件的介绍与配置流程

微服务是一种架构方式,而SpringCloud与其集成的各类组件框架是实现微服务架构的一种方式,因为其基于Spring、使用便利、善于集成等优势而被广泛使用

SpringCloud主要涉及的组件包括,本文也按以下顺序来介绍:

  1. Eureka:注册中心
  2. Ribbon:负载均衡
  3. Hystix:熔断器
  4. Feign:隐藏服务的调用信息
  5. Zuul:服务网关

Eureka注册中心

  • 基于日益复杂的互联网环境,一个项目肯定会拆分出十几,甚至数十个微服务,此时如果还人为管理这些微服务的地址,不仅开发困难,将来测试、发布上线都会非常麻烦;
  • 所以我们要需要一个管理者(Eureka)来帮我们管理庞大的地址,我们一般可以把服务分为服务调用者(customer)与服务提供者(service),customer直接面对从浏览器或客户端发来的请求,之后再去调用service中的方法,那customer如何获取service的服务信息而去调用其方法呢,这就需要Eureka,service往Eureka中注册自己的信息,而customer从Eureka中获取服务提供者的信息;
  • 这就好比网约车平台中滴滴司机与乘客的区别,司机给乘客提供服务,Eureka就是平台,司机是service,乘客是customer;

在这里插入图片描述
上图为Eureka、service、customer三者的关系

  • Eureka就是管理各类微服务地址的工具,Eureka负责管理、记录service的信息,service定期向Eureka发送renew(心跳、续约),告诉Eureka我还活着,当一段时间内没有心跳了,Eureka自然会把它从服务列表中剔除;customer把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉customer;

Eureka配置流程

配置Eureka应用
在父项目中新建一个maven模块,加入依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

在启动类上加入注解@EnableEurekaServer,表明该SpringBoot是一个Eureka应用,例如:

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

在application.yml配置文件中加入配置:

server:
  port: 10086
spring:
    application:
      name: eurekaServer # 应用名称
eureka:
    client:
      service-url: # EurekaServer地址
        defaultZone: http://127.0.0.1:10086/eureka 
      register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
      fetch-registry: false # 是否拉取其它服务的信息,默认是true
    server:
      enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
      eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)

配置服务提供者service

以上EurekaServer就配置好了,接下来配置提供服务者service,创建service模块,加入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在service启动类上加入注解@EnableDiscoveryClient,表示开启Eureka客户端功能;我的service直接与数据库联通,引入了通用Mapper,例如:

@EnableEurekaClient
@SpringBootApplication
@MapperScan("cn.hp.animal.mapper")
public class ServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }
}

在其application.yml配置文件中加入配置:

server:
  port: 8080
spring:
  application:
    name: animal-service # 应用名称
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: root
mybatis:
  type-aliases-package: cn.hp.animal.beans

eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka #,http://127.0.0.1:10087/eureka
    registry-fetch-interval-seconds: 5   #5秒间隔获取服务列表
  instance:
    prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
    #lease-expiration-duration-in-seconds: 90 #服务失效时间,默认值90秒
    #lease-renewal-interval-in-seconds: 30 #服务续约(renew)的间隔,默认为30秒

要留心的配置是spring.application.name: animal-service,该属性是指定该微服务的应用名称,未来customer调用该服务的时候就要用到;

配置服务调用者customer
一样新建customer模块,加入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在启动类上加入注解@EnableDiscoveryClient,表示开启Eureka客户端,例如:

@EnableDiscoveryClient
@SpringBootApplication
public class CustomApplication {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    public static void main(String[] args) {
        SpringApplication.run(CustomApplication.class, args);
    }
}

customer多出来一个RestTemplate并将其加入到SpringIOC容器当中,RestTemplate是Spring自带的在模块中发送http请求的工具,customer借助其向service发送http请求调用方法;然后修改application.yml配置:

server:
  port: 8088
spring:
  application:
    name: consumer # 应用名称
eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka #,http://127.0.0.1:10087/eureka
    registry-fetch-interval-seconds: 5 #5秒间隔获取服务列表
  instance:
    prefer-ip-address: false # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

三者都配置好之后,就可以往Controller中写入代码了,以下依次是customer的Controller方法与service的Controller方法:

//customer
@RequestMapping("custom")
@RestController
public class CustomController {

	@Autowired
    private RestTemplate template;

    //eureka客户端,可以获取服务实例信息
    @Autowired
    private DiscoveryClient client;

    @GetMapping("get/{id}")
    public String getAnimals(@PathVariable("id") Integer id) {
        //通过service的应用名‘animal-service’从eureka获取服务实例
        ServiceInstance instance = client.getInstances("animal-service").get(0);
        //通过服务实例获取ip与端口名,并拼接对应service的方法RequestMapping
        //instance.getHost()可以获取到对应服务的ip地址
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/animal/get/" + id;
        return template.getForObject(url,String.class);
    }
//service 就是简单的Controller与请求方法
@RequestMapping("animal")
@RestController
public class AnimalController {

    @Autowired
    private AnimalMapper mapper;

    @GetMapping("get/{id}")
    public Animal getAnimals(@PathVariable("id") Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

}

直接去请求url ‘ localhost:8088/custom/get/{1} ’ 可获取结果

高可用的Eureka Server

Eureka之前我们只配置了一个,当然也可以配置多个,形成高可用的Eureka集群,多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点;所以不论客户端访问到任意一个Eureka,都可以获取到完整的服务列表信息;

如何配置?

  • 假设要搭建两条Eureka的集群,端口分别为:10086和10087
  1. 修改初始Eureka的配置,将defaultZone: http://127.0.0.1:10086/eureka改为http://127.0.0.1:10087/eureka

  2. 开启该Eureka Server

  3. 复制一个Eureka,流程:在这里插入图片描述

  4. 再修改Eureka的yml配置文件,将端口改为server.port: 10086,defaultZone改为:defaultZone: http://127.0.0.1:10086/eureka其实该配置文件被两个Eureka共同使用

  5. 再开启第二个Eureka应用

  6. customer与service的配置也需要改动Eureka的defaultZone,例如:

eureka:
  client:
    service-url: # EurekaServer地址,多个地址以','隔开
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
  • 以上高可用Eureka就配置好了,端口一个10086一个10087,defaultZone互相指向对方的ip地址

访问localhost:10086 或是 localhost:10087 可以看到开起了两个Eureka-Server

Robbin负载均衡

  • 在企业级的项目中,例如service服务提供者的模块不仅仅只有一个,service也会形成一个集群,那么customer获取的服务列表中就会有多个,到底该访问哪一个呢?而且在访问量很大的情况下如何平均这些访问
  • 这时就需要部署负载均衡工具,在多个实例列表中进行选择;Eureka中已经帮我们集成了Robbin,加入依赖与注解即可使用

负载均衡配置流程

  1. 首先准备启动两个service,像配置高可用的Eureka一样,先启动初始的service,再修改端口号,再复制一个service启动
    在这里插入图片描述
    在这里插入图片描述
    可以访问 http://localhost:10086/ ,有两个ANIMAL-SERVICE正在运行
    在这里插入图片描述

  2. 在customer的依赖中添加负载均衡依赖,因为是customer去请求service,负载均衡要帮助customer去选择访问哪一个service;加入:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
 </dependency>
  1. 在RestTemplate的配置方法上添加@LoadBalanced注解:
@EnableDiscoveryClient
@SpringBootApplication
public class CustomApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(CustomApplication.class, args);
    }
    
}
  1. 修改customer的Controller里的方法,可以看到之前用client获取ip与端口的方式被淘汰,而只需要在url中指定应用名animal-service,ribbon即可定位到相应service应用
@RequestMapping("custom")
@RestController
public class CustomController {

    @Autowired
    private RestTemplate template;

    @GetMapping("get/{id}")
    public String getAnimals(@PathVariable("id") Integer id) {
     	/*ServiceInstance instance = client.getInstances("animal-service").get(0);
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/animal/get/" + id;*/
        //负载均衡:
        String url = "http://animal-service/animal/get/" + id;
        return template.getForObject(url, String.class);
    }

ribbon在底层会通过应用名获取对应应用的ip与端口

Hystrix熔断器

当用户访问量很大时,service很可能会被堵塞,如果customer继续请求service的话,不保证service不会宕机,Hystrix可以判断某些服务反应慢或者存在大量超时的情况,能够主动熔断,防止整个系统被拖垮,可以直接拒绝后续的请求,当后续服务压力变低时,又可以实现重连,能够对后续服务灵活的调用
在这里插入图片描述
Hystrix配置流程

  1. 在customer中引入依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  1. 在customer主类中加入注解@EnableCircuitBreaker,而注解@EnableCircuitBreaker+@EnableDiscoveryClient+@SpringBootApplication 等价于 @SpringCloudApplication,所以只需要一个注解即可
//@EnableCircuitBreaker //开启熔断器功能
//@EnableDiscoveryClient
//@SpringBootApplication
@SpringCloudApplication
public class CustomApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(CustomApplication.class, args);
    }
  1. 修改customer的Controller,在方法上加入注解@HystrixCommand(fallbackMethod = "XXX")fallbackMethod设定熔断器的降级服务方法(降级服务就是不能访问后续服务时,进入另一个方法,该方法可以返回友好提示或是错误页面)
@RequestMapping("custom")
@RestController
public class CustomController {

    @Autowired
    private RestTemplate template;

    @HystrixCommand(fallbackMethod = "fallback") //声明该方法使用默认的降级方法
    @GetMapping("get/{id}")
    public String getAnimals(@PathVariable("id") Integer id) {
        String url = "http://animal-service/animal/get/" + id;
        return template.getForObject(url, String.class);
    }

    //熔断的降级逻辑方法必须跟正常逻辑方法保证:相同的参数列表和返回值声明
    public String fallback(Integer id) {
        return "服务器拥挤!请稍后访问!";
    }

}
  • 还是第三个步骤,刚才把降级服务方法定义在了业务方法上,这样比较繁琐;所以我们可以把fallbackMethod定义在类上,实现默认的fallback方法:
@DefaultProperties(defaultFallback = "fallback") //声明默认降级服务方法
@RequestMapping("custom")
@RestController
public class CustomController {

    @Autowired
    private RestTemplate template;

    @HystrixCommand //使用默认的降级方法
    @GetMapping("get/{id}")
    public String getAnimals(@PathVariable("id") Integer id) {
        String url = "http://animal-service/animal/get/" + id;
        return template.getForObject(url, String.class);
    }

    /*如在类上定义了默认降级方法,降级方法可以不用传任何参数,
    以匹配更多方法,但是返回值一定与目标方法一致*/
    public String fallback() {
        return "服务器拥挤!请稍后访问!";
    }

}
  1. 熔断器肯定有一个超时参数,一旦访问service方法超时,则熔断,接下来配置超时,在customer的yml配置文件中加入:
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 
           	# 设置hystrix的超时时间为3秒
           	# hystrix默认的超时时间为1秒

可以在service的Controller方法中让其睡上几秒,验证熔断是否起作用

Feign

Feign可以将customer发给service的请求进行隐藏;你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做;为什么这么干呢,之前使用Ribbon的负载均衡功能,大大简化了远程调用时的代码:

String url = "http://animal-service/animal/get/" + id;
return template.getForObject(url, String.class);

虽说只有两行代码,如果每一次都要自己手动写应用名称animal-service与手动拼接参数,代码还不够精简,所以需要使用到Feign,通过调用接口中方法来实现请求service

Feign的配置流程

  1. customer中导入依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 在启动类上开启Feign,Feign中已经自动集成了Ribbon负载均衡,因此不需要自己定义RestTemplate
@EnableFeignClients
@SpringCloudApplication
public class CustomApplication {
    public static void main(String[] args) {
        SpringApplication.run(CustomApplication.class, args);
    }
}
  1. customer通过调用Feign接口中的方法来请求service,先不急于修改Controller
  • 新建一个接口,Feign会通过动态代理,帮我们生成实现类
  • @FeignClient声明这是一个Feign客户端,同时通过value属性指定service应用名称
  • 接口中的定义的@GetMapping()与请求service中目标方法的映射一一对应
@FeignClient(value = "animal-service")
public interface ServiceClient {

    @GetMapping("animal/get/{id}")
    String getAnimal(@PathVariable("id") Integer id);

}
  1. 再来修改Controller,Controller只注入该接口,目标方法调用接口中方法,的确隐藏了请求service的url信息
@RequestMapping("custom")
@RestController
public class CustomController {

    @Autowired
    private ServiceClient client;

    @GetMapping("get/{id}")
    public String getAnimals(@PathVariable("id") Integer id) {
        return client.getAnimal(id);
    }

}

以上Feign配置完成

Feign对Ribbon负载均衡与Hystix熔断器的支持

  1. Feign已经封装了Ribbon,所以在customer的yml加入负载均衡配置即可:
ribbon:
  ConnectionTimeOut: 500 #建立连接时间
  ReadTimeOut: 2000 #feign中ribbon配置
  1. Feign默认也有对Hystix的集成:
  • 2.1加入配置:
feign:
  hystrix:
    enabled: true # 开启Feign的熔断功能
  • 2.2但Feign中的Fallback方法配置不像Ribbon中那样简单了;首先要定义一个类,实现刚才编写的ServiceClient ,作为fallback方法的处理类,例如:
@Component
public class ServiceClientFallBack implements ServiceClient {

    //getAnimal方法的降级方法
    @Override
    public String getAnimal(Integer id) {
        return "服务器繁忙,请稍后访问!";
    }

}
  • 2.3然后在ServiceClient的@FeignClient中,指定刚才编写的实现类即可,例如:
@FeignClient(value = "animal-service", 
			fallback = ServiceClientFallBack.class)
public interface ServiceClient {

    @GetMapping("animal/get/{id}")
    String getAnimal(@PathVariable("id") Integer id);

}

Zuul服务网关

Zuul是Netlix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用;Zuul部署在项目中后会直接面对所有从客户端发来的请求,接收到请求后通过Zuul中的过滤器判断该请求是否符合要求,符合则请求后续服务;Zuul的核心也是一系列过滤器,可以完成以下功能:

  • 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图
  • 动态路由:动态地将请求路由到不同的后端集群
  • 压力测试:逐渐增加指向集群的流量,以了解性能
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
  • 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群
  • 多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(Elastic Load Balancing)使用的多样化,以及让系统的边缘更贴近系统的使用者

Zuul加入后的项目架构:
在这里插入图片描述
Zuul的配置流程:

  1. 首先还是导入依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
  1. 在启动类中加入注解@EnableZuulProxy,表示开启zuul网关功能,同时也要开启Eureka客户端功能,例如:
@EnableDiscoveryClient
@EnableZuulProxy //开启Zuul的网关功能
@SpringBootApplication
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}
  1. 在配置文件中加入配置,zuulService该命名指路由id,path定义url访问格式,例如localhost:10010/zuulAnimal/**格式的url才可被zuul接受,而serviceId指定我要请求的后续应用名,配置如下:
server:
  port: 10010 #服务端口
spring:
  application:
    name: gateway #指定服务名

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
    registry-fetch-interval-seconds: 5 # 获取服务列表的周期:5s
  instance:
    prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

zuul:
  routes:
    zuulService: # 这里是路由id,随意写
      path: /zuulAnimal/** # 这里是映射路径
      serviceId: animal-service # 指定服务名称

以上Zuul的基本配置就已完成

当开启zuul服务后在这里插入图片描述
因为我的zuul后续直接请求service(服务提供端),所以customer没必要开了,直接访问 http://localhost:10010/zuulAnimal/animal/get/10
在这里插入图片描述
zuul底层将该url转为 localhost:8081/animal/get/10

当然之前的path参数也可以不配置,zuul有默认的路由规则

zuul的默认路由规则
默认情况下,一切去往后续服务的映射路径就是后续的服务名本身,配置例如:

#简化的路由配置,把routes下面的名字指定为应用名,zuul会通过该应用名去寻找该应用的ip
zuul:
  routes:
    #如果 animal-service: 不指定路由规则,则默认的路由规则是 /animal-service/** ,也就是以定义的应用名作为路由规则
    animal-service: 

访问结果:
在这里插入图片描述

zuul路由前缀
单纯在请求url中加入请求前缀,prefix指定了路由的前缀,这样在发起请求时,路径就要以/api开头,strip-prefix指是否在转换url时截取映射路径,配置例如:

zuul:
  prefix: /api#如果定义prefix参数,表名请求url要加上该前缀才能被zuul处理
  routes:
    service:
      path: /zuulAnimal/** #映射路径
      serviceId: animal-service #指定后续服务名称
      #strip-prefix: false #不截取path路径中的/zuulAnimal,默认为true

这里是引用
由 http://localhost:10010/api/zuulAnimal/animal/get/51 转为 http://localhost:8081/animal/get/51

zuul过滤器

  • Zuul作为网关的其中一个重要功能,就是实现请求的鉴权;而这个动作我们往往是通过Zuul提供的过滤器来实现的
  • ZuulFilter是过滤器的顶级父类,在这里看一下其中定义的4个最重要的方法:
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过滤器了

zuul自定义过滤器
写一个自定义过滤器类:

@Component
public class Filter extends ZuulFilter {
    @Override
    public String filterType() {
        return null;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
    	//判断该过滤器是否需要执行
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = ctx.getRequest();
        //获取请求参数
        String token = request.getParameter("access-token");
        //判断是否存在
        if (StringUtils.isBlank(token)) {
            //返回403
            ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
            //不存在,未登陆,则拦截
            ctx.setSendZuulResponse(false);
        }
        return null;
    }
}

访问后:这里是引用

  • Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制;但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了;因此手动进行配置:
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMillisecond: 6000 # 熔断超时时长:6000ms
            
ribbon:
  ConnectionTimeOut: 500 # 连接超时时间(ms)
  ReadTimeOut: 4000 # 通信超时时间(ms)
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  • 以上就是Zuul

Spring Cloud Config

因为在开发中存在大量的微服务,一个微服务对应一套配置信息,这些配置信息庞大又难以管理,所以出现了 Spring Cloud Config
在这里插入图片描述
以上是 Spring 官方的解释,Spring Cloud Config 可以分为服务器与客户端,服务器可以从远程仓库中获取其他微服务的配置信息(例如下图),而 client 客户端(例如服务提供者、消费者、Eureka 服务器)可以从服务器获取各自的配置信息,Spring Cloud Config 就是一个微服务配置信息管理工具
在这里插入图片描述
使用流程,首先创建一个 git 远程仓库:
使用码云创建一个仓库,将其下载到本机,加入一些 yml 配置文件,例如:
在这里插入图片描述
选择 config-client.yml 为例子:
在这里插入图片描述
在使用 git 工具将该文件夹 push 到仓库中,这样仓库就创建好了

创建 Config Server 服务器

  1. 首先导入依赖,对应的 spring boot 版本是 2.2.7 :
    maven 仓库:Spring Cloud Config Server 依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-server</artifactId>
</dependency>
  1. 在主类上加注解,开启 config server
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
  1. 在 application.yml 中配置远程仓库地址
server:
  port: 3344

spring:
  application:
    name: springcloud-config-server
    #连接远程仓库
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/ xxx /springcloud-config.git #gitee的https链接

在这里插入图片描述
以上三步服务器就配置好了

创建 Config Client 客户端

  1. 首先导入依赖:
    maven仓库:Spring Cloud Starter Config 依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
	<version>2.2.2.RELEASE</version>
</dependency>
  1. 写配置文件,在 application.yml 写微服务独有的配置信息,创建 bootstrap.yml 文件写入与服务器的连接信息:
#application.yml
#用户级别的配置
spring:
  application:
    name: config-client
#bootstrap.yml
#系统级别的配置
spring:
  cloud:
    config:
      name: config-client #需要从git上读取的资源名称,不要后缀
      profile: dev #选择配置环境
      label: master #选择git上的分支
      uri: http://localhost:3344 #config server 的IP地址与端口号

以上两步客户端就配置好了
在这里插入图片描述
接下来测试客户端,创建一个 ConfigClientController ,里面配置的三个属性值都在远程仓库中,服务器先从远程获取配置,客户端再去向服务器获取对应配置信息

@RestController
public class ConfigClientController {

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${eureka.client.service-ur1.defaultZone}")
    private String eurekaServer;

    @Value("${server.port}")
    private String port;

    @GetMapping("getProfilesInfo")
    public String getInfo() {
        return "applicationName:" + applicationName + ",eurekaServer:" + eurekaServer + ",port:" + port;
    }

}

测试结果,之前客户端选择了开发环境,端口的确为 3355,访问测试方法,拿到的结果与客户端dev配置信息一致:
在这里插入图片描述
在这里插入图片描述
开发中存在很多微服务,例如每个服务提供者都要注册 Eureka,这样相同的信息就可以通过 config server 去管理,对于每个微服务都不同的配置(例如端口),可以在 application.yml 中独立配置,Spring Cloud Config 为管理配置提供了极大的便利

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值