Spring Cloud【Finchley】实战-05配置中心的搭建(配合使用Eureka)和Config Server高可用

简介: Spring Cloud【Finchley】实战-05配置中心的搭建(配合使用Eureka)和Config Server高可用

概述


入门文章请看我之前整理的博客: Spring Cloud【Finchley】-19Spring Cloud Config之Config Server和Config Client


搭建Config Server


总结下Spring Cloud的三部曲

1. 增加依赖

2. 启用注解@EnableXXX

3. 配置文件


Step1: 新建Config Server微服务,添加依赖

关键依赖如下:

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


Step2: 将Config Server 注册到Eureka Server上

2.1启动类增加 @EnableEurekaClient 注解 ,作为Eureka Client 注册到注册中心上去

20190404150510429.png


2.2application.yml 新增配置如下

spring:
  application:
    name: artisan-config
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/


Step3: 启动@EnableConfigServer,将服务变更为Config Server


2.1启动类增加 @EnableConfigServer注解


20190404150717893.png

2.2application.yml 新增配置如下


20190404151043424.png

又加了个指定端口 9898 和 force-pull 属性 。 完整配置如下


20190404170119156.png



Cannot pull from remote the working tree is not clean. 这种报错可以通过配置强制拉属性force-pull: true 。 由于Spring Cloud配置服务器会复制远程git存储库,如果本地副本变得不干净,那么Spring Cloud配置服务器就不能更新远程存储库中的本地副本。通过设置强制拉属性为true,使Spring Cloud配置服务器从远程存储库中强制pull。


官方指导: https://github.com/spring-cloud/spring-cloud-config/blob/master/docs/src/main/asciidoc/spring-cloud-config.adoc#force-pull-in-git-repositories


Step5: 新建远端Git工程,用于存放配置文件


之前创建了一个远端Git, 地址为: https://github.com/yangshangwei/spring-cloud-config-center 我们就直接拿来用吧

搭建过程: 搭建Config Server的后端存储

为了测试下,我们新建几个order的配置文件 ,放些配置进去



20190404165743708.png


Step6: 启动测试


启动Eureka Server 和 该工程

访问Eureka http://localhost:8761/


20190404151135864.png


访问: http://localhost:9898/artisan-order-dev.yml


20190404170010503.png

basedir的配置看日志

20190404170202849.png


20190404170324136.png

搭建Config Client


上面我们把Order微服务的配置文件放到了远端的Git,自然而然本地的工程直接使用远端存储的配置文件既可以了,本地的配置自然而言就应该不需要了。


Step1.添加spring-cloud-config-client依赖

在Order工程中添加 spring-cloud-config-client 依赖

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>


Step2. 新建bootstrap.yml

spring:
  application:
    name: artisan-order
  cloud:
    config:
      profile: dev
      # 可配置多个,不推荐使用,因为需要设置具体的ip.服务端修改或者新增IP后,要同步修改
      # uri: http://localhost:9898/,http://localhost:9999/
      discovery:
        # 指定Config Server在服务发现中的service Id ,默认为configserver
        service-id: ARTISAN-CONFIG
        # 表示使用服务发现组件中的Config Server,而不自己指定Config Server的uri,默认为false
        enabled: true


上述配置信息一定要写到bootstrap.yml中。 如果配到了application.yml中,spring.cloud.config.uri 就会访问默认的8888端口,而非配置的端口了。


bootstrap.yml 是被一个父级的 Spring ApplicationContext 加载的,在加载application.yml 的 ApplicationContext之前。配置在 bootstrap.yml 中的属性优先级更高,默认情况下不能被本地配置覆盖。


当启动不了的时候,比如从远端加载不到配置文件的时候,注意观察日志:

2019-04-04 16:42:41.844  INFO 27888 --- [  restartedMain] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:9898/
2019-04-04 16:42:45.426  INFO 27888 --- [  restartedMain] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=artisan-order, profiles=[dev], label=null, version=16152eaaf132cd054c2ac538a11fe4bb7fff6583, state=null
2019-04-04 16:42:45.427  INFO 27888 --- [  restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}


