Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >client-go 源码分析(2) - discovery模块:discovery cache

client-go 源码分析(2) - discovery模块:discovery cache

作者头像
后端云
发布于 2023-02-10 06:12:50
发布于 2023-02-10 06:12:50
41500
代码可运行
举报
文章被收录于专栏:后端云后端云
运行总次数:0
代码可运行

DiscoveryClient可以将资源相关信息存储于本地,默认存储位置为~/.kube/cache和~/.kube/http-cache。缓存可以减轻client-go对KubernetesAPI Server的访问压力。默认每10分钟与Kubernetes API Server同步一次,同步周期较长,因为资源组、源版本、资源信息一般很少变动。DiscoveryClient第一次获取资源组、资源版本、资源信息时,首先会查询本地缓存,如果数据不存在(没有命中)则请求Kubernetes API Server接口(回源),Cache将Kubernetes API Server响应的数据存储在本地一份并返回给DiscoveryClient。当下一次DiscoveryClient再次获取资源信息时,会将数据直接从本地缓存返回(命中)给DiscoveryClient。本地缓存的默认存储周期为10分钟(对应CachedDiscoveryClient 结构体的ttl属性,超时时间)。代码示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type CachedDiscoveryClient struct {
	delegate discovery.DiscoveryInterface

	// cacheDirectory is the directory where discovery docs are held.  It must be unique per host:port combination to work well.
	cacheDirectory string

	// ttl is how long the cache should be considered valid
	ttl time.Duration

	// mutex protects the variables below
	mutex sync.Mutex

	// ourFiles are all filenames of cache files created by this process
	ourFiles map[string]struct{}
	// invalidated is true if all cache files should be ignored that are not ours (e.g. after Invalidate() was called)
	invalidated bool
	// fresh is true if all used cache files were ours
	fresh bool

	// caching openapi v3 client which wraps the delegate's client
	openapiClient openapi.Client
}

var _ discovery.CachedDiscoveryInterface = &CachedDiscoveryClient{}

// ServerResourcesForGroupVersion returns the supported resources for a group and version.
func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
	filename := filepath.Join(d.cacheDirectory, groupVersion, "serverresources.json")
	cachedBytes, err := d.getCachedFile(filename)
	// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
	if err == nil {
		cachedResources := &metav1.APIResourceList{}
		if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
			klog.V(10).Infof("returning cached discovery info from %v", filename)
			return cachedResources, nil
		}
	}

	liveResources, err := d.delegate.ServerResourcesForGroupVersion(groupVersion)
	if err != nil {
		klog.V(3).Infof("skipped caching discovery info due to %v", err)
		return liveResources, err
	}
	if liveResources == nil || len(liveResources.APIResources) == 0 {
		klog.V(3).Infof("skipped caching discovery info, no resources found")
		return liveResources, err
	}

	if err := d.writeCachedFile(filename, liveResources); err != nil {
		klog.V(1).Infof("failed to write cache to %v due to %v", filename, err)
	}

	return liveResources, nil
}

结构体CachedDiscoveryClient的方法ServerResourcesForGroupVersion,首先读取放在 filepath.Join(d.cacheDirectory, groupVersion, “serverresources.json”) 路径下的缓存。

尝试调用k8s.io/apimachinery/pkg/runtime/DecodeInto 对文件读取的内容解码到结构体metav1.APIResourceList中。若解码成功,返回结构体metav1.APIResourceList内容;若解码不成功,继续下面的语句,即d.delegate.ServerResourcesForGroupVersion(groupVersion),这里特别的地方是,结构体属性delegate,中文意思是委托,因为使用接口DiscoveryInterface的CachedDiscoveryClient中的ServerResourcesForGroupVersion去读取缓存失败了,需要去kubernetes API实时去取数据了,这件事就委托这个接口DiscoveryInterface去实现多态中的DiscoveryClient中的ServerResourcesForGroupVersion方法去实现。该方法的代码分析参考 client-go 源码分析(1) - discovery模块:discoveryclient获取所有的gv和gvr

