技术

上下文记忆 agentic chat 图数据库的一些考量 LLM一些探索 Agent实践 LLM预训练 向量数据库的一些考量 fastapi+sqlalchemy进行项目开发 LLM微调实践 Python协程实现 Agent Functon Calling LLamaIndex入门 Multi-Agent探索 Python虚拟机 LLM工作流编排 Python实践 下一个平台Agent 激发LLM涌现——提示工程 LLM微调理论 大佬沉思 LLM外挂知识库 LLMOps 多模态LLM Python一些比较有意思的库 Transformers源码学习 LangChain源码学习 通用分布式计算引擎Ray Python并发 go依赖注入 go collection gc的基本原理 golang性能分析及优化 数据湖 高性能计算与存储 Linux2.1.13网络源代码学习 《大数据经典论文解读》 三驾马车学习 Spark 内存管理及调优 Yarn学习 从Spark部署模式开始讲源码分析 容器狂占内存资源怎么办? 多角度理解一致性 golang io使用及优化模式 Flink学习 c++学习 学习ebpf go设计哲学 ceph学习 学习mesh kvm虚拟化 学习MQ go编译器以及defer实现 学习go 为什么要有堆栈 汇编语言 计算机组成原理 运行时和库 Prometheus client mysql 事务 mysql 事务的隔离级别 mysql 索引 坏味道 学习分布式 学习网络 学习Linux go堆内存分配 golang 系统调用与阻塞处理 Goroutine 调度过程 重新认识cpu mosn有的没的 负载均衡泛谈 单元测试的新解读 《Redis核心技术与实现》笔记 《Prometheus监控实战》笔记 Prometheus 告警学习 calico源码分析 对容器云平台的理解 Prometheus 源码分析 并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go channel codereview gc分析 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes扩缩容 神经网络模型优化 直觉上理解深度学习 如何学习机器学习 TIDB源码分析 什么是云原生 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 共识算法 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全访问机制 jvm crash分析 Prometheus 学习 Kubernetes监控 Kubernetes 控制器模型 容器日志采集 容器狂占资源怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes类型系统 源码分析体会 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 线程排队 jib源码分析之细节 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI——容器网络是如何打通的 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 精简代码的利器——lombok 学习 《深入剖析kubernetes》笔记 编程语言那些事儿 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 如何分发计算 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 calico学习 AQS——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记 log4j学习 为什么netty比较难懂? 递归、回溯、动态规划 apollo client源码分析及看待面向对象设计 学习并发 docker运行java项目的常见问题 OpenTSDB 入门 spring事务小结 分布式事务 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型和jvm内存布局 java exception Linux IO学习 netty内存管理 测试环境docker化实践 netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker namespace和cgroup zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 深度学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM执行 git maven/ant/gradle/make使用 再看tcp kv系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 Go基础 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

架构

