目录
1、在http://start.spring.io中添加Web、Actuator、Consul Discovery、Consul Configuration模块
1)、在启动类中添加@EnableAutoConfiguration和@EnableDiscoveryClient注解
2)、使用Spring profiles将consul-provider三个节点注册到注册中心
2)、在启动类中添加@EnableFeignClients和@EnableDiscoveryClient注解
3)、在根目录下添加Controller、Service和FallBack类
一、Spring Cloud Consul集群搭建
服务器ip | consul类型 | Node(节点名称) |
192.168.0.103 | server | server-1 |
192.168.0.104 | server | server-2 |
192.168.0.105 | server | server-3 |
192.168.0.106 | client | client-1 |
1、在每台服务器上安装consul(每台服务操作一致)
1)、下载解压安装包
可以在百度云下载consul_1.5.1_linux_amd64安装包:https://pan.baidu.com/s/1hNOD3dwQjnVeT6wMUC4NWw 密码:tsdr , 也可以直接用yum进行安装:
wget https://releases.hashicorp.com/consul/1.5.1/consul_1.5.1_linux_arm64.zip
解压
使用root用户或权限,将加压后的二进制包 copy到目录/usr/local/bin
cp ./consul /usr/local/bin
在每个节点上使用 consul version命令查询是否安装成功:
[root@localhost ~]# consul version
Consul v1.5.1
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
2)、配置启动脚本
consul启动参数说明:
agent 通过consul agent client 来收集服务本身的信息
-server 表示以服务端的身份进行启动
-bind 绑定的ip(有的服务器可能绑定多个网卡,一般绑定自己的ip即可192.168.0.103等)
-client 指定客户端能访问的ip,类似于ip白名单。0.0.0.0表示不限制
-bootstrap-expect=3 表示组成集群最少节点数,类似zookeeper的配置一样,为了防止脑裂,一般为奇数
-data-dir 数据存放目录,这个最后自己先进行创建,比如我的为-data-dir=/data/consulData/
-node 集群的节点名称,也是Consul提供的web ui的显示名称
-ui 启动内置的Web UI,访问地址为 http://ip:port/ui, 如下面的http://192.168.0.106:8500/ui
为了启动方便也是个人习惯,可以编写一个启动脚本(在每个节点上使用touch 或者vim命令):
vim startConsul.sh
服务端192.168.0.103的启动脚本如下:
nohup consul agent -server -bind=192.168.0.103 -client=0.0.0.0
-bootstrap-expect=3 -data-dir=/data/consulData/ -node=server-1 > /dev/null 2>&1 &
服务端192.168.0.104的启动脚本如下:
nohup consul agent -server -bind=192.168.0.104 -client=0.0.0.0
-bootstrap-expect=3 -data-dir=/data/consulData/ -node=server-2 > /dev/null 2>&1 &
服务端192.168.0.105的启动脚本如下:
nohup consul agent -server -bind=192.168.0.105 -client=0.0.0.0
-bootstrap-expect=3 -data-dir=/data/consulData/ -node=server-3 > /dev/null 2>&1 &
客户端192.168.0.106的启动脚本如下:
nohup consul agent -client=0.0.0.0 -data-dir=/data/consulData/ -node=client-1 -ui > /dev/null 2>&1 &
3)、启动每一个节点的脚本
./startConsul.sh
启动后查看节点的启动状态,可以使用下面的命令:
[root@localhost data]# consul members
Node Address Status Type Build Protocol DC Segment
client-1 192.168.0.106:8301 alive client 1.5.1 2 dc1 <default>
启动的时候一直报错Error retrieving members: Get http://127.0.0.1:8500/v1/agent/members?segment=_all: dial tcp 127.0.0.1:8500: connect: connection refused
刚开始以为是哪里没有环境什么的有问题,后面发现服务根本没有起来,可以使用 netstat -ann|grep 8500查看是否启动:
[root@localhost data]# netstat -ano|grep 8500
tcp6 0 0 :::8500 :::* LISTEN off (0.00/0/0)
后面改了几次都是这个问题,愿意就是启动脚本启动的非常有问题
4)、Consul UI页面
刚才我们的client-1节点添加-ui参数启动内置的Web UI,可以使用http://192.168.0.106:8500/ui查看页面如下:
2、将每个节点组成集群
consul的命令列表如下:
[root@localhost data]# consul
Usage: consul [--version] [--help] <command> [<args>]Available commands are:
acl Interact with Consul's ACLs
agent Runs a Consul agent
catalog Interact with the catalog
config Interact with Consul's Centralized Configurations
connect Interact with Consul Connect
debug Records a debugging archive for operators
event Fire a new event
exec Executes a command on Consul nodes
force-leave Forces a member of the cluster to enter the "left" state
info Provides debugging information for operators.
intention Interact with Connect service intentions
join Tell Consul agent to join cluster
keygen Generates a new encryption key
keyring Manages gossip layer encryption keys
kv Interact with the key-value store
leave Gracefully leaves the Consul cluster and shuts down
lock Execute a command holding a lock
login Login to Consul using an auth method
logout Destroy a Consul token created with login
maint Controls node or service maintenance mode
members Lists the members of a Consul cluster
monitor Stream logs from a Consul agent
operator Provides cluster-level tools for Consul operators
reload Triggers the agent to reload configuration files
rtt Estimates network round trip time between nodes
services Interact with services
snapshot Saves, restores and inspects snapshots of Consul server state
tls Builtin helpers for creating CAs and certificates
validate Validate config files/directories
version Prints the Consul version
watch Watch for changes in Consul
现在每个节点使用 consul members命令,查看到的都只有自己节点的信息,那么需要使用consul join命令把自己加到集群中,如下在后面三个节点添加到第一个节点上即可(即在后面三个节点允许命令):
[root@localhost data]# consul join 192.168.0.103
Successfully joined cluster by contacting 1 nodes.
[root@localhost data]# consul members
Node Address Status Type Build Protocol DC Segment
server-1 192.168.0.103:8301 alive server 1.5.1 2 dc1 <all>
server-2 192.168.0.104:8301 alive server 1.5.1 2 dc1 <all>
server-3 192.168.0.105:8301 alive server 1.5.1 2 dc1 <all>
client-1 192.168.0.106:8301 alive client 1.5.1 2 dc1 <default>
当然也可以使用consul leave让节点从集群中剥离并且进行关闭(Gracefully leaves the Consul cluster and shuts down),如下:
[root@localhost data]# consul leave
Graceful leave complete
[root@localhost data]# consul members
Error retrieving members: Get http://127.0.0.1:8500/v1/agent/members?segment=_all: dial tcp 127.0.0.1:8500: connect: connection refused
从其他节点看到的数据是:
[root@localhost data]# consul members
Node Address Status Type Build Protocol DC Segment
server-1 192.168.0.103:8301 alive server 1.5.1 2 dc1 <all>
server-2 192.168.0.104:8301 left server 1.5.1 2 dc1 <all>
server-3 192.168.0.105:8301 alive server 1.5.1 2 dc1 <all>
client-1 192.168.0.106:8301 alive client 1.5.1 2 dc1 <default>
二、Consul注册中心的服务调用
maven项目结构:
consul-demo :项目根目录
consul-config :consul的K/V 分布式配置服务器
consul-provider :consul服务端
consul-consumer :consul客户端
1、在http://start.spring.io中添加Web、Actuator、Consul Discovery、Consul Configuration模块
2、在项目创建consul-provider子项目
1)、在启动类中添加@EnableAutoConfiguration和@EnableDiscoveryClient注解
为了方便直接在类是添加@RestController提供一个hello服务,启动类如下:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@EnableAutoConfiguration
@EnableDiscoveryClient
@SpringBootApplication
public class ConsulProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProviderApplication.class, args);
}
/**
* 获取启动节点的端口
*/
@Value("${server.port}")
private int port;
@RequestMapping("/hello")
public String hello() {
return "hello : " + port;
}
}
2)、使用Spring profiles将consul-provider三个节点注册到注册中心
consul-1:
application-consul-1.properties
# 服务端口 server.port=8501 # 服务名称 spring.application.name=consul-provider
bootstrap-consul-1.properties
# 注册集群的节点地址(ip和端口) spring.cloud.consul.host=192.168.0.103 spring.cloud.consul.port=8500 # 是否开启注册发现服务 spring.cloud.consul.enabled=true # 是否将服务注册到Consul集群中心 spring.cloud.consul.discovery.register=true # consul注册名称,使用 spring.cloud.consul.discovery.serviceName = kevin-${spring.application.name} # 健康检查地址 spring.cloud.consul.discovery.healthCheckPath = /actuator/health # 健康检查间隔 spring.cloud.consul.discovery.healthCheckInterval = 15s spring.cloud.consul.discovery.tags = url-prefix-/${spring.application.name} # Consul注册服务的ID,可以与 eureka.instance.instance-id 进行对比 spring.cloud.consul.discovery.instanceId = ${spring.application.name}:${spring.cloud.consul.port}
consul-2:
application-consul-2.properties
# 服务端口 server.port = 8502 # 服务名称 spring.application.name = consul-provider
bootstrap-consul-2.properties
# 注册集群的节点地址(ip和端口) spring.cloud.consul.host=192.168.0.103 spring.cloud.consul.port=8500 # 是否开启注册发现服务 spring.cloud.consul.enabled=true # 是否将服务注册到Consul集群中心 spring.cloud.consul.discovery.register=true # consul注册名称,使用 spring.cloud.consul.discovery.serviceName = kevin-${spring.application.name} # 健康检查地址 spring.cloud.consul.discovery.healthCheckPath = /actuator/health # 健康检查间隔 spring.cloud.consul.discovery.healthCheckInterval = 15s spring.cloud.consul.discovery.tags = url-prefix-/${spring.application.name} # Consul注册服务的ID,可以与 eureka.instance.instance-id 进行对比 spring.cloud.consul.discovery.instanceId = ${spring.application.name}:${spring.cloud.consul.port}
consul-3:
application-consul-3.properties
# 服务端口 server.port=8503 # 服务名称 spring.application.name=consul-provider
bootstrap-consul-3.properties
# 注册集群的节点地址(ip和端口) spring.cloud.consul.host=192.168.0.103 spring.cloud.consul.port=8500 # 是否开启注册发现服务 spring.cloud.consul.enabled=true # 是否将服务注册到Consul集群中心 spring.cloud.consul.discovery.register=true # consul注册名称,使用 spring.cloud.consul.discovery.serviceName = kevin-${spring.application.name} # 健康检查地址 spring.cloud.consul.discovery.healthCheckPath = /actuator/health # 健康检查间隔 spring.cloud.consul.discovery.healthCheckInterval = 15s spring.cloud.consul.discovery.tags = url-prefix-/${spring.application.name} # Consul注册服务的ID,可以与 eureka.instance.instance-id 进行对比 spring.cloud.consul.discovery.instanceId = ${spring.application.name}:${spring.cloud.consul.port}
3)、启动服务
3、在项目创建consul-consumer子项目
子项目使用feign进行客户端的负载均衡调用consul-provider。
1)、在pom.xml中添加feign的maven依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
2)、在启动类中添加@EnableFeignClients和@EnableDiscoveryClient注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsulConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulConsumerApplication.class, args);
}
}
3)、在根目录下添加Controller、Service和FallBack类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsulConsumerController {
@Autowired
private HelloService helloService;
@GetMapping("/hello")
public String getHelloInfo() {
return helloService.hello();
}
}
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "consul-provider", fallback = FeignFallBack.class)
public interface HelloService {
/**
* hello服务
*
* @return hello
*/
@RequestMapping("/hello")
String hello();
}
import org.springframework.stereotype.Component;
@Component
public class FeignFallBack implements HelloService {
public String hello() {
return null;
}
}
3)、配置文件
application.properties
# 服务端口 server.port=8505 # 服务名称 spring.application.name=consul-consumer
bootstrap.properties
# 注册集群的节点地址(ip和端口) spring.cloud.consul.host=192.168.0.103 spring.cloud.consul.port=8500 # 是否开启注册发现服务 spring.cloud.consul.enabled=true # 是否将服务注册到Consul集群中心 spring.cloud.consul.discovery.register=true # consul注册名称,使用 spring.cloud.consul.discovery.serviceName = kevin-${spring.application.name} # 健康检查地址 spring.cloud.consul.discovery.healthCheckPath = /actuator/health # 健康检查间隔 spring.cloud.consul.discovery.healthCheckInterval = 15s spring.cloud.consul.discovery.tags = url-prefix-/${spring.application.name} # Consul注册服务的ID,可以与 eureka.instance.instance-id 进行对比 spring.cloud.consul.discovery.instanceId = ${spring.application.name}:${spring.cloud.consul.port}
4、服务调用
在浏览器中访问http://127.0.0.1:8505/hello,consul-consumer调用consul-provider服务: