spring-boot整合consul随记

1.创建父项目。

首先创建一个maven项目,使用的spring-boot版本为2.3.5.RELEASE,对应的spring cloud版本为Hoxton.RELEASE。我们如果不知道该怎么选版本怎么办呢?可以参考如下版本选取的对照参表:

Release TrainSpring Boot Generation
2023.0.x aka Leyton3.2.x
2022.0.x aka Kilburn3.0.x, 3.1.x (Starting with 2022.0.3)
2021.0.x aka Jubilee2.6.x, 2.7.x (Starting with 2021.0.3)
2020.0.x aka Ilford2.4.x, 2.5.x (Starting with 2020.0.3)
Hoxton2.2.x, 2.3.x (Starting with SR5)
Greenwich2.1.x
Finchley2.0.x
Edgware1.5.x
Dalston1.5.x

确定好自己想要的版本后,父maven配置如下依赖。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>mydubbo</groupId>
  <artifactId>dubbo-parent</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <modules>
    <module>consul-dev</module>
  </modules>

  <name>dubbo-parent</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>11</java.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
    <apache-curator.version>5.2.0</apache-curator.version>
    <junit.version>3.8.1</junit.version>
  </properties>


  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.5.RELEASE</version>
    <relativePath/>
  </parent>

  <dependencyManagement>
    <dependencies>
      <!--spring boot的bom依赖,如果使用parent 那么就不需要在这里面用import导入了-->
      <!--<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>-->

      <!--spring cloud的bom依赖,要和spring boot版本对应上才行-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

    </dependencies>

  </dependencyManagement>



  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <version>3.2.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>


</project>

2.创建子模块。

我们在这个父项目里创建一个子模块consul-dev,如果使用idea的话,就在父项目上,右键new module,完善模块信息后就创建出来了,模块会配置在上面<modules>标签中。

3.配置POM依赖。

在子模块的pom文件中引用依赖如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-parent</artifactId>
        <groupId>mydubbo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consul-dev</artifactId>


    <dependencies>
        <!--spring-boot-starter-actuator 是Spring Boot的一个Starter模块,它提供了一系列用于监控和管理Spring Boot应用的端点(endpoints),使得开发者可以方便地对运行中的应用进行健康检查、指标监控、审计跟踪、HTTP跟踪、环境信息查看、 Beans信息查看等操作。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--spring boot,parent里的版本-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--consul 的监听服务,来源于spring cloud模块-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--测试模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--web模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>


</project>

为啥上面没写版本号呢?因为我们依赖了父模块,在父模块中各组件版本已经定义好了。我们在这里引用了 spring-boot-starter-actuator健康监控模块,使用spring-boot-starter引入了spring boot(使用spring boot的starter相信你懂的,不懂的可以搜一下这个面试可能会问),引入了spring-cloud-starter-consul-discovery(这个是spring cloud的组件,用来注册consul服务注册发现),使用spring-boot-starter-web引入了web模块(为我们提供web功能)等,由此可见spring-boot还是很方便的,作为一个copy工程师,只要发现是有,想用啥拿来就用。

4.配置consul相关参数。

在子模块的resources中创建一个application.yml(或者application.properties)文件,配置如下:

spring:
  application:
    name: consul-dev #定义此服务名称
  cloud:
    consul:
      host: 124.223.114.XXX #consul注册地址
      port: 8500 #consul注册地址的端口,8500是默认端口
      discovery:
        enabled: true #启用服务发现
        instance-id: ${spring.application.name}-01 # 注册实例id(必须唯一)
        service-name: ${spring.application.name} # 引用上面的服务名称
        port: ${server.port} # 服务端口
        prefer-ip-address: true #是否使用ip地址注册
        ip-address: ${spring.cloud.client.ip-address} # 服务请求ip
        register: true #启用自动注册
        deregister: true #停服务自动取消注册
        health-check-url: http://XXXXXX.vicp.fun/actuator/health # 健康检查
        health-check-interval: 10s #健康检查时间10秒
        health-check-critical-timeout: 5s #健康超时时间5秒

server:
  port: 8080 #我们服务的端口地址

 health-check-url: http://XXXXXX.vicp.fun/actuator/health # 为健康检查地址,这个会注册给consul告诉其健康检查的地址和时间间隔。我的consul是用docker部署在远程个人服务器上的,你们可以换成你自己的地址。

5.服务启动类。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

 使用此@EnableDiscoveryClient注解允许此项目进行服务注册。

6.自定义的web服务类

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

@RestController
public class TestControler {

