当前位置: 首页 > news >正文

4.Consul服务注册与发现

目录

一、为什么要引入微服务 

二、为什么不再使用传统老牌的Eureka

1.Eureka停更进维

2.Eureka对初学者不友好

3.注册中心独立且和微服务功能解耦

4.Consul与阿里巴巴Nacos的崛起

三、Consul简介

Consul官方地址

consul简述

Consul功能

四、安装运行consul

官方下载

Window下载安装

linux下载安装

五、Consul常用命令

Consul agent常用命令解读

开发启动模式

生产模式启动

查看集群节点信息

Consul修改常用端口号

阿里云服务器部署高可用集群

六、服务注册与发现

服务提供者8001

支付服务provider8001注册进consul

POM 添加consul依赖包

配置来源

YML

主启动

启动8001并查看consul控制台

服务消费者80

修改微服务cLoud-consumer-order80

POM-添加服务器注册与发现依赖包

YML

Controller

启动80并查看consul控制台

访问测试地址

配置修改RestTemplateconfig

三个注册中心异同点

CAP

经典CAP图

七、服务配置与刷新

分布式系统面临的 → 配置问题

官网说明

服务配置案例步骤

需求

修改cloud-provider-payment8001

POM

YML

consul服务器key/value配置填写

 controller

测试

动态刷新案例步骤

问题

步骤

思考


一、为什么要引入微服务 

 微服务所在的IP地址和端口号硬编码到订单微服务中,会存在非常多的问题 

(1)如果订单微服务和支付微服务的IP地址或者端口号发生了变化,则支付微服务将变得不可用,需要同步修改订单微服务中调用支付微服务的IP地址和端口号。 

(2)如果系统中提供了多个订单微服务和支付微服务,则无法实现微服务的负载均衡功能。 

(3)如果系统需要支持更高的并发,需要部署更多的订单微服务和支付微服务,硬编码订单微服务则后续的维护会变得异常复杂。 

所以,在微服务开发的过程中,需要引入服务治理功能,实现微服务之间的动态注册与发现,从此刻开始我们正式进入SpringCloud实战

二、为什么不再使用传统老牌的Eureka

1.Eureka停更进维

2.Eureka对初学者不友好

首次看到自我保护机制

3.注册中心独立且和微服务功能解耦

目前主流服务中心,希望单独隔离出来而不是作为一个独立微服务嵌入到系统中

按照Netflix的之前的思路,注册中心Eureka也是作为一个微服务且需要程序员自己开发部署;

实际情况:

希望微服务和注册中心分离解耦,注册中心和业务无关的,不要混为一谈。

提供类似tomcat一样独立的组件,微服务注册上去使用,是个成品。

4.Consul与阿里巴巴Nacos的崛起

Consul与Nacos都可以实现服务器注册与发现、分布式配置管理两种功能。

Service discovery and configuration management

三、Consul简介

Consul官方地址

  • spring consul官网教学地址:Spring Cloud Consul(自主学习可通过该网站)
  • consul官网地址:Consul | HashiCorp Developer
  • github源码地址:https://github.com/hashicorp/consul
  • consul官网学习文档:What is Consul? | Consul | HashiCorp Developer
  • consul下载地址:Install | Consul | HashiCorp Developer

consul简述

Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。

提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。

Consul优点包括: 基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows

Consul的主要作用:分布式服务发现和配置管理

禁止使用问题

Consul并不禁止,静止的是Vault

条款链接:https://www.hashicorp.com/terms-of-evaluation

HashiCorp是一家非常知名的基础软件提供商,很多人可能没听过它的名字,但是其旗下的6款主流软件,Terraform、Consul、Vagrant、Nomad、Vault,Packer 相信不少程序员都听说或使用过,尤其是Consul使用者不尽其数。截止目前为止,从HashiCorp 官网上的声明来看,开源项目其实还是“安全”的,被禁用的只是Vault企业版(并且原因是Vault产品目前使用的加密算法在中国不符合法规,另一方面是美国出口管制法在涉及加密相关软件上也有相应规定。因此这两项原因使得HashiCorp不得不在声明中说明风险)而非其他所有开源产品(Terraform、Consul等)。因此,大家可以暂时放下心来,放心使用!

