Junedayday Blog

六月天天的个人博客

0%

五分钟技术小分享 - 2022Week01

2022-01

2022-01-04 Go1.18概览

在2021年年底,Go推出了1.18Beta版本。由于正式版本没有完全敲定,普通开发人员没有必要研究到底层实现,但如果能先形成一个全局上的认知,能帮助我们领先一步。

关于1.18的核心改动,是 对泛型(Generics)的支持。Go语言的泛型语法比较简单,如下:

1
2
3
4
5
6
7
8
9
10
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
}

如果要在实际工程上落地,还有很多考量点,我这边重点提三点:

  1. 主流IDE的支持 - 包括Goland与VSCode,尽量帮助开发者能在编码时发现问题;
  2. 历史库的迁移与兼容 - 实现泛型后,许多主流库会有大量的冗余函数,如何提供迁移方案,值得我们去关注;
  3. 泛型的最佳工程实践 - 作为一种新特性,Go的泛型如何应用在工程中、尤其是复杂工程中,需要一定的实践摸索,并总结规律(可借鉴其余支持泛型的语言);

除了泛型,另外一个比较大的特性就是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

2022-01-05 CNCF-概览

CNCF作为云原生的代表性组织,提供了大量开源的软件,以及配套的、开箱即用的解决方案。有很多朋友对CNCF和云原生的认识可能仍停留在新闻报道里。今天,我先带大家在整体上入个门,后续选择具有代表性的软件进行分析。

由于篇幅所限,我的分享只会提重点知识,帮大家建立这部分的知识框架,更详细的内容需要大家自行学习。

CNCF的概览可以参考这个全景图 - https://landscape.cncf.io/,更新迭代非常频繁。其中,最核心的为下面五块:

landscape

  • App Definition and Development 应用定义与开发
    • Database 数据库
    • Streaming & Messaging 流处理和消息通信
    • Application Definition & Image Build 应用定义与镜像构建
    • Continuous Integration & Delivery 持续集成与交付
  • Orchestration & Management 编排和管理
    • Scheduling & Orchestration 调度与编排
    • Coordination & Service Discovery 协调与服务发现
    • Remote Procedure Call 远程过程调用
    • Service Proxy 服务代理
    • API Gateway API网关
    • Service Mesh 服务网格
  • RunTime 运行时
    • Cloud Native Storage 云原生存储
    • Container Runtime 容器运行时
    • Cloud Native Network 云原生网络
  • Provisioning 提供者
    • Automation & Configuration 自动化与配置
    • Container Registry 容器注册
    • Security & Compliance 安全与合规
    • Key Management 密钥管理
  • Observability and Analysis 可观察性和分析
    • Monitoring 监控
    • Logging 日志
    • Tracing 跟踪
    • Chaos Engineering 混沌工程

其余还包括Kubernetes的平台提供商、Serverless、成员、认证的服务提供商等周边内容,并不在我们讨论的范围之内。但从基金会来看,它提供了一整套生态,非常有助于落地。

那么,如何认识这五块呢?其实Landscape提供了很好的图形效果,我们只要记住两点:

  1. 应用定义与开发编排和管理运行时提供者 这四块是自上而下的核心链路,下层为上层提供能力支撑
  2. Observability and Analysis 是核心链路旁边的重要支撑

相信到这里,你对CNCF已经有了初步认识。

2022-01-06 《我做系统架构的一些原则》From 陈皓

今天,给大家推荐一篇来自左耳朵耗子-陈皓的文章

  1. 关注于真正的收益而不是技术本身
  2. 以应用服务和 API 为视角,而不是以资源和技术为视角
  3. 选择最主流和成熟的技术
  4. 完备性会比性能更重要
  5. 制定并遵循服从标准、规范和最佳实践
  6. 重视架构扩展性和可运维性
  7. 对控制逻辑进行全面收口
  8. 不要迁就老旧系统的技术债务
  9. 不要依赖自己的经验,要依赖于数据和学习
  10. 千万要小心 X – Y 问题,要追问原始需求
  11. 激进胜于保守,创新与实用并不冲突

以上11点,理解会因人而异,我重点挑三个争议性比较大的聊聊,其余的内容建议大家阅读原文。

完备性会比性能更重要

借用书中的一句话:使用最科学严谨的技术模型为主,并以不严谨的模型作为补充,也就是先紧后松。

有不少开发者在实际工程中的实践往往相反:为了追求快速落地,会希望毕其功于一役,引入所谓的“一站式解决方案”(如例子中NoSQL),但实践下来引入大量的问题,让后人叫苦不迭。

关于这个问题,我个人有三个思考:

  • 不断提高自己的基础能力。很多架构上的局限性,往往是设计者停留于自己的舒适区,不愿意往前一步。
  • 分清主次、合理分工。 在设计时,我们要分清楚核心功能和非核心功能,懂得取舍,将功能交由合适的模块或软件。
  • 功能的实现不是对应到单模块,而是整个系统的涌现。性能问题的解法不仅仅限于单个软件,而是有一整套生态,可以多去查一些大厂的分享。

