前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Java学习笔记-微服务(2)-原生服务注册Consul

Java学习笔记-微服务(2)-原生服务注册Consul

原创
作者头像
咸鱼程序员
发布2025-03-03 23:44:25
发布2025-03-03 23:44:25
460
举报

Consul 服务注册与发现

为什么不用 Eureka

1.Eureka 停止更新

2.初学者学习 Eureka 有困难

3.希望注册中心独立且和微服务功能解耦

4.阿里巴巴 Nacos 的进化

Consul

Consul 是一个开源的分布式服务发现和配置管理系统,使用 Go 语言进行开发,它提供了微服务中的服务治理、配置中心、控制总线等功能,这些功能可以单独使用,也可以共同使用以构建全方位的服务网络。

关于禁用规则:由于中美关系制裁,该公司(HashiCorp)的开源产品在中国大陆内禁止使用 Vault 企业版。

下载并启动Consul

在官方网站下载Consul,下载成功后在 Consul 文件夹内启用 cmd 命令窗口,输入

代码语言:txt
复制
consul agent -dev

之后,访问 localhost:8500 即可。

如何将服务注册进 Consul

在子工程 pom 文件内添加依赖,步骤如下:

代码语言:xml
复制
        <!--Consul-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

在 application.yml 的 spring: 下添加

代码语言:yml
复制
  cloud:
    consul:
      host: localhost
      port: 8500

在启动类上新增 @EnableDiscoveryClient 注解

代码语言:java
复制
@SpringBootApplication
@EnableDiscoveryClient
public class Main8001 {
    public static void main(String[] args) {
        SpringApplication.run(Main8001.class, args);
    }
}

完成后启动服务,可以在Consul的localhost:8500下看到服务。服务可以更改名称

代码语言:yml
复制
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

处理ip硬编码

在第一节笔记中,跨服务通信组件TemplateComfig写入了一个ip硬编码,可以使用consul进行修改。

代码语言:java
复制
// 原硬编码ip 删除   
public static final String pay_url = "http://localhost:8001";
// 新名称ip 新增,此处的名字为前文演示名称,若名称不同请自行修改
public static final String pay_url = "http://cloud-payment-service";

再次访问后进行调试会报出500错误,原因是因为Consul默认支持负载均衡,需要对通信组件进行负载均衡处理。

代码语言:java
复制
@Configuration
public class RestTemplateConfig {
    @Bean
    // 添加LoadBalanced负载均衡注解
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

再次重启并发送请求,即可正常使用。

服务注册相关

CAP 原则:

  • Consistency 强一致性
  • Availability 可用性
  • Partition tolerance 分区容错性

一个分布式系统,不可能同时做到这三点,最多可以同时满足两个。

Consul 分布式配置

当我们将一个整体业务拆分为很多个子服务时,由于每个服务颗粒度很小,因此会出现大量的子服务。那么由于每个子服务都需要一些配置信息才能运行,所以我们需要一套动态的配置管理来实现对每个子服务的通用配置。我们不希望出现每一个子服务的通用配置都需要手动配置的情况。

针对这种情况,添加依赖:

代码语言:xml
复制
<!--consul config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

Consul Config 的官网中指明了要实现分布式配置,就要新增一个 BootStrap.yml 配置。

  • application.yml 是用户级的资源配置
  • bootstrap.yml 是系统级的资源配置,优先级更高一些。

Spring Cloud 会创建一个 BootStrap Context 来作为这个 Spring 应用的 Application Context 的父上下文。在初始化时,BootStrap Context 负责从外部源加载并解析配置,这两个上下文共享一个从外部获取的Environment。

BootStrap 属性具有高优先级,不会被本地配置覆盖。因为两个 Context 有不同的约定,所以需要新增 bootStrap.yml 文件来保证两个 Context 的配置分离。

提取后极简yml示例:

代码语言:yml
复制
# 8001 application.yml
server:
  port: 8001

spring:
    # 多环境配置加载内容
  profiles:
    active: dev
  datasource:
    # 自行配置
代码语言:yml
复制
# 8001 bootstrap.yml
spring:
  application:
    name: cloud-payment-service

  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        import: consul:8500
        # consul 配置是否开启
        enabled: true
        # consul 所有工程的父文件夹
        default-context: config
        # consul 的分隔符
        profile-separator: '-'
        # consul 上的文件格式
        format: YAML

yml 文件拆分完毕后,在 consul 8500 界面中,点击左侧的 KEY/VALUE 选项,新建默认文件夹 config。点击屏幕右侧的 create 按钮,在输入框中输入 config/ ,创建 config 文件夹,分别名为 cloud-payment-service、cloud-payment-service-dev。

此处我们选择使用 - 作为分隔符,是因为我们在 yml 文件中采用了 profile-separator 配置,将命名习惯改为符合大部分人逻辑的分隔方式。

之后,我们在各个 service 文件夹中新建 data 文件,文件的创建方法是命名后不加 /,创建文件过程略。注意,在文件创建时,文件的格式需要与 Spring Boot 项目中 Consul 声明的配置相同,此处文件格式选择 YAML,与项目配置文件中 format: YAML 对应。

cloud-payment-service 内容略;cloud-payment-service-dev,data文件内容示例:

代码语言:yml
复制
name:
 info: start dev!

点击保存后即可在 Spring Boot 项目中读取相应配置,我们可以通过修改 application.yml 中的 profiles-active 的内容变更访问的 data 配置,例如该演示读取的环境配置为 dev,那么我们读取的实际配置就为 cloud-payment-service-dev 中的配置。

配置的读取有很多种方式,此处我们选择对象-注解读取,其余方式可以自行探索。首先我们在 Java 项目中新建一个对象,对象内容为配置项的内容,并在对象上添加 @Component、@ConfigurationProperties 注解。注解的 prefix 属性为配置项的根键:

代码语言:java
复制
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author salt fish
 */
@Component
@ConfigurationProperties(prefix = "name")
@Data
public class ConsulProperties {
    private String info;
}

此时可以通过注入的形式验证data文件正确使用。

代码语言:java
复制
    @Value("${server.port}")
    private String port;

    @Resource
    private ConsulProperties consulProperties;

    @RequestMapping("/test")
    public String test() {
        return "info:" + consulProperties.getInfo() + ",port:" + port;
    }

若希望读取多层配置,例如

代码语言:yml
复制
name:
 info:
  info: start dev!

则将配置类做如下修改即可。

代码语言:java
复制
@Component
@ConfigurationProperties(prefix = "name")
@Data
public class ConsulProperties {
    private Info info;

    @Data
    public static class Info {
        private String info;
    }
}

在这个类中,我们将根键 name 的子键 info 定义成一个新的内部类,在这个内部类中将配置内容读取。这个过程可以无限循环,但是过多的层级会导致类维护困难,尽量使配置文件的层级可控来确保 Java 代码的正确性和可维护性。

Consul动态刷新

我们现在已经实现了一个在 Consul 上的通用配置,那么如果我们在项目不重启的情况下修改这个配置,虽然 Consul 可以成功保存,但是项目读取到的配置却不会更新,这就需要 Consul 实现动态刷新来保证项目读取到的配置是我们最新的配置。

按照官方的解释,Consul 的配置刷新为 55 秒,他会在 55 秒后自动刷新。那么我们可以通过手动修改这个时间来完成我们想要的效果。

在 Bootstrap.yml 中,我们在 Consul 的 config 配置下添加一个配置:

代码语言:yml
复制
   # consul 配置的刷新时间
        watch:
          wait-time: 55

55 就是 Consul 的默认配置,我们可以调整这个时间,来完成我们指定时间刷新 Consul 配置的目的。

第二个方法是在引用时添加 @RefreshScope 注解,有需要使用这种方法的可以自行探索如何使用。

Consul 的重启对于配置的影响

当 Consul 重启时,我们会发现我们所有的配置都已经消失,如果我们需要继续使用,那么还需要重新对 Consul 进行配置,这样对于我们的使用是非常不便的。所以,我们需要一种使配置持久化的工具或方式来保存我们的配置。

暂时使用一个简单的方式进行持久化存储,我们将 Consul 使用 windows 脚本的方式直接注册到 win 服务中并使它开机自启,脚本内容仅供参考:

代码语言:bat
复制
@echo
@echo off
@sc stop Consul
@sc delete Consul
@sc create Consul binpath= "E:\学习资料\SpringCloud\consul_1.18.0_windows_amd64\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect 1 -data-dir E:\学习资料\SpringCloud\consul_1.18.0_windows_amd64\consulData"
@net stop Consul
@net start Consul
@sc config Consul start= AUTO
@echo Consul start is OK ...... success
@pause

这段脚本里制定了数据存储的地址为 consulData 文件夹,所以并不会丢失数据。

一般在正常情况下并不使用 windows 进行服务配置,所以不再深入。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Consul 服务注册与发现
    • 为什么不用 Eureka
    • Consul
    • 下载并启动Consul
    • 如何将服务注册进 Consul
    • 处理ip硬编码
    • 服务注册相关
    • Consul 分布式配置
    • Consul动态刷新
    • Consul 的重启对于配置的影响
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档