Docker安装consul + go使用consul + consul知识
1. 什么是服务注册和发现
假如这个产品已经在线上运行,有一天运营想搞一场促销活动,那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时,作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这三个微服务实例的 ip 与port ,一个真正在线的微服务系统可能有成百上千微服务,难道也要一个一个去手动添加吗?有没有让系统自动去实现这些操作的方法呢?答案当然是有的。
当我们新添加一个微服务实例的时候,微服务就会将自己的 ip 与 port 发送到注册中心,在注册中心里面记录起来。当 API gateway 需要访问某些微服务的时候,就会去注册中心取到相应的 ip 与 port。从而实现自动化操作。
1. 技术选型
Consul 与其他常见服务发现框架对比
| 名称 | 优点 | 缺点 | 接口 | 一致性算法 |
|---|---|---|---|---|
| zookeeper | 1.功能强大,不仅仅只是服务发现 2.提供 watcher 机制能实时获取服务提供者的状态 3.dubbo 等框架支持 | 1.没有健康检查 2.需在服务中集成 sdk,复杂度高 3.不支持多数据中心 | sdk | Paxos |
| consul | 1.简单易用,不需要集成 sdk 2.自带健康检查 3.支持多数据中心 4.提供 web 管理界面 | 1.不能实时获取服务信息的变化通知 | http/dns | Raft |
| etcd | 1.简单易用,不需要集成 sdk 2.可配置性强 | 1.没有健康检查 2.需配合第三方工具一起完成服务发现 3.不支持多数据中心 | http | Raft |
2.consul的安装和配置
2.1. 安装
docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client=0.0.0.0docker container update --restart=always 容器名字
2.2. 访问
浏览器访问 127.0.0.1:8500
2.3. 访问dns
consul提供dns功能,可以让我们通过, 可以通过dig命令行来测试,consul默认的dns端口是8600, 命令行:
linux下的dig命令安装:
yum install bind-utils
dig @192.168.1.103 -p 8600 consul.service.consul SRV
windows下载dig命令 : BIND9.17.2.x64.zip
3.consul的api接口
3.1. 添加服务
https://www.consul.io/api-docs/agent/service#register-service
3.2. 删除服务
https://www.consul.io/api-docs/agent/service#deregister-service
3.3. 设置健康检查
https://www.consul.io/api-docs/agent/check
3.4. 同一个服务注册多个实例
3.5. 获取服务
https://www.consul.io/api-docs/agent/service#list-services
4.go操作consul
package main
import ("fmt""github.com/hashicorp/consul/api")
func Register(address string, port int, name string, tags []string, id string) error {cfg := api.DefaultConfig()cfg.Address = "192.168.1.103:8500"client, err := api.NewClient(cfg)if err != nil {panic(err)}//生成对应的检查对象check := &api.AgentServiceCheck{HTTP: "http://192.168.1.102:8021/health",Timeout: "5s",Interval: "5s",DeregisterCriticalServiceAfter: "10s",}//生成注册对象registration := new(api.AgentServiceRegistration)registration.Name = nameregistration.ID = idregistration.Port = portregistration.Tags = tagsregistration.Address = addressregistration.Check = checkerr = client.Agent().ServiceRegister(registration)if err != nil {panic(err)}return nil
}
func AllServices(){cfg := api.DefaultConfig()cfg.Address = "192.168.1.103:8500"client, err := api.NewClient(cfg)if err != nil {panic(err)}data, err := client.Agent().Services()if err != nil {panic(err)}for key, _ := range data{fmt.Println(key)}
}
func FilterSerivice(){cfg := api.DefaultConfig()cfg.Address = "192.168.1.103:8500"client, err := api.NewClient(cfg)if err != nil {panic(err)}data, err := client.Agent().ServicesWithFilter(`Service == "user-web"`)if err != nil {panic(err)}for key, _ := range data{fmt.Println(key)}
}
func main(){//_ = Register("192.168.1.102", 8021, "user-web", []string{"mxshop", "bobby"}, "user-web")//AllServices()FilterSerivice()
}
5.grpc下的健康检查
5.1. grpc的健康检查规范
官方文档
grpc健康检查重要点:
-
check = { “GRPC”: "ip:port", “GRPCUseTLS”: False, “Timeout”: “5s”, “Interval”: “5s”, “DeregisterCriticalServiceAfter”: “5s”, } -
一定要确保网络是通的
- 一定要确保srv服务监听端口是对外可访问的(公网ip地址不是本地的127.0.0.1)
- GRPC一定要自己填写
5.2. go配置grpc的健康检查
//注册服务健康状态检查
grpc_health_v1.RegisterHealthServer(g, health.NewServer())
6.动态获取可用端口号
package utils
import ("net"
)
func GetFreePort() (int, error) {addr, err := net.ResolveTCPAddr("tcp", "localhost:0")if err != nil {return 0, err}l, err := net.ListenTCP("tcp", addr)if err != nil {return 0, err}defer l.Close()return l.Addr().(*net.TCPAddr).Port, nil
}
7.负载均衡策略
1. 什么是负载均衡