bert rerank微调 大模型推理tips RAG向量检索与微调 dddfirework源码分析 RAG与知识图谱 大模型推理服务框架vLLM 大模型推理服务框架 模型服务化(未完成) 大模型Post-Training 大模型训练 大模型推理 从Attention到Transformer k8s设备管理 ddd从理念到代码 如何应用LLM 小鼠如何驾驭大象(LLM)? 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 kubevela源码分析 容器和CPU那些事儿 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 AutoML和AutoDL 特征平台 实时训练 分布式链路追踪 K8S YAML 资源清单管理方案 tensorflow原理——python层分析 如何学习tensorflow 数据并行——allreduce 数据并行——ps 推荐系统embedding原理及实践 机器学习中的python调用c 机器学习训练框架概述 tensornet源码分析 大模型训练和推理 X的生成——特征工程 tvm tensorflow原理——core层分析 模型演变 《深度学习推荐系统实战》笔记 keras 和 Estimator tensorflow分布式训练 分布式训练的一些问题 基于Volcano的弹性训练 图神经网络 pytorch弹性分布式训练 从混部到统一调度 从RNN到Attention pytorch分布式训练 CNN 《动手学深度学习》笔记 pytorch与线性回归 多活 volcano特性源码分析 推理服务 kubebuilder 学习 mpi 学习pytorch client-go学习 提高gpu 利用率 GPU与容器的结合 GPU入门 AI云平台梳理 tensorflow学习 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 学习rpc BFF openkruise学习 可观察性和监控系统 基于Kubernetes选主及应用 《许式伟的架构课》笔记 Admission Controller 与 Admission Webhook 发布平台系统设计 k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? 《软件设计之美》笔记 mecha 架构学习 Kubernetes events学习及应用 CRI——kubelet与容器引擎之间的接口 资源调度泛谈 业务系统设计原则 grpc学习 元编程 以应用为中心 istio学习 下一代微服务Service Mesh 《实现领域驱动设计》笔记 概率论 serverless 泛谈 《架构整洁之道》笔记 处理复杂性 那些年追过的并发 服务器端编程 网络通信协议 架构大杂烩 如何学习架构 《反应式设计模式》笔记 项目的演化特点 反应式架构摸索 函数式编程的设计模式 服务化 ddd反模式——CRUD的败笔 研发效能平台 重新看面向对象设计 业务系统设计的一些体会 函数式编程 《左耳听风》笔记 业务程序猿眼中的微服务管理 DDD实践——CQRS 项目隔离——案例研究 《编程的本质》笔记 系统故障排查汇总及教训 平台支持类系统的几个点 代码腾挪的艺术 abtest 系统设计汇总 《从0开始学架构》笔记 初级权限系统设计 领域驱动理念 现有上传协议分析 移动网络下的文件上传要注意的几个问题 推送系统的几个基本问题 做配置中心要想好的几个基本问题 不同层面的异步 分层那些事儿 性能问题分析 用户认证问题 资源的分配与回收——池 消息/任务队列

标签

k8s设备管理 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 kubevela源码分析 容器和CPU那些事儿 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 K8S YAML 资源清单管理方案 从混部到统一调度 volcano特性源码分析 kubebuilder 学习 client-go学习 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 openkruise学习 基于Kubernetes选主及应用 Admission Controller 与 Admission Webhook k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? Kubernetes events学习及应用 CRI——kubelet与容器引擎之间的接口 资源调度泛谈 如何学习Kubernetes 以应用为中心 kubernetes operator kubernetes扩缩容 serverless 泛谈 什么是云原生 自定义CNI IPAM docker和k8s安全访问机制 Kubernetes监控 Kubernetes 控制器模型 Kubernetes资源调度——scheduler Kubernetes类型系统 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 Kubernetes源码分析——从kubectl开始 kubernetes yaml配置 CNI——容器网络是如何打通的 当我在说PaaS时,我在说什么 《深入剖析kubernetes》笔记 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件
上下文记忆 agentic chat bert rerank微调 大模型推理tips LLM一些探索 Agent实践 LLM预训练 RAG向量检索与微调 LLM微调实践 RAG与知识图谱 大模型推理服务框架vLLM Agent Functon Calling LLamaIndex入门 Multi-Agent探索 LLM工作流编排 大模型推理服务框架 模型服务化(未完成) 大模型Post-Training 大模型训练 大模型推理 从Attention到Transformer 下一个平台Agent 激发LLM涌现——提示工程 LLM微调理论 大佬沉思 LLM外挂知识库 LLMOps 多模态LLM Transformers源码学习 LangChain源码学习 如何应用LLM 小鼠如何驾驭大象(LLM)? AutoML和AutoDL 特征平台 实时训练 tensorflow原理——python层分析 如何学习tensorflow 数据并行——allreduce 数据并行——ps 推荐系统embedding原理及实践 机器学习中的python调用c 机器学习训练框架概述 tensornet源码分析 大模型训练和推理 X的生成——特征工程 tvm tensorflow原理——core层分析 模型演变 《深度学习推荐系统实战》笔记 keras 和 Estimator tensorflow分布式训练 分布式训练的一些问题 基于Volcano的弹性训练 图神经网络 pytorch弹性分布式训练 从RNN到Attention pytorch分布式训练 CNN 《动手学深度学习》笔记 pytorch与线性回归 推理服务 mpi 学习pytorch 提高gpu 利用率 GPU与容器的结合 GPU入门 AI云平台梳理 tensorflow学习 kaggle泰坦尼克问题实践 神经网络模型优化 概率论 直觉上理解深度学习 如何学习机器学习 深度学习泛谈

