24.4 基于consul服务发现模式

本节重点介绍 :

  • consul 安装
  • consul go代码注册服务,注销服务,获取服务
  • node_exporter改造为consul服务发现
  • 在数量比较大时,在注册服务的时候,关闭check,可以降低consul的压力

consul 安装

准备工作


# 下载consul
wget -O /opt/tgzs/consul_1.9.4_linux_amd64.zip  https://releases.hashicorp.com/consul/1.9.4/consul_1.9.4_linux_amd64.zip cd /opt/tgzs/
unzip consul_1.9.4_linux_amd64.zip/bin/cp -f consul /usr/bin/

启动单机版consul


# 
mkdir  /opt/app/consul# 准备配置文件
cat <<EOF > /opt/app/consul/single_server.json
{"datacenter": "dc1","node_name": "consul-svr-01","server": true,"bootstrap_expect": 1,"data_dir": "/opt/app/consul/","log_level": "INFO","log_file": "/opt/logs/","ui": true,"bind_addr": "0.0.0.0","client_addr": "0.0.0.0","retry_interval": "10s","raft_protocol": 3,"enable_debug": false,"rejoin_after_leave": true,"enable_syslog": false
}
EOF# 多个ip地址时,将bind_addr 改为一个内网的ip# 写入service文件
cat <<EOF > /etc/systemd/system/consul.service
[Unit]
Description=consul server
Wants=network-online.target
After=network-online.target[Service]
ExecStart=/usr/bin/consul agent  -config-file=/opt/app/consul/single_server.json
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=consul
[Install]
WantedBy=default.target
EOF# 启动服务
systemctl daemon-reload && systemctl start consul   systemctl status consul 

验证访问

  • http://localhost:8500/

node_exporter的job改造为consul的服务发现

编写go代码注册服务到consul

初始化consul

  • 使用包 github.com/hashicorp/consul/api
import ("fmt"consul "github.com/hashicorp/consul/api""log"
)type client struct {consul *consul.Client
}func NewConsulClient(addr string) (*client, error) {config := consul.DefaultConfig()config.Address = addrc, err := consul.NewClient(config)if err != nil {return nil, err}return &client{consul: c}, nil
}

编写注册服务方法

  • 需要指定参数为
    • 服务的名称
    • 实例地址
    • 实例端口
    • 实例探活path
    • 实例标签map
  • check.HTTP 代表使用http类型的check
  • 调用 consul.Agent().ServiceRegister(reg)注册服务
// 注册服务
func (c *client) ServiceRegister(srvName, srvHost string, srvPort int, healthyCheckPath string, metaMap map[string]string) error {reg := new(consul.AgentServiceRegistration)reg.Name = srvNamethisId := fmt.Sprintf("%s_%d", srvHost, srvPort)reg.ID = thisIdreg.Port = srvPortreg.Address = srvHostreg.Meta = metaMaplog.Printf("ServiceRegisterStart :%v", thisId)//增加checkcheck := new(consul.AgentServiceCheck)check.HTTP = fmt.Sprintf("http://%s:%d%s", reg.Address, reg.Port, healthyCheckPath)//设置超时 5s。check.Timeout = "2s"check.DeregisterCriticalServiceAfter = "5s"//设置间隔 5s。check.Interval = "5s"//注册check服务。reg.Check = checkreturn c.consul.Agent().ServiceRegister(reg)
}

编写获取服务信息的方法

  • 使用consul.Health().Service获取 passing的服务
// Service return a service
func (c *client) GetService(service, tag string) ([]*consul.ServiceEntry, error) {passingOnly := truess, _, err := c.consul.Health().Service(service, tag, passingOnly, nil)if len(ss) == 0 && err == nil {return nil, fmt.Errorf("service ( %s ) was not found", service)}return ss, err
}

编写根据服务id注销服务的方法

