2022-01
在2021年年底,Go
推出了1.18Beta
版本。由于正式版本没有完全敲定,普通开发人员没有必要研究到底层实现,但如果能先形成一个全局上的认知,能帮助我们领先一步。
关于1.18的核心改动,是 对泛型(Generics)的支持。Go语言的泛型语法比较简单,如下:
type numeric interface {
type int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
}
func min[T numeric](a, b T) T {
if a < b {
return a
}
return b
}
如果要在实际工程上落地,还有很多考量点,我这边重点提三点:
除了泛型,另外一个比较大的特性就是Fuzzy Testing
。
这个特性是为单元测试提供更全面的数据输入,这样就能覆盖更多的case,提前发现问题。关键词Fuzzy
支持的主要特性是将一个输入参数,从具体的值变成范围,如原先输入a=1
,现在支持a
输入范围为[-10,10]
。在跑单元测试时,大量的Fuzzy
肯定会带来一定的性能压力,这时可以引入一定的并发特性。
总体来说,Go1.18
对工程侧的影响更多地是提高代码的 简洁性。新特性的学习成本很低,我们不用过于急着引入,可以多花时间学习底层原理。
Go Blog - https://go.dev/blog/go1.18beta1 Medium - https://betterprogramming.pub/golang-1-18-what-you-need-to-know-a5701f7e14ab
CNCF作为云原生的代表性组织,提供了大量开源的软件,以及配套的、开箱即用的解决方案。有很多朋友对CNCF和云原生的认识可能仍停留在新闻报道里。今天,我先带大家在整体上入个门,后续选择具有代表性的软件进行分析。
由于篇幅所限,我的分享只会提重点知识,帮大家建立这部分的知识框架,更详细的内容需要大家自行学习。
CNCF的概览可以参考这个全景图 - https://landscape.cncf.io/,更新迭代非常频繁。其中,最核心的为下面五块:
其余还包括Kubernetes的平台提供商、Serverless、成员、认证的服务提供商等周边内容,并不在我们讨论的范围之内。但从基金会来看,它提供了一整套生态,非常有助于落地。
那么,如何认识这五块呢?其实Landscape提供了很好的图形效果,我们只要记住两点:
相信到这里,你对CNCF已经有了初步认识。
今天,给大家推荐一篇来自左耳朵耗子-陈皓的文章。
以上11点,理解会因人而异,我重点挑三个争议性比较大的聊聊,其余的内容建议大家阅读原文。
借用书中的一句话:使用最科学严谨的技术模型为主,并以不严谨的模型作为补充,也就是先紧后松。
有不少开发者在实际工程中的实践往往相反:为了追求快速落地,会希望毕其功于一役,引入所谓的“一站式解决方案”(如例子中NoSQL),但实践下来引入大量的问题,让后人叫苦不迭。
关于这个问题,我个人有三个思考:
为了缩小讨论范围,我对这里 技术债务 做一个收口:不仅仅是指有弊端的技术问题,更是需要投入时间精力等成本去维护。有技术债务,不代表就一定要去还,而需要一个契机 - 维护的成本 > 修复的收益。
举个例子,某个程序写得很烂,性能很差:
还技术债,技术能力只是一个基本,以下两点更为重要:
这个观点是很aggressive的,遇到这样的观念冲突时,决策者找不到客观标准去评估,就很难有二义性的定义:要么激进,要么保守;要么创新,要么实用。这种情况下,我遇到过的比较好的解法有两种:
第一种情况在实际工作场景中并不多见,尤其当团队规模很大时,就像CTO往往不是公司技术最强的那位。所以,我更倾向于大家多尝试第二种途径。
当然,我也遇到过很多效果不好的解法,比如说:决策者既然不清楚怎么做才好,那就找2个执行者进行battle,一个代表创新方,另一个代表保守方。也许在少数情况下,最后能帮助决策者找到正确的方向;但更多的实际场景中,会产生如下问题:
在我看来,这类决策者往往是偏管理,技术上的掌控力不足,导致在决策时没有足够的倾向性;同时,与执行者之间的信任也不足,就希望把决策这件事下移、尝试着走平衡之道。
我个人的想法是:先选择一个能力相对优秀的执行者,认真评估其方案,然后交由对方执行;最后哪怕失败了,也可以通过复盘改进,想想下次如何更好地决策,更好地把控方案;当然,如果你认为纯粹是执行者的问题,那就换个可信赖的人。
今天,我们一起来看看CNCF中的最核心项目 - Kubernetes
。Kubernetes
相关内容非常庞大,我们依旧关注聚焦于核心能力。
Kubernetes
位于CNCF核心的 调度与编排 模块,也就是整个解决方案的基石。在CNCF上的介绍为:
Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.
对这个定义,我们关注两个点:
automating deployment, scaling, and management
自动化的部署、扩缩容和管理,这是k8s核心能力;containerized applications
容器化应用,这是k8s操作的基本对象;为了更好地介绍Kubernetes,我对官方首页描述中的关键特性再做一些更详细地说明:
自动化扩缩容和升级回滚。这个特性是k8s最核心的,也是大规模推广的根本原因。
看起来,这功能描述与CICD
流程差不多,但使用体验差距很大。在传统的模式下,我们执行的是一个具体的动作,比如扩1个应用、升级2个程序等;而在k8s里,使用者只要声明最终的预期状态,比如5个应用运行v1.0版本的程序,那么整个系统该扩容还是缩容、该升级还是回滚,都由k8s自行根据当前状态进行判断。
这个,就是云原生的一大特性:声明式API ,而不是传统上的命令式API。
声明式API不一定比命令式API好。在应用程序开发时,命令式API更容易理解。
服务发现与负载均衡。这个功能很大程度上减少了分布式软件运行模式的复杂性。
服务发现,以前非常依赖zookeeper
/etcd
等这类注册中心,往往需要侵入到业务代码;而负载均衡,则很依赖nginx
这类软件,并在上面做复杂配置。
当然,k8s给出的只是通用解法,对一些具备很强业务属性的服务发现与负载均衡,仍需要程序自行实现。
存储编排。存储的编排是k8s重点演进的功能。
k8s抽象了存储概念,从传统的本地存储扩展为分布式云存储,对上层应用屏蔽了存储这块的复杂度。
为扩展性而设计。
扩展性是k8s非常重视的点,无论是开放出容器、网络、存储等接口规范,还是像自定义资源(CRD)等插件的开放,都体现出了一种开放的精神,也是k8s如今能作为云原生标志性的软件的立足之本。
有一个点希望大家认识到:k8s的成功不是简单地因为开放性,更重要的是,它定义的这些开放性的规范与接口,都是Google
经过实践总结出来的经验,符合主流厂商的趋势与开发者的需求。
Github: https://github.com/Junedayday/code_reading Blog: http://junes.tech/ Bilibili: https://space.bilibili.com/293775192