    @GetMapping("/")
    public String home() {
        return "Hello World!";
    }
}

7.consul相关。

我的consul是用docker部署到Linux服务器上的,你自己测试的时候可以本地下载个windows版本的。下载地址:Install | Consul | HashiCorp Developer

我自己用的是latest最新版,你可以选择你喜欢的版本。

 启动consul,然后再启动你的服务 ,就可以看到服务已经注册上了。如果你是测试环境且没用docker可以类似这样启动:consul agent -dev -client=0.0.0.0 -datacenter=mydc -node=myagent -ui -log-level=info -grpc -bind=192.168.1.100 -disable-host-node-id

  • consul agent: 启动Consul代理服务,它是Consul集群的核心组成部分,负责健康检查、KV存储、服务发现等功能。

  • -dev: 开启开发者模式(Development Mode)。在开发模式下,Consul会运行在一个单节点集群中,无需加入其他节点即可快速启动和测试Consul的功能,数据保存在内存中,不会持久化到磁盘,重启后数据会丢失。

  • -client=0.0.0.0: 设置Consul监听客户端请求的地址。这里设置为0.0.0.0表示Consul会在所有网络接口上监听客户端的HTTP和DNS请求。

  • -datacenter=mydc: 指定数据中心名称为mydc。在Consul中,数据center是用来组织节点的逻辑单元,同一数据中心内的节点之间可以直接通信。

  • -node=myagent: 指定当前Consul节点的名称为myagent。每个节点都需要一个唯一的名称以便于识别。

  • -ui: 开启内置的Web UI界面,允许用户通过浏览器访问Consul的可视化管理界面,默认监听8500端口。

  • -log-level=info: 设置日志级别为info。Consul的日志可以根据这个参数设定详细程度,info表示记录一般信息级别的日志。

  • -grpc: 启用gRPC支持。gRPC是Google开发的一种高性能、开源和通用的RPC框架,Consul使用gRPC来提供更高效的服务间通信。

  • -bind=192.168.1.100: 设置Consul代理绑定的IP地址,所有网络通信都会通过这个地址进行。在这里,Consul将通过192.168.1.100地址对外提供服务。

  • -disable-host-node-id: 禁止使用主机名作为节点ID。在默认情况下,Consul会尝试使用主机名和MAC地址生成一个唯一节点ID,这个选项禁止了这种行为,通常在需要手动指定节点ID时使用。

刚好对应上我们配置里的服务名和实例名。

 8.结合feign进行远程调用。

        我们可以再创建一个consul-test服务,通过open-feign用来调用consul-dev。那么open-feign和feign有啥区别呢?其实open-feign是feign的增强版本:

  1. Spring Cloud 集成

    • Feign:最初是由 Netflix 开发的声明式 HTTP 客户端库,其本身并不直接支持 Spring Cloud 的全部特性。
    • OpenFeign:是基于 Feign 的扩展版本,由 Spring Cloud 团队进行了专门的封装和增强,使得它可以无缝地与 Spring Cloud 生态系统集成,尤其是 Spring MVC 注解和 Spring Boot 配置。
  2. 注解支持

    • Feign:原生 Feign 支持自身的注解来描述服务调用接口,但不一定能直接识别和利用 Spring MVC 的注解,如 @RequestMapping 等。
    • OpenFeign:除了支持 Feign 自身的注解外,还支持 Spring MVC 标准注解,开发者可以直接使用这些注解来定义 RESTful API 调用,简化了开发流程。
  3. 依赖管理与启动器

    • Feign:单独使用时,需要自行管理和配置相关的依赖,如 Ribbon 进行负载均衡。
    • OpenFeign:作为 Spring Cloud 的一部分,提供了 spring-cloud-starter-openfeign 依赖启动器,方便在 Spring Boot 项目中快速引入和使用,且集成了 Ribbon 或者 Spring Cloud LoadBalancer 用于服务发现和负载均衡。
  4. 扩展性和配置

    • OpenFeign 提供了更丰富的配置选项,比如可以通过 Spring Boot 的配置文件轻松配置超时、重试等策略,并且可以更好地与 Spring Cloud 的其他组件如 Hystrix、Zuul、Eureka 等配合,实现服务熔断、路由等功能。

