Archive for the '技术相关' Category
互联网产品的灰度发布
在传统软件产品发布过程中(例如微软的Windows 7的发布过程中),一般都会经历Pre-Alpha、Alpha、Beta、Release candidate(RC)、RTM、General availability or General Acceptance (GA)等几个阶段(参考Software release life cycle)。可以看出传统软件的发布阶段是从公司内部->外部小范围测试>外部大范围测试->正式发布,涉及的用户数也是逐步放量的过程。
在互联网产品的发布过程中也较多采用此种发布方式:产品的发布过程不是一蹴而就,而是逐步扩大使用用户的范围,从公司内部用户->忠诚度较高的种子用户->更大范围的活跃用户->所有用户。在此过程中,产品团队根据用户的反馈及时完善产品相关功能。此种发布方式,按照中国特色的叫法被冠以”灰度发布“、”灰度放量“、”分流发布“。
关于“灰度发布”叫法的来源无从考察。只不过按照中国传统哲学的说法来看,很符合中国人中庸的思维模式:自然界所有的事物总是以对称、互补、和谐的形式存在,例如黑与白、阴与阳、正与负、福与祸。在二元对立的元素间存在相互过渡的阶段,所谓”祸兮福所倚,福兮祸所伏“。具体到黑与白,在非黑即白中间还有中间色——灰色。于是出现了很多关于灰色的说法:灰盒测试,灰色管理(极力推荐 任正非:管理的灰度),灰色收入,灰色地带等等。因此对于灰度发布实际上就是从不发布,然后逐渐过渡到正式发布的一个过程。
1、灰度发布的作用
- 及早获得用户的意见反馈,完善产品功能,提升产品质量
- 让用户参与产品测试,加强与用户互动
- 降低产品升级所影响的用户范围
- 。。。
2、灰度发布的步骤
1)、定义目标
2)、选定策略:包括用户规模、发布频率、功能覆盖度、回滚策略、运营策略、新旧系统部署策略等
3)、筛选用户:包括用户特征、用户数量、用户常用功能、用户范围等
4)、部署系统:部署新系统、部署用户行为分析系统(web analytics)、设定分流规则、运营数据分析、分流规则微调
5)、发布总结:用户行为分析报告、用户问卷调查、社会化媒体意见收集、形成产品功能改进列表
6)、产品完善
7)、新一轮灰度发布或完整发布
3、常见问题
3.1)、以偏概全
1)、问题特征:
a、选择的样本不具有代表性;
b、样本具有代表性,但选择样本用户使用习惯并没有涵盖所有核心功能
2)、解决方案:
样本选择要多样化,样本的组合涵盖大部分核心功能
3.2)、知识的诅咒
”知识的诅咒“的说法来自《粘住》中实验,具体可以自己搜索一下。我们自己对于自己开发的产品极为熟悉,于是乎想当然认为用户也应当能够理解产品的设计思路、产品的功能使用。
1)、问题特征:
a、结果没有量化手段;
b、只依赖于用户问卷调查;
c、没有web analytics系统;
d、运营数据不全面,只有核心业务指标(例如交易量),没有用户体验指标
e、对结果分析,只选择对发布有利的信息,对其他视而不见
2)、解决方案:
a、产品设计考虑产品量化指标
b、结果分析依据量化指标而不是感觉
3.3)、发布没有回头路可走
1)、问题特征:
a、新旧系统用户使用习惯差异太大,没有兼容原有功能
b、新旧系统由于功能差异太大,无法并行运行,只能强制升级
c、新系统只是实现了旧系统部分功能,用户要完整使用所有功能,要在 在新旧系统切换
d、新旧系统数据库数据结构差异太大,无法并行运行
2)、解决方案:
前期产品策划重点考虑这些问题,包括:
回滚方案、 新旧系统兼容方案、用户体验的一致性、用户使用习惯的延续性、新旧系统数据模型兼容性
3.4)、用户参与度不够
1)、问题特征:
a、指望用户自己去挖掘所有功能。对于一个产品,大部分用户经常只使用部分功能,用户大部分也很懒惰,不会主动去挖掘产品功能
b、互动渠道单一
c、陷入“知识的诅咒”,不尊重参与用户意见
2)、解决方案:
a、善待吃螃蟹的样本用户,包括给予参与测试的用户小奖励(例如MS给参与Win7测试用户正版License)、给用户冠以title
b、通过邮件、论坛、社区、Blog、Twitter等新媒体与用户形成互动
c、提供产品功能向导。在hotmail最近的升级后的功能tip,gmail的tip都有类似的产品功能导向。在产品中会提示类似于:你知道吗,xx还提供xx功能,通过它你可以xx 。
4、灰度发布 VS. A/B测试
灰度发布于互联网公司常用A/B测试似乎比较类似,老外似乎并没有所谓的灰度发布的概念。按照wikipedia中对A/B测试的定义,A/B测试又叫:A/B/N Testing、Multivariate Testing,因此本质上灰度测试可以算作A/B测试的一种特例。只不过为了术语上不至于等同搞混淆,谈谈自己理解的两者的差异。
灰度发布是对某一产品的发布逐步扩大使用群体范围,也叫灰度放量
A/B测试重点是在几种方案中选择最优方案
关于A/B测试可以参考这篇文章:A/B测试终极指南
5、灰度发布引擎
对于一般的小系统并不需要单独的灰度发布引擎,可以参考A/B测试中做法,在页面javascript或服务器端实现分流的规则即可。但对于大型的互联网应用而言,单独的用于管理用户分流的发布引擎就很有必要了。“钱掌柜”分流发布模式 提到了原来阿里软件所使用的灰度发布引擎,设计思路具有普遍性,可以供参考
6、参考文档
复杂事件处理(Complex Event Processing)入门1
一个新产品需要重点考虑业务风险控制。关于风险控制系统整体的技术方案可以参考 支付系统风控系统建设思考 。此方案尽管能够满足业务需求,但对于海量交易数据分析、风险事件的实时处理、大量的风险规则处理上,在实时性、性能、架构的可扩展性上都不是很理想,有必要重新从架构上考虑一下实现方案。
一般而言,风险控制系统标准的软件架构如下:
1、风控系统实现的几种方案
1)、数据库方案:将风险规则、交易数据等都采用关系数据库存放。正如 支付系统风控系统建设思考 所提到的方案,交易库和风险库一般分别部署在不同的服务器上,在事件触发上可以采用数据库触发器、消息队列事件等方案。此种方案技术实现相对简单,但在进行海量交易数据查询以及大量风险规则处理时候,数据库系统查询性能及扩展性成为一个较大的瓶颈。很难满足风险事件实时分析的要求。
2)、内存数据库方案:由于对海量交易数据的查询、分析极其消耗数据库资源,可以采用内存数据库方案来替代关系数据库,保证风险事件实时处理的性能。 但目前开源的内存数据中VoltDB、H2、MonetDB、FastDB、Berkeley DB、SQLite等在大规模的业务场合应用的成熟度尚待考察,而Oracle TimesTen、MCObject eXtremeDB、Altibase价格太高。
3)、分布式缓存方案:采用Memcached等NOSQL的分布式缓存来缓存交易数据、风险规则等,但由于NOSQL解决方案并不擅长数据间的关系逻辑处理,需要在程序中大量维护业务处理逻辑,远不如关系数据库或内存数据库方案方便。
以上方案,都可以通过规则引擎(例如drools)来完成风险规则的管理和维护,避免了风险规则维护的繁琐及规则间复杂关系处理。
2、Complex Event Processing (复杂事件处理)
Complex Event Processing (复杂事件处理)是一种新兴的基于事件流的技术,它将系统数据看作不同类型的事件,通过分析事件间的关系,建立不同的事件关系序列库,利用过滤、关联、聚合等技术,最终由简单事件产生高级事件或商业流程。CEP适合的场景包括实时风险管理、实时交易分析、网络诈欺、网络攻击、市场趋势分析等等。
CEP的几大特点:
- 基于数据流
- 时间序列
- 实时
- 复杂
数据库方案与CEP方案 对比(摘自Sybase CEP方案)
3、开源项目
Esper – Complex Event Processing
JBoss – Drools Fusion
http://www.jboss.org/drools/drools-fusion.html
Open ESB IEP SE
http://wiki.open-esb.java.net/Wiki.jsp?page=IEPSE
ActiveInsight
其他产品或开源项目,可以参考:Complex Event Processing Vendors
其中Esper和Drools Fusion很值得考虑,后续作为重点研究对象。
4、参考资料
Complex Event Processing:An attempt at clarity on an often confusing topic
互联网产品重构
1、为什么要进行产品重构
旧系统人员流失,系统的业务规则、原始需求谁都不清楚,需求文档、使用文档、架构文档极其缺乏,成为一个无底洞,可维护性很差。
旧系统越来越复杂,潜规则太多,原本修改一个小需求,一不小心搞得上线后影响一堆用户
旧系统的业务架构、技术架构无法满足新的业务模式需要
旧系统性能无法满足公司业务高速发展的需要
旧系统的产品生命周期已经到头,需要延长期生命周期
等等
2、产品重构 VS. 重做新产品
对现有产品进行重构还是重新做一套全新的系统并没有标准答案。技术人员们都倾向于重做新系统,并都倾向于高估自身的管理能力、架构设计能力,大家都会承诺完美的架构、完美的产品规划。但如果没解决根本性的管理问题,重构或是重做宿命都是一样的。这些管理问题包括产品规划能力、业务架构能力、项目管理能力、架构管理能力、架构设计能力等等。
在管理能力尚未改善的情况下,怎样保证重做新系统时候不落入旧系统“新做系统,承诺完美架构->管理失衡,系统维护陷入混乱->再重做新系统”同样的命运。好的架构是管理出来的,不是设计出来的。
产品重构第一困难的是反向工程过程阶段,必须搞清楚现有系统的遗产状况。对于一个在线运营的系统,不管是重构还是重做都必须经历此过程
产品重构第二困难的是旧系统迁移到重构系统的过程。怎样做到不影响现有客户使用的情况下完成灰度切换,这是最大的挑战。不管是重构或是重做都必须经历此过程
3、关于产品重构的思考
4、参考资料
不可能完成项目的Scrum实践
某一天老板或者销售人员跑过来亲切和蔼地拍拍你说:有个战略性产品需要在一个月之内开发出来,对搞定几个重点大商户至关重要,时间没有商量的余地。党组织从众多的党员同志中选择了你,这是党对你的信任,也是考验你的时候了。在生活的压力和生命的尊严之间,你只好泪流满面地接了下来。
1、不可能完成项目的典型特征
对于互联网公司及做传统系统集成的公司的同志们而言,接到这样不可能完成的项目开发任务的情况已经司空见惯了。这些不可能完成项目的典型特征如下:
- 老板说:项目对公司具有战略意义,必须搞定
- 项目突发:销售跑过来告诉你,一个月内必须搞定这个项目
- 需求不明确
- 对现有系统架构有较大冲击,改动风险很大
- 项目给的时间很短且交付时间固定(time boxing) ,只能够倒推
- 销售过度承诺,必须实现狂复杂、狂大的需求
- 资源有限
- 设计诸多部门协调,很难短期搞定
2 、失败项目的典型症状
- 项目组所有成员及利益相关者对项目愿景及目标没有达成一致
- 为了赶进度,压缩需求分析、系统设计时间,需求理解尚未统一就投入开发
- 每个人只关心自己负责的一小块业务,对系统整体需求、架构、设计没有达成一致
- 为了赶进度,只关注功能的完成而忽视了功能实现的质量,导致大规模的返工
- 为了赶进度,不进行统一设计,由各模块负责人自己设计,设计存在较大缺陷
- 公用问题没有专人负责,工作重复
- 项目组成员沟通不畅,出问题后才沟通,导致无谓的时间浪费
- 项目组没有形成团队文化,团队成员只是为了完成项目目标而加班赶工,没有归属感
3、不可能完成项目的Scrum实践
对于这样的不可能完成项目的管理使用Scrum这样的Time Boxing迭代开发过程很恰当,关于实践方法有兴趣的可以参考脑图。
4、参考资料:
互联网敏捷开发配置管理策略思考
由于互联网行业需求变化快、开发迭代周期短、上线频繁的现实状况决定了合理的软件配置管理策略对于软件质量保证、协作开发效率至关重要。
目前公司配置管理在策略上采用的是不稳定主干(unstable trunk)模式,所有的项目都在同一主干上进行修改,在每周上线后并没有明确的stable分支版本,基本上是靠SCM人员手工拷贝代码来管理维护的。这就引起了很多问题:
1)、多个项目组开发人员都可能并发对同样代码进行修改,造成了严重的代码冲突问题。例如张三修改了a.java并上QA测试服务器,在QA测试过程中,李四也对a.java进行修改并上QA,李四的代码覆盖了张三的代码。由于是SCM人员并不清楚代码冲突情况,这样张三和李四的代码上QA很容易相互影响并很难查具体原因
2)、由于没有明确stable分支版本,导致上QA、上生产只能采用增量更新,上QA、上生产出问题后的代码回滚很麻烦,严重影响了测试、上线效率。对于生产环境运行的代码的具体版本并没有明确的管理,导致生产系统出问题后要排查问题也很难查。
3)、由于核心基础包没有与上层应用隔离,导致大家都会对核心包进行修改,修改后代码质量并没有有效控制。于是出现因为修改基础包影响整个系统功能等现象
类似的问题很多。要在新的项目实施及后期运营中避免类似问题的重现,至少要从如下几个方面来:
1)、分支管理策略:采用适当的分支管理策略来保证开发库、测试库、发布库的隔离
2)、适当引入每日编译、持续集成、Code Review等敏捷开发的最佳实践
3)、采用自动化脚本完成上QA、上生产的部署工作,避免人工失误
4)、对核心框架、后台应用、前端页面开发采用不同的配置管理策略
1、分支策略(Branching Strategy)
代码分支管理策略一般分为3种(参考Branching Strategy Questioned)
1)、不稳定主干策略(The unstable trunk strategy)
此种分支策略使用主干作为新功能开发主线,分支用作发布。此种分支管理策略被广泛的应用于开源项目。比如freebsd的发布就是一个典型的例子。freebsd的主干永远是current,也就是包括所有最新特性的不稳定版本。然后随着新特性的逐步稳定,达到一个发布的里程碑以后,从主干分出来一个stable分支。freebsd是每个大版本一个分支。也就是说4.x,5.x,6,x各一个分支。每个发布分支上只有bug修改和现有功能的完善,而不会再增加新特性。新特性会继续在主干上开发。当稳定分支上发生的修改积累到一定程度以后,就会有一次发布。发布的时候会在稳定分支上再分出来一个 release分支。
此种分支管理策略比较适合诸如传统软件产品的开发模式,例如微软Windows开发,对于互联网开发不是很适合。已经在主干上集成的新功能,如果达不到里程碑的要求,稳定分支就不能创建,很有可能影响下一个发布的计划。还有一个问题就是bug修改必须在各个分支之间合并。
2)、稳定主干策略(The stable trunk)
此种分支策略使用主干作为稳定版的发布。主干上永远是稳定版本,可以随时发布。bug的修改和新功能的增加,全部在分支上进行。而且每个bug和新功能都有不同的开发分支,完全分离。而对主干上的每一次发布都做一个标签而不是分支。分支上的开发和测试完毕以后才合并到主干。
这种发布方法的好处是每次发布的内容调整起来比较容易。如果某个新功能或者bug在下一次发布之前无法完成,就不可能合并到主干,也就不会影响其他变更的发布。另外,每个分支的生命期比较短,唯一长期存在的就是主干,这样每次合并的风险很小。每次发布之前,只要比较主干上的最新版本和上一次发布的版本就能够知道这次发布的文件范围了。
此种分支策略的缺点之一是如果某个开发分支因为功能比较复杂,或者应发布计划的要求而长期没有合并到主干上,很可能在最后合并的时候出现冲突。另外由于对于每一分支都要进行测试才能够合并到主干中,测试工作量较大。
3)、敏捷发布策略(The agile release strategy)
此种模式在采用敏捷开发模式(例如Scrum)的项目中广泛采用,这些项目有固定的迭代周期(例如Scrum中每个Sprint的两周时间),新的功能开发都在Task branch(Feature branch)上进行,在接近迭代周期的发布阶段时候,新建Release branch来完成本迭代周期的发布,各Task branch(Feature branch)的功能merge到Release Branch中。在完成发布后,Release branch的功能merge到Trunk和尚在进行的Task branch中。
采用敏捷发布策略要求主干的版本:
- 任何时候都可以发布 :在任何时候,产品所有者都可以基于主干的最新版本,发布新版本的产品
- 希望尽早发布
此种模式较适合敏捷开发软件的要求,但对程序员及SCM要求较高。
关于敏捷发布策略可以参考:多个敏捷团队之间的版本控制
2、配置管理策略
根据目前公司的实际情况,建议采用稳定主干策略为主(The stable trunk)。参考淘宝网最佳实践之ABS自动编译 可以看到,淘宝也采用了类似的版本管理策略。
具体操作策略如下(尚需要细化):
1)、trunk保持稳定,保证可以随时发布。trunk只有SCM人员才具有写权限,开发人员等只有读权限。
2)、为降低SCM分支管理的压力,branch的权限可以授予给指定的几个组长
3)、在每一个项目开始前,采用Branch per feature(Branch per Task)的分支管理模式(Common Branching Patterns),由各组长或SCM人员按照branch管理规范建立对应项目的开发分支development branch,例如airline_product1_feature_leader_date、airline_product2_bug_leader_date。
项目定义:新功能开发、bug修复、需求变更等
4)、在每周的上线发布后,在主干建立基线release版本(通过svn tag),以当前的主干作为基线,建立下一发布周期的test branch
5)、开发人员在所在项目的development branch完成开发及集成测试后提交上线单,由SCM人员根据项目上线单的分支名称merge分支代码到本发布周期的test branch,进行测试。如果在测试过程中有新的上线单且有可能与其他上线单存在冲突,则在merge到test branch的过程中,SCM人员可以很容易及时排查问题。
只要对上线单命名按照规范进行定义(例如与分支名称相同),此部分工作可以由脚本来自动化,存在冲突再人工干预。
6)、测试人员完成本发布周期test branch所有上线单的功能测试后,由SCM人员将本发布周期的test branch合并到trunk,并通过打tag来release 一个上线版本
7)、系统人员利用自动化部署脚本从trunk检出对应的release版本进行上线部署
此部分工作采用自动化脚本完成,自动化脚本主要完成如下操作:从trunk检出完整的release 版本并打包,并包含部署包的md5验证码-> 上传部署包到生产系统各服务器->校验发布包的md5验证码是否正确,保证文件正确传输->完整备份生产系统的运行包->部署生产系统
8)、每日晚上对trunk进行持续集成,保证能够正常编译和部署。工具建议采用hudson
9)、对于核心代码及后台代码的修改,采用Pre-commit review模式,必须通过code review后,才能够提交到trunk中。工具可以采用reviewboard
10)、其他一些值得讨论的问题
开发分支的生命周期问题:上线后,原有的development branch变为只读的或者可以定期删除掉。
紧急上线策略:紧急上线不遵循每周两次的上线周期,因此对于需要紧急上线的程序可以从trunk检出最近的release版本代码建立临时测试分支(test branch),紧急上线仍然需要按照规范建立对应的development branch,然后与临时测试分支合并,测试通过后上线,同时由SCM人员将紧急上线的development branch合并到当前的测试分支,继续进行测试。
不同项目的配置管理策略:对核心框架、后台应用、前端页面开发可以采用不同的配置管理策略,例如核心框架可以采用不稳定主干策略(The unstable trunk strategy);后台应用采用稳定主干策略(The stable trunk)
3、版本控制工具选择
SVN的集中管理模式较为适合目前公司协作开发的需要,例如SVN所提供的集中式权限控制,对代码、二进制文件及文档的集中管理,类似TortoiseSVN的支持工具以及Eclipse 插件等。而Git/Mercurial(hg)的分布式管理特性,很适合开发人员本地版本开发管理。
因此可以结合SVN和Git/Mercurial(hg)来作为版本控制工具。用SVN进行集中管理,用Mercurial(hg)在多个不同机器上进行开发,功能完善并测试完成后再提交至 SVN Repository。可以借助git-svn、HgSubversion、hgsvn这样的工具来结合使用。考虑到目前的开发环境为Windows环境,建议采用Mercurial。
值得一提的是SVN从1.5版本开始,对branching merge的支持有很大的提升,大大简化了分支合并的难度,可以参考What’s New in Subversion 1.6?。
4、一些工具
code review
持续集成
自动部署
商业软件中采用atlassian的系列产品倒是不错的选择:Jira+Crucible+FishEye+Bamboo
5、参考文档
http://www.programmer.com.cn/3223/
http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.branchmerge.commonpatterns.feature
http://martinfowler.com/bliki/FeatureBranch.html
http://codicesoftware.blogspot.com/2010/03/branching-strategies.html
http://msdn.microsoft.com/en-us/library/bb668955.aspx
http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx
http://www.cmcrossroads.com/bradapp/acme/branching/
http://www.vance.com/steve/perforce/Branching_Strategies.html
http://blog.gravityfree.ca/2009/02/using-feature-branches.html
http://blogs.open.collab.net/svn/2008/07/subversion-merg.html
http://thinkernel.bokee.com/4518935.html
http://www.infoq.com/cn/articles/agile-version-control
Comments(7)