目录
6、consul集群搭建(linux环境:3server+1client)
1、Consul介绍
consul是hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。 与其它分布式服务注册与发现方案相比,consul的方案更“一站式”, 内置了服务注册与发现框架、分布一致性协议实现、健康检查、key/value存储、多数据中心方案,不再需要依赖其它工具(比如zookeeper等),使用起来也比较简单。 consul使用go语言编写,因此具有天然可移值性(支持linux,windows,mac os); 安装包仅包仿一个可执行文件,方便部署,与docker等轻量级容器可无缝配合。
项目 | Eureka | Consul | Etcd | Zookeeper | Nacos |
---|---|---|---|---|---|
编写语言 | Java | Go | Go | Java | Java |
客户端支持(接口) | HTTP | HTTP、DNS | HTTP、Etcd3、gRPC | 跨语言弱,Cucrator组件 | HTTP、动态DNS、UDP |
服务健康检查 | 需要显示配置健康检查支持 | 提供详细的服务状态、内存、硬盘检查 | 连接心跳 | 长连接、Keepalive | TCP/HTTP/MySQL |
多数据中心 | 无 | 通过WAN的Gossip协议支持 | 无 | 无 | 支持单机模式、集群模式、多集群模式 |
Key-Value | 无 | 支持 | 支持 | 支持 | 支持 |
一致性 | 只能保证最终一致性,不能保证强一致性 | Raft | Raft | Paxos | Raft |
CAP | AP(高的可用性) | AP(高的可用性) | CP(牺牲可用性) | CP(牺牲可用性) | 通知遵循CP原则(一致性+分离容忍)和AP原则(可用性+分离容忍) |
Watch支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
自身监控 | Metrics | Metrics | Metrics | 需要使用第三方组件 | Metrics |
安全 | ACL (Access Control List,是一种网络安全机制,用于限制用户、进程或设备对网络资源的访问权限) | ACL/HTTPS | HTTPS | ACL | ACL/HTTPS |
1、Metrics(监控工具):Metrics提供了一个强大的工具包,用于衡量生产环境中关键组件的行为。其提供了一个工具包,让我们可以对服务中的一些行为进行监控和统计。按照官方的说法Metrics为Jetty、Logback、Log4j、Apache HttpClient、Ehcache、JDBI、Jersey等多个开源库提供支持
2、ACL:Access Control List,是一种网络安全机制,用于限制用户、进程或设备对网络资源的访问权限
2、Consul特性
- Raft算法
- 服务发现
- 健康检查
- Key/Value存储
- 多数据中心
- 支持http和dns协议接口
- 官方提供web管理界面
3、Consul角色
dev:用于开发,以下两种用于生产环境
client:客户端,无状态,将http和dns接口请求转发给局域网内的服务端集群,它只是一个代理的角色。
server:服务端 ,保存配置信息,高可用集群,每个数据中心的server数据推荐为3个或5个
上图是一个简单的consul cluster架构,consul cluster有server和client两种角色,不管是server还是client,统称为agent,consul client是相对无状态的,只负责转发rpc到server,资源开销很少.server是一个有一组扩展功能的代理,这些功能包括参与raft选举,维护集群状态,响应rpc查询,与其它数据中心交互wan gossip和转发查询给leader或远程数据中心。
每个数据中心,client和server是混合的。一般建有3-5台server.这是基于有故障情况下的可用性和性能之间的权衡结果,因为越多的机器加入达成共识越慢,server之初间会选择出一个leader.然而并不限制client的数量,一般建议一个服务对应一个client,它们可以很容易的扩展到数千或者数万台,在开发的时候我们绑定一组服务注册中心中的客户端 即可。
4、Consul工作原理
服务发现及注册:
producer启动时,会将自己的ip/host等信息通过发送请求告知consul,consul接受到producer的注册信息后,每隔10秒(默认)会向producer发送一个健康检查的请求,检查producer是否处于可用状态,防止consumer调到不可用的服务。
服务调用
当consumer请求producer时,会先从consul中拿存储的producer服务的ip和port的临时表(temp table),从表中人选一个producer的ip和port,然后根据这个ip和port,发送访问请求;此表只包含通过健康检查的producer信息,并且每隔10秒更新。
5、Consul下载
consul官方下载地址:
Install | Consul | HashiCorp Developer
window下安装:
下载对应版本的文件即可,下载后解决,目录中会得到一个consul.exe文件
cd到对应的目录下,使用cmd启动consul:
#-dev表示开发模式运行,另外还有-server表示服务模式运行
consul agent -dev -client=0.0.0.0
为了方便启动,也可以在consul.exe同级目录下创建一个脚本(xx.bat)来启动,脚本内容如下:
consul agent -dev -client=0.0.0.00
pause
访问管理后台:http://localhost:8500,能看到正常界面即表示consul服务启动成功了
tips:-client=0.0.0.0表示允许所以ip访问
6、consul集群搭建(linux环境:3server+1client)
6.1 环境准备
服务器ip | consul类型 | node节点 | 系统 |
---|---|---|---|
192.168.190.201 | server | server-01 | centos |
192.168.190.202 | server | server-02 | centos |
192.168.190.203 | server | server-03 | centos |
172.16.0.100 | client | client-01 | windows |
6.2 安装
wget https://releases.hashicory.com/consul/1.6.1/consul_1.6.1_ linux_amd64.zip
mkdir -p /usr/local/consul
unzip consul consul_1.6.1_ linux_amd64.zip -d /usr/local/consul/
#consul数据目录
mkdir -p /usr/local/consul/data
6.3 server端启动
注册中心服务端:
#分别在3台server上(/usr/local/consul目录)执行以下命令(-bind及-node改为对应的即可)
192.168.190.201
./consul agent -server -bind=192.168.190.201 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/consul/data/ -node=server-01
192.168.190.202
./consul agent -server -bind=192.168.190.202 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/consul/data/ -node=server-02
192.168.190.203
./consul agent -server -bind=192.168.190.203 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/consul/data/ -node=server-03
在server-02和server-03执行以下命令加入到集群
/usr/local/consul/consul join 192.168.190.201
参数含义如下:
-server:以服务端身份启动(注册中心)
-bind:表示绑定以哪个ip
-client:指定客户端访问的ip,0.0.0.0不限制客户端ip
-bootstrap-expect: 集群要求的最少Server数量。当低于这个数量是集群失效
-data-dir: data存放的目录
-node: 节点的ID ,在同一集群中不能存在重复的ID
6.4 windows下启动一个client端
在windows下的consul.exe所在目录中执行,-data-dir对应目录先建好
consul agent -client=0.0.0.0 -bind=172.16.0.199 -data-dir=D:\JavaRevelant\software\consul\data -node=client-01
6.5 Consul常用命令
- consul members: 查看集群成员信息
- consul members -detailed: 查看集群成员的详细信息
- consul monitor: 持续打印当前Consul的日志
- consul force-leave <node-id>: 删除consul的节点
6.6 访问页面
访问
访问任务一个server的8500端口即可
如:http://192.168.190.201:8500/
6.7 对外接口
Consul默认提供一下对外接口
- http://host:8500/v1/status/leader:显示当前集群的Leader
- http://host:8500/v1/agent/members:显示集群所有成员的信息
- http://host:8500/v1/status/peers:显示集群中的Server成员
- http://host:8500/v1/catalog/services:显示所有服务
- http://host:8500/v1/catalog/nodes:显示集群节点的详细信息
7、Consumer实现“服务提供者”集群和“服务消费者”
7.1 实现“服务提供者”集群
这里在测试过程中不知道什么原因,本机client端不好使,于是又开了个linux虚拟端,启动一个client
在192.168.190.101启动一个consul client
[root@node1 consul]# ./consul agent -client=0.0.0.0 -bind=192.168.190.101 -data-dir=/usr/local/consul/data -node=client-02
[root@node1 consul]# ./consul join 192.168.190.201
(1)创建SpringBoot项目,添加依赖Consul、Acutator、Web
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Generated by https://start.springboot.io -->
<!-- 优质的 spring/boot/data/security/cloud 框架中文文档尽在 => https://springdoc.cn -->
<groupId>com.dolphin</groupId>
<artifactId>ConsulProvider1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ConsulProvider1</name>
<description>ConsulProvider1</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
</project>
(2)application.yml配置文件
spring:
application:
name: consul-provider
cloud:
consul:
host: 192.168.190.101
port: 8500
discovery:
register: true #是否需要注册
service-name: ${spring.application.name} #服务名称
prefer-ip-address: true #是否使用IP地址注册 (默认会根据电脑名称注册,健康检查会不通过)
ip-address: ${spring.cloud.client.ip-address} #服务请求IP
instance-id: ${spring.application.name}-01 #服务实例ID
port: ${server.port} #服务端口
server:
port: 8081
(3)开启服务注册功能,在启动类中添加注解@EnableDisableDiscoveryClient注解
(4)Controller类 实现服务接口
package com.dolphin.consulprovider1.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private String port;
@RequestMapping("/hello")
public String hello() {
return "appliationName: "+ applicationName +" port:"+ port;
}
}
至此,一个服务提供者创建成功
(5)同样在再配置一个服务提供者,其它相同,配置文件修改如下
spring:
application:
name: consul-provider
cloud:
consul:
host: 192.168.190.101
port: 8500
discovery:
register: true #是否需要注册
service-name: ${spring.application.name} #服务名称
prefer-ip-address: true #是否使用IP地址注册 (默认会根据电脑名称注册,健康检查会不通过)
ip-address: ${spring.cloud.client.ip-address} #服务请求IP
instance-id: ${spring.application.name}-02
port: ${server.port}
server:
port: 8082
(6)启动“服务提供者” 集群
进行访问均可提供服务
查看consul集群,服务提供者已注册到consul
注意:服务提供者需要这个依赖,不然会报错,会出现下图Service Check X 红叉的情况
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
7.2 实现服务消费者
(1)创建SpringBoot项目,添加依赖Consul、Web
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Generated by https://start.springboot.io -->
<!-- 优质的 spring/boot/data/security/cloud 框架中文文档尽在 => https://springdoc.cn -->
<groupId>com.dolphin</groupId>
<artifactId>ConsulConsumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ConsulConsumer</name>
<description>ConsulConsumer</description>
<properties>
<java.version>21</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)添加配置application.yaml
spring:
application:
name: consul-consumer
cloud:
consul:
discovery:
register: false
host: 192.168.190.101
port: 8500
server:
port: 8090
(3)编写服务调用接口
package com.dolphin.consulconsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
@RestController
public class HelloContrler {
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/hello")
public String hello() {
ServiceInstance serviceInstance = loadBalancerClient.choose("consul-provider");
URI uri = serviceInstance.getUri();
String callService = new RestTemplate().getForObject(uri+"/hello",String.class);
System.out.println(callService);
return callService;
}
}
7.3 测试
访问 http://localhost:8090/hello
交替出现如下信息测试成功
appliationName: consul-provider port:8081
appliationName: consul-provider port:8082