创建的新服务依赖如下:增加了spring-cloud-starter-openfeign(用来远程调用) 和 spring-cloud-starter-netflix-hystrix(断路器) 组件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-parent</artifactId>
        <groupId>mydubbo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consul-test</artifactId>

    <dependencies>

        <!--spring-boot-starter-actuator 是Spring Boot的一个Starter模块,它提供了一系列用于监控和管理Spring Boot应用的端点(endpoints),使得开发者可以方便地对运行中的应用进行健康检查、指标监控、审计跟踪、HTTP跟踪、环境信息查看、 Beans信息查看等操作。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--spring boot,parent里的版本-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--consul 的监听服务,来源于spring cloud模块-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--测试模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--web模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

       
    </dependencies>


</project>

添加如下yml配置,添加断路器并配置超时时间。

spring:
  application:
    name: consul-test
  #  profiles:
  #    active: dev
  cloud:
    consul:
      host: 124.223.114.XXX
      port: 8500
      discovery:
        enabled: true
        instance-id: ${spring.application.name}-01 # 注册实例id(必须唯一)
        service-name: ${spring.application.name} # 服务名称
        port: ${server.port} # 服务端口
        prefer-ip-address: true #是否使用ip地址注册
        ip-address: http://XXXXXXX1.goho.co # 服务请求ip
        register: true
        deregister: true
        health-check-url: http://XXXXXXX1.goho.co/demo/actuator/health # 健康检查
        health-check-interval: 10s
        health-check-critical-timeout: 5s

server:
  port: 8081
  servlet:
    context-path: /demo

# 熔断器
feign:
  hystrix:
    enabled: true
  httpclient:
    connection-timeout: 3000

主启动类增加两个注解@EnableCircuitBreaker (启用断路器)和@EnableFeignClients(启用feign)。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.test.api"})
public class TestConsul {
    public static void main(String[] args) {
        SpringApplication.run(TestConsul.class, args);
    }
}

定义一个接口,设置feign要访问的服务名和url(如果在你配了正确的host地址映射的情况下,url不必需),添加一个失败兜底的类TestFallbackOne。

import com.test.fallback.TestFallbackOne;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "consul-dev",
        url="http://XXXXX.vicp.fun",fallback = TestFallbackOne.class ) // 替换为在Eureka或Consul等注册中心注册的服务名
public interface DemoService {
    @GetMapping("/sayHello/{name}")
    String sayHello(@PathVariable("name") String name);

}
@Component
public class TestFallbackOne implements DemoService {
    @Override
    public String sayHello(String name) {
        return name + "熔断了";
    }

}

在consul-dev服务里增加相应的controller和DemoService接口,注意了这里的DemoService要和consul-test的DemoService要访问的方法保持一致,当然也可以把它俩的接口抽出来单独放在一个模块里维护,这样开发着更方便。

@RestController
public class TestControler {

    @Resource
    private DemoService demoService;

    @GetMapping("/sayHello/{name}")
    public String sayHello(@PathVariable("name") String name) {
        return demoService.sayHello(name);
    }

}
public interface DemoService {
    String sayHello(String name);
}

启动测试。

在服务提供方consul-dev,打个断点,模仿服务未响应。

这时请求服务消费方,发现服务熔断了。

 9.负载均衡

在 Spring Cloud 中,@FeignClient 默认使用 Ribbon 作为客户端负载均衡器,但 Ribbon 的具体负载均衡策略是通过 Ribbon 的配置来实现的,而不是直接在 @FeignClient 注解中定义。不过,可以通过全局配置或者自定义 Ribbon 客户端的方式来改变负载均衡策略。

例如,要更改 Ribbon 的负载均衡策略为轮询(默认也是轮询),可以在配置文件中定义:

ribbon:
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

 从 Spring Cloud Finchley 版本开始,还可以通过 @Configuration 类来自定义 Ribbon 客户端并设置负载均衡策略:

@Configuration
public class RibbonConfig {

    @Bean
    public IRule ribbonRule() {
        return new RandomRule(); // 使用随机策略
    }
}

不过从 Spring Cloud 2020.0.0(Ilford)版本开始,Ribbon 不再作为默认的负载均衡器,而是推荐使用 Spring Cloud LoadBalancer。在 Spring Cloud LoadBalancer 中,可以通过 LoadBalancerClientConfigurationProperties 设置负载均衡策略,或者自定义 org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancerRandomLoadBalancer 等实现类来实现不同的策略。

例如,使用 Spring Cloud LoadBalancer 时,若要全局配置为随机策略,可以在配置文件中写入:

spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: true # 启用 Ribbon 作为底层负载均衡器
      default-load-balancer:
        rule: random # 设置默认负载均衡规则为随机

最后记录一下consul配置相关:

consul下文件相关:

/etc/consul.d/consul.env: 这个文件通常用于设置 Consul 运行时的环境变量。环境变量可以影响 Consul 的行为,例如设置日志级别、数据目录路径等。在这个文件中,你可以配置一些 Consul 运行时所需的环境变量。

/etc/consul.d/consul.hcl: 这是 Consul 的主要配置文件。在这个文件中,你可以配置 Consul 的各种选项,包括集群配置、数据中心、节点名称、绑定地址、广告地址、加入集群的地址、监听端口、日志设置等。通过编辑这个文件,你可以定制 Consul 的行为和功能。

/usr/bin/consul: 这是 Consul 的可执行文件。通过执行这个文件,你可以启动 Consul Agent,并根据配置文件中的设置来运行 Consul。

/usr/lib/systemd/system/consul.service: 这是 Consul 的 Systemd 服务单元文件。它定义了 Consul 作为 Systemd 服务的配置,包括服务的启动方式、依赖关系等。通过 Systemd,你可以使用 systemctl 命令来管理 Consul 服务的启动、停止、重启等操作。

# Consul 配置文件

# 数据中心设置
datacenter = "dc1"

# 节点名称设置(注意:不可重名)
node_name = "consul-36"

# 数据目录设置
data_dir = "/opt/consul"

# 日志级别设置(可选值:TRACE, DEBUG, INFO, WARN, ERR)
log_level = "ERR"

# 绑定地址设置(监听所有 IPv6 地址和所有 IPv4 地址)
bind_addr = "[::]"
bind_addr = "0.0.0.0"

# 广播自己地址给集群访问(用于集群内部通信)
advertise_addr = "192.168.0.36"

# 加入集群的地址列表(需要提供至少一个已知的集群节点地址,:8301默认端口可省略)
retry_join = ["192.168.0.122:8301", "192.168.0.123", "192.168.0.124"]
# 用于指定 Consul Agent 在启动时尝试通过加入集群节点。
start_join = ["192.168.0.122", "192.168.0.123", "192.168.0.124"]

# 服务节点设置(是否为服务器节点)
server = true
# 这会告诉Consul在引导期间等待2个服务器节点就绪,然后再引导整个集群。
bootstrap_expect = 2

# 加密设置(consul keygen 生成的用于集群网络通信的加密)
encrypt = ""

# 客户端地址设置(用于监听客户端请求的地址)
client_addr = "0.0.0.0"

# UI 配置(用于启用内置的 Web UI)
ui_config {
  enabled = true
  content_path = "/ui/" #可自定义路径
}

# 默认端口设置
ports {
  # HTTP API 端口(默认值:8500)与 Consul 进行交互,包括服务注册、UI、健康检查等
  http = 8500
  # DNS 端口(默认值:8600)用于提供 DNS 查询服务,允许客户端通过 DNS 协议来查询服务实例的地址
  dns = 8600
  # Serf LAN 端口(默认值:8301)局域网内进行集群节点间的通信
  serf_lan = 8301
  # Serf WAN 端口(默认值:8302) 广域网(WAN)内进行集群节点间的通信,用于跨数据中心的通信
  serf_wan = 8302
  # 服务器 RPC 端口(默认值:8300)服务器节点之间进行 RPC 通信
  server = 8300
}

# 启动
consul agent -config-file=/etc/consul.d

以下是一些常用的 Consul 集群管理命令:

启动 Consul Agent:consul agent -config-file=<config_file>
这个命令用于启动 Consul Agent,并指定配置文件。

加入集群:consul join <address>
这个命令用于将当前节点加入到 Consul 集群中,<address> 是一个已存在的集群节点的地址。

离开集群:consul leave
这个命令用于将当前节点从 Consul 集群中移除。

查看集群节点:consul members
这个命令用于查看当前 Consul 集群中的成员节点列表。

查看 Leader:consul operator raft list-peers
这个命令用于列出当前的 Consul 集群中的领导者节点。

手动推选 Leader:consul operator raft promote <node_id>

这个命令用于手动推选指定节点为 Consul 集群的领导者。

重启集群节点:consul reload
这个命令用于重新加载 Consul 配置文件并重启 Consul Agent。

查看服务列表:consul catalog services
这个命令用于列出所有在 Consul 中注册的服务。

注册服务:consul services register <service.json>
这个命令用于注册一个新的服务到 Consul 中,<service.json> 是包含服务定义的 JSON 文件。

移除服务:consul services deregister <service_id>
这个命令用于从 Consul 中移除一个已注册的服务,<service_id> 是服务的唯一标识符。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值