Consul功能

  • 服务发现---提供HTTP和DNS两种发现方式。
  • 健康监测----支持多种方式,HTTP、TCP、Docker、Shell脚本定制化监控
  • KV存储-----Key、Value的存储方式
  • 多数据中心可视化Web界面----Consul支持多数据中心
  • 可视化Web界面

功能详解:

  • 服务发现: Consul 的客户端可以注册服务,其他客户端可以使用 Consul 发现给定服务的提供者。使用DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务。
  • 健康检查: Consul客户端可以提供任意数量的健康检查,可以与给定的服务关联(“web服务器是否返回200 OK”),也可以与本地节点关联(“内存利用率是否低于90%”)。操作人员可以使用此信息监视集群运行状况,服务发现组件也可以使用此信息将通信流量路由到远离不健康主机的地方,支持多种方式,HTTP, TCP、 Docker, Shell脚本定制化监控。
  • KV 存储: 应用程序可以使用Consul的分级 key/value 存储来实现各种目的,包括动态配置、特性标记、协调、leader选举等等。简单的HTTP API使其易于使用。
  • 安全服务通信: Consul可以生成和分发服务的TLS证书,以建立相互的TLS连接。可以使用意图来定义允许哪些服务进行通信。可以很容易地管理服务细分,目的可以实时更改,而不是使用复杂的网络拓扑和静态防火墙规则。
  • 多数据中心: Consul 支持开箱即用的多个数据中心。这意味着 Consul 的用户不必担心构建额外的抽象层以扩展到多个区域。
  • Raft 算法: 使用Raft算法完成一致性,Raft将一致性问题分解成了三个独立的部分:leader选举、日志复制、安全性。
  • 自带web管理界面: 这一点相比于zookeeper注册中心要好一点,zookeeper是没有自带管理界面的。通过管理界面可以清晰的看到注册了多少个服务,以及在管理界面还可以使用服务配置功能。

Consul命令解析

Agent: Consul集群中长时间运行的守护进程,以consul agent 命令开始启动. 在客户端和服务端模式下都可以运行,可以运行DNS或者HTTP接口, 它的主要作用是运行时检查和保持服务同步。

Client: 客户端, 无状态, 以一个极小的消耗将接口请求转发给局域网内的服务端集群.

Server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.

Datacenter: 数据中心,多数据中心联合工作保证数据存储安全快捷

Consensus: 一致性协议使用的是Raft Protocol

RPC: 远程程序通信

Gossip: 基于 Serf 实现的 gossip 协议,负责成员、失败探测、事件广播等。通过 UDP 实现各个节点之间的消息。分为 LAN 上的和 WAN 上的两种情形。

相关知识扩展:

Raft协议

Raft协议的设计着眼于提供更易理解和实现的一致性算法,以替代复杂且难以理解的Paxos算法。

Raft协议核心机制,主要包括领导者选举(Leader Election)、日志复制(Log Replication)和安全性(Safety)。

优点

  • 易于理解和实现:与Paxos相比,Raft的算法设计更加直观和清晰,易于开发人员理解和掌握。
  • 高可靠性和一致性:通过领导者选举和日志复制等机制,Raft能够确保分布式系统的高可靠性和一致性。
  • 容错能力强:即使在部分节点故障或网络分割的情况下,Raft协议也能够保证系统的正常运行。

应用场景举例

  • 分布式数据库:如etcd、TiKV等分布式数据库系统采用Raft协议来管理数据的复制和一致性。
  • 分布式存储:一些分布式存储系统也采用Raft协议来确保数据的高可靠性和一致性。

四、安装运行consul

官方下载

consul下载地址:https://developer.hashicorp.com/consul/install?product_intent=consu

Window下载安装

下载完成后只有一个consul.exe文件,对应全路径下查看版本号信息

设置环境变量path够添加consul全路径(D:\javapro\consul_1.19.1_windows_386),然后cmd执行consul命令即可。

使用开发模式启动

consul agent -dev

通过以下地址可以访问Consul的首页:http://localhost:8500

Consul可视化界面

linux下载安装

Ubuntu/Debian

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install consul

CentOS/RHEL

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install consul