研发效能平台

2018年10月15日

简介

毕玄:为什么大厂现在总提研发效能,因为大厂到了后面人效比是下降的,所以只要过了那个点,很多公司都会提。因为他每年都会觉得我业务增长是这样,但你研发人员怎么还在不断增长,他当然觉得有问题,加上研发又比较贵,成本比较高,他就会说你们研发的效能得提高啊。但关键是研发效率到底怎么提高?大家就指望那个研发效能团队,但其实那个团队根本就承担不了这活,他承担的只是很小的一部分,最大的部分实际是管理问题。你想为什么一家创业公司研发很快?以前淘宝也很快,上午提需求,下午就上线了,为什么?因为以前根本不需要评审,也不需要各种环节,你过来说一下,我立刻就开始写代码。现在怎么可能?现在你一个需求提过来,背后可能涉及十个团队,那这十个团队我得先讨论一下吧,还得排个期吧,开会就已经好几天了,这还做个啥?两周做完一个需求就不错了。所以总的来看研发效能,没做出东西很尴尬,做出了东西还是挺无力的,这怎么办?就看团队定位了,如果对公司来说,能接受这个团队在某些点上能做到全球 TOP,不需要我们去论证自己做出来的东西的价值,那这个团队的存在空间就有了。像美国很多公司都认为工具才是核心,不需要说来论证一下你为什么做了这个工具?你效率提高了多少?他们信仰,只要工具做好了,效率就提高了。我以前拜访 Facebook,他们的工具团队很受重视,大家都很向往,觉得他们简直太牛了,因为他觉得我用的都是你们团队做的东西。但中美在软件这一侧的信仰差别是很大的。美国可能因为人太贵了,所以他们一开始就特别相信工具,中国相对来讲人的成本低一些,所以一开始中国不觉得工具有多重要,我就是堆人。只有等到两种情况:一发现堆人也解决不了问题,二开始感受到堆人的成本,只有到这两个阶段才会觉得那我们得做好工具。所以我跟他们讲,研发效率是个综合过程,你不能做的,再怎么叽歪也没用,但我们能做的,那就尽可能做好呗。如果你能做到世界顶流,就算不能在公司被认可,但你在圈子里是会被认可的,就像 Google 做 Bazel 的团队,你以后的职业生涯是没有问题的,如果在这家公司身上获取不到,在另外一家公司身上也会获取到。那就别纠结了,关键纠结也没啥用。

你真的懂效率?

  1. 定义效率
  2. 度量效率
  3. 提高效率

从持续交付到业务创新(上):互联网时代研发效能的核心

为什么要效率以及定义效率

  1. 瀑布开发的本质问题并不是阶段,而是批量。
  2. 一个功能有多少价值, 不仅取决于其本身,还取决于什么时候交付。所以要敏捷开发,分feature,以最快的速度交付第一个feature。
  3. 团队(包括产品也包括开发、业务)什么时候对于产品和项目的知识最充分、最多?项目结束的时候。产品和业务开发本来就是一个探索的过程,开始时一定是最无知的时刻。项目中的大部分决策,是什么时间做出的呢?项目开始的时刻。这里埋藏了一个重大的悖论,我们在最无知的时刻,做出了最重要而且是绝大部分的决策,并把它作为随后执行的依据。对于这一悖论,敏捷的对策还是迭代。

  4. 敏捷指的是创建一个组织更快(早)的交付价值,和更有效学习和灵活应变的能力。
  5. 产品开发的最终目的是交付价值,那我们就必须让价值交付的过程顺畅起来,也就是让价值流动顺畅起来。计划、管理、协调活动,以及资源的配置等等,都应该服务于价值的流动。价值流动是目的,资源忙起来不是。