2. 负载均衡策略
1. 集中式load balance
集中式LB方案,如下图。首先,服务的消费方和提供方不直接耦合,而是在服务消费者和服务提供者之间有一个独立的LB(LB通常是专门的硬件设备如F5,或者基于软件如LVS,HAproxy等实现)。

LB上有所有服务的地址映射表,通常由运维配置注册,当服务消费方调用某个目标服务时,它向LB发起请求,由LB以某种策略(比如Round-Robin)做负载均衡后将请求转发到目标服务。
LB一般具备健康检查能力,能自动摘除不健康的服务实例。
服务消费方如何发现LB呢?通常的做法是通过DNS,运维人员为服务配置一个DNS域名,这个域名指向LB。
这种方案基本可以否决,因为它有致命的缺点:所有服务调用流量都经过load balance服务器,所以load balance服务器成了系统的单点,一旦LB发生故障对整个系统的影响是灾难性的。为了解决这个问题,必然需要对这个load balance部件做分布式处理(部署多个实例,冗余,然后解决一致性问题等全家桶解决方案),但这样做会徒增非常多的复杂度。
2. 进程内load balance
进程内load balance。将load balance的功能和算法以sdk的方式实现在客户端进程内。先看架构图:

可看到引入了第三方:服务注册中心。它做两件事:
- 维护服务提供方的节点列表,并检测这些节点的健康度。检测的方式是:每个节点部署成功,都通知服务注册中心;然后一直和注册中心保持心跳。
- 允许服务调用方注册感兴趣的事件,把服务提供方的变化情况推送到服务调用方。
这种方案下,整个load balance的过程是这样的:
- 服务注册中心维护所有节点的情况。
- 任何一个节点想要订阅其他服务提供方的节点列表,向服务注册中心注册。
- 服务注册中心将服务提供方的列表(以长连接的方式)推送到消费方。
- 消费方接收到消息后,在本地维护一份这个列表,并自己做load balance。
可见,服务注册中心充当什么角色?它是唯一一个知道整个集群内部所有的节点情况的中心。所以对它的可用性要求会非常高,这个组件可以用Zookeeper实现。
这种方案的缺点是:每个语言都要研究一套sdk,如果公司内的服务使用的语言五花八门的话,这方案的成本会很高。第二点是:后续如果要对客户库进行升级,势必要求服务调用方修改代码并重新发布,所以该方案的升级推广有不小的阻力。
3. 独立进程load balance
该方案是针对第二种方案的不足而提出的一种折中方案,原理和第二种方案基本类似,不同之处是,他将LB和服务发现功能从进程内移出来,变成主机上的一个独立进程,主机上的一个或者多个服务要访问目标服务时,他们都通过同一主机上的独立LB进程做服务发现和负载均衡。如图