// 根据server id注销服务
func (c *client) DeRegister(id string) error {return c.consul.Agent().ServiceDeregister(id)
}

注册node_exporter服务

func main() {c, err := NewConsulClient("http://172.20.70.205:8500")if err != nil {log.Printf("NewConsulClient.err:%v", err)return}nodes := []string{"172.20.70.205","172.20.70.215",}nodeExporterSrv := "node_exporter"for _, h := range nodes {m := map[string]string{"region": "bj", "cloud": "huawei"}err = c.ServiceRegister(nodeExporterSrv, h, 9100, "/", m)if err != nil {log.Printf("[ServiceRegister.err][srv:%v][host:%v][err:%v]", nodeExporterSrv, h, err)} else {log.Printf("[ServiceRegister.success][srv:%v][host:%v]", nodeExporterSrv, h)}}ss, err := c.GetService(nodeExporterSrv, "")for _, s := range ss {log.Printf("[c.GetService][service_id:%v][err:%v]", s.Service.ID, err)//c.DeRegister(s.Service.ID)}}

完整的go代码

package mainimport ("fmt"consul "github.com/hashicorp/consul/api""log"
)type client struct {consul *consul.Client
}func NewConsulClient(addr string) (*client, error) {config := consul.DefaultConfig()config.Address = addrc, err := consul.NewClient(config)if err != nil {return nil, err}return &client{consul: c}, nil
}// 注册服务
func (c *client) ServiceRegister(srvName, srvHost string, srvPort int, healthyCheckPath string, metaMap map[string]string) error {reg := new(consul.AgentServiceRegistration)reg.Name = srvNamethisId := fmt.Sprintf("%s_%d", srvHost, srvPort)reg.ID = thisIdreg.Port = srvPortreg.Address = srvHostreg.Meta = metaMaplog.Printf("ServiceRegisterStart :%v", thisId)//增加checkcheck := new(consul.AgentServiceCheck)check.HTTP = fmt.Sprintf("http://%s:%d%s", reg.Address, reg.Port, healthyCheckPath)//设置超时 5s。check.Timeout = "2s"check.DeregisterCriticalServiceAfter = "5s"//设置间隔 5s。check.Interval = "5s"//注册check服务。reg.Check = checkreturn c.consul.Agent().ServiceRegister(reg)
}// 根据server id注销服务
func (c *client) DeRegister(id string) error {return c.consul.Agent().ServiceDeregister(id)
}// Service return a service
func (c *client) GetService(service, tag string) ([]*consul.ServiceEntry, error) {passingOnly := truess, _, err := c.consul.Health().Service(service, tag, passingOnly, nil)if len(ss) == 0 && err == nil {return nil, fmt.Errorf("service ( %s ) was not found", service)}return ss, err
}func main() {c, err := NewConsulClient("http://172.20.70.205:8500")if err != nil {log.Printf("NewConsulClient.err:%v", err)return}nodes := []string{"172.20.70.205","172.20.70.215",}nodeExporterSrv := "node_exporter"for _, h := range nodes {m := map[string]string{"region": "bj", "cloud": "huawei"}err = c.ServiceRegister(nodeExporterSrv, h, 9100, "/", m)if err != nil {log.Printf("[ServiceRegister.err][srv:%v][host:%v][err:%v]", nodeExporterSrv, h, err)} else {log.Printf("[ServiceRegister.success][srv:%v][host:%v]", nodeExporterSrv, h)}}ss, err := c.GetService(nodeExporterSrv, "")for _, s := range ss {log.Printf("[c.GetService][service_id:%v][err:%v]", s.Service.ID, err)//c.DeRegister(s.Service.ID)}}

注册服务的结果

注册service

image.png

注销服务

配置 node_exporter的job为consul服务发现模式

  • 配置文档
  • 配置文件
  - job_name: 'node_exporter'honor_timestamps: truescrape_interval: 15sscrape_timeout: 10smetrics_path: /metricsscheme: httpconsul_sd_configs:- server: 172.20.70.205:8500services:- node_exporterrelabel_configs:- source_labels:  ["__meta_consul_dc"]target_label: "dc"- separator: ;regex: __meta_consul_service_metadata_(.+)replacement: $1action: labelmap
  • target页面和service discovery 页面观察服务发现结果
  • image.png
  • image.png

本节重点总结 :

  • consul 安装
  • consul go代码注册服务,注销服务,获取服务
  • node_exporter改造为consul服务发现
  • 在数量比较大时,在注册服务的时候,关闭check,可以降低consul的压力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/448165.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软考24.10.15每日一练打卡 - 错题笔记

题目来源&#xff1a;https://ruankaodaren.com/ ##1. M公司将其开发的某软件产品注册商标为S&#xff0c;为确保公司在市场竞争中占据地位&#xff0c;M公司对员工进行了保密约束&#xff0c;此情形下&#xff0c;该公司不享有&#xff08; 商标权&#xff09;。 本题题干中提…

打造卓越APP体验:13款界面设计软件推荐

你知道如何选择正确的UI设计软件吗&#xff1f;你知道设计美观的用户界面&#xff0c;及带来良好用户体验的APP&#xff0c;需要什么界面设计软件吗&#xff1f;基于APP界面的功能不同&#xff0c;选择的APP界面设计软件也会有所不同。然而&#xff0c;并不是要把所有APP界面设…

低代码策略量化平台更新|大模型agents生态的一些思考

原创内容第680篇&#xff0c;专注量化投资、个人成长与财富自由。 用户判断星球会员后&#xff0c;会获得10个积分&#xff1a; 当其他用户发布策略&#xff0c;设置为下载需要积分时&#xff1a; 下载策略会扣除相应的积分&#xff0c;扣除的积分属于策略所有者。 策略运行结…

谈谈我的理解:引用计数 vs 可达性分析

前言 在学习垃圾回收机制时&#xff0c;首先需要了解如何判定哪些对象需要被回收&#xff0c;以及如何实现垃圾回收。本文将分享作者对两种常见的垃圾回收判断机制——引用计数法和可达性分析法——的理解与思考&#xff0c;旨在帮助读者更深入地理解这两种机制。 一、引用计数…

结合seata和2PC,简单聊聊seata源码

当前代码分析基于seata1.6.1 整体描述 整体代码流程可以描述为 TM开启全局事务&#xff0c;会调用TC来获取XID。TC在接收到通知后&#xff0c;会生成XID&#xff0c;然后会将当前全局事务保存到global_table表中&#xff0c;并且返回XID。在获取到XID后&#xff0c;会执行业务…

conda创建的新环境不干净!一定要注意!

总是出现明明是不同的环境&#xff0c;但是总是出现包交叉混用的问题&#xff0c;导致跑很多模型总是出现改了这个环境的包&#xff0c;那个环境又用不了了。就像下面这样&#xff0c;明明激活的是pyskl&#xff0c;安装mediapipe包显示在thwircamera中索引到就显示Requirement…

postgresql 安装

一、下载 PostgreSQL: File Browser 下载地址 PostgreSQL: File Browser 上传到服务器,并解压 二、安装依赖 yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel 创建postgresql 和目录 useradd …

『Mysql集群』Mysql高可用集群之主从复制 (一)

Mysql主从复制模式 主从复制有一主一从、主主复制、一主多从、多主一从等多种模式. 我们可以根据它们的优缺点选择适合自身企业情况的主从复制模式进行搭建 . 一主一从 主主复制 (互为主从模式): 实现Mysql多活部署 一主多从: 提高整个集群的读能力 多主一从: 提高整个集群的…

一、定时器的时钟来源

计数器的时钟选择8个时钟源&#xff0c;可以分成4类: 一、来自RCC的内部时钟TIMx CLK 二、芯片内部其他定时器的触发输入ITR 使用某一个定时器作为另外一个定时器的分频 ITR1、ITR2、ITR3和ITR4 三、外部时钟源模式1&#xff1a; 外部捕获引脚上的边沿信号 TI1FP…

【jeston】torch相关环境安装

参考&#xff1a;玩转NVIDIA Jetson &#xff08;25&#xff09;— jetson 安装pytorch和torchvision 我的jeston信息&#xff1a; torch install 安装环境 conda create -n your_env python3.8 conda activate your_envpytorch_for_jeston 安装.whl文件 验证&#xff1…

循环神经网络(Recurrent Neural Network,RNN)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 一. 核心理念 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类专门用于处理序列数据的神经网络架构。其独特之处在于能够处理输入序列中元素的时序关系&…

STM32定时器

目录 STM32定时器概述 STM32基本定时器 基本定时器的功能 STM32基本定时器的寄存器 STM32通用定时器 STM32定时器HAL库函数 STM32定时器概述 从本质上讲定时器就是“数字电路”课程中学过的计数器&#xff08;Counter&#xff09;&#xff0c;它像“闹钟”一样忠实地为处…

41 C 语言共用体:共用体数据类型、共用体变量、访问共用体成员、与结构体的区别

目录 1 什么是共用体 2 共用体与结构体的区别 3 声明共用体类型 4 声明共用体变量 5 共用体内存分析 6 共用体成员的获取和赋值 7 综合案例 7.1 共同体特点演示 7.2 使用共用体存储学生和教师信息 1 什么是共用体 共用体&#xff08;Union&#xff09;是一种特殊的数据…

大型企业软件开发是什么样子的? - Web Dev Cody

引用自大型企业软件开发是什么样子的&#xff1f; - Web Dev Cody_哔哩哔哩_bilibili 一般来说 学技术的时候 我们会关注 开发语言特性 &#xff0c;各种高级语法糖&#xff0c;底层技术 但是很少有关注到企业里面的开发流程&#xff0c;本着以终为始&#xff08;以就业为导向…

OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在指定的窗口中显示一幅图像。 函数 imshow 在指定的窗口中显示一幅图像。如果窗口是以 cv::WINDOW_AUTOSIZE 标志创建的&#xff0c;图像将以原…

An.如何在an中截取音频片段

如何在an中截取音频片段 在an动画制作过程中&#xff0c;部分片段需要插入音乐&#xff0c;如果想要插入一首歌曲的其中一小节&#xff0c;打开音频编辑软件操作就很麻烦&#xff0c;不妨直接在an中操作&#xff1a; 以这首节气歌为例&#xff0c;前奏太长需要剪掉前面的部分 …

TOGAF 9.2 与 TOGAF 10 的对比分析:架构演进之路

TOGAF 9.2 与 TOGAF 10 的对比分析&#xff1a;架构演进之路 前言 TOGAF&#xff08;The Open Group Architecture Framework&#xff09;自诞生以来&#xff0c;已成为企业架构&#xff08;EA&#xff09;领域的全球标准框架。随着时代的发展&#xff0c;TOGAF也在不断进化&…

基于SpringBoot+Vue+uniapp的在线招聘平台的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

第二课:Python入门学习之开发工具的安装

今天我们进行Python开发工具的安装&#xff0c;其实网上的开发工具是很多的&#xff0c;每个人的习惯也都不一样&#xff0c;我们先去官网下载一个比较常用的吧。废话不多开始操作。 第一步&#xff1a;打开官网地址&#xff1a;https://www.jetbrains.com.cn/ 第二步&#xf…

面试题:Redis(三)

1. 面试题 背景 问题&#xff0c;上面业务逻辑你用java代码如何写&#xff1f; 2. 缓存双写一致性谈谈你的理解&#xff1f; 3. 双检加锁策略 多个线程同时去查询数据库的这条数据&#xff0c;那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。 其他的线程走到这…