「技术人生」第10篇:如何做研发效能提升(即指标体系建设过程回顾)

  1. 你在日常工作中用各种工具、各种快捷键、各种飞花摘叶信手拈来的代码片段节省出来的 10 分钟,抵不过一场 15 分钟都没把问题聚焦起来的对焦大会;你用 git + docker + CI/CD 系统+蓝绿发布偶尔还来下金丝雀发布一整套云原生豪华大礼包跑完全部流程节省下来的 60 分钟,也抵不过产品经理路过你工位时轻飘飘的给你来一句“需求要改了,晚上加个班”;当然,你用 teambition + 甘特图 + 项目任务燃尽图费劲脑汁地做多项目并行排班并发推进多条任务线最后节省出来的 10 天,也抵不过 leader 拉你进入紧急处置群,里面看到的第一句话就是“老板改想法了”。
  2. 技术产品本身要回答 “做产品”还是“做项目” 的问题,因此选择“做产品”的一定瞄准尽可能多的客户的共性问题,在此基础上再解决定制化的问题,即提出各种架构、模式、机制来支持未来可能的定制化,因此它对更上层的、更具体的效能问题其实不解决的,或者说,从投入产出比的角度来看,产品型效能工具在诞生之初就无法做特例情况的支持,只能通过后期的基于各个团队实际情况的自定义开发来解决。所以这就是为什么用了效能工具还有效能问题的根本原因:它只解决了它要解决的效能问题,但是它没有解决你所面临的全部的效能问题。作为研发团队的 Leader,要非常清晰地看到哪些产品解决哪些问题,更要非常清晰地知道自己的团队目前面临的效能问题究竟是什么,怎么形成的,如何解决,事实上就是分析清楚当前团队在研发效能建设领域面临的主要矛盾次要矛盾是什么
  3. 很多团队的效能指标会停留在编码量、需求交付量,实际上只是照顾到了最基础的效能指标,却没有分团队类型、分业务阶段做动态调整,自然很难发挥出指标的牵引作用,原因就在于不够实事求是,对团队和业务的个性考虑不足。

度量效率

我们在阿里内部做团队效能改进时,提出了称之为“2-1-1”的愿景,得到了不少部门的认可。什么是211呢?

  1. “2”指的是交付周期2周——85%以上的需求可以在2周内交付;它涉及到整个组织各职能,和部门的协调一致,紧密协作。
  2. 第一个“1”指的是开发周期1周——85%以上的需求可以在1周内开发完成;
  3. 第二个“1”指的是发布前置时间1小时——提交代码后可以在1小时内完成发布。需要持续交付流水线,产品架构体系和自动化测试、部署等有力保障。

提高效率

路灯下醉汉在找什么东西,很长时间过去了,警察一直看着他,终于忍不住走上前,问道:“你在找啥?”。醉汉说:“找我的钥匙”。警察看了一下钥匙好像不在这,就问:“钥匙是丢在这吗?”醉汉说:“不是”。警察奇怪的问道:“那你为什么在这找?”。“只有这儿能看到啊”

  1. 现实中我们更多关注资源是否停滞,人是否闲着,但真正的问题并不在这儿。真正的问题是需求的停滞,需求在各个阶段的积压——如分析阶段、测试阶段、发布阶段等等。需求不能顺畅流动才是真正的问题所在,也就是我们所说的关键所在。
  2. 为什么我们往往对需求的积压很少关注?因为它很难看到,不是光照亮的地方。我们很难觉察(至少很难即时的察觉)。需求的停滞、积压和返工,而那才是改进价值交付的关键所在。

  3. 要改进端到端的流程,我们必须看到价值端到端的流动过程,在哪里出现了积压和停滞。为此,改进的第一步,就是要让光照亮关键所在——可视化端到端的价值流动过程,基于价值流发现流动过程中的问题。

  4. 我们还要保障价值流动的过程质量,把交付质量内建到开发过程中,而不是依赖最后环节的测试。为了做到内建质量,我们需要明确定义需求流动的标准

  5. 潘季驯,他是明朝治理黄河的水利专家,被称为“千古治黄第一人”,治黄河难,难在泥沙不断淤积。清淤是治理黄河的传统办法,问题是清了又会淤,年复一年。嘉靖到万历年间潘季驯四次临危受命治理黄河,取得前所未有的成效,并总结了切实可行的方略,其中最为重要的思想就是“束水攻沙”。什么是“束水攻沙”呢?潘季驯在治理黄河时既没有蛮力清淤,也不是一味地加高、加宽河堤。他反其道而行,收窄河堤——在大堤(称为遥堤)内再修筑一道更窄的堤(称为缕堤),遥堤用以防溃,缕堤用以束水。河堤收窄了,水流的速度就会加快,将沉积的泥沙带走,这就是所谓”束水攻沙”。“束水攻沙”与产品开发有什么关系呢?“束水”加快了水的流速,也带走了泥沙。对应的,产品开发中我们也要限制并行需求的数量,同样是为了缩短需求从开始到完成的平均交付周期——加快流速,并即时发现和处理交付过程中的问题——带走泥沙。

  6. 以站会为例,团队在站会上,会去审视需求的状态。这里面有两个策略,一种是从左向右审视,还有一个从右往左审视,大家认为哪个合适?对,大家都说从右往左。为什么呢?因为我们应该聚焦于完成而不是开始,我们应该聚焦于尽快的交付,比如测试中的需求是不是有缺陷,并优先解决这些缺陷,好让需求尽快上线;开发中的需求,有没有阻碍,并即时解决这些阻碍,完成它们。

