图解kubernetes中的api多版本中反序列化与转换
在之前的文章中分析过kubernetes是如何进行多版本管理中提到了一个关键的设计解码器, 负责将请求对象反序列化成一个具体的数据模型,今天一起来了解下其内部是如何实现多版本管理、转换的设计要点
1.版本化管理的关键设计
1.1 从拓扑转换到星状转换
在通常的web开发中更多的时候,大家都是断代向前兼容更新,大多数情况下当版本更新之后会独立演进,如果要在多版本之间转换通常则会出现如下的情况 如果我们要为每个版本都去适配其他所有的版本,则复杂度会指数级上升,而在kubernetes中则通过一个内部版本的设计来进行解决,内部版本是一个稳定的版本,所有的版本都只针对目标版本来进行转换的实现,而不关注其他版本
1.2 兼容设计之转换
那如果谋个版本需要独立的演进,或者增设一些新的字段,修改字段名称等破坏性更新的时候,则就需要一种转换机制,负责在当前版本和内部版本之间来进行字段或者数据的转换
1.3 转换的最终之反射
转换其实核心目标是完成从目标对象的字段中获取数据,然后经过一系列操作最终为目标对象的对应的字段进行赋值操作,要完成该操作,则就需要借助反射来实现,通过枚举字段,来获取对应的转换函数,执行转换函数,完成目标赋值
2. 关键设计的实现
为了实现上面的方案,kubernetes中设计了如下组件:Scheme(负责各个版本的注册和管理)、Convert(转换实现)、Serializer(实现对应版本的反序列化),让我们依次看下其关键设计
2.1 Convert
Convert实现从一个目标对象到另外一个目标对象的转换, 为了实现这种转换,kubernetes里面主要是借助反射和不同版本的转换函数来共同完成
1.首先我们通过目标函数来获取对应的属性字段,然后针对该字段进行计算赋值操作 2.如果发现对应的字段需要来转换,则会调用对应的转换函数来进行赋值操作,如果不需要转换则会直接通过反射来进行赋值
2.2 外部版本到内部版本的转换
在构建rest接口的时候,每个rest接口都会持有一个生成当前版本对象的构造函数,当请求进入之后,会首先通过目标版本获取对应的decoder decoder会利用当前的GroupVersionKind来进行第一步解析,首先将字节数组解析成当前版本,然后在解析成目标对象之后,又会根据目标版本进行转换
2.3 Scheme
Scheme负责各个资源版本的统一注册和管理,为其他组件提供根据GVK来获取对应的资源对象,也提供通过资源对象获取版本等操作,内部还持有convert对象,包装了源对象到目标对象的转换操作
Scheme对象是一个复合的数据结构,其实现了多种结果,诸如typer、defaulter、creater等,很多地方都是通过直接传递scheme来进行对应的参数的填充, 其内部关键数据结构如下
GVK与资源类型的映射,以及当前资源类型支持哪些GVK
gvkToType map[schema.GroupVersionKind]reflect.Type typeToGVK map[reflect.Type][]schema.GroupVersionKind
则创建对象的时候可以直接通过New来实例化对应的对象
func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) { if t, exists := s.gvkToType[kind]; exists { // 利用反射来创建对象 return reflect.New(t).Interface().(Object), nil } // 省略相关代码 }
默认初始化函数
defaulterFuncs map[reflect.Type]func(interface{})
根据对应的类型来完成初始化操作
func (s *Scheme) Default(src Object) { if fn, ok := s.defaulterFuncs[reflect.TypeOf(src)]; ok { fn(src) } }
提供转换函数注册接口, 注册到convert中
func (s *Scheme) AddConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error { return s.converter.RegisterUntypedConversionFunc(a, b, fn) }
3.学习总结
实现上无疑是复杂的作为一个工业设计有很多需要care的边缘情况,剖丝抽茧每个人看到的都不一样,这可能就是源码阅读的乐趣,从上面可以看到核心其实就三个点:将HTTP数据反序列化成为当前URL的资源对象,然后目标资源对象进行初始化默认值函数的执行,最后通过convert来处理不同版本之间的差异,最后统一操作内部版本,好了今天就到这了,希望对大家有所帮助 > 微信号:baxiaoshi2020 > 关注公告号阅读更多源码分析文章 > 更多文章关注 www.sreguide.com > 本文由博客一文多发平台 OpenWrite 发布
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
好程序员Java培训分享Java工程师应具备哪些好习惯?
作为当前市场上人才需求最大、应用领域最广的编程语言,Java一直深受企业和转行IT行业人士的青睐。而分析普通Java工程师和高薪Java工程师之间的区别,不难发现编程习惯是一个非常关键的因素。高薪Java工程师具备哪些编程好习惯呢?接下来就给大家分享一下。1、尽量避免过多过常的创建Java对象尽量避免在经常调用的方法,循环中new对象,由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本的数据类型或数组来替代对象。2、尽量使用final修饰符带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。3、尽量使用局部变量调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Sta...
- 下一篇
Scrum模拟微信看一看“疫情专区”的敏捷开发过程
无论作为产品用户还是管理咨询顾问,都非常非常喜欢微信。自认感情比较克制属于“高冷”挂,但从很多方面都太佩服太崇拜张小龙了(新书里微信也会是最喜欢的案例之一,真的不只是一个产品而已,很多方面都太牛了)。不知道大家是否有注意到,在疫情爆发后,微信的响应大概最快速也相对最到位的了,看一看立马有了“疫情专区”(不知道官方名称是什么,以下暂以此代称),对于了解疫情整体数据和最新动态都很有帮助,真是觉得太棒了。 之前了解到微信也是使用敏捷开发,最近也在筹备ASM实战课程和Scrum咨询服务产品,奇葩开个脑洞用Scrum YY一下看一看“疫情专区”开发过程,也通过这种方式简单科普一下敏捷开发基本理念与价值以及Scrum的流程实践吧。 本文包括4部分: 敏捷开发基本理念与价值 敏捷开发实践方法 Scrum的3个角色与5个活动 如何通过Scrum实现微信看一看“疫情专区” 敏捷开发基本理念与价值 敏捷开发根源于适应性项目管理和精益开发,相较于传统基于“预测+规划+控制”的瀑布式开发方式,能够适应需求变化的风险,及时理解与响应客户需求,通过周期迭代交付可工作的增量产品的方式,增强项目管理灵活性与可预测性,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS关闭SELinux安全模块
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Redis,开启缓存,提高访问速度