被校园卡升级点燃的“爆点”

    2017年6月,我们完成了校园卡核心软件升级,经过一段时间的试运行和调整,升级后的系统基本运行稳定。其实,大家心中都明白,对升级后系统的最大考验将发生在新生入学之时,届时,将新发超过9000张的校园卡。8月20日,本科新生3832人报到,迎新现场热热闹闹,一切顺利,但与校园卡相关的问题陆续出现,首先是一批新生在入驻的宿舍一打开水就锁卡,解卡后去打开水再次被锁;然后就是一批新生不能刷卡进入图书馆大门,图书馆的老师只能让学生拿着卡到图书馆人工进行处理。

    这两个与校园卡相关的问题给新生的生活带来了明显的不便,经过紧急抢修与协调,打水锁卡的问题先得到解决,图书馆的问题也在第三天得到解决。9月1日研究生报到,校园卡运行顺利。在解决这些问题的过程中,经历了不少无奈,还是颇有点意思的。

前行:必须背负历史

    先说说锁卡之事。开发校园卡的某科公司关于锁卡原因的直接解释是:用“非法”卡进行消费。所谓“非法”:一是校园卡上保存的余额与后台数据库中的余额有“明显差距”(这个是一个BUG,会产生另一个故事);二是校园卡被注销进入了“黑名单”(这是本次故事的引子),为了保证用户在断网情况下仍然可以刷卡消费,所以黑名单必须保存到终端设备(诸如消费POS机、水控机等)中。

    本次锁卡的直接原因是安装在宿舍的终端设备(水控设备)在暑期维修宿舍时断网脱机了,脱机后的终端设备中保存的黑名单是老的,宿舍维修之后终端设备没有及时联网,因此黑名单就没有及时更新。解决方案比较简单,马上恢复全部离线终端设备的网络,系统重新下发最新的黑名单。

    再仔细分析会发现一个明显的问题,卡被锁是因为黑名单,为什么新生的卡会在黑名单中?按照常规理解,新发的卡应该直接可用。公司最初给的解释是,新发的卡编号要进入“白名单”,白名单与黑名单都要存到终端设备中。显然这样的解释无法满足我的好奇,经过与公司多次技术讨论和质疑,最后只能回溯到校园卡最初的系统设计。

    我校目前使用的还是M1卡,设计之初每张卡有三个编码:卡ID(生产每张卡片时产生的,N位长的全球唯一编码)、学工号(全校10位的标记到每个人的唯一编码,打印在校园卡上,学生日常使用)和卡编号(8位的数字,用户不可见,校园卡系统内部使用)。

    卡编号是关键。为了保证校园卡在无网情况下正常刷卡消费,全部终端设备(POS机和水控)中必须保存一个黑名单,进入黑名单的卡是不能消费要被锁卡的。所谓黑名单就是“卡编号”列表,无论何种原因,只要注销了一张校园卡黑名单中就会产生一条记录。

    理论上“8位数字”的卡编号可以支撑千万级别的发卡量,但这只是表面现象,由于终端设备存黑名单的存储器容量有限,所以黑名单的长度被终端设备的存储容量决定了。进一步,为了保证终端设备快速查询黑名单,采用bit-map技术,终端设备中存储的数据即是“黑名单”,也是“白名单”。因此,终端设备硬件的存储容量直接决定了校园卡的发卡总量,所以,实际的发卡量不能超过26万张!这就完美解释了,为什么公司反复强调8位的卡编号前3位要保持为0,也解释了卡编号为什么只能是从0开始的连续26万个数字编码,同时也解释了不论黑名单记录有多少,每次下发黑名单的时长为什么是一样的。

    呵呵,“26万”是问题的关键。我们的校园卡系统已经运行超过了15年,累计各种发卡的数量在今年已经接近极限,黑名单累计也超过了8万,于是公司决定重新启用一批早期已经注销的卡编号(即至少三年前已进入黑名单的老的卡编号)。从理论上说,启用老的卡编号也没有问题,只要及时更新各个终端设备中的黑名单也就可以正常使用。可理想很丰满,现实很骨感,几千台正在运行的终端设备中,总有离线的设备,特别是在大规模修缮后,终端设备离线情况就更多,于是新生开学后只要使用了离线的终端设备,锁卡就在所难免。

    那么,是否可以打破这个26万的限制呢?当年的软硬件设计已经很难改变了,存储容量升级后的终端设备已可以保存52万条,但软件的更新对于开发校园卡的公司来说,几乎就是颠覆性的。于是现在只能在原来系统的基础上打补丁。

前行:必须环顾左右

    再说说图书馆进不了门的问题,这也是由卡编号重复使用引爆的。

    目前运行的图书管理系统之初就是独立建设的,后来加上了门禁和自助借还书等与校园卡相关的设备,但图书系统并没有与校园卡系统进行有效数据连接,目前还是靠手工导入校园卡数据。即,在新生入校时一次性手工初始化数据。同时,学生在更换新卡后也要亲自到图书馆再进行一次“换卡”操作,才能保证在图书馆中正常使用校园卡。

    本次新生入校时,当校园卡系统将学工号与卡编号对照表发给图书馆后,图书系统的管理员发现,有一批新生使用的卡编号是“老”编号,但这些“老”编号对应的学生还没有毕业,校园卡在图书系统中还是有效的!于是图书系统坚决拒绝让这批“老的”新生的数据入库!于是就出现了大批新生被拒绝在图书馆门禁之外,要到图书馆排队进行人工处理。显然,这是由老的卡编号重复使用带来的新问题。

    再一个意思的事情出现了。对比图书管理与校园卡系统中的典型数据,根据图书系统中出现冲突的卡编号的学生信息,到校园卡系统查找,发现该学生正在使用的校园卡是另一个卡编号。即该学生日常消费正在使用的卡编号并没有出现在图书系统中,该生在图书系统中记录的有效校园卡是已在校园卡系统中注销的老卡。呵呵,显然,这个学生在上次更换校园卡之后(不少于三年的时间)就再也没有进入过图书馆,更没有借过书!

    呵呵,还是数据不同步,又是脱机惹的祸!问题找到,制定一个放新生进门的临时性解决方案并不难,校园卡系统与图书系统的技术人员再人工配合一次即搞定了。

    锁卡问题解决了,但图书馆的技术人员告诉我:卡编号重复使用给他们造成的麻烦,不是简单修改就可以解决的,搞不好可能会使他们“损失历史信息”,即老生原来的借书信息(尽管学生借的书已经还回,借书信息已经成为历史)。对此,我真心没有想通。

    在我的想象中,图书管理为了与校园卡衔接,仅要增加一张卡编号与学工号的对照表,当图书馆的读卡机读出卡编号后,通过对照表找到对应的学工号;在图书系统中使用学工号(或者内部一个唯一不变的编码)作为关键字,实现表间的各种联系,然后通过学工号即可在图书系统中进行各种操作了(呵呵,这些又都是停留在我的想象之中)。

    正在运行的图书系统中,校园卡的卡编号占据了重要的地位(这一点完全超出了我的想象,图书系统中没有使用学工号唯一标识人员),卡编号不止是用在了门禁和自助借还书(设备读取卡编号然后进行后续处理),而且用到了系统内部:卡编号成了系统内人员的唯一标识和主键,并通过卡编号关联相关表!(真不敢想象如此的数据库设计,技术人员是如此告诉我的,我还是不愿相信!有机会我一定要看看系统内部的表结构,再次进行确认)。这样就理解了,为什么图书系统的管理员非常不愿意卡编号重复,发出了要“损失历史信息”警告。

    这样也就理解了图书系统中存在的另一个相关设计,用一张表中记载了一个学生曾经办理的全部校园卡,且每张卡片对应的记录中都有一个是否有效的标志(每名学生只能有一张卡是有效的)。我们在其中看到,有一个学生曾经先后办理过14张卡片。

前行:信息化在路上

    校园卡系统和图书管理系统是两个典型的在高校不同时期分别独立建设的信息系统,现在的用户需求已经到了必须将它们连为一个有机整体的时候,需求巨大,难度极大。本次带着问题进行分析,还是深有体会的。

    1.现在已经不能苛求当年的系统设计,已购置的系统没法立即更改,只能打补丁。当年的设计受当时条件(硬件、软件、技术水平)所限,当年技术人员埋下的种种BUG是在考验现在的我们的智慧,不论这样BUG是多大的一坨~~~,现在的我们都不得不面对并解决。更深入的分析,更有效的沟通,更具前瞻性的修补是长期运维工作的必须。

    2.任何投入运行的信息系统都要长期运维、不断升级,功能的不断完善与更新是系统生命力的体现,也是长期运维中必须面对的难题。长期运维的核心是要有可靠的、胜任工作的技术队伍,关键时刻只有自己的技术人员才能依靠。

    3.任何系统升级或局部功能扩展都要小心,不能仅考虑满足系统的基本功能,更要站在信息化和全局来进行总体思考,特别要注意相互关联的信息系统之间可能存在的联系和相互影响。

    4.坚持软件工程的基本原则:测试,测试,再测试。不要信任任何开发者,不要信任任何软件开发公司,BUG是绝对存在的。不要被信息系统目前可以正常运行的表面现象麻痹,潜在的BUG就是定时炸弹,随时可能爆发。

你可能感兴趣的:(被校园卡升级点燃的“爆点”)