在精益和敏捷开发实施过程中,我们首先做的是可视化价值流动,并以此为基础逐步减小并行需求的数目,力求需求的持续流动——持续小批量的输入、开发、转测试和交付。在减小批量的过程中,问题逐渐暴露。

更重要的是:要让团队看见问题(前提是统一对问题的认识),并且提供合适的路径,一个时间解决一个问题,并且解决问题后要能看到立即的想过。核心有两个,第一:“看见”,它的关键是看见系统,看见价值的端到端流动,以此为基础看到问题和改进机会;第二:“路径”,它的关键是小步快走,但每一步都要有可感知的成果。

小结

  1. 效率的本质:需求的高速流动
  2. 需求流动可视化,是否产生积压
  3. 保障价值流动的过程质量,未达标时不允许流动到下一阶段

持续交付

南京银行Devops持续交付实践之路

主要想表达的是:

  1. 研发效率里包含什么?
  2. 每个一个部分如何自动化,提高效率
  3. 串起来如何自动化,提高效率

承担集团数万应用、研发人员日常工作,阿里持续交付平台的设计、迭代之道

  1. 平台不能只是工具的堆砌,更需要针对互联网时代的研发模式进行深度思考,不断打磨,将工程师文化和工程师实践不断地融入其中。
  2. 从需求到代码,从交付到反馈的一站式平台。项目、需求、代码、构建、测试、发布、流水线、舆情反馈等等等等,产品大图基本完备。
  3. 发展历程

    1. 自动化,配置、代码、测试、运维的自动化。
    2. 标准化
    3. 定制化
    4. 一站式,一个需求的研发过程中,相关的所有同学要访问几个系统?
  4. 当交付速度决定市场:我们 CTO 曾说过,研发工具要保障一个 idea 从诞生到上线在 2 周内完成,快速试错,不行就干掉,好了就拉一帮人做大做强。
  5. 借助中间件全链路 trace 技术,建立测试用例与业务方法的关联关系,当代码变更时推荐需要执行的用例,精准回归,快速反馈。
  6. 双引擎测试,首先通过 client 对线上请求进行采集,其中包括 request 和 response,以及下游系统,缓存、db 等等的调用链路快照。通过 mq 消息发送给 beta 环境的 client 进行回放。这里就简单进行回放请求就完成了么?显然不是,该工具最核心的是对应用所有的下游依赖进行了隔离和 mock,比如应用发送给 db 一条 sql 查询数据,双引擎测试平台会将这个请求阻断,并返回线上同样查询的快照数据。最终拿到应用的 response 进行实时对比,存储不一致结果。

测试环境

阿里测试环境运维及研发效率提升之道

  1. 资源稳定性
  2. 部署效率
  3. 业务稳定性

    发布上线完之后我们会去部署一个基础环境,开发环境去调用稳定环境的服务。基础环境部署的是主干代码,也就是线上的代码,会自动部署。

rick 的疑惑:对于一个服务实例,是启动时就知道隔离组,还是后面拖进去的,拖一拖的动作是为了什么?

