consul服务注册中心使用

353 阅读2分钟

启动

consul agent -dev # 开发模式启动
consul agent -server # 非开发模式启动

启动模式

开发模式

-dev

非开发模式

-server

-clinet

只使用Consul的Server模式有以下2个问题:

  • 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题。
  • Server很少导致一个Server下会注册很多微服务,当Server挂掉,这个Server节点下注册的微服务都会视为无效。

基于上述问题我们在架构中加入Consul Client模式,Client因为加入了LAN gossip协议组成网络中(高速局域网),可以识别故障的Server节点并找到可用的Server节点继续工作,其实Server模式负责的是用WAN gossip协议组成的网络进行跨广域网的数据同步(多个数据中心),这点Client模式是做不到的,Client模式也提供服务的注册和查询,但Client模式不存储节点数据,Client将请求转发给Server进行处理,节点注册数据在Server端是持久化保存的,Client的数量可以无限多,Server的数量是受控制的。总之:Client模式+LAN gossip协议组成了一个数据中心中的各个节点,Server负责投票选出Leader进行数据中心内的数据同步,这个Leader还负责利用WAN gossip协议跨广域网的与其他数据中心进行数据同步。 PS:在Client注册的服务心跳监控检查由Client负责。

集群一般3-5个。server和clinet搭配使用,服务注册全部注册到clinet。

consul客户端开发

cloud依赖

  <!--用于服务consul发现-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <!--用于健康检查-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

配置文件

server:
  port: 8889
spring:
  application:
    name: MyconsulClient
  cloud:
    consul:
      host: ekkosblog.online #注册consul服务的主机
      port: 8500 #注册consul服务的端口号
      discovery:
#        register-health-check: false #关闭consu了服务的健康检查[不推荐]
        instance-id: ${spring.application.name}+02
        service-name: ${spring.application.name} #指定注册的服务名称 默认就是应用名
        heartbeat:
          enabled: true
spring.application.name=spring-boot-consul-config
#================== consul 服务发现与注册中心配置 =======================## 指定consul的地址
spring.cloud.consul.host = 127.0.0.1
# 指定consul的端口 == 默认8500
spring.cloud.consul.port = 8500#指定服务的实例id(唯一)
spring.cloud.consul.discovery.instance-id=${spring.application.name}-001
# 指定服务的 consul service name
spring.cloud.consul.discovery.service-name=consul-config
# 是否启用服务发现
spring.cloud.consul.discovery.enabled=true
# 是否启用服务注册
spring.cloud.consul.discovery.register=true
# 是否服务停止时s取消注册
spring.cloud.consul.discovery.deregister=true
# 在注册时使用 consul IP, 而不是 hostname
spring.cloud.consul.discovery.prefer-ip-address=true# 健康检查url
spring.cloud.consul.discovery.health-check-url=http://localhost:8081/actuator/health
# 健康检查的频率, 默认 10 秒
spring.cloud.consul.discovery.health-check-interval=10s
# 健康检查失败多长时间后,取消注册
spring.cloud.consul.discovery.health-check-critical-timeout=5s
​
# 启用配置中心
spring.cloud.consul.config.enabled=true
# 表示consul上面文件的格式 有四种 YAML PROPERTIES KEY-VALUE FILES
spring.cloud.consul.config.format=properties
#表示consul上面的KEY值(或者说文件的名字) 默认是data
spring.cloud.consul.config.data-key=data
#prefix设置配置值的基本文件夹
spring.cloud.consul.config.prefix=config
# 表示如果没有发现配置,是否抛出异常,true为是,false为否,当为false时,consul会打印warn级别的日志信息
spring.cloud.consul.config.fail-fast=false
#defaultContext设置所有应用程序使用的文件夹名称,指定consul配置的配置文件父路径
spring.cloud.consul.config.defaultContext=consul-config
#profileSeparator设置用于使用配置文件在属性源中分隔配置文件名称的分隔符的值
spring.cloud.consul.config.profileSeparator=,
​
#================== consul 服务发现与注册中心配置 =======================#

开启服务

@SpringBootApplication
@EnableDiscoveryClient //spring提供的统一开启服务注册中心
@RestController
public class ClinetApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClinetApplication.class);
    }
​
    @GetMapping("/index")
    String test(){
        return "{'msg':'hello world!'}";
    }
}
​

consul集群搭建

注册中心集群搭建

consul agent -server -bind=<your_local_ip> -data-dir=/var/lib/consul -client=<访问ip> -node=<node name> # server搭建 3台
consul agent -client -bind=<your_local_ip> -data-dir=/var/lib/consul -client=<访问ip> -node=<node name> # client搭建 多台或者1台
consul join 父节点ip
cusul menmbers # 查询集群命令

docker部署集群

docker pull consul # 拉取镜像
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [容器名称] # 查看容器ip
#启动第1个Server节点,集群要求要有3个Server,将容器8500端口映射到主机8900端口,同时开启管理界面
docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect 2 -ui -node=root -bind=0.0.0.0 -client=0.0.0.0
 
#启动第2个Server节点,并加入集群
docker run --name consul2 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
 
#启动第3个Server节点,并加入集群
docker run --name consul3 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
 
curl -i -X PUT http://127.0.0.1:8501/v1/agent/service/deregister/test-server1 # 删除服务

服务集群

设置相同服务名称,不同实例id即可

server:
  port: 8889
spring:
  application:
    name: MyconsulClient
  cloud:
    consul:
      host: ekkosblog.online #注册consul服务的主机
      port: 8500 #注册consul服务的端口号
      discovery:
#        register-health-check: false #关闭consu了服务的健康检查[不推荐]
        instance-id: ${spring.application.name}+02
        service-name: ${spring.application.name} #指定注册的服务名称 默认就是应用名
        heartbeat:
          enabled: true

docker服务集群端口问题

打算用docker在服务器搭建一个简单服务集群环境用于学习springcloud,但是通过docker部署的集群端口是docker内部的ip和默认服务的端口号。拉取到的服务列表中的服务ip和端口都不是映射到服务器主机的服务ip和端口。如下图,我搭建了简单的producer的集群,ip和端口都不是映射后的。

1683777322216.png

解决方案应该很多,但我只找到了下面的方法。

修改服务配置文件

server:
  port: 8889
spring:
  application:
    name: producerOnline
  cloud:
    consul:
      host: ekkosblog.online #注册consul服务的主机
      port: 8500 #注册consul服务的端口号
      discovery:
#        register-health-check: false #关闭consu了服务的健康检查[不推荐]
        instance-id: ${spring.application.name}+01
        service-name: ${spring.application.name} #指定注册的服务名称 默认就是应用名
        heartbeat:
          enabled: true
        
        #--自定义ip和端口
        prefer-ip-address: true
        ip-address: ekkosblog.online #自定义ip
        port: 9999 #自定义端口