紧接上篇 TFS在项目中Devops落地进程(上)html
再接着说TFS相关以前先插入一个番外篇,虽然跟TFS关系不大但跟DevOps关系很大,以为有必要在此乱入一下。前端
咱们以前并无任何监控类产品(我指的是应用程序级别的),发生任何异常都是往数据库的表里insert个错误日志,all系统共用同一张错误表。git
这其实意味着咱们当时的系统是:系统异常基本不关注(线上数据库开发确定无法查对吧),关注的时候确定都出事了,对本身负责的系统的运行状态基本不了解,什么性能之类东西纯粹靠猜。程序员
而后我就但愿咱们能有办法获取到咱们系统的各类状态,而此时在VS2015的时候整合在VS里的application insights引发了个人关注。github
简要介绍下application insights,是微软基于azure所推出的一款SAAS性质的APM(Application Performance Management,应用程序性能管理)服务,本人不会详细介绍这个,详情可参阅官方文档。shell
而后也感谢我大学年代曾经当过MSP(微软校园菁英)并透过这个拿到过Visual Studio Enterprise的订阅,而后里面附赠的每月150美圆额度的Azure费用,让我有条件能够先试用Application Insights。数据库
而后本身将本身负责的站点搭上Insights作了个小Demo展现了给老大看,而后老大也对此表示满意。缓存
(Application Insights的概览图)服务器
在后续的一次PMO会上我将此拿出来进行了演示,也得到了CTO的承认和支持,而后终于能够将Application Insights投入到线上使用(固然此时用的是公司正式的帐号而不是我那个150刀每个月的测试号了)。网络
可是有Insights投入初期其余小伙伴热情度并不高,你们仍是以为记数据库挺好的,直到后面发生了一件事…
事情是这样的,那是一个要常规发布的夜晚,由于并无数据库相关的修改,因此DBA已经下班了(要加班到夜里发布,DBA只是正常下班),而后某站点发布上去的时候报错了,而后对应的开发小伙伴不知道为何,就知道出异常了。
而后此时DBA不在,没法查线上数据库,而后就干着急,最后经过在代码里让异常本地写txt临时解决了发布上的问题,但这个问题完整暴露出记录数据库的不靠谱:万一DBA不在呢?毕竟若是没数据库内容的话总把DBA留下来的话其实也不合理,咱们应该要从更长远和更科学的方案解决这个问题。
至此后续咱们全部项目加入Insights的进程就加快了,由于Insights里咱们能够自主的查看到性能/请求/异常等各类数据了。
另外有了Insights后咱们开发本身第一次有了本身的程序运行数据,有时候咱们也会针对Insights里的数据作一些对应的优化。
如上图,这是一个经过城市Id获取城市名称的接口,原先调用量巨大(当时设置了50%采样率,因此实际调用量要比图中翻一倍)可是其实这个接口返回的内容可变性不高,而后让前端加了缓存后从原来至少10K以上每小时调用量降低到如今100多的调用量,而这些都是由于咱们有了Insights以后才能进行的。
因此说:优化不能靠猜,咱们要用数听说话。
而Insights的Analysis功能/智能预警功能等特性也在实际中帮咱们解决了很多问题。
而后Insights也是能够跟TFS进行必定程度的整合的,其中主要包括自动发布的时候打上注解和在TFS的面板里查看Insights的信息
版本注解,有了这个咱们能够从监控系统里知道何时上了预发布环境
可添加在TFS上的widget(新版本的,详情可参看Application Insights: VSTS dashboard chart widget now available)
而后最近Insights里还有各类Preview的功能,好比新的Preview性能面板里能查看到95线/99线等,新的异常面板里还能给你分析出你异常的共同点之类的,Insights也一直在进步着。
在定型监控系统的时候咱们曾经议论过听云和是否自建服务端(当时肯定了监控的SDK都是用Insights的,可是纠结因而否基于ELK自建服务端)
听云:
老实说从默认的图表来讲,听云比Insights的图表更全面,但听云缺少一个Insights里有的一个很重要功能,查询分析Analysis:
在Insights的Analysis里,能够经过一个长的很像Sql的一种语句,能够快速查询你想要的任何原始数据(精确到每一条),此语句也能绘制图表,这个绝对是对程序员Friendly的一个功能
比方说出了异常,可能从运维层面更关注异常的趋势,而开发层面更关注的是具体的每个异常,和每个异常对应的每个请求等,另外听云由于是服务器层面的监控没法在代码层面埋点,咱们Insights里则埋了若是异常的话将错误请求的Body记录到Insights的Traces里,这样就算是Post/Put之类的请求报错咱们也能拿到原始请求报文。
自建服务端:
关于这个我以为在咱们如今连Redis啊队列啊这些更紧急的东西都没有落实的状况下在分出人力去搞这个,就担忧作出来后就是个永恒的1.0版本,以为相似这种东西除非说有专职负责这个的人/团队否则不该该自建,再说那个时候咱们组已经用Insights好一段时间了(有接近1年了吧)习惯了上面各类高级特性,而原始版的ELK则呵呵哒(一个自个买的原始毛胚房VS一个租来的豪华精装房),固然若是有专职人员专门投入到上面基于ELK作定制开发我相信也确定能作的跟Insights那样或者比Insights更好,可是,咱们有更多更紧急的事不是么?
不过却是有一点是由于费用问题咱们的Insights是使用了采样率的(就是说并非收集所有而是部分收集),可是咱们但愿异常不要被采样,因此后面可能要基于ELK搞个Exceptionless来专门记录异常。
另外Insights跟VS的整合也是棒棒哒,好比下面这样,直接告诉我哪一个方法发生了异常,直接反映在CodeLens里
原先整个TFS服务器的搭建和维护都在运维那边,那为何要拿出这个来讲呢?
首先咱们如今正处于一个快速发展的年代,什么框架啊每个月总能冒出几个,技术各类突飞猛进,虽然绝大多数企业本着稳定至上的原则不会说老是用最新,但这不是固步自封,不思进取的借口,在一个“最新”变为”稳定“以后总要试着跳出温馨区步入现代化进程吧?
而后咱们遇到的第一件事就是.Net版本升级,咱们计划升级到.Net 4.6.2(原来是4.0到4.5.1不等),而后由于自动打包的缘由因此要求Build Agent也要升级,而后原先运维部署配置的TFS是服务器+Build Agent放在同一个机器上的,搭载的是VS2015.
而后除了4.6.2以外的话咱们有个别类库项目使用上了.Net Core里全新的xproj格式来进行多target framework的开发,这也要求服务器上要有.Net Core的Sdk。
在另外此时在讨论到代码质量审核,而后咱们初定使用Sonarqube,而这个也要求Build Agent服务器要有Java的功能。
基于上述缘由外加后面咱们技术部某神秘人物毛哥批了一批(2台)服务器(也就通常工做电脑)资源给我,后面还有CTO批了一台大服务器(真·服务器,当时但是嘻嘻哒的心里),而后我开始本身搭建Build Agent。
当前咱们组自行维护的4台Build Agent,承载了包括持续集成,自动打包,代码分析,自动测试等一系列任务
装上了一堆如今要用或未来但愿想用的功能,知足当前及其可预见的一段时间内的需求
其实关于Build Agent主要以为这个必需要能适应开发组的步伐,首先咱们.Net 4.5->.Net 4.6.2的时候,要求Build Agent要支持.Net 4.6.2或以上,以后咱们有计划要上.Net Core(此时已经有基于.Net Core项目的Dll包了),并且以后.Net Core还有2.0版本(主要是NetStandard 2.0),因此我以为这个Build Agent在咱们组内的话咱们能更好适配咱们的前进步伐。
如今咱们的Build Agent里装的是Vs2017 17.3 + .Net 4.7 + .Net Core 2.0 + Docker 17.03.2-ee + CMake 3.9.1 + Python 3.6.2(x64) + JMeter 3.0 + F# 4.1 + Node.js 8.4(x64) + Java 1.8
估计小半年内基本都能知足需求。
接着上篇说,咱们有了本身的Build Agent,而后自动发布之类的基础功能也有了,因而咱们就有更高层次的自动化追求了。
首先就是自动化代码质量检查,在此先声明一点:任何自动化代码质量检查工具都不能代替人肉的Code Review,但能减小人肉Code Review的工做量。
而后在选型上咱们选了Sonarqube,固然大家会问为何选Sonarqube,说来惭愧其实我以前并不了解相关产品,而后在TFS商店里看到了这货而后才知道还能自动化代码检查…而后就去研究这货,发觉整体还能够(规则之类的啊,还有跨平台等),在跟咱们技术部神秘人物毛哥上报下技术选型得到认证后就拍板开始干。
经过本身手头有的服务器资源,搭建了个Sonarqube服务器,而后经过TFS的任务加上去
一个带Sonarqube分析的编译过程,做为C#程序员看上去好像一个using的结构(开始->释放)
某项目分析结果
好,而后代码分析质量有了,你们就能照着上面去“优化”代码了。
慢着,我写了一段代码,由于水平问题我也不知道有没有咖喱,而后一提交,而后上面就留下了一个永恒的污点(有历史记录的),这样确定很不爽,因此后面咱们就纠结有没办法可以让代码在进入到Sonarqube系统以前先有个反馈。
而后此时微软就发布了TFS2017,具体参考 TFS2017RTM Release Note
其中它引入了这么一个功能
在拉取请求的时候显示Sonarqube的分析结果(直接定位到你代码上),且该分析结果不记录到Sonarqube服务器里
接着怂恿下老大出面让运维那边帮忙升个级。
而后为了配合Sonarqube,那么每一个项目在Pull Request的时候都要进行编译的过程(编译了Sonarqube才能分析),所以也顺带加上了阻止合并不能编译的代码这个额外附加项。
赞成一次Pull Request须要一个非本人外的其余人赞成且要编译成功
而后审核人也能看到Sonarqube分析的结果就不用每行仔细看也能大概知道个因此然。
固然实践过程当中,看别人的代码发现很多什么超过3重if嵌套啊,类超过1000行啊这些,他们总说因为某些缘由实在很差改的,那就只能忍了(你能怎么办呢,特别是多重if的每每都是各类业务条件判断复杂,而后本身也没空深刻去看他们的业务),但本身项目要求要严格点,要严格控制不能出现任何形式的咖喱。
另外在此吐槽一点:TFS不能直接在Dashboard里浏览Sonarqube的结果,要看Sonarqube结果还要跳到Soanrqube里去,这不符合All in one的TFS理念啊,就没人想过弄个Widget什么的来解决解决这个问题?
自动测试在这里想主要分2块来讲,单元测试和集成测试。
首先我以为对于这2个概念尽管有很官方的说明但实践中不少人都有本身的理解,我简单说下我本身对上述2个词的理解和定义
单元测试:在代码内部进行的不依赖外部环境(网络/数据库等)进行的对某个方法级的测试,特色是只能测试一小块逻辑,能模拟数据且运行较快(毫秒级),代码执行结果可预测。
集成测试:多是代码也多是脚本依赖外部环境(网络/数据库等)进行的针对某个流程上的测试,特色是要造数据且运行较慢(至少是秒级),代码执行结果绝大多数状况下可预测(受外部因素影响不能100%可控)。
单元测试:
要让代码能够被单元测试,首先代码先要是可测试的,要如何作到代码可测试呢?答案很简单,随便街上抓一个伪计算机专业的都能给出你正确答案:解耦。
可是你要真的落实“解耦”到你的代码里,又每每是一个异常艰巨的任务(Talk is cheat, show me the code)。
首先在我本身负责的项目里,彻底使用依赖注入的形式重构了,另外抽象出了各类各样的接口,理论上要作到全部的”Service“都是能够”被替换”的。
严格限制对static和new这2个关键字的使用(绝大多数状况下static或者new都意味着不可测试,固然static一个数据无关的方法好比Math.Min之类的或者new一个纯数据类这些例外)
在本身一番折腾下,如今本身负责的项目单元测试覆盖率70%+,也算是一个本身比较满意的数字了(这个是Resharper收集的,它将单元测试项目自己也包含进去了的)
在单元测试的加持下,本身想重构代码什么的都能放开手去重构,有没有影响老逻辑?测试跑一下就知道了。
而加新逻辑的时候也能知道会对原有流程形成怎么样的影响。
总之有单元测试后,你会对你的代码更加倍有信心。关于单元测试看看往后是否专门开一篇文章来讲说,里面也有大学问。
上面说了那么多单元测试,那么它跟TFS有啥关系呢?测试写完了是吧?你怎么能确保它必定是有在跑呢?这时就能够将单元测试的运行整合在自动编译的流程里
整合到编译流程里的单元测试,每次跑完后会报告结果,若是单元测试失败那么会阻止pull request
在TFS主页的Dashboard里展现单元测试结果
集成测试
咱们的集成测试如今主要是QA那边负责,QA那边有基于Jmeter来进行的测试,具体细节由于不是我负责因此我不是特别清楚,可是在Build Agent里装好Jmeter后(QA配置好了各类他们要的插件的版本)而后在自动发布的时候运行下就行了
运行QA他们指定的Jmeter,先从一个位置拷贝配置文件过来而后运行命令行,没错,从TFS角度去理解的话它只是去执行个命令行而已
不过当前QA他们弄的Jmeter是运行后发一个结果邮件,若是可以将Jmeter的测试结果转变为TFS可接收的某种测试结果格式(什么JUnit或者Xunit之类的测试结果)展现到TFS上那就更好了(若是有会的人请赐教)
在集成测试方面我本身也有一套基于代码的(固然如今主流都是基于脚本了)
基于Specflow+xunit的方式我本身作了几个我旗下项目主流程的测试用例(就是那种一出问题QA就邮件出来:”测试环境挂拉“的那种)
基于Specflow的BDD形式的描述文档,尽量弄的贴近业务层面
描述文档背后对应的是若干代码
目前我本身这套集成测试仅放在Demo环境(第一个测试环境)使用,主要是一旦发觉个风吹草动,立马还原代码…(逃…
关于集成测试按道理此处应有以Selenium为表明的UI自动化测试,不过我本身主要负责的是接口,而后让折腾UI的那位同事目前也只是处于演示级阶段还没正式投入使用,此处就不献丑了。
固然TFS上还有管理手工测试等各类功能,不过因为QA组是基于Jira来管理任务因此并没使用。
尽管咱们当前在通过一番折腾后全组项目目前已经统一到.Net 4.6.2,但短期内也不会用上NetCore,但背后一直为了NetCore的迁移在默默准备着。
主要是考虑到在NetCore 2.0后出了个NetStandard2.0,它跟NetCore 2.0以及.Net Framework 4.6.1是兼容的。
那么咱们如今项目代码的目标都是兼容Netstandard2.0(底层类库),但以后真要迁移的时候就改个TargetFramework以及表现层稍微改下就行了(嗯,很丰满的理想)。
说这篇呢主要是分享一个,咱们如今TFS是2017Update2,在这个版本下你用常规方法是没法引用任何Netstandard2.0的包的(不信大家试试)
其本质是由于TFS2017Update2自带的Nuget还原工具是4.0版,而4.0是不支持NetStandard2.0,要4.3才能够,那难道咱们在现有的TFS下(2018又没Release)就拿NetStandard没辙了?
而后就找到了这篇文章Using the latest NuGet in your build
在这篇文章指引下,将它 那堆Powershell脚本 粘贴上去执行,下面参数写个4.3.0
而后使用自定义的nuget
而后就迎来了胜利的曙光
任务管理
虽然我司一直是基于Jira作任务管理的,不过由于Jira并不能直接跟TFS上的代码进行关联,因此我私自上是喜欢在TFS里建对应任务而后关联上去
还能跟代码里结合起来
在TFS里也能作可视化的关联查询
自动备份分支
这是最近折腾出来的小玩意
在Release里加上这个步骤(这是个插件提供的,插件详情请点此处)
而后在执行到对应发布步骤的时候就会自动将当前发布的代码拉一个分支出来,全自动的哟。
上面的大概就是咱们如今折腾TFS的成果,但咱们的道路远没结束,或者说,如今又处在某种程度上的开始。
首先,Docker这个大趋势确定以后或多或少都要涉足进去的(不过以为先将诸如服务发现之类的前置条件先搞定在作这个)
还有撇了下隔壁TFS2018的Release Note,这回引入了Wiki功能,回头可能能够直接在TFS上直接写上各类知识库文章了
还有想整个OWASP ZAP而后跟TFS流程整合下来个自动渗透测试分析什么的,让咱们自动化更上一层楼(if有空弄的话)。
大概就是扯那么多了。
The End。