不要迁就老旧系统的技术债务

为了缩小讨论范围,我对这里 技术债务 做一个收口:不仅仅是指有弊端的技术问题,更是需要投入时间精力等成本去维护。有技术债务,不代表就一定要去还,而需要一个契机 - 维护的成本 > 修复的收益

举个例子,某个程序写得很烂,性能很差:

  • 前期可以通过扩容快速解决,上线后业务收益很高,那就是 成本大于收益,不需要排到最高优先级去修复;
  • 但随着业务收益稳定下来,增长只有个位数,但发现在机器上投入的成本很高,通过优化预计能缩容50%,可以让总收益提升20%,那这时还技术债务的优先级就很高了。

还技术债,技术能力只是一个基本,以下两点更为重要:

  • 评估成本与收益,尽可能地做到有数据支撑,有助于决策者下决心还债;
  • 用更长远、更广维度地看待技术债务问题,不要拆东墙补西墙。

激进胜于保守,创新与实用并不冲突

这个观点是很aggressive的,遇到这样的观念冲突时,决策者找不到客观标准去评估,就很难有二义性的定义:要么激进,要么保守;要么创新,要么实用。这种情况下,我遇到过的比较好的解法有两种:

  1. 决策者自身技术能力强,能掌控团队技术的大致走向。
  2. 决策者和执行者之间培养出足够的信任,适当评审与把控,放权实践。

第一种情况在实际工作场景中并不多见,尤其当团队规模很大时,就像CTO往往不是公司技术最强的那位。所以,我更倾向于大家多尝试第二种途径。

当然,我也遇到过很多效果不好的解法,比如说:决策者既然不清楚怎么做才好,那就找2个执行者进行battle,一个代表创新方,另一个代表保守方。也许在少数情况下,最后能帮助决策者找到正确的方向;但更多的实际场景中,会产生如下问题:

  • 两个执行者碰撞越来越激烈,但始终谁也说服不了谁
  • 决策者越听越迷茫,不知道该如何抉择

在我看来,这类决策者往往是偏管理,技术上的掌控力不足,导致在决策时没有足够的倾向性;同时,与执行者之间的信任也不足,就希望把决策这件事下移、尝试着走平衡之道。

我个人的想法是:先选择一个能力相对优秀的执行者,认真评估其方案,然后交由对方执行;最后哪怕失败了,也可以通过复盘改进,想想下次如何更好地决策,更好地把控方案;当然,如果你认为纯粹是执行者的问题,那就换个可信赖的人。

2022-01-07 CNCF-Kubernetes

今天,我们一起来看看CNCF中的最核心项目 - KubernetesKubernetes相关内容非常庞大,我们依旧关注聚焦于核心能力。

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,我对官方首页描述中的关键特性再做一些更详细地说明:

Automated rollouts and rollbacks

自动化扩缩容和升级回滚。这个特性是k8s最核心的,也是大规模推广的根本原因。

看起来,这功能描述与CICD流程差不多,但使用体验差距很大。在传统的模式下,我们执行的是一个具体的动作,比如扩1个机器、升级2个程序等;而在k8s里,使用者只要声明最终的预期状态,比如5台机器运行v1.0版本的程序,那么整个系统该扩容还是缩容、该升级还是回滚,都由k8s自行根据当前状态进行判断。

这个,就是云原生的一大特性:声明式API ,而不是传统上的命令式API

声明式API不一定比命令式API好。在应用程序开发时,命令式API更容易理解。

Service discovery and load balancing

服务发现与负载均衡。这个功能很大程度上减少了分布式软件运行模式的复杂性。

服务发现,以前非常依赖zookeeper/etcd等这类注册中心,往往需要侵入到业务代码;而负载均衡,则很依赖nginx这类软件,并在上面做复杂配置。

当然,k8s给出的只是通用解法,对一些具备很强业务属性的服务发现与负载均衡,仍需要程序自行实现。

Storage orchestration

存储编排。存储的编排是k8s重点演进的功能。

k8s抽象了存储概念,从传统的本地存储扩展为分布式云存储,对上层应用屏蔽了存储这块的复杂度。

Designed for extensibility

为扩展性而设计。

扩展性是k8s非常重视的点,无论是开放出容器、网络、存储等接口规范,还是像自定义资源(CRD)等插件的开放,都体现出了一种开放的精神,也是k8s如今能作为云原生标志性的软件的立足之本。

有一个点希望大家认识到:k8s的成功不是简单地因为开放性,更重要的是,它定义的这些开放性的规范与接口,都是Google经过实践总结出来的经验,符合主流厂商的趋势与开发者的需求。

Github: https://github.com/Junedayday/code_reading

Blog: http://junes.tech/

Bilibili: https://space.bilibili.com/293775192

公众号: golangcoding

二维码