Spring Cloud Consul简介

Posted shigongp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Consul简介相关的知识,希望对你有一定的参考价值。

Spring Cloud Consul通过自动配置和绑定到Spring Environment和其他Spring编程模型习惯用法,为Spring Boot应用程序提供Consul集成。通过一些简单的注释,您可以快速启用和配置应用程序中的常见模式,并使用Hashicorp的Consul构建大型分布式系统。提供的模式包括服务发现、分布式配置和控制总线。服务发现是基于微服务的体系结构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能非常困难,而且可能非常脆弱。Consul通过HTTP API和DNS提供服务发现服务。Spring Cloud Consul利用HTTP API进行服务注册和发现。这并不能阻止非Spring Cloud应用程序利用DNS接口。Consul代理服务器在集群中运行,该集群通过gossip协议进行通信,并使用Raft共识协议。

特点

1、服务发现:可以向Consul代理注册实例,客户端可以使用Spring托管bean发现实例。
2、通过Spring Cloud Netflix支持Ribbon客户端负载均衡器。
3、支持Spring Cloud LoadBalancer-Spring Cloud项目提供的客户端负载平衡器
4、通过Spring Cloud Netflix支持Zuul,一个动态路由器和过滤器
5、分布式配置:使用Consul密钥/值存储
6、控制总线:使用Consul事件的分布式控制事件

使用Consul

将Consul作为服务注册和发现的服务器,微服务作为客户端。Consume(端口是8001)和Producer(两个服务,一个端口是8000,一个端口是8002)添加依赖:

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

 
并在application.properties配置:

spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

 
 

启动Consumer,Producer。访问http://127.0.0.1:8500/,结果如下:
 

看到consumer左边有个红叉,点进去看到:

HTTP GET http://192.168.31.148:8001/actuator/health: 404  Output: <html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id=\'created\'>Sat Apr 08 12:52:07 CST 2023</div><div>There was an unexpected error (type=Not Found, status=404).</div></body></html>

Consul通过spring-boot-actuator与客户端进行健康检查,只需在consumer中加入依赖:

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

并在application.properties配置:

management.endpoints.web.exposure.include=*

开启spring-boot-actuator端点重启即可。当客户端向Consul注册时,它会提供有关自身的元数据,如主机和端口、id、名称和标记。默认情况下,会创建一个HTTP检查,Consul每10秒命中一次/actuator/health端点。如果运行状况检查失败,则服务实例被标记为critical实例。
 
 

Consumer的application.properties:

server.port=8001

spring.application.name=consumer

#eureka.client.service-url.defaultZone=http://test1.com:8761/eureka/

#eureka.client.healthcheck.enabled=true

management.endpoints.web.exposure.include=*
#management.endpoint.health.show-details=always

spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

 
 

Producer的application.properties:

server.port=8002

spring.application.name=producer

#eureka.client.service-url.defaultZone=http://user:123@localhost:8761/eureka/

spring.zipkin.base-url=http://localhost:9411/
spring.zipkin.sleuth.sampler.rate=1

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
spring.boot.admin.client.url=http://localhost:7500

spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

 
 

在Consumer的controller中:

@Autowired
private DiscoveryClient discoveryClient;

@RequestMapping("/serviceList")
public List<String> serviceList() 
    return discoveryClient.getServices();

访问http://localhost:8001/serviceList,看到

["consul","consumer","producer"]

健康检查

Consul实例的运行状况检查默认为“/actuator/health”,这是Spring Boot actuator应用程序中运行状况端点的默认位置。如果您使用非默认上下文路径或servlet路径(例如server.servletPath=/foo)或管理端点路径(例如management.server.servlet.context path=/admin),即使对于Actuator应用程序,也需要更改这一点。
 
Consul用于检查健康端点的间隔也可以进行配置。“10s”和“1m”分别表示10秒和1分钟。健康检查间隔默认是10s。通过以下的配置改变健康检查端点的路径和时间间隔:

spring.cloud.consul.discovery.healthCheckPath=/actuator/health
spring.cloud.consul.discovery.healthCheckInterval=15s

可以通过设置spring.cloud.consor.discovery.register health-check=false来完全禁用HTTP健康检查。

 

还可以在健康检查时添加请求头参数,例如:

spring.cloud.consul.discovery.health-check-headers.X-Config-Token=6442e58b-d1ea-182e-cfa5-cf9cddef0722
上报健康指标

可以实现HealthIndicator,ConsulHealthIndicator,DiscoveryClientHealthIndicator来上报服务的健康指标。

 
例子

@Service
public class HealthStatusService implements HealthIndicator 

    private Boolean status = true;

    public void setStatus(Boolean status) 
        this.status = status;
    

    @Override
    public Health health() 
        if (status)
            return new Health.Builder().up().build();
        return new Health.Builder().down().build();
    

    public String getStatus() 
        return this.status.toString();
    


在Controller中:

@Autowired
private HealthStatusService healthStatusSrv;


@GetMapping("/health")
public String health(@RequestParam("status") Boolean status) 

    healthStatusSrv.setStatus(status);
    return healthStatusSrv.getStatus();