./consul agent -server -bootstrap-expect 1 -data-dir=/tmp/consul -node=n1 -bind=127.0.0.1 -client=0.0.0.0 -ui

-server 表示是server模式-bootstrap-expect=3 表示是集群中有3台服务器 bootstrap该模式node可以指定自己作为leader ,如果是非leader可不加该参数-data-dir=/tmp/consul 目录-node=n2 该服务器节点名-bind=127.0.0.1 节点绑定的ip-ui 非必须 webui的路径 用web来管理consul

启动命令如下(默认是8500端口):

./consul agent -server -bootstrap-expect 1 -data-dir=/tmp/consul -node=n1 -bind=127.0.0.1 -client=0.0.0.0 -ui

Consul 开机自启动

1. 路径/usr/lib/systemd/system/,新建一个service命名为,consul.service

自启动脚本

[Unit]
Description=consul-serviceAfter=network.target[Service]
Type=forking
PIDFile=/run/consul-service.pid
ExecStart=/usr/service/consul.start.sh
ExecReload=/bin/kill -SIGHUP $MAINPID
ExecStop=/bin/kill -SIGINT $MAINPID[Install]
WantedBy=multi-user.target graphical.target

上面的ExecStart 是启动的脚本,我之前把consul 是安装在/user/service 下面,

2. 创建启动脚本

我们再service 目录中创建Consul开机自启动的脚本文件consul.start.sh

#!/bin/bash
/usr/service/consul agent -server  -bootstrap-expect 1 -node=127.0.0.1 -data-dir=/usr/service/data/  -log-file=/usr/service/log/consul_log-$(date +%Y-%m-%d--%H-%M) -bind=127.0.0.1

3. 重新加载配置

systemctl daemon-reload

4. 设置开机自启动

systemctl enable consul.service

Consul 启动

systemctl start consul

Consul 停止

systemctl stop consul

上面创建开机自启动脚本实践的时候大家可能会发现 通过systemctl start consul 无法启动问题,这时候可以通过status 来查询状态,命令如下

systemctl status consul
查询创建的自启动脚本执行过程中出现 code =exited,  status =203/EXEC异常错误信息,这个信息一般有如下几个原因造成:
  • 错误的脚本路径
  • 脚本的权限无效
    • 服务用户没有读取脚本的权限
    • 脚本未标记为可执行
根据上面三种情况去排查解决,基本上就可以完美解决自启动脚本无法启动问题

五、Consul常用命令

以下是一些常用的 Consul 集群管理命令:

1.启动 Consul Agent:

consul agent -config-file=<config_file>

这个命令用于启动 Consul Agent,并指定配置文件。

2.加入集群:

consul join <address>

这个命令用于将当前节点加入到 Consul 集群中,是一个已存在的集群节点的地址。

3.离开集群:

consul leave

这个命令用于将当前节点从 Consul 集群中移除。

4.查看集群节点:

consul members

这个命令用于查看当前 Consul 集群中的成员节点列表。

5.查看 Leader:

consul operator raft list-peers

这个命令用于列出当前的 Consul 集群中的领导者节点。

6.手动推选 Leader:

 consul operator raft promote <node_id>

这个命令用于手动推选指定节点为 Consul 集群的领导者。

7.重启集群节点:

consul reload

这个命令用于重新加载 Consul 配置文件并重启 Consul Agent。

8.查看服务列表:

consul services register

这个命令用于列出所有在 Consul 中注册的服务。

9.注册服务:

 consul services register <service.json>

这个命令用于注册一个新的服务到 Consul 中, 是包含服务定义的 JSON 文件。

10.移除服务:

consul services deregister <service_id>

这个命令用于从 Consul 中移除一个已注册的服务, 是服务的唯一标识符。

  • consul agent -dev 或者consul agent -dev -config-dir /etc/consul.d/ #开发模式启动
  • consul agent -dev -http-port 8080 #修改成8080端口或在-config-dir中修改
  • consul agent -dev -http-port 8080 -client 0.0.0.0 #公网可以访问使用-client 0.0.0.0

Consul agent常用命令解读