Step3. 启动artisan-order

启动后观察是否注册到Eureka上


20190404170606231.png

Step4. 验证

package com.artisan.order.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
    @Value("${spring.datasource.url}")
    private String url;
    @GetMapping("/value")
    public String getValueFromGit(){
        return url;
    }
}


获取 spring.datasource.url的值


20190408105447573.png

访问 http://localhost:8081/value

20190408105414397.png

配置中心的高可用

Config Server注册到注册中心上的场景

这种情况最简单,启动多个Config Server即可。 下面我们来验证下

20190408112229724.png


配置中心再启动另外一个端口


20190408110624362.png

可以看到我们启动了两个进程

20190408110725682.png

去Eureka Server上看也可以。

20190408111318881.png

然后重启下artisan-order微服务,观察日志 中的 server url

Multiple Config Server Urls found listed.
Fetching config from server at : http://localhost:9898/
Located environment: name=artisan-order, profiles=[dev], label=null, version=06a183a4820a618cc1dc53b33d77e22106a9c4e4, state=null
Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order-dev.yml'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}

再次重启下 ,或者多重启几次

Multiple Config Server Urls found listed.
Fetching config from server at : http://localhost:9999/
Located environment: name=artisan-order, profiles=[dev], label=null, version=06a183a4820a618cc1dc53b33d77e22106a9c4e4, state=null
Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order-dev.yml'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}


停掉9898节点 ,再次重启下artisan-order服务 ,观察日志

20190408111800278.png


Config Server未注册到注册中心上的场景

借助负载均衡设备即可 ,比如 Nginx , F5,A10等等


20190408112327423.png

修改Eureka Server的默认端口8761的情况


如果我们不使用Eureka Server默认的端口呢? 比如我们使用8762

先把Eureka Server的端口改为8762


20190408144551789.png


其他eureka client客户端将 defaultZone修改为 8762端口对应的url .


Step1. 将Eureka的配置下沉到客户端上

改完默认的端口,我们启动Eureka Server , artisan-config , 发现都可以起来

访问: http://localhost:8762/

20190408144906723.png

紧接着我们启动 artisan-order ,报错了。。。。

2019-04-08 14:47:29.463 ERROR 30340 --- [  restartedMain] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
  at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
  ........
Caused by: java.net.ConnectException: Connection refused: connect
  at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_191]
2019-04-08 14:47:29.466  WARN 30340 --- [  restartedMain] c.n.d.s.t.d.RetryableEurekaHttpClient    : Request execution failed with message: java.net.ConnectException: Connection refused: connect
2019-04-08 14:47:29.468 ERROR 30340 --- [  restartedMain] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_ARTISAN-ORDER/localhost:artisan-order - was unable to refresh its cache! status = Cannot execute request on any known server
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
  at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.2.jar:1.9.2]
  ....
  at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.0.3.RELEASE.jar:2.0.3.RELEASE]
