启动
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和端口都不是映射后的。
解决方案应该很多,但我只找到了下面的方法。
修改服务配置文件
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 #自定义端口