-data-dir
作用:指定agent储存状态的数据目录,这是所有agent都必须的,对server尤其重要,因为他们必须持久化集群的状态
-config-dir
作用:指定service的配置文件和检查定义所在的位置。目录必需为consul.d,文件内容都是json格式的数据。配置详解见官方
-config-file
作用:指定一个要装载的配置文件
-dev
作用:开发服务器模式,虽然是server模式,但不用于生产环境,因为不会有任何持久化操作,即不会有任何数据写入到磁盘
-bootstrap-expect
作用: 参数表明该服务运行时最低开始进行选举的节点数,当设置为1时,则意味允许节点为一个时也进行选举;当设置为3时,则等到3台节点同时运行consul并加入到server才能参与选举,选举完集群才能够正常工作。 一般建议服务器结点3-5个。
-node
作用:指定节点在集群中的名称,该名称在集群中必须是唯一的(默认这是机器的主机名),直接采用机器的IP
-bind
作用:指明节点的IP地址,一般是0.0.0.0或者云服务器内网地址,不能写阿里云外网地址。这是Consul侦听的地址,它必须可以被集群中的所有其他节点访问。虽然绑定地址不是绝对必要的,但最好提供一个。
-server
作用:指定节点为server,每个数据中心(DC)的server数推荐3-5个。
-client
作用:指定节点为client,指定客户端接口的绑定地址,包括:HTTP、DNS、RPC
默认是127.0.0.1,只允许回环接口访问
-datacenter
作用:指定机器加入到哪一个数据中心中。老版本叫-dc,-dc已经失效

开发启动模式

consul agent -dev #开发模式启动

Consul agent输出的重要信息:

节点名称:这是代理的唯一名称。默认情况下,这是机器的主机名,但您可以使用该-node标志对其进行自定义 。

数据中心:这是配置代理运行的数据中心。每个节点都必须设置其它向数据中心报告。-datacenter 标志可用于设置数据中心。对于单DC配置,代理将默认为“dc1”。

服务器:这表明代理是以服务器还是客户端模式运行。Server: false (bootstrap: false),表示不是以服务器模式运行,事实上-dev是开发服务器模式。

客户端地址:这是用于代理的客户端接口的地址。这包括HTTP和DNS接口的端口。默认情况下,它只绑定到localhost。

群集地址:这是用于集群中的Consul代理之间通信的地址和端口集。并非所有集群中的Consul代理都必须使用相同的端口,但该地址必须可供所有其他节点访问。

-dev:该模式不能用于生产环境,因为该模式下不会持久化任何状态,该启动模式仅仅是为了快速便捷的启动单节点consul

生产模式启动

server服务器模式启动

-dev开发者服务器模式运行的,生产环境以-server模式运行consul.

consul agent -server -ui -bootstrap-expect=1 -data-dir=/tmp/consul -node=agent-one -advertise=116.62.184.190 -bind=0.0.0.0 -client=0.0.0.0

-server:服务器模式

-ui:能webui展示

-bootstrap-expect:server为1时即选择server集群leader

-data-dir:consul状态存储文件地址

-node:指定结点名

advertise:本地ip地址

-client:指定可访问这个服务结点的ip

查看集群节点信息

consul members #查看集群节点信息

Node  Address         Status  Type    Build  Protocol  DC   Segment
n3    127.0.0.0:8301  alive   server  1.1.0  2         dc1  <all>
  • node:节点名
  • Address:节点地址
  • Status:alive表示节点健康
  • Type:server运行状态是server状态
  • DC:dc1表示该节点属于DataCenter1

Consul修改常用端口号

方法1:consul agent -dev -http-port 8080

方法2:使用-config-dir命令行参数,指定配置文件(可修改端口)

就是指定加载置文件的目录,该目录下所有的以.json结尾配置文件加载进去,它的加载顺序是根据26个字母的顺序加进行加载配置文件的。目录必需为consul.d,文件内容都是json格式的数据。默认后面文件定义配置会覆盖前面文件定义的配置。

例如/etc/consul.d目录下合建base-config.json:

其它默认端口

  • dns : 默认8600.
  • http :默认8500.
  • https: 默认-1 (disabled).
  • serf_lan:默认8301.
  • serf_wan: 默认 8302.
  • server: 默认8300
{  "ports": {    "http": 8080}  
} 

阿里云服务器部署高可用集群

Consul join使用:

2台阿里云服务器 云1:116.62.184.190和云2:139.196.123.97

在云1上创建consul服务器agent-one:

consul agent -server -ui -bootstrap-expect=1 -data-dir=/tmp/consul -node=agent-one -advertise=116.62.184.190 -bind=0.0.0.0 -client=0.0.0.0

在云2上创建consul服务器agent-two:

consul agent -server -ui -bootstrap-expect=1 -data-dir=/tmp/consul -node=agent-two -advertise=139.196.123.97 -bind=0.0.0.0 -client=0.0.0.0

在云1上执行命令,将agent-one添加到agent-two:

consul join 139.196.123.97WWWWWWWWWWWWWWWW

访问consul地址:http://139.196.123.97:8500

六、服务注册与发现

服务提供者8001

  • 支付服务provider8001注册进consul
  • POM 添加consul依赖包
  • YML
  • 主启动
  • 启动8001并查看consul控制台

支付服务provider8001注册进consul
POM 添加consul依赖包

其他包依赖不变

 <!--SpringCloud consul discovery --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency>
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-consumer-order80</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--SpringCloud consul discovery --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- 引入自己定义的api通用包 --><dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--web + actuator--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool-all--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--fastjson2--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
配置来源

pom配置来源官网地址:Quick Start :: Spring Cloud Consul

YML

将consul引入application.yml文件

 ####Spring Cloud Consul for Service Discovery

  cloud:

    consul:

      host: localhost

      port: 8500

      discovery:

        service-name: ${spring.application.name}

server:port: 8001# ==========applicationName + druid-mysql8 driver===================
spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: 123456####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}# ========================mybatis===================
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.cloud.entitiesconfiguration:map-underscore-to-camel-case: true
主启动

@EnableDiscoveryClient 开启服务发现注解

@EnableDiscoveryClient 是Spring Cloud框架中的一个注解,它用于开启服务发现功能。当你在Spring Boot应用的主配置类上使用这个注解时,Spring Cloud会自动配置一个客户端,这个客户端能够与服务注册中心通信,获取服务实例的信息。

使用@EnableDiscoveryClient的好处在于,它具有一定的抽象性,可以与多种服务发现实现兼容,比如Eureka、Consul、Zookeeper等。具体使用哪种服务发现实现取决于你的类路径中包含的依赖。如果类路径中有Eureka的相关依赖,那么它会默认使用Eureka作为服务发现机制;如果没有指定,它会尝试找到可用的服务发现实现

package com.atguigu.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;@SpringBootApplication
@MapperScan("com.atguigu.cloud.mapper") //import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient
public class Main8001
{public static void main(String[] args){SpringApplication.run(Main8001.class,args);}
}
启动8001并查看consul控制台

服务消费者80

修改微服务cLoud-consumer-order80
POM-添加服务器注册与发现依赖包
 <!--SpringCloud consul discovery 服务器注册与发现依赖包--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency>
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.atguigu.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-consumer-order80</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--SpringCloud consul discovery 服务器注册与发现依赖包--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency><!-- 引入自己定义的api通用包 --><dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--web + actuator--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--hutool-all--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--fastjson2--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId></dependency><!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
YML
server:port: 80spring:application:name: cloud-consumer-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}
Controller

http://cloud-payment-service 服务注册中心上的微服务名称

package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;@RestController
public class OrderController
{//public static final String PaymentSrv_URL = "http://localhost:8001";//先写死,硬编码public static final String PaymentSrv_URL = "http://cloud-payment-service";//服务注册中心上的微服务名称@Autowiredprivate RestTemplate restTemplate;/*** 一般情况下,通过浏览器的地址栏输入url,发送的只能是get请求* 我们模拟消费者发送get请求,but底层调用post方法,客户端消费者参数PayDTO可以不添加@RequestBody* @param payDTO* @return*/@GetMapping("/consumer/pay/add")public ResultData addOrder(PayDTO payDTO){return restTemplate.postForObject(PaymentSrv_URL + "/pay/add",payDTO,ResultData.class);}@GetMapping("/consumer/pay/get/{id}")public ResultData getPayInfo(@PathVariable Integer id){return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/"+id, ResultData.class, id);}
}
启动80并查看consul控制台