用下面的构造方法构造CachedDiscoveryClient结构体的时候,将属性delegate赋值给实现了接口的discovery.DiscoveryInterface的DiscoveryClient结构体即可实现上面的多态或者形象说是委托行为。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func newCachedDiscoveryClient(delegate discovery.DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient {
	return &CachedDiscoveryClient{
		delegate:       delegate,
		cacheDirectory: cacheDirectory,
		ttl:            ttl,
		ourFiles:       map[string]struct{}{},
		fresh:          true,
	}
}

上面的 func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) 方法还有个重要的地方,就是读取缓存失败,去实时调用Kubernetes API获取信息后,还要写入缓存中 d.writeCachedFile,这样下次再获取gvr信息时候,读取缓存这一步就能读取到信息,不用调用Kubernetes API接口了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
	if err := os.MkdirAll(filepath.Dir(filename), 0750); err != nil {
		return err
	}

	bytes, err := runtime.Encode(scheme.Codecs.LegacyCodec(), obj)
	if err != nil {
		return err
	}

	f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)+".")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	_, err = f.Write(bytes)
	if err != nil {
		return err
	}

	err = os.Chmod(f.Name(), 0660)
	if err != nil {
		return err
	}

	name := f.Name()
	err = f.Close()
	if err != nil {
		return err
	}

	// atomic rename
	d.mutex.Lock()
	defer d.mutex.Unlock()
	err = os.Rename(name, filename)
	if err == nil {
		d.ourFiles[filename] = struct{}{}
	}
	return err
}

