Consul服务注册中心

目录

1、Consul介绍

2、Consul特性

3、Consul角色

4、Consul工作原理

5、Consul下载

6、consul集群搭建(linux环境:3server+1client)

6.1 环境准备

 6.2 安装

6.3 server端启动

6.4 windows下启动一个client端

6.5 Consul常用命令

6.6 访问页面

6.7 对外接口


1、Consul介绍

        consul是hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。 与其它分布式服务注册与发现方案相比,consul的方案更“一站式”, 内置了服务注册与发现框架、分布一致性协议实现、健康检查、key/value存储、多数据中心方案,不再需要依赖其它工具(比如zookeeper等),使用起来也比较简单。 consul使用go语言编写,因此具有天然可移值性(支持linux,windows,mac os); 安装包仅包仿一个可执行文件,方便部署,与docker等轻量级容器可无缝配合。

常见的注册中心
项目EurekaConsulEtcdZookeeper Nacos
编写语言JavaGoGoJavaJava
客户端支持(接口)HTTPHTTP、DNSHTTP、Etcd3、gRPC跨语言弱,Cucrator组件HTTP、动态DNS、UDP
服务健康检查需要显示配置健康检查支持提供详细的服务状态、内存、硬盘检查连接心跳长连接、KeepaliveTCP/HTTP/MySQL
多数据中心通过WAN的Gossip协议支持支持单机模式、集群模式、多集群模式
Key-Value支持支持支持支持
一致性只能保证最终一致性,不能保证强一致性RaftRaftPaxosRaft
CAP AP(高的可用性)AP(高的可用性)CP(牺牲可用性)CP(牺牲可用性)通知遵循CP原则(一致性+分离容忍)和AP原则(可用性+分离容忍)
Watch支持支持支持支持支持支持
自身监控MetricsMetricsMetrics需要使用第三方组件Metrics
安全

ACL

(Access Control List,是一种网络安全机制,用于限制用户、进程或设备对网络资源的访问权限)

ACL/HTTPSHTTPSACLACL/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有serverclient两种角色,不管是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 环境准备

服务器ipconsul类型node节点系统
192.168.190.201serverserver-01centos
192.168.190.202serverserver-02centos
192.168.190.203serverserver-03centos
172.16.0.100clientclient-01windows

 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

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值