近期,公司为了锻炼开发人员技能,举办了一场涵盖多个技术线的技能大练兵,我有幸受邀负责java技术方向的出题和评审工做。下面从如下几个方面回顾下整个过程:java
题目设计主要考虑如下几点:nginx
技术演进需求:在公司系统云迁移的战略背景下,咱们的应用即将从原来传统的虚拟机部署向PAAS云环境进行大规模迁移,须要开发人员掌握云环境的开发技能,应用开发框架须要从原来的SpringMVC+dubbo升级为SpringCloud服务治理框架。redis
新老员工兼顾:目前公司的开发人员构成中,入职一两年的新员工超过一半,题目设计须要考虑到新员工的技能水平,不宜难度过大,不然会打消新员工参与的积极性。同时,还须要能体现正真的技术实力,不能由于题目过于简单而使得分数拉不开差距。所以,题目设计要使你们都能完成基本功能,同时拿高分的难度较大。算法
解决生产难题:大练兵的初衷就是锻炼开发人员技术实力,提高企业级应用的开发技能,更好的完成平常任务,最终要解决生产难题,保障线上系统稳定。相似力扣网上的算法题,不适合做为这次大练兵的题目。sql
基于以上几点考虑,最终题目设计以下:docker
完成一个交易系统:
产品子系统(product)、订单子系统(order)、积分经验子系统(experience),3个子系统完成分布式部署和调用。
业务场景:
一笔交易过程当中,产品子系统要扣减库存,订单子系统要新增订单,积分子系统要有相应的积分增长。积分规则为每消费1元增长1积分。数据库功能要求:缓存
完成5只接口:下单、查询库存、查询订单、查询积分、我的交易信息概览框架
题目意在考察你们在完成基本功能的同时,如何保证数据的一致性。分布式
根据前期统计的报名意向来看,预计会有50人左右提交比赛交付物。这么多交付物若是要依靠线下演示评审打分的话,周期很长,并且须要人工部署调试,带来巨大的工做量。所以,必须使用自动化的方式进行打分。同时为了控制程序实现范围,防止开发人员无限蔓延开发需求,增长过多考察范围以外的扩展,所以对程序作了如下限制:
中间件限制:因为本次大练兵意在为后续的云迁移作技术储备,所以中间件的选型必须控制在云上中间件的范围内,所以要求使用SpringCloud+consul的服务治理框架、Nginx软负载等中间件,不能使用Apache、Dubbo等云上不用的中间件。
数据格式:题目提供3个子系统中核心的数据库表结构,例如产品信息表、订单信息表、用户经验表等。同时给出5个接口的上送和返回字段,全部人必须按照此格式对前提供服务。
组包格式:因为决定要实现自动化的打分程序,就必需要统一组包要求,包括压缩包的目录层级结构、sql脚本格式、nginx配置文件、start和stop脚本等。题目要求必须实现3个模块(product、order、experience),同时提供了一个可选的其它模块(other),参赛者可根据须要本身实现,如网关、聚合服务等功能均可以放在other模块实现。other模块组包要求同其它3个模块一致。
本次题目主要的考察难点是如何保证数据的一致性。可是因为测试环境是同网段的机器,内网测试环境很是稳定,在正常的程序运行过程当中,很难发生数据不一致的状况。如何产生使数据可能不一致的事件,是本次出题的重点。
所以除了以上几个限制,本次大练兵还引入了一个大杀器:chaos-monkey。
chaos-monkey:是由netflix开源的一款软件,它能在生产系统中随机产生异常事件,包括超时、程序异常、宕机等。chaos-monkey的想法源自于“混沌工程”。
混沌工程,是一门对系统进行实验的学科,旨在了解系统对应生产环境各类混乱情况的能力,创建对系统的信心。经过开展混沌工程方面的实验,能够测试出系统是否存在缺陷,从而了解系统在混乱的生产条件下如何表现。
chaos-monkey的原则,避免大多数失效的主要方式就是常常失效。经过常常在生产环境制造故障,以保证生产环境的弹性。
本次比赛提供了chaos-monkey的jar包和配置,要求参赛者必须引入,以模拟超时或者异常,从而引起数据不一致,测试程序的健壮性。
测试主要分为两步骤:自动部署和自动测试。
服务拓扑图以下:
全部选手的交付物都提交到统一的ftp目录,所以从ftp中遍历文件并触发部署便可。
流水线步骤以下:
for(遍历ftp上的包) 清除redis缓存 执行题目提供的sql建表语句,初始化数据库 从FTP获取压缩包,并解压 If(有nginx配置文件) 替换nginx配置文件,并重载 else 分发默认的nginx配置文件,并重载 执行铺底数据脚本 For(遍历服务个数) 按规则将各个服务压缩包分发至各服务节点 if(存在额外的init.sql) 执行init.sql 执行服务的启动脚本start.sh 运行测试脚本,收集测试结果,计算分数,并输出到CSV文件 中止各服务
一般状况下,自动部署使用Jenkins实现。可是Jenkins不支持循环遍历,一个job只能完成一个参赛者的部署和测试。若是每一个参赛者一个job,不能保证每一个job配置的正确性,而且因为只有一套评审环境,每一个人一个job的话,不能保证job的串行执行,多个job同时执行会相互影响。所以决定本身编写部署脚本,仅在部署完成后,须要测试时触发测试job,由测试job完成测试和打分。部署脚本监听测试job的状态,测试完成后,再开始执行下个参赛者的部署流程。
公司原本就具有完善的Robot Framework自动化测试基础设施,本次测试直接使用便可。因为部署程序已经在程序启动前完成了数据库和缓存的初始化,所以测试程序仅需读取测试数据并向Nginx发起调用便可。
因为要测试程序异常时,数据的一致性,所以要在测试开始以前开启chaos-monkey,在执行写入数据的逻辑后(即下单接口),关闭chaos-monkey,再开始查询,经过查询各个接口的数据并于写入的数据相比对,验证数据的一致性,并打分,步骤以下:
1.开启各服务的chaos-monkey功能;
2.执行写数据的测试脚本,即调用数百次下单接口;
3.关闭各服务的chaos-monkey功能;
4.执行单个数据查询接口,验证每一个接口的可用性,并记录分数;
5.执行组合验证逻辑,验证多个服务的数据一致性,并记录分数。
每一个参赛者的测试执行完成后,要将计算的分数写入汇总到csv文件中。拿到最终的csv文件后,便可利用excel实现按照成绩排序。
经过本次大练兵,有如下几点思考:
最后,感谢你们对个人容忍。2021,愿全部程序都不出bug!