作者介绍:以诺行CTO 刘自强 团队使用云效3年
杭州以诺行汽车科技股份有限公司(以下简称“以诺行”)成立于2016年8月,位于杭州市余杭区文一西路科技高地海创科技中心。以诺行是一家集研发、销售及服务为一体的科技型企业,主要核心业务包括汽车软件、 汽车喷漆及汽车配件,致力于用精湛的技术和超前的互联网思维打造汽车维修平台全新格局。
以诺行目前有以下软件产品
所有软件产品由以诺行软件部门进行开发维护。整个部门分为产品、设计、开发、测试和实施岗位,共30人左右。
因为软件产品线较多,各职能部门人手无法做到每条产品线专人负责,所以并没有采用项目制,而是由项目经理和产品经理根据需求优先级与开发资源情况安排开发迭代。因此每个迭代安排人手时,需要清楚的了解每个职能岗位的工作状态,开发过程中也要及时跟进开发进度,及早识别风险。
出于以上原因,我们需要选择或者自己搭建一套项目管理和持续集成系统,并且需要考虑以下因素。
最初,我们团队在自己的ECS服务器上搭建了开源的项目管理和持续集成工具,并经过配置实现了基本的需求。但是在使用一段时间后决定选择一款在线SaaS性质的项目管理工具,原因如下
1.管理效率低下
a.很多传统项目管理工具并没有非常直观的统计视图,需要将任务明细导出Excel再进行透视或者公式图表分析,无论是日常管理还是向公司提交汇报都很不方便。
b.缺少直观的日常统计,也会导致安排后续任务进度时得不到充分的数据支持,以至于进度安排过紧或过松,导致因赶工而产出质量下降或研发资源浪费。
2.运维成本高
a.开源产品部署后不易升级,大版本升级容易产生兼容性问题,并且可能需要重新调整配置。
b.资源存储在ECS上,对存储资源消耗较大,不过这个问题可以使用NAS服务缓解。
c.若日常使用时有较多截图,文档的读写操作,ECS带宽占用较大,容易导致ECS上部署的服务争抢带宽资源,而带宽成本较高。
d.后端技术转型,后端服务不再部署在ECS上,而是部署到了阿里云SAE(Serverless App Engine)产品,不再需要ECS。对于中小企业来讲,单独为项目管理工具保留一台ECS比较浪费资源。
我们调研了市面上比较流行的SaaS项目管理工具,部分功能满足我们的需求,但是普遍有以下的制约因素。
在调研试用各种项目管理工具期间,偶然在阿里云官网上看到了云效产品的推广,并且小微企业有一年期限的30人内免费。而云效可以基于阿里云RAM账号登录,并且对阿里云产品提供无缝对接,于是便开通试用了。
由于大部分研发人员需要对各种云产品进行查看管理,所以已经开通了各自的RAM账号。因此使用RAM账号对我们来讲并不是额外的负担,对于不使用RAM账号的企业来讲,云效也支持使用钉钉账号进行绑定。
为每一个员工建立阿里云RAM账号,并在云效中配置好部门和角色就可以开始使用了。
通过配置合理的项目管理功能,可以完成以下工作流程
其中涉及到了以下功能:
版本管理和迭代功能提供了便捷的手段来管理各种任务、计划和资源。管理者借此可以清晰的查看开发迭代进展,识别进度风险。产品部门也可以预先对任务进行分类、评审和排期。

需求模块提供了基本的需求管理功能,并支持自定义各种类型的字段、状态和工作流。
任务中可以关联各种文件任务资源和知识库条目作为附件,以更加丰富的媒体方式呈现需求内容。
进入开发的需求可以创建对应的子任务分配给研发人员,研发人员也可以快捷地打开关联需求查看设计细节。

在开发迭代之前或开发过程中,测试人员可以使用测试计划模块来管理测试用例,也可以将研发人员特地声明的风险加入的测试计划。借此可以有效的追踪每一个迭代的测试情况,避免有遗漏,也可以在复盘时进行回顾分析。
项目管理中可以根据现状来自定义各种基于工作流的任务,比如开发任务。通过配置好的状态和工作流,帮助各职能人员识别关注自己的任务,避免遗漏延期。


缺陷由测试人员发起,经过研发的修复,再由测试人员验证关闭。借此闭环来管理研发中或者线上突发的缺陷。