discovery cache是client-go中相对简单的缓存机制,通过缓存设计,实时发送rest api请求,缓存超时,实现了即能获取相对较新的信息,又减轻rest api请求的压力,这种通过缓存和rest API请求结合的方式也是Kubernetes架构设计的重要思想,后面会分析相对复杂的list-watch机制,目的都是为了减轻Kubernetes API请求的压力。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端云 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android开发笔记(七十三)代码混淆与反破解
ProGuard是ADT自带的apk混淆器,它的用途有: 1、压缩apk包的大小,能删除无用的代码,并简化部分类名和方法名。 2、加大破解源码的难度,因为部分类名和方法名被重命名,使得程序逻辑变得难以理解。 代码混淆的规则在proguard-project.txt中编写,然后在project.properties补充规则文件的路径,如下所示:
aqi00
2019/01/18
2K0
ProGuard混淆
1.压缩(shrinks) :检查并移除代码中无用的类,字段,方法,属性。 2.优化(optimizes):对字节码进行优化,移除无用的指令。 3.混淆(obfuscates):使用a,b,c,d等简短而无意义的名称,对类,字段和方法进行重名,这样即使代码被逆向工程,对方也比较难以读懂。 4.预检测(Preveirfy):在java平台上对处理后的代码进行再次检测。
acc8226
2022/05/17
3.4K1
Android代码混淆常见配置[通俗易懂]
1.manifest中注册的都不能混淆,如果混淆了就找不到了,所以一下类不能被混淆,一般保持原样。
全栈程序员站长
2022/08/23
8130
Android项目实战(二十五):Android studio 混淆+打包+验证是否成功
前言: 单挑Android项目,最近即时通讯用到环信,集成sdk的时候 官方有一句 在 ProGuard 文件中加入以下 keep。 -keep class com.hyphenate.** {*;} -dontwarn com.hyphenate.** 即:混淆规则。 自己没写过关于混淆打包的文章,在此补上。 下面了解Android studio环境下 项目混淆打包的操作。 ----------------------------------------------------------------
听着music睡
2018/05/18
1.7K0
android混淆那些坑
ProGuard简介 在最新的Android Studio 2.2.2版本创建的Android工程中,module中的build.gradle有如下一段配置。这里的minifyEnabled即用来控制在编译时是否需要启用Proguard,将minifyEnabled修改为true,即表示启用Proguard。’proguard-android.txt’是Android SDK中自带的一个基本Progurad配置文件,默认是空白的,需要由开发者自行添加哪些需要混淆哪些不混淆,形如: -ignorewarnin
xiangzhihong
2018/02/05
3.4K0
android混淆那些坑
Android 代码混淆
简介 在我们日常开发中,对已经开发完成的源代码,需做一些代码混淆工作,以对代码起到一种保护和降低安装包体积的作用。
全栈程序员站长
2022/09/02
1.6K0
Android 代码混淆
Android 代码混淆语法讲解及常用模板
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/78253651
程序员徐公
2018/09/17
1.8K0
Android 代码混淆语法讲解及常用模板
Android 代码混淆配置总结[通俗易懂]
为何需要混淆呢?简单的说,就是将原本正常的项目文件,对其类,方法,字段,重新命名,a,b,c,d,e,f…之类的字母,达到混淆代码的目的,这样反编译出来,结构乱糟糟的,看了也头大。
全栈程序员站长
2022/09/07
3.7K0
Android 代码混淆配置总结[通俗易懂]
Android代码混淆之混淆规则
因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆。SDK已经集成了ProGuard工具,开发者可以从SDK目录下的\tools\proguard目录中进行查看。
全栈程序员站长
2022/09/02
1.9K0
Android 混淆打包
Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。
Yif
2019/12/26
1.6K0
Android 代码混淆规则
Android SDK自带了混淆工具Proguard。它位于SDK根目录\tools\proguard下面。 ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器。它可以检测并删除未使用的类,字段,方法和属性。它可以优化字节码,并删除未使用的指令。它可以将类、字段和方法使用短无意义的名称进行重命名。最后,预校验的Java6或针对Java MicroEdition的所述处理后的码。
全栈程序员站长
2022/08/23
2.9K0
Android代码混淆及调试错误「建议收藏」
代码混淆需要对apk进行签名,签名后才是混淆过的(前提是已经放开代码混淆配置,详见以下步骤),直接从eclipse项目bin下拷贝的apk是没有进行混淆的。
全栈程序员站长
2022/09/02
1K0
【详解】使用proguard混淆javaweb项目代码
在开发JavaWeb应用时,为了保护源代码不被轻易反编译和阅读,通常会采用代码混淆技术。ProGuard是一个广泛使用的免费工具,可以用来优化、缩小和混淆Java字节码。本文将详细介绍如何使用ProGuard对JavaWeb项目进行代码混淆。
大盘鸡拌面
2025/05/07
5130
Android插件化基础3----Android的编译打包流程详解
.apk文件其实就是一个压缩包,把文件的后缀改成.zip,用压缩软件解压搜就可的下图(我是mac)
隔壁老李头
2018/08/30
2.3K0
Android插件化基础3----Android的编译打包流程详解
Android 代码混淆 混淆方案
本篇文章:自己在混淆的时候整理出比较全面的混淆方法,比较实用,自己走过的坑,淌出来的路。请大家不要再走回头路,可能只要我们代码加混淆,一点不对就会导致项目运行崩溃等后果,有许多人发现没有打包运行好好地,打包完成以后而又不不可以了,导致了许多困惑,本片文章来问大家解决困惑,希望对大家有帮助。
全栈程序员站长
2022/09/02
3.2K0
Android 混淆(我的模板)
#-------------------------------------------定制化区域---------------------------------------------- #---------------------------------1.实体类--------------------------------- -keep class com.gieseckedevrient.convego.appworld.prod.bean.** { *; } #--------------
胖虎哥
2023/05/10
5160
Android安全攻防战,反编译与混淆技术完全解析(下)
在上一篇文章当中,我们学习了Android程序反编译方面的知识,包括反编译代码、反编译资源、以及重新打包等内容。通过这些内容我们也能看出来,其实我们的程序并没有那么的安全。可能资源被反编译影响还不是很
用户1158055
2018/01/08
1.9K0
Android安全攻防战,反编译与混淆技术完全解析(下)
Android Studio实现打渠道包,切换环境,混淆配置等
最近遇到项目从Eclispe迁移到Android studio,以前的Ant自动打包脚本已经兼容不好了,所以用了Gradle实现打渠道包,切换环境等。
开发者技术前线
2020/11/23
1.5K0
Android Studio实现打渠道包,切换环境,混淆配置等
android代码混淆
proguard 原理 Java代码编译成二进制class 文件,这个class 文件也可以反编译成源代码 ,除了注释外,原来的code 基本都可以看到。为了防止重要code 被泄露,我们往往需要混淆(Obfuscation code , 也就是把方法,字段,包和类这些java 元素的名称改成无意义的名称,这样代码结构没有变化,还可以运行,但是想弄懂代码的架构却很难。 proguard 就是这样的混淆工具,它可以分析一组class 的结构,根据用户的配置,然后把这些class 文件的可以混淆java 元素
xiangzhihong
2018/01/29
1.9K0
android开发笔记之 Android代码混淆打包
缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。
全栈程序员站长
2022/09/02
1K0
相关推荐
Android开发笔记(七十三)代码混淆与反破解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验