从中可以看到

  1. 开发环境不是一个全服务的存在,只有正在测试的服务,最大限度的去复用基础环境下的服务。
  2. 基础环境的服务 不是想部署就部署的,是你上线后,同样的代码自动部署的
  3. 源头ip 也可以拖到隔离组,并且对于A调用B来说,怎么路由的,跟A和B在不在一个隔离组没关系,跟源头ip 和 B在不在一个隔离组有关系。
  4. 可以推断:实例创建的时候便已经指定了隔离组。否则,一个实例创建出来,并且没有分配隔离组的话,便游离在“三界”之外,既不是顶掉原来的服务,也不会有流量进来。
  5. 在新的理念下,开发/测试环境 不是一个全服务的、服务之间互通的、每个服务都由开发者各自管理的环境。而是一个自动管理的稳定环境 + 服务间隔离的开发环境。从每一个开发者的视角看,他们都拥有稳定的上下游服务。

分支管理策略

在阿里,我们如何管理代码分支?

  1. 开始工作前,从主干创建特性分支。
  2. 通过合并特性分支,形成发布分支。从主干上拉出一条新分支,将所有本次要集成或发布的特性分支依次合并过去,从而得到发布分支。发布分支通常以release/前缀命名。

    发布分支的用途可以很灵活

    1. 基础玩法是将每条发布分支与具体的环境相对应,比如release/test分支对应部署测试环境,release/prod分支对应线上正式环境等等,并与流水线工具相结合,串联各个环境上的代码质量扫描和自动化测试关卡,将产出的部署包直接发布到相应环境上。
    2. 进阶点的玩法是将一个发布分支对应多个环境,比如把灰度发布和正式发布串在一起,中间加上人工验收的步骤。
    3. 高级的玩法呢,要是按迭代计划来关联特性分支,创建出以迭代演进的固定发布分支,再把一系列环境都串在这个发布分支的流水线上,就有点经典持续集成流水线的味道了。

    当然,这些花哨的高级玩法是我臆想的,阿里的发布分支一般都还是比较中规中矩。

  3. 发布到线上正式环境后,合并相应的发布分支到主干,在主干添加标签,同时删除该发布分支关联的特性分支。

由于测试环境、集成环境、预发布环境、灰度环境和线上正式环境等发布流程通常是顺序进行的,在流程上可以要求只有通过前一环境验证的特性,才能传递到下一个环境做部署,形成漏斗形的特性发布流。

AoneFlow 的技术门槛以及阿里内部的应对之道

  1. 除了开发流程和代码分支的管理方式以外,还包括日常开发中的一些约定俗成的规约。
  2. 工具可以使得团队协作更加平滑,在阿里内部,使用 AoneFlow 流程的团队基本上不用自己运行 Git 来处理分支的事情

    • 由于是内部工具,平台的功能高度内聚。对于项目而言,从提出原始需求,将需求拆分为任务,然后根据任务在线创建特性分支,再聚合生成发布分支,同时根据模板自动创建测试环境,直到后期的运维保障都可以一站式的搞定。
    • 平台对于 AoneFlow,向前做到了将特性分支和需求项关联起来,确保了特性分支的命名规范性;向后做到了将发布分支与部署行为关联起来,确保了各环境版本来源的可靠性。打通了端到端交付的任督二脉。
    • 发布分支的流水线。当这些分支被创建或更新时,往往需要伴随其他的一系列行为,比如自动进行集成测试、代码检查与部署
    • 平台提供代码仓库各个分支状况的统一展示,包括分支所对应部署环境的机器信息、操作记录等全都一览无余

要点:

  1. master分支
  2. 特性分支
  3. 发布分支,发布分支的操作关联流水线
  4. 特性分支与发布分支关联,这个关联数据要记录下来

平台实践

阿里云效平台

阿里云效平台 简介

阿里云效平台 官网

28位阿里技术专家解密研发效能升级之道(含PDF文件下载) 所有的pdf 文件阅读

关键字

  1. 软件生命周期流程 线上化,透明化和自动化。说白了,每一个阶段要先做好,提高单个效率
  2. 打通。提供沟通效率。
  3. 借鉴敏捷的研发模式,摸索出了一套行之有效的方法和理念,并沉淀出一整套研发效能平台。

云效,一站式企业协同研发云,源于阿里巴巴多年先进的管理理念和工程实践,提供从“需求->开发->测试->发布->运维->运营”端到端的协同服务和研发工具支撑。