测试人员创建缺陷后,填写优先级和备注后指派给对应开发,也可以挂接到对应需求上面。
在动态栏中相关人员可以进行便捷的沟通。缺陷修复后标记为已解决并自动指派回测试人员进行验证,验证修复后关闭即可。
知识库是文档管理中心,可以依托于具体项目,也可以独立项目之外。提供了协同编辑能力,并具备细粒度的权限管理。

Codeup代码托管服务提供了完整的git仓库基本的功能,包括可视化的权限管理,代码合并,分支管理,Webhook等。
此外还提供了代码安全检测功能,比如代码中的明文密码,高风险的依赖包等, 比如这几天爆出来的log4j 2.14的高危漏洞。
报表功能也可以直观的追溯代码的提交评审行为,对于代码质量管理很有帮助。
值得一提的是,在代码库中可以一键开启WebIDE签出代码进行开发。在远程办公,紧急处理问题时很有帮助。

项目管理还提供了很多其它模块来促进项目人员间的共享和协作能力。
工作台中可以方便的追溯自己相关的工作,在日常工作中,每个岗位只需专注于“我执行的”页签内的任务并保证按时完成即可。
任务会根据截止时间和优先级进行分组排序,可以有效的帮助个人优先处理筛选出更加重要紧急的任务。
工作台同时提供了非常便捷的创建个人任务的功能,这类任务不依托于项目,可以很大程度上替代个人日常的TODO list。
"我执行的","我参与的"和"我创建的"页签基本上可以覆盖大部分对自己相关任务的管理场景,避免频繁的到具体项目的任务视图中查询。

云效流水线功能提供了从代码直到部署的流程配置。原生支持与代码仓库Codeup的对接,并且可以方便的配置各种Webhook触发器。
以下是我们软件产品的架构图:

对于后端应用,配置好Dockerfile后,流水线根据Dockerfile执行构建并且把制品上传到阿里云容器镜像服务产品中。在需要部署时,则把镜像推送给对应的SAE应用执行灰度部署。这些都是在流水线中原生支持的。
对于前端资源,流水线中调用webpack打包脚本生成制品,在需要部署时,推送到OSS服务的对应bucket即可。
以下是流水线的列表页面,可以自定义表头来展示运维人员关心的字段。


流水线配置中也有丰富的触发器可以支持手动/代码库行为/流水线联动触发等。
云效提供了丰富的统计功能,可以从各维度汇总数据。无论是内部管理还是对公司高层汇报,都可以方便的导出相关统计。
截止到当前,我们已有十多个应用产品线通过云效进行管理,其中核心应用已产生过万个任务,大部分都可以按时完成。

现在对于中小企业,基本都不会自己搭建服务器和机房进行部署,而是选择各大云平台,选择一款SaaS项目管理工具可以极大的降低运维成本。
而持续集成,选择一款可以与自己选择的云产品方便对接的平台也是非常重要的,尤其是现今Serverless应用越来越广泛,持续集成平台担负的任务也越来越重,需要谨慎选择。
对于核心功能托管在阿里云产品(如ECS, OSS, NAS, SAE, ADAS等)的企业,云效流水线可以提供原生的对接支持,也会在第一时间适配各云产品的新特性,可以让运维人员专注于对部署流程配置。
项目管理方面,云效提供了易用的项目管理,知识库,统计等功能,可以覆盖大部分的项目管理场景。
最后价格方面,现在云效常用基础功能免费开放,且不对使用人数做限制,对于中小企业节约成本非常友好。
以上内容是以诺行在实施使用云效后的效果,对于中小企业,基本都不会自己搭建服务器和机房进行部署,而是选择各大云平台,选择一款SaaS项目管理工具可以极大的降低运维成本。感谢以诺行CTO 刘自强及团队对云效的信任和肯定,希望云效可以陪伴他们不断进步。
如果你也有故事要分享,请留言联系我们,一起打造10倍效能提升案例集。
欢迎大家使用云效,云原生时代新DevOps平台,通过云原生新技术和研发新模式,大幅提升研发效率。现云效公共云基础版不限人数0元使用。
点击下方链接立即体验云效DevOps全家桶!
https://help.aliyun.com/document_detail/153739.html?channel=case

我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解