访问测试地址

http://localhost/consumer/pay/get/10

java.net.UnknownHostException: cloud-payment-service(财务原因没有添加负载均衡注解@LoadBalanced)

配置修改RestTemplateconfig

注意:consult默认是负载均衡支持多集群,需要添加@LoadBalanced注解

@LoadBalanced注解用于在‌Spring Cloud环境中启用‌RestTemplate的负载均衡功能。 当你在RestTemplate的Bean定义上添加此注解时,Spring Cloud会自动为该RestTemplate配置负载均衡器,使其能够从‌服务注册中心获取服务实例列表,并根据负载均衡策略选择合适的服务实例进行请求转发。常见的负载均衡策略包括‌轮询、随机和‌加权轮询等,可以根据实际需求进行配置。此外,通过添加@LoadBalanced注解,Spring Cloud还可以通过LoadBalancerInterceptor拦截器对RestTemplate进行定制,实现服务调用的负载均衡和容错能力,从而提高微服务架构的稳定性和性能。

package com.atguigu.cloud.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig
{@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}

三个注册中心异同点

CAP

C:Consistency(强一致性)

A:Availability(可用性)

P:Partition tolerance(分区容错性)

经典CAP图

最多只能同时较好的满足两个。

CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,

因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:

CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。

CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。

AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

 

AP(Eureka)

AP架构

当网络分区出现后,为了保证可用性,系统B可以返回旧值,保证系统的可用性。

当数据出现不一致时,虽然A, B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如此保证了可用性但牺牲了一致性结论:违背了一致性C的要求,只满足可用性和分区容错,即AP

 

CP(Zookeeper/Consul)

CP架构

当网络分区出现后,为了保证一致性,就必须拒接请求,否则无法保证一致性,Consul 遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。结论:违背了可用性A的要求,只满足一致性和分区容错,即CP

 

七、服务配置与刷新

分布式系统面临的 → 配置问题

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。比如某些配置文件中的内容大部分都是相同的,只有个别的配置项不同。就拿数据库配置来说吧,如果每个微服务使用的技术栈都是相同的,则每个微服务中关于数据库的配置几乎都是相同的,有时候主机迁移了,我希望一次修改,处处生效。

当下我们每一个微服务自己带着一个application.yml,上百个配置文件的管理......

consult可以进行统一分布式配置

官网说明

 

服务配置案例步骤

需求

通用全局配置信息,直接注册进ConsuI服务器,从Consul

获取既然从Consul获取自然要遵守Consul的配置规则要求

修改cloud-provider-payment8001
POM
!--SpringCloud consul config  consul分布式配置 consul-config与bootstrap-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

若启动时报commons-logging异常,则将commons-logging排除

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-config</artifactId><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions>
</dependency>
YML

配置规则说明新增配置文件

新增配置文件 bootstrap.yml

bootstrap简介

applicaiton.yml是用户级的资源配置项

bootstrap.yml是系统级的,优先级更加高

Spring Cloud会创建一个“Bootstrap Context”,作为Spring应用的Application Context的父上下文。初始化的时候,Bootstrap Context负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment。

Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap context和Application Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap Context和Application Context配置的分离。

application.yml文件改为bootstrap.yml,这是很关键的或者两者共存

因为bootstrap.yml是比application.yml先加载的。bootstrap.yml优先级高于application.yml

bootstrap.yml内容

spring:application:name: cloud-payment-service####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}config:profile-separator: '-' # default value is ",",we update '-'format: YAML# config/cloud-payment-service/data
#       /cloud-payment-service-dev/data
#       /cloud-payment-service-prod/data

application.yml

去除consult配置添加profiles

profiles:

    active: dev

server:port: 8001# ==========applicationName + druid-mysql8 driver===================
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: 123456profiles:active: dev # 多环境配置加载内容dev/prod,不写就是默认default配置# ========================mybatis===================
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.cloud.entitiesconfiguration:map-underscore-to-camel-case: true
consul服务器key/value配置填写

1.参考规则

 2.创建config文件夹,以/结尾

 To create a folder, end a key with /

3.config文件夹下分别创建其它3个文件夹,以/结尾

  1. cloud-payment-service
  2. cloud-payment-service-dev
  3. cloud-payment-service-prod

