golang学习笔记19——golang做服务发现与注册的深度剖析

  • 推荐学习文档
    • golang应用级os框架,欢迎star
    • 基于golang开发的一款超有个性的旅游计划app经历
    • golang实战大纲
    • golang优秀开发常用开源库汇总
    • golang学习笔记01——基本数据类型
    • golang学习笔记02——gin框架及基本原理
    • golang学习笔记03——gin框架的核心数据结构
    • golang学习笔记04——如何真正写好Golang代码?
    • golang学习笔记05——golang协程池,怎么实现协程池?
    • golang学习笔记06——怎么实现本地文件及目录监控-fsnotify
    • golang学习笔记07——使用gzip压缩字符减少redis等存储占用的实现
    • golang学习笔记08——如何调用阿里oss sdk实现访问对象存储?
    • golang学习笔记09——golang优秀开发常用开源库汇总
    • golang学习笔记10——golang 的 Gin 框架,快速构建高效 Web 应用
    • golang学习笔记11——Go 语言的并发与同步实现详解
    • golang学习笔记12——Go 语言内存管理详解
    • golang学习笔记13——golang的错误处理深度剖析
    • golang学习笔记14——golang性能问题的处理方法
    • golang学习笔记15——golang依赖管理方法
    • golang学习笔记16——golang部署与运维全攻略
    • golang学习笔记17——golang使用go-kit框架搭建微服务详解
    • golang学习笔记18——golang 访问 mysql 数据库全解析

文章目录

    • 引言
    • 服务发现与注册的基本概念
      • 1.服务发现
      • 2.服务注册
    • 常见问题及解决方案
      • 1.注册中心的高可用性
      • 2.服务实例的健康检查
      • 3.服务发现的实时性
      • 4.服务发现的负载均衡
    • 总结

引言

在微服务架构中,服务发现与注册是核心组件之一。它确保各个微服务能够相互找到并进行通信。在 Go 语言开发中,虽然有多种工具和库可用于服务发现与注册,但仍会遇到一些问题。本文将详细探讨这些问题并给出相应的解决方案,同时配合代码示例进行说明。

服务发现与注册的基本概念

1.服务发现

服务发现是指在一个分布式系统中,服务消费者能够自动地找到服务提供者的网络位置(如 IP 地址和端口号)的过程。

2.服务注册

服务注册是指服务提供者在启动时,将自身的服务信息(如服务名称、IP 地址、端口号等)注册到一个中心化的服务注册中心或者分布式的注册网络中。

常见问题及解决方案

1.注册中心的高可用性

注册中心本身可能成为单点故障。如果注册中心出现故障,新的服务实例无法注册,已有的服务实例也无法被发现,这将导致整个微服务架构陷入混乱。

  • 解决方案
    • 使用高可用的注册中心集群。例如,Consul 支持多数据中心的部署,可以在不同的数据中心部署多个 Consul 节点,通过数据同步来保证服务注册信息的一致性和高可用性。
  • 代码示例(以 Consul 为例):
package mainimport ("log"consulapi "github.com/hashicorp/consul/api"
)func main() {// 创建 Consul 客户端config := consulapi.DefaultConfig()client, err := consulapi.NewClient(config)if err!= nil {log.Fatal("创建 Consul 客户端失败: ", err)}// 注册服务registration := new(consulapi.AgentServiceRegistration)registration.ID = "my-service-1"registration.Name = "my-service"registration.Address = "127.0.0.1"registration.Port = 8080err = client.Agent().ServiceRegister(registration)if err!= nil {log.Fatal("服务注册失败: ", err)}log.Println("服务注册成功")
}

2.服务实例的健康检查

注册中心可能仍然保留着已经故障或者不健康的服务实例的注册信息,这会导致服务消费者调用到不可用的服务实例。

  • 解决方案
    • 配置服务注册中心的健康检查机制。服务提供者在注册服务时,同时注册健康检查的接口或者脚本。注册中心定期调用这些健康检查接口来判断服务实例是否健康。
  • 继续以 Consul 为例的代码示例:
registration.Check = &consulapi.AgentServiceCheck{HTTP:     "http://127.0.0.1:8080/health",Interval: "10s",
}

3.服务发现的实时性

服务注册信息的更新可能存在延迟,导致服务消费者不能及时发现新的服务实例或者已下线的服务实例的变化。

  • 解决方案
    • 优化注册中心的内部数据同步机制,尽量减少数据同步的延迟。
      服务消费者可以采用主动拉取和被动通知相结合的方式。例如,定期主动从注册中心拉取服务实例列表,同时注册中心在服务实例状态发生变化时,主动通知服务消费者。
  • 以下是一个简单的服务消费者示例,使用 Go 语言的 channel 来模拟被动通知:
package mainimport ("fmt""time"
)func serviceConsumer(serviceList chan []string) {for {services := <-serviceListfmt.Println("当前可用服务列表: ", services)// 进行服务调用等操作time.Sleep(5 * time.Second)}
}func main() {serviceList := make(chan []string)go serviceConsumer(serviceList)// 模拟注册中心通知服务实例变化for i := 0; i < 5; i++ {serviceList <- []string{"service1", "service2"}time.Sleep(10 * time.Second)}
}

4.服务发现的负载均衡

即使服务发现机制能够正确地找到所有可用的服务实例,但如果没有合理的负载均衡策略,可能会导致某些服务实例负载过重,而其他服务实例负载过轻。

  • 解决方案
    • 实现多种负载均衡算法,如轮询、随机、加权轮询、一致性哈希等。根据服务的特性和实际需求选择合适的负载均衡算法。
  • 以下是一个简单的加权轮询负载均衡示例:
package mainimport ("fmt""math/rand""time"
)type ServiceInstance struct {name    stringweight  intcurrent int
}func weightedRoundRobin(instances []ServiceInstance) string {totalWeight := 0for _, instance := range instances {totalWeight += instance.weight}rand.Seed(time.Now().UnixNano())randomValue := rand.Intn(totalWeight)for _, instance := range instances {if randomValue < instance.current+instance.weight {instance.current += totalWeightreturn instance.name}instance.current += instance.weight}return ""
}func main() {instances := []ServiceInstance{{name: "service1", weight: 3},{name: "service2", weight: 2},{name: "service3", weight: 1},}for i := 0; i < 10; i++ {selected := weightedRoundRobin(instances)fmt.Println("选择的服务实例: ", selected)}
}

总结

在 Go 语言的微服务开发中,服务发现与注册是至关重要的环节。通过解决注册中心的高可用性、服务实例的健康检查、服务发现的实时性以及负载均衡等问题,可以构建更加稳定、高效的微服务架构。

关注我看更多有意思的文章哦!👉👉

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

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

相关文章

[linux 驱动]内核定时器详解与实战

目录 1 描述 2 结构体 2.1 timer_list 3 相关函数 3.1 DEFINE_TIMER 3.2 add_timer 3.3 del_timer 3.4 msecs_to_jiffies 3.5 usecs_to_jiffies 5 示例 4 延迟工作队列delayed_work 4.1 结构体 4.1.1 delayed_work 4.2 相关函数 4.2.1 DECLARE_DELAYED_WORK 4.2…

Grafana面板-linux主机详情(使用标签过滤主机监控)

1. 采集器添加labels标签区分业务项目 targets添加labels &#xff08;模板中使用的project标签&#xff09; … targets: [‘xxxx:9100’] labels: project: app2targets: [‘xxxx:9100’] labels: project: app1 … 2. grafana面板套用 21902 模板 演示

Python 错误 ValueError 解析,实际错误实例详解 (一)

文章目录 前言Python 中错误 ValueError: No JSON object Could Be Decoded在 Python 中解码 JSON 对象将 JSON 字符串解码为 Python 对象将 Python 对象编码为 JSON 字符串Python 中错误 ValueError: Unsupported Pickle Protocol: 3Python 中的 Pickling 和 UnpicklingPython…

微信小程序原生支持TS、LESS、SASS能力探究

文章目录 原生支持开始使用旧项目新建项目TS声明文件更新 功能说明less 使用全局变量sass 使用全局变量 可以参考原文 在之前开发小程序中&#xff0c;无法使用 less/sass 等 css 预编译语言&#xff0c;也无法使用 TS 进行开发&#xff0c;但在最新的编辑器版本中&#xff0c…

Vue3:el-table实现日期的格式化

后端如果返回的是时间戳&#xff0c;需要我们进行日期格式化 例如&#xff1a;2024-09-11T14:19:14 定义一个日期解析的工具组件 export function formatDateAsYYYYMMDDHHMMSS(dateStr: any) {const date new Date(dateStr);const year date.getFullYear();const month S…

Android 12 SystemUI下拉状态栏禁止QuickQSPanel展开

1.概述 遇到需求&#xff0c;QuickQSPanel首次下拉后展示快捷功能模块以后就是显示QuickQSPanel&#xff0c;而不展开QSPanel&#xff0c;接下来要从下滑手势下拉出状态栏分析功能实现。也就是直接是展开状态。 2、涉及核心类 frameworks\base\packages\SystemUI\src\com\and…

高级实时通信:基于 Python 的 WebSocket 实现与异步推送解决方案

高级实时通信&#xff1a;基于 Python 的 WebSocket 实现与异步推送解决方案 目录 &#x1f7e2; WebSocket 协议概述&#x1f535; 在 FastAPI 中实现 WebSocket&#x1f7e3; Django Channels 实现异步实时通信&#x1f534; 使用 Redis 实现实时推送 &#x1f7e2; 1. WebS…

关于 Camera Tuning 岗位的一些认识和看法

前言&#xff1a; 之前也写过几篇关于Camera Tuning岗位的相关介绍&#xff1a; IQ Tuning 学习路线 关于入职 ISP Tuning 岗位的几个问题及解答 随着工作时间越长&#xff0c;对这个岗位的认识较之前也有了一些更深刻的理解&#xff0c;这里整理总结一下。 一方面是当做现阶…

PHP一键约课高效健身智能健身管理系统小程序源码

一键约课&#xff0c;高效健身 —— 智能健身管理系统让健康触手可及 &#x1f3cb;️‍♀️ 告别繁琐&#xff0c;一键开启健身之旅 你还在为每次去健身房前的繁琐预约流程而烦恼吗&#xff1f;现在有了“一键约课高效健身智能健身管理系统”&#xff0c;所有问题都迎刃而解…

智能体-AI-Agent-简介

文章目录 一&#xff0c;什么是AI Agent二&#xff0c;扣子个人空间团队空间探索区 一&#xff0c;什么是AI Agent AI智能体并没有什么特别&#xff0c;本质上就是一个帮助你解决工作和学习中的一个工具。 很多自媒体把智能体描述的天花乱坠&#xff0c;那不过是他们畅想的智…

Spring Security认证与授权

1 Spring Security介绍 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统中的一员&#xff0c;因此它伴随着整个Spring生态系统不断修正、升级&#xff0c;在spring boot项目中加入springsecurity更是…

Vue的学习(三)

目录 一、for循环中key的作用 1‌.提高性能‌&#xff1a; ‌2.优化用户体验‌&#xff1a; ‌3.辅助Vue进行列表渲染‌&#xff1a; 4‌.方便可复用组件的使用‌&#xff1a; 二、methods及computed及wacth的区别 三、过滤器 1.Vue 2 过滤器简介 定义过滤器 使用过滤…

用 Swift 写 Android App ?来了解下 Skip 原生级跨平台框架

最近在找资料的时候&#xff0c;机缘巧合发现了一个有趣的商业跨平台框架 Skip &#xff0c;刚好看到了它发布 1.0 正式版&#xff0c;主要作用是将 Swift 开发引入到 Android 领域&#xff0c;这样 App 就可以共享 Swift 的业务逻辑&#xff0c;在 SwiftUI 中完成 Android App…

C#基础(8)函数

前言 我们先前已经具备了一些自己写小程序的能力&#xff0c;但是依旧还是逃不过大量的代码&#xff0c;那么今天&#xff0c;我们就将学习一个减少我们重复工作量的东西&#xff1a;函数。 在数学中我们知道&#xff0c;函数就是一个固定的公式&#xff0c;会画固定的图。 …

Python | Leetcode Python题解之第395题至少有K个重复字符的最长子串

题目&#xff1a; 题解&#xff1a; class Solution:def longestSubstring(self, s1: str, k: int) -> int:if k 1: return len(s1)n len(s1)res 0for c in range(1, len(set(s1)) 1):# 滑窗中字母种类个数恰好为 cfreq Counter()l cnt tcnt 0 for r, ch in enu…

代码随想录训练营Day3 | 链表理论基础 | 203.移除链表元素 | 707.设计链表 | 206.反转链表

今天任务&#xff1a;学习链表理论基础 链表的类型 链表的存储方式 链表的定义…

开发一款通过蓝牙连接控制水电表的微信小程序

增强软硬件交互 为了更好的解决师生生活中的实际问题&#xff0c;开发蓝牙小程序加强了和校区硬件的交互。 比如通过蓝牙连接控制水电表&#xff0c;减少实体卡片的使用。添加人脸活体检测功能&#xff0c;提高本人认证效率&#xff0c;减少师生等待时间。 蓝牙水电控展示 蓝…

计算机科学基础 -- 超流水线

超流水线的概念 超流水线是一种进一步提高处理器性能的技术&#xff0c;它在传统流水线的基础上&#xff0c;将多个流水线组合在一起&#xff0c;能够在同一个时钟周期内同时执行多条指令。这种设计允许处理器的多个功能单元并行处理不同的指令&#xff0c;从而提高指令级并行…

HashMap常用方法及底层原理

目录 一、什么是HashMap二、HashMap的链表与红黑树1、数据结构2、链表转为红黑树3、红黑树退化为链表 三、存储&#xff08;put&#xff09;操作四、读取&#xff08;get&#xff09;操作五、扩容&#xff08;resize&#xff09;操作六、HashMap的线程安全与顺序1、线程安全2、…

【LeetCode每日一题】2024年9月第二周(上)

2024.9.9 中等 难度评分 1333 链接&#xff1a;2181. 合并零之间的节点 &#xff08;1&#xff09;题目描述&#xff1a; &#xff08;2&#xff09;示例 &#xff08;3&#xff09;分析 整体来说&#xff0c;描述还算清晰的题目&#xff0c;找到0节点所框定的区域&#xff0c…