访问http://localhost:8001/health?status=false,等待10秒左右可以看到consumer的状态变为Critical,在访问http://localhost:8001/health?status=true,consumer的状态变为Passing。

将HealthStatusService改成下面可看到相同效果:

@Service
public class MyHealthStatus extends ConsulHealthIndicator 

    private Boolean status = true;

    public void setStatus(Boolean status) 
        this.status = status;
    


    @Autowired
    public MyHealthStatus(ConsulClient consul, ConsulHealthIndicatorProperties properties) 
        super(consul, properties);
    

    @Override
    public Health getHealth(boolean includeDetails) 
        if (status)
            return new Health.Builder().up().build();
        return new Health.Builder().down().build();
    

元数据

配置以下参数添加元数据:

spring.cloud.consul.discovery.metadata.myfield=myvalue
spring.cloud.consul.discovery.metadata.anotherfield=anothervalue

访问http://127.0.0.1:8500/,进入具体服务,看到元数据:

&nbsp;
 

Consul自动生成了元数据:

key value
\'group\' 属性值spring.cloud.consul.discovery.instance-group ,不为空才展示
\'secure\' 如果属性spring.cloud.consol.discovery.scheme等于“https”,则为True,否则为false。
属性spring.cloud.consol.discovery.default-zone-metadata-name,默认为“zone” 属性spring.cloud.consol.discovery.instance-zone。只有实例区域不为空时才会生成此值。

Consul Instance ID唯一

默认情况下,consur实例注册的ID等于其Spring应用程序上下文ID。默认情况下的Spring应用程序语境ID为\\({Spring.Application.name}:逗号,分隔,profiles:\\){server.port}。在大多数情况下,这将允许一个服务的多个实例在一台计算机上运行。如果需要进一步的唯一性,则使用Spring Cloud可以通过在Spring.Cloud.consol.discovery.instanceId中提供唯一标识符来覆盖这一点。

 

访问http://127.0.0.1:8500/,看到服务的默认Instance id:

 

在Consumer的application.properties中加入配置:

spring.cloud.consul.discovery.instance-id=$spring.application.name-$server.port-$random.value

访问http://127.0.0.1:8500/,看到consumer的Instance id:

运行测试时禁用 Spring cloud consul

【中文标题】运行测试时禁用 Spring cloud consul【英文标题】:Disabling Spring cloud consul when running Test 【发布时间】:2016-06-12 09:56:41 【问题描述】:

我喜欢在没有 consul 的情况下使用测试弹簧配置文件运行我的单元测试。我正在尝试对测试配置文件使用spring.cloud.config.enabled:false 并禁用EnableDiscoveryClient 注释,但它不起作用。

我正在使用spring.cloud.consul 1.0.0.BUILD-SNAPSHOT。 这是一个例外:

com.ecwid.consul.transport.TransportException: java.net.ConnectException:连接被拒绝:连接在 com.ecwid.consul.transport.DefaultHttpTransport.executeRequest(DefaultHttpTransport.java:87) 在 com.ecwid.consul.transport.DefaultHttpTransport.makeGetRequest(DefaultHttpTransport.java:46) 在 com.ecwid.consul.v1.ConsulRawClient.makeGetRequest(ConsulRawClient.java:66)

【问题讨论】:

“不起作用”并没有真正的帮助。你得到什么错误?你用的是什么版本? 你在哪里设置了spring.cloud.config.enabled:false,你是如何禁用EnableDiscoveryClient的?完整的异常有助于查看它是来自发现还是配置。 【参考方案1】:

尝试在您的个人资料中使用 spring.cloud.consul.enabled:false 禁用 Consul。

我使用@IntegrationTest("spring.cloud.consul.enabled=false") 标签来禁用我的测试的领事,作为一个类标签。我在 Spring Cloud Consul GitHub 问题跟踪器上发现了这一点,here。

该帖子的另一个建议是使用类似以下内容作为您的bootstrap.yml

spring:
  application:
    name: <myServiceName>
  cloud:
    bus:
      enabled: false
    discovery:
      enabled: false
    consul:
      enabled: false
      config:
        enabled: false

【讨论】:

【参考方案2】:

试试@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)

【讨论】:

【参考方案3】:

添加到

@SpringBootTest(properties = "spring.cloud.consul.enabled=false", "spring.cloud.consul.discovery.enabled=false")

或 测试/资源/bootstrap.yml as

spring.cloud.consul.enabled: 假 spring.cloud.consul.discovery.enabled: 假

【讨论】:

以上是关于Spring Cloud Consul简介的主要内容,如果未能解决你的问题,请参考以下文章

spring-cloud-starter-consul-config 和 spring-cloud-consul-config 区别是什么?从网上没有搜到答案,待跟进。

Spring Cloud Consul—git2consul与配置

Spring Cloud Consul

“spring.cloud.consul.host”配置值可以有多个领事代理吗?

运行测试时禁用 Spring cloud consul

Spring Boot + Spring Cloud 集成 Consul 服务注册发现