4.上述3个文件夹下分别创建data内容,data不再是文件夹

 controller
@Value("${server.port}")
private String port;@GetMapping(value = "/pay/get/info")
private String getInfoByConsul(@Value("${atguigu.info}") String atguiguInfo)
{return "atguiguInfo: "+atguiguInfo+"\t"+"port: "+port;
}
测试
spring:profiles:active: dev # 多环境配置加载内容dev
spring:profiles:active: prod # 多环境配置加载内容prod
spring:profiles:active:  # 多环境配置加载内容默认

通过修改application.yml里面的激活配置部分,进行内容的验证

http://localhost:8001/pay/get/info

动态刷新案例步骤

问题

接上一步,我们在consul的dev配置分支修改了内容

马上访问,结果无效

http://localhost:8001/pay/get/info

 会发现还是原来的内容,/(ㄒoㄒ)/~~ ,没有做到及时响应和动态刷新

步骤

@Refreshscope主启动类添加

bootstrap.yml修改下(只为教学实际别改)--spring.cloud.consu.config.watch.wait-time

controller

@Refreshscope主启动类添加

package com.atguigu.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import tk.mybatis.spring.annotation.MapperScan;@SpringBootApplication
@MapperScan("com.atguigu.cloud.mapper") //import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient //服务注册和发现
@RefreshScope // 动态刷新
public class Main8001
{public static void main(String[] args){SpringApplication.run(Main8001.class,args);}
}

bootstrap.yml修改下

注意:spring.cloud.consu.config.watch.wait-time 默认55秒自动修改,测试时可修改快一些,生产环境别修改

官方说明

 修改步骤

spring:application:name: cloud-payment-service####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}config:profile-separator: '-' # default value is ",",we update '-'format: YAMLwatch:wait-time: 1# config/cloud-payment-service/data
#       /cloud-payment-service-dev/data
#       /cloud-payment-service-prod/data

Controller

@Value("${server.port}")
private String port;@GetMapping(value = "/pay/get/info")
private String getInfoByConsul(@Value("${atguigu.info}") String atguiguInfo)
{return "atguiguInfo: "+atguiguInfo+"\t"+"port: "+port;
}

思考

截止到这,服务配置和动态刷新全部通过,假设我重启Consu,之前的配置还在吗?

try try——引用问题——Consul配置持久化......

http://www.xdnf.cn/news/690985.html

相关文章:

  • 【深度学习】10. 深度推理(含链式法则详解)RNN, LSTM, GRU,VQA
  • 33.第二阶段x64游戏实战-InLineHook
  • Jmeter——JDBC连接数据库相关
  • 【vscode】切换英文字母大小写快捷键如何配置
  • 《Google I/O 2025:AI浪潮下的科技革新风暴》
  • 宁夏农业科技:创新引领,赋能现代农业新篇章
  • c语言实现Linux命令行补全机制
  • 运用集合知识做斗地主案例
  • 智能指针的使用及原理
  • MCP 登场:掘金开启 AI 前端项目部署新时代
  • 第三章、数据链路层
  • C++智能指针用法及内存管理
  • 双因子COX 交互 共线性 -spss
  • 多态 向上转型
  • YOLO人体姿态估计Pytorch推理ONNX模型推理
  • Android-GestureDetector学习总结
  • 微信小程序(uniapp)对接腾讯云IM
  • Vue 实例生命周期
  • 2025.5.28总结
  • 接口幂等性原理与方案总结
  • Avue表单个别字段实现全选的思路
  • 【Pandas】pandas DataFrame drop
  • Transformer核心技术解析LCPO方法:精准控制推理长度的新突破
  • Redis学习(十四)主从复制的工作原理、集群搭建(一主二从)
  • Android 云手机横屏模式下真机键盘遮挡输入框问题处理
  • [AD] Noxious LLMNR+DHCP+NTLMv2+Kerberos+SMB
  • 高精度导航 | RTK:2025年高精度导航算法综述,包括:原理,数据,公式,完整代码,开源代码链接
  • 网络协议之办公室网络是怎样的?
  • Mac M1编译OpenCV获取libopencv_java490.dylib文件
  • xcode 旧版本、历史版本下载