这个简单的小功能,半年为我们产研团队省下213个小时实现任务状态的自动流转、需求的自动指派、自动催办。比如

  1. 当需求关联代码分支,需求状态就变更为开发中
  2. 当需求在计划完成日期前3天,就邮件/钉钉通知需求负责人尽快完成
  3. 当子任务完成时,父任务就自动完成

加速应用上云的最后一公里 值得细读。

云效下一步 AppStack

超越流水线,企业研发规范落地新思路仅靠文档定义规范是行不通的,当面临某个问题时,使用者需要按照文档规定的流程将各项任务串联起来解决,且中间不能出错。因此完全依赖使用者处理问题是不可靠的。流程是工具自动化的过程,人不是流程本身和驱动者,而是参与方之一。只有这样,我们才能保证研发规范符合设计和成功落地。产品的交付粒度是一个产品特性,部署粒度是一个应用,开发粒度是一个 feature 分支。feature 分支必须经过开发、测试,最后到达部署。在 feature 的整个交付过程中,每个阶段都有准入卡点。比如,如果某个 feature 分支没有经过开发阶段的验证,那么将不能进入测试验收阶段。

  1. 有了这些规范之后,如果基于代码库和流水线,如何落地呢?首先,代码库与应用最好一一对应,且代码库会将 master 分支配置为保护分支,其只能被合入,而不能被推送。并且被合入时具有条件限制,其必须通过前面的验证。其次,我们应该会有两条或三条流水线。此处为开发测试流水线和生产流水线。在开发测试流水线上,开发测试都在这个 feature 分支上。生产流水线比较清晰。当代码合入到 master 分支后,流水线依次经过构建、发布准入和部署到生产环境等阶段。
  2. 基于代码和流水线的解决方案,存在两个局限:
    1. 要正确地执行研发规范,需要配合手册让使用者了解并正确执行操作步骤。包括开始一个新的特性开发时,使用者自行创建一个以 feature- 开头的分支,将代码提交后,使用者需要关注开发测试流水线是否有问题,然后按照要求创建合并请求,把 feature 分支合并到主干。然后,再去检查生产部署流水线是否运行正常。同时,在配置流水线时,使用者需要在执行的层面,保证流水线所对应的环境是正确的。
    2. 即使我们根据手册正确地执行研发规定,还是会有信息传递不了,需要依靠线下传递的问题。最典型的就是部署所涉及的特性清单有哪些,而这类清单信息在研发规范中是很常见的。例如当我们作为验收测试的角色,这次测试的范围是什么,测试的东西包含哪些特性和改变,而这些信息需要彼此间传递。但是在传递的中间过程中,信息是否准确完整具有未知性,可能会产生信息丢失,并且后续无法再追溯,除非我们再去另找渠道补充丢失的信息。
  3. 研发规范承载在哪里?按照原来的思路,会发现代码库模板、流水线模板这些研发规范的对象对接不到真实的载体上,这显然是不对的。如果我们参考其他产品或工具的思路,会发现早已有解决方案,只是在工程交付上,没有明确把这个概念提取出来。很早之前就有了项目的概念,例如云效的项目管理工具 projex,第一步操作往往就是创建项目。项目是研发规范的天然承载体。进入到工程交付的层面,载体又不太一样。此时项目、代码库已不适合作为载体,因为具体的工作负载、服务、人员在很多时候并不能与代码库和项目一一对应。此外,大库模式或者一个应用涉及到多个代码库。所以在这样的情况下,需要一个名为应用的载体。以应用承载研发规范在模型上是清晰且合理的。因此,我们引入应用这个概念,并且产生了一个新的产品:云效 AppStack。应用对应于协作项目或者交付团队、团队空间或产品空间等。相对于项目下的需求,应用下的技术任务被定义为变更请求。
    1. 用应用研发流程代替流水线,保证研发规范被正确执行。首先,我们用应用研发流程代替流水线。因为流水线能定义研发阶段内部的逻辑,无法定义 2 个阶段之间的逻辑。我们引入了一个更上层的概念:研发流程。简单来说,我们认为研发流程就是 N 条流水线的组合加上流水线的准入限制。
    2. 用变更请求贯穿整个应用研发生命周期,保证信息被完整连结