2019-04-08 14:47:29.474  WARN 30340 --- [  restartedMain] com.netflix.discovery.DiscoveryClient    : Using default backup registry implementation which does not do anything.
2019-04-08 14:47:29.476  INFO 30340 --- [  restartedMain] com.netflix.discovery.DiscoveryClient    : Not registering with Eureka server per configuration
2019-04-08 14:47:29.480  INFO 30340 --- [  restartedMain] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1554706049479 with initial instances count: 0
2019-04-08 14:47:29.590  WARN 30340 --- [  restartedMain] lientConfigServiceBootstrapConfiguration : Could not locate configserver via discovery
java.lang.IllegalStateException: No instances found of configserver (ARTISAN-CONFIG)
  at org.springframework.cloud.config.client.ConfigServerInstanceProvider.getConfigServerInstances(ConfigServerInstanceProvider.java:25) ~[spring-cloud-config-client-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  ....


一看就知道是Eureka 的问题,我们想到,统一配置中心上artisan-order-dev.yml的Eureka Server的端口还没改,改下再试试吧


20190408145354225.png

访问下 http://localhost:9898/artisan-order-dev.yml 看下效果

20190408145446253.png

再次启动artisan order ,还是报错

20190408150606837.png


访问了配置中心的默认端口8888 ,

这样的话 我们把Eureka的配置

# Eureka
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka/


下沉到artisan order 中

20190408150934994.png

意思就是:启动的时候会优先加载bootstrap中的配置,从该配置文件中找到注册中心的地址,然后再注册中心上去找配置中心的service-id .

同时把配置中心artisan-order-dev.yml 中的eureka的配置注释或者删掉。

20190408150815788.png

Step2. 注释掉默认配置文件的配置

再次访问下 http://localhost:9898/artisan-order-dev.yml 看下


20190408150850908.png


怎么又是8761了。。。。

我们来观察下 artisan cofig的日志

20190408151147765.png

当我们按照这种格式访问 http://localhost:9898/artisan-order-dev.yml 配置文件时,config server同时也会把默认配置文件的artisan-order中的配置合并后返回。

那看下 artisan-order.yml的配置看下吧


20190408151346727.png


把artisan-order.yml的配置注释掉吧


20190408151522200.png

再次访问 http://localhost:9898/artisan-order-dev.yml


20190408151551824.png


可以发现已经没有eureka的相关信息了。

再次启动artisan order ,启动成功。 查看注册中心 http://localhost:8762/


20190408151839781.png


遗留问题


修改配置自动刷新,还是没有实现,仅仅实现了从远端Git读取配置的功能,下一篇我们来实战下如何通过Spring Cloud Bus自动刷新配置


代码


配置文件远端存储Git: https://github.com/yangshangwei/spring-cloud-config-center

artisan order : https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan_order

artisan config: https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan_config

eureka server : https://github.com/yangshangwei/springcloud-o2o/tree/master/eureka-server

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
5月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
6月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1061 3
|
4月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
Spring Boot 3.x 微服务架构实战指南
|
4月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
11月前
|
人工智能 搜索推荐 Java
Spring AI与DeepSeek实战三:打造企业知识库
本文基于Spring AI与RAG技术结合,通过构建实时知识库增强大语言模型能力,实现企业级智能搜索场景与个性化推荐,攻克LLM知识滞后与生成幻觉两大核心痛点。
1246 7
|
9月前
|
人工智能 Java API
Spring AI 实战|Spring AI入门之DeepSeek调用
本文介绍了Spring AI框架如何帮助Java开发者轻松集成和使用大模型API。文章从Spring AI的初探开始,探讨了其核心能力及应用场景,包括手动与自动发起请求、流式响应实现打字机效果,以及兼容不同AI服务(如DeepSeek、通义千问)的方法。同时,还详细讲解了如何在生产环境中添加监控以优化性能和成本管理。通过Spring AI,开发者可以简化大模型调用流程,降低复杂度,为企业智能应用开发提供强大支持。最后,文章展望了Spring AI在未来AI时代的重要作用,鼓励开发者积极拥抱这一技术变革。
3189 71
Spring AI 实战|Spring AI入门之DeepSeek调用
|
10月前
|
安全 Java 数据库
Spring Security 实战指南:从入门到精通
本文详细介绍了Spring Security在Java Web项目中的应用,涵盖登录、权限控制与安全防护等功能。通过Filter Chain过滤器链实现请求拦截与认证授权,核心组件包括AuthenticationProvider和UserDetailsService,负责用户信息加载与密码验证。文章还解析了项目结构,如SecurityConfig配置类、User实体类及自定义登录逻辑,并探讨了Method-Level Security、CSRF防护、Remember-Me等进阶功能。最后总结了Spring Security的核心机制与常见配置,帮助开发者构建健壮的安全系统。
1293 0
|
6月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。

热门文章

最新文章