[k8s源码]6.reflector
Reflector 和 Informer 是 Kubernetes 客户端库中两个密切相关但职责不同的组件。Reflector 是一个较低级别的组件,主要负责与 Kubernetes API 服务器进行交互,执行资源的初始列表操作和持续的监视操作,将获取到的数据放入队列中。而 Informer 是一个更高级别的抽象,它内部使用了 Reflector,但提供了更全面的功能。Informer 不仅负责数据同步,还维护了资源对象的本地缓存,并提供了事件处理机制,允许开发者注册自定义的事件处理函数。
Informer 实际上通过一个称为 Controller 的内部组件来管理 Reflector。在这个架构中,Reflector 负责从 Kubernetes API 服务器获取数据并将其放入一个 DeltaFIFO queue。Controller 则从这个 queue 中取出数据,更新 Informer 的 LocalStore(这是一个持久化的缓存),并触发相应的事件处理器。这种设计允许 Informer 提供一个高级抽象,隐藏了底层的复杂性。虽然 Informer 不直接调用 Reflector 的方法,但它们通过 Controller 紧密集成。这种架构确保了各个组件职责单一:Reflector 专注于 API 交互,DeltaFIFO 管理变更队列,Controller 协调数据流,而 Informer 则提供高级 API 和缓存管理。这种设计使得开发者可以方便地使用 Informer,而无需直接处理 Reflector 或了解内部 queue 和 store 的细节。
以kubernetes源码中的reflector的一个测试为例:
执行这个test-reflector.go文件,这种test文件可以封装一些测试的代码,更好的帮助我们理解reflector的工作原理。
func TestReflectorListAndWatch(t *testing.T) {createdFakes := make(chan *watch.FakeWatcher)// The ListFunc says that it's at revision 1. Therefore, we expect our WatchFunc// to get called at the beginning of the watch with 1, and again with 3 when we// inject an error.expectedRVs := []string{"1", "3"}lw := &testLW{WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {rv := options.ResourceVersionfw := watch.NewFake()if e, a := expectedRVs[0], rv; e != a {t.Errorf("Expected rv %v, but got %v", e, a)}expectedRVs = expectedRVs[1:]// channel is not buffered because the for loop below needs to block. But// we don't want to block here, so report the new fake via a go routine.go func() { createdFakes <- fw }()return fw, nil},ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {return &v1.PodList{ListMeta: metav1.ListMeta{ResourceVersion: "1"}}, nil},}s := NewFIFO(MetaNamespaceKeyFunc)r := NewReflector(lw, &v1.Pod{}, s, 0)go r.ListAndWatch(wait.NeverStop)ids := []string{"foo", "bar", "baz", "qux", "zoo"}var fw *watch.FakeWatcherfor i, id := range ids {if fw == nil {fw = <-createdFakes}sendingRV := strconv.FormatUint(uint64(i+2), 10)fw.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: id, ResourceVersion: sendingRV}})if sendingRV == "3" {// Inject a failure.fw.Stop()fw = nil}}// Verify we received the right ids with the right resource versions.for i, id := range ids {pod := Pop(s).(*v1.Pod)if e, a := id, pod.Name; e != a {t.Errorf("%v: Expected %v, got %v", i, e, a)}if e, a := strconv.FormatUint(uint64(i+2), 10), pod.ResourceVersion; e != a {t.Errorf("%v: Expected %v, got %v", i, e, a)}}if len(expectedRVs) != 0 {t.Error("called watchStarter an unexpected number of times")}
}
第一部分初始化一个通道createdFakes,初始化一个watcher,有两个方法,为watch和list。watch方法会创建watcher,并传递到createdFakes通道里面。这里的watchFunc是一个闭包:
闭包(Closure)是指一个函数可以捕获并“记住”其作用域外部的变量,即使这个变量在闭包函数的作用域之外。这种特性使得闭包能够访问和操作其外部函数中的变量。捕获外部变量:闭包可以捕获外部函数的局部变量,并且在闭包函数内使用这些变量,即使外部函数已经执行完毕。持久性:闭包会“记住”它捕获的变量,即使外部函数已经返回。状态共享:通过闭包,可以在不同的函数调用之间共享状态。
这里的fw是闭包里面创建的watcher,并不和外面的fw冲突,如果不理解,这里的fw也可以改为别的名字。
fw := watch.NewFake()
go func() { createdFakes <- fw }()
然后初始化reflector
s := NewFIFO(MetaNamespaceKeyFunc)
r := NewReflector(lw, &v1.Pod{}, s, 0)
go r.ListAndWatch(wait.NeverStop)
然后下面是测试部分,首先为fw赋值为watcher,一开始为nil,而在上面r=NewReflector初始化的时候,就已经自动调用了watchFunc,创建了一个watcher。随后这个watcher被拿出来给了fw。sendingRV随机生成一个资源的版本,随着从ids拿出来的值,作为pod的属性用来创建pod,在测试中,fw.Add(...)
模拟了 Kubernetes API 服务器添加新 Pod 的行为。在实际环境中,当新 Pod 被创建时,Watch 操作会接收到这个事件。测试使用 fw.Add(...)
来模拟这个过程,向 FakeWatcher 发送一个新 Pod 被添加的事件。
ids := []string{"foo", "bar", "baz", "qux", "zoo"}
var fw *watch.FakeWatcher
for i, id := range ids {
if fw == nil {
fw = <-createdFakes
}
sendingRV := strconv.FormatUint(uint64(i+2), 10)
fw.Add(&v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: id, ResourceVersion: sendingRV}})
if sendingRV == "3" {
// Inject a failure.
fw.Stop()
fw = nil
}
}
如果sendingRV=3,那么就会将fw停止并设为nil。这模拟了如果resourceVersion错误会发生什么,但是reflector已经设为neverStop,那么此时ListAndWatch会重新调用watchFunc,然后创建新的watcher,放入createdFakes中,从而fw可以重新拿取。
相关文章:
[k8s源码]6.reflector
Reflector 和 Informer 是 Kubernetes 客户端库中两个密切相关但职责不同的组件。Reflector 是一个较低级别的组件,主要负责与 Kubernetes API 服务器进行交互,执行资源的初始列表操作和持续的监视操作,将获取到的数据放入队列中。而 Informe…...
前台文本直接取数据库值doFieldSQL插入SQL
实现功能:根据选择的车间主任带出角色。 实现步骤:OA的“字段联动”功能下拉选项带不出表“hrmrolemembers”,所以采用此方法。 doFieldSQL("select roleid from HrmResource as a inner join hrmrolemembers as b on a.id b.resource…...
【06】LLaMA-Factory微调大模型——微调模型评估
上文【05】LLaMA-Factory微调大模型——初尝微调模型,对LLama-3与Qwen-2进行了指令微调,本文则介绍如何对微调后的模型进行评估分析。 一、部署微调后的LLama-3模型 激活虚拟环境,打开LLaMA-Factory的webui页面 conda activate GLM cd LLa…...
数学建模学习(1)遗传算法
一、简介 遗传算法(Genetic Algorithm, GA)是一种用于解决优化和搜索问题的进化算法。它基于自然选择和遗传学原理,通过模拟生物进化过程来寻找最优解。 以下是遗传算法的主要步骤和概念: 初始化种群(Initialization&a…...
NumPy冷知识66个
NumPy冷知识66个 多维切片: NumPy支持多维切片,可以通过指定多个索引来提取多维数组的子集。 复杂数支持: NumPy可以处理复数,提供了复数的基本运算和函数。 比特运算: NumPy支持比特运算,如与、或、异或等。 数据存储格式: NumPy可以将数…...
Wi-SUN无线通信技术 — 大规模分散式物联网应用首选
引言 在数字化浪潮的推动下,物联网(IoT)正逐渐渗透到我们生活的方方面面。Wi-SUN技术以其卓越的性能和广泛的应用前景,成为了大规模分散式物联网应用的首选。本文将深入探讨Wi-SUN技术的市场现状、核心优势、实际应用中的案例以及…...
在 Ubuntu Server 22.04 上安装 Docker 的详细步骤
在 Ubuntu Server 22.04 上安装 Docker 的详细步骤 本文档详细记录了在 Ubuntu Server 22.04 上安装 Docker 的完整过程,包括解决过程中遇到的问题。希望能对读者有所帮助。 安装过程,重点需要看官方文档。https://docs.docker.com/engine/install/ubu…...
前端使用 Konva 实现可视化设计器(18)- 素材嵌套 - 加载阶段
本章主要实现素材的嵌套(加载阶段)这意味着可以拖入画布的对象,不只是图片素材,还可以是嵌套的图片和图形。 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ github源码 g…...
vue3 -layui项目-左侧导航菜单栏
1.创建目录结构 进入cmd,先cd到项目目录(项目vue3-project) cd vue3-project mkdir -p src\\views\\home\\components\\menubar 2.创建组件文件 3.编辑menu-item-content.vue <template><template v-if"item.icon"><lay-ic…...
Spring AOP(1)
目录 一、AOP 概述 什么是Spring AOP? 二、Spring AOP 快速入门 1、引入AOP依赖 2、编写AOP程序 三、Spring AOP 详解 1、Spring AOP的核心概念 (1)切点(Pointcut) (2)连接点ÿ…...
第1关 -- Linux 基础知识
闯关任务 完成SSH连接与端口映射并运行hello_world.py ssh -p 37367 rootssh.intern-ai.org.cn -CNg -L 7860:127.0.0.1:7860 -o StrictHostKeyCheckingno可选任务 1 将Linux基础命令在开发机上完成一遍 可选任务 2 使用 VSCODE 远程连接开发机并创建一个conda环境 …...
tensorflow keras Model.fit returning: ValueError: Unrecognized data type
题意:TensorFlow Keras 的 Model.fit 方法返回了一个 ValueError,提示数据类型无法识别 问题背景: Im trying to train a keras model with 2 inputs: an image part thats a tf.data.Dataset and a nor mal part represented by a pd.DataF…...
虚拟机固定配置IP
在Hyper-V中,vEthernet (Default Switch) 是Hyper-V自带的默认虚拟交换机,它允许虚拟机直接连接到宿主机网络或外部网络。这个虚拟交换机可以通过Hyper-V管理器或PowerShell等工具进行管理和配置。以下是具体的操作步骤: 一、通过Hyper-V管理…...
【Pytorch实用教程】pytorch中random_split用法的详细介绍
在 PyTorch 中,torch.utils.data.random_split 是一个非常有用的函数,用于将数据集随机分割成多个子集。这在机器学习和深度学习中非常常见,特别是当你需要将数据集分割成训练集和测试集或验证集时。这里是 random_split 的详细用法介绍: 功能 random_split 用于随机地将…...
第二讲:NJ网络配置
Ethernet/IP网络拓扑结构 一. NJ EtherNet/IP 1、网络端口位置 NJ的CPU上面有两个RJ45的网络接口,其中一个是EtherNet/IP网络端口(另一个是EtherCAT的网络端口) 2、网络作用 如图所示,EtherNet/IP网络既可以做控制器与控制器之间的通信,也可以实现与上位机系统的对接通…...
pytorch中常见的模型3种组织方式 nn.Sequential(OrderedDict)
在nn.Sequential中嵌套OrderedDict组织网络,以对层进行命名 import torch import torch.nn as nn from collections import OrderedDictclass OrderedDictCNN(nn.Module):def __init__(self):super(OrderedDictCNN, self).__init__()# 使用 OrderedDict 定义网络层self.model …...
达梦数据库DM8-索引篇
目录 一、前景二、名词三、语法1、命令方式创建索引1.1 创建索引空间1.2.1 创建普通索引并指定索引数据空间1.2.2 另一种没验证,官方写法1.3 复合索引1.4 唯一索引1.5 位图索引1.6 函数索引 2、创建表时候创建索引3、可视化方式创建索引3.1 打开DM管理工具3.2 找到要…...
【中项】系统集成项目管理工程师-第4章 信息系统架构-4.5技术架构
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...
随机梯度下降 (Stochastic Gradient Descent, SGD)
SGD 是梯度下降法的一种变体。与批量梯度下降法不同,SGD 在每次迭代中仅使用一个样本(或一个小批量样本)的梯度来更新参数。它能更快地更新参数,并且可以更容易地跳出局部最优解。 原理 SGD 的基本思想是通过在每次迭代中使用不…...
TDengine 3.3.2.0 发布:新增 UDT 及 Oracle、SQL Server 数据接入
经过数月的开发和完善,TDengine 3.3.2.0 版本终于问世了。这一版本中既有针对开源社区的功能优化,也有从企业级用户需求出发做出的功能调整。在开源版本中,我们增强了系统的灵活性和兼容性;而在企业级版本中,新增了关键…...
Ubuntu 24.04 LTS 无法打开Chrome浏览器
解决办法: 删除本地配置文件,再次点击Chrome图标,即可打开。 rm ~/.config/google-chrome/ -rf ref: Google chrome not opening in Ubuntu 22.04 LTS - Ask Ubuntu...
linux中RocketMQ安装(单机版)及springboot中的使用
文章目录 一、安装1.1、下载RocketMQ1.2、将下载包上传到linux中,然后解压1.3、修改runserver.sh的jvm参数大小(根据自己服务器配置来修改)1.4、启动mqnamesrv (类似于注册中心)1.5、修改runbroker.sh的jvm参数大小&am…...
亚信安全终端一体化解决方案入选应用创新典型案例
近日,由工业和信息化部信息中心主办的2024信息技术应用创新发展大会暨解决方案应用推广大会成功落幕,会上集中发布了一系列技术水平先进、应用效果突出、产业带动性强的信息技术创新工作成果。其中,亚信安全“终端一体化安全运营解决方案”在…...
Django视图与URLs路由详解
在Django Web框架中,视图(Views)和URLs路由(URL routing)是Web应用开发的核心概念。它们共同负责将用户的请求映射到相应的Python函数,并返回适当的响应。本篇博客将深入探讨Django的视图和URLs路由系统&am…...
怎么关闭 Windows 安全中心,手动关闭 Windows Defender 教程
Windows 安全中心(也称为 Windows Defender Security Center)是微软 Windows 操作系统内置的安全管理工具,用于监控和控制病毒防护、防火墙、应用和浏览器保护等安全功能。然而,在某些情况下,用户可能需要关闭 Windows…...
洛谷看不了别人主页怎么办
首先,我们先点进去 可以看到,看不了一点 那我们看向上方,就可以发现,我们那有个URL,选中 把光标插到n和/中间 把.cn删了,变成国际服 我们就可以看了 但是国际服还没搭建完,跳转的时候可能503&a…...
邮件安全篇:企业电子邮件安全涉及哪些方面?
1. 邮件安全概述 企业邮件安全涉及多个方面,旨在保护电子邮件通信的机密性、完整性和可用性,防止数据泄露、欺诈、滥用及其他安全威胁。本文从身份验证与防伪、数据加密、反垃圾邮件和反恶意软件防护、邮件内容过滤与审计、访问控制与权限管理、邮件存储…...
软件测试09 自动化测试技术(Selenium)
重点/难点 重点:理解自动化测试的原理及其流程难点:Selinum自动化测试工具的使用 目录 系统测试 什么是系统测试什么是功能测试什么是性能测试常见的性能指标有哪些 自动化测试概述 测试面临的问题 测试用例数量增多,工作量增大ÿ…...
记录解决springboot项目上传图片到本地,在html里不能回显的问题
项目场景: 项目场景:在我的博客系统里:有个相册模块:需要把图片上传到项目里,在html页面上显示 解决方案 1.建一个文件夹 例如在windows系统下。可以在项目根目录下建个photos文件夹,把上传的图片文件…...
C++ 中 const 关键字
C 中 const 关键字 2009-02-19 2024-07-23 补充C11后的做法 在 C 中,const 是一个关键字(也称为保留字),它用于指定变量或对象的值在初始化后不能被修改。关键字是编程语言中具有特殊含义的词汇,编译器会识别这些词并…...
万网网站备案多久/商丘seo博客
Android 8.0正式版在今年8月22日被推出,如今已经过了近三个月,但是它的装机量如何呢?谷歌近日在安卓开发者信息中心网站公布了安卓各个版本的用户比例,结果令人大吃一惊。 Android各版本用户比例 Android 8.0目前的用户比例…...
对我国政府网站建设和管理的现状/一键优化下载
一、反向代理 正向代理: 客户端要获取的资源就在服务器上,客户端请求的资源路径就是最终响应资源的服务器路径,这就是正向代理。正向代理的特点:就是我们明确知道要访问哪个网站地址。 反向代理: 客户端想获取服务器集…...
wordpress 获取当前位置/无锡百度推广开户
目录 前言 一、ImportBeanDefinitionRegistrar 方式一 方式二 二、EnableDubboConfig与DubboComponentScan 三、DubboConfigConfigurationRegistrar与DubboComponentScanRegistrar 扫描并注册Service Bean 扫描并注册Reference Bean 四、EnableDubbo 五、要点总结 前…...
35互联做的网站/外贸接单平台
一、简单数据类型和复杂数据类型 1.简单类型(基本数据类型、值类型): 在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null 复杂数据类型(引用类…...
英文网站模板cms/网站建设技术
转载自:http://blog.csdn.net/greenerycn/article/details/1458231 先来说一下交错: 交错:Interlace 就是指浏览器下载它的时候隔行下载,这样下载一张图只用一半的时间就可以看到它的样子,只不过只是隔行的图,然后它再下载另一般,这样可以减少你等待看它…...
个人做的网站百度搜索不到/最近新闻有哪些
读取resources资源-class.getResource、ClassLoader.getResource和getResourceAsStream的区别 1.基础说明: javaweb项目部署到服务器中,会将项目打包成jar包或者war包,此时就不会存在src/main/resources 目录了,jvm在编译项目时…...