这个方案解决了上一种方案的问题,不需要为不同语言开发客户库,LB的升级不需要服务调用方改代码。
但新引入的问题是:这个组件本身的可用性谁来维护?还要再写一个watchdog去监控这个组件?另外,多了一个环节,就多了一个出错的可能,线上出问题了,也多了一个需要排查的环节。
8.常见的负载均衡算法
在分布式系统中,多台服务器同时提供一个服务,并统一到服务配置中心进行管理,消费者通过查询服务配置中心,获取到服务到地址列表,需要选取其中一台来发起RPC远程调用。如何选择,则取决于具体的负载均衡算法,对应于不同的场景,选择的负载均衡算法也不尽相同。负载均衡算法的种类有很多种,常见的负载均衡算法包括轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接法等,应根据具体的使用场景选取对应的算法。
1. 轮询(Round Robin)法
轮询很容易实现,将请求按顺序轮流分配到后台服务器上,均衡的对待每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
2. 随机法
通过系统随机函数,根据后台服务器列表的大小值来随机选取其中一台进行访问。由概率概率统计理论可以得知,随着调用量的增大,其实际效果越来越接近于平均分配流量到后台的每一台服务器,也就是轮询法的效果。
3. 源地址哈希法
源地址哈希法的思想是根据服务消费者请求客户端的IP地址,通过哈希函数计算得到一个哈希值,将此哈希值和服务器列表的大小进行取模运算,得到的结果便是要访问的服务器地址的序号。采用源地址哈希法进行负载均衡,相同的IP客户端,如果服务器列表不变,将映射到同一个后台服务器进行访问。
4. 加权轮询(Weight Round Robin)法
不同的后台服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不一样。跟配置高、负载低的机器分配更高的权重,使其能处理更多的请求,而配置低、负载高的机器,则给其分配较低的权重,降低其系统负载,加权轮询很好的处理了这一问题,并将请求按照顺序且根据权重分配给后端。
5. 加权随机(Weight Random)法
加权随机法跟加权轮询法类似,根据后台服务器不同的配置和负载情况,配置不同的权重。不同的是,它是按照权重来随机选取服务器的,而非顺序。
6. 最小连接数法
前面我们费尽心思来实现服务消费者请求次数分配的均衡,我们知道这样做是没错的,可以为后端的多台服务器平均分配工作量,最大程度地提高服务器的利用率,但是,实际上,请求次数的均衡并不代表负载的均衡。因此我们需要介绍最小连接数法,最小连接数法比较灵活和智能,由于后台服务器的配置不尽相同,对请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器。
9.grpc的负载均衡策略
9.1. grpc的负载均衡策略
文档
9.2. go使用grpc负载均衡
grpc-consul-resolver地址
9.3. 关于serverconfig
官方文档
9.4. go的grpc测试
package main
import ("OldPackageTest/grpclb_test/proto""context""fmt""log"_ "github.com/mbobakov/grpc-consul-resolver" // It's important"google.golang.org/grpc"
)
func main() {conn, err := grpc.Dial("consul://192.168.1.103:8500/user-srv?wait=14s&tag=srv",grpc.WithInsecure(),grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),)if err != nil {log.Fatal(err)}defer conn.Close()for i := 0; i<10; i++{userSrvClient := proto.NewUserClient(conn)rsp, err := userSrvClient.GetUserList(context.Background(), &proto.PageInfo{Pn: 1,PSize: 2,})if err != nil {panic(err)}for index, data := range rsp.Data{fmt.Println(index, data)}}
}
相关文章:
Docker安装consul + go使用consul + consul知识
1. 什么是服务注册和发现 假如这个产品已经在线上运行,有一天运营想搞一场促销活动,那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时,作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这…...
JWT 漏洞 - 学习手册
0x01:JWT 前导知识 0x0101:JWT 详解 0x02:JWT 漏洞介绍 0x0201:JWT 漏洞介绍 0x03:JWT 挖掘思路 JWT 漏洞挖掘思路 - JWT Payload 敏感信息泄露 备注:通过泄露的 JWT Payload 获取用户的敏感信息&#…...
HTML【知识改变命运】03font 字体标签
题目:在页面上显示"北京"两个字,字体为微软雅黑,颜色为红色,大小为40xp; font标签可以修饰字体的大小,颜色,和字体 属性:color颜色,face字体,size大…...
集师专属知识付费小程序搭建 心理咨询小程序搭建
一、产品简介 集师SaaS知识付费软件,为知识创业者或商家提供一站式内容交付解决方案,助力商家搭建集品牌传播、商业变现和用户运营于一体的线上知识服务系统,覆盖全渠道经营场景,占据每个流量入口,使流量变现快速高效…...
https://www.aitoolpath.com/ 一个工具数据库,目前储存了有2000+各种工具。每日更新
AI 工具爆炸?别怕,这个网站帮你整理好了! 哇塞,兄弟们!AI 时代真的来了!现在各种 AI 工具跟雨后春笋似的,噌噌噌地往外冒。AI 写作、AI 绘画、AI 代码生成……简直是要逆天啊! 可是…...
科技的成就(六十三)
583、八小时工作制 最先提出这种理念的人竟然也是一名企业家,而且还是一名空想社会主义者。这名叫做罗伯特欧文的英国人,也凭借先进的人本管理理念成为了现代人事管理之父。 584、SDN(软件定义网络) "SDN(软件定…...
浅谈抗量子密码学:保护未来的数字安全
一、引言 随着量子计算机技术的发展,传统的加密算法面临前所未有的挑战。量子计算机利用量子位(qubits)的特性,能够在理论上比经典计算机更快地破解现有的加密系统。为了应对这一威胁,研究者们正在开发所谓的“抗量子…...
10款物联网开源嵌入式操作系统对比分析
摘要 本文对目前市场上广受欢迎的10款物联网开源嵌入式操作系统进行了深度对比分析,包括Huawei LiteOS、RT-Thread、AliOS Things等。通过探讨这些操作系统的实时性、可扩展性、特点、运行要求、开发社区活跃度和应用领域等方面,帮助开发者更好地理解它…...
Elasticsearch深度攻略:核心概念与实践应用
目录 一、Elasticsearch简介1、Elasticsearch是什么2、Elasticsearch的应用场景3、Elasticsearch的核心概念 二、Elasticsearch安装与配置1、安装Elasticsearch(1)系统要求(2)下载Elasticsearch(3)解压安装…...
TLS详解
什么是TLS TLS(Transport Layer Security)传输层安全性协议 ,它的前身是SSL(Secure Sockets Layer)安全套接层,是一个被应用程序用来在网络中安全的通讯协议, 防止电子邮件、网页、消息以及其他协议被篡改或是窃听。是用来替代SSL的…...
正则表达式中的特殊字符
正则表达式中的特殊字符 字符类预定义字符类量词锚点分组和捕获选择、分支和条件反义和否定转义字符示例 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 在正则表达式中,有许…...
EP42 公告详情页
文件路径: E:/homework/uniappv3tswallpaper/api/apis.js 先添加相应的api。 import {request } from "/utils/requset.js"export function apiGetBanner() {return request({url: "/homeBanner"}) } export function apiGetDayRandom() {ret…...
游戏找不到xinput1_3.dll的原因及解决方法
1. xinput1_3.dll 基本信息 1.1 文件名 xinput1_3.dll 是一个动态链接库(DLL)文件,它属于 Microsoft DirectX for Windows 的一部分。这个文件主要负责处理与 Xbox 360 控制器和其他兼容 XInput 标准的游戏手柄相关的输入信号,确…...
防反接电路设计
方案1 串联二极管, 优点:成本低、设计简单 缺点:损耗大,P ui 方案2 串联自恢复保险丝 当电源反接的时候,D4导通,F2超过跳闸带你留,就会断开,从而保护了后级电路 方案3 H桥电路…...
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
SpringMVC九大内置组件之HandlerMapping处理器映射器-AbstractHandlerMethodMapping类以及子类RequestMappingHandlerMapping如何将Controller修饰的注解类以及类下被注解RequestMapping修饰的方法存储到处理器映射器中。 从RequestMappingHandlerMapping寻找: AbstractHandle…...
毕业设计选题:基于ssm+vue+uniapp的购物系统小程序
开发语言:Java框架:ssmuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:M…...
【动态规划-最长公共子序列(LCS)】力扣583. 两个字符串的删除操作
给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1: 输入: word1 “sea”, word2 “eat” 输出: 2 解释: 第一步将 “sea” 变为 “ea” ,第二步将 "e…...
【分布式微服务云原生】8分钟探索RPC:远程过程调用的奥秘与技术实现
摘要 在分布式系统中,RPC(Remote Procedure Call,远程过程调用)技术是连接各个组件的桥梁。本文将深入探讨RPC的概念、技术实现原理、以及请求处理的详细过程。通过清晰的结构、流程图、代码片段和图表,我们将一起揭开…...
Linux操作系统中Redis
1、什么是Redis Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 可以理解成一个大容量的map。…...
每日论文5—06TCAS2锁相环电流匹配的gain-boosting电荷泵
《Gain-Boosting Charge Pump for Current Matching in Phase-Locked Loop》 06TCAS2 本质上和cascode来增加输出电阻,从而减小电流变化的思路是一样的。这里用了放大器来增加输出电阻。具体做法如下图: 如图1(a),A3把Vb和Vx拉平࿰…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
