背景:这年小P已经参加工作4年了,在前同事Z的极力劝说下,小P加入了Z新开的公司Y,公司一共有三个人:老板Z、程序员小P、前台W。项目名为XX交易系统
小P加班加点,终于在两个月后把系统开发完成,版本为V1.0,这中间还包括需求分析(其实就是跟老板聊),概要设计。而系统的架构也是简单得不能再简单,如下图:
前台和后台都是最简单的java web,使用了当时最常用的SSH(Spring、Struts、Hibernate)框架,前端直接用了jsp(即html中嵌入java代码段)+jquery。
而这段时间,陆续入职了一个应届生X,一个美工兼前端J,老板跑市场还进展挺顺利的,刚上线注册用户数很快就突破5万了。根据市场的反鐀,很快确定V1.1版本的需求。不到一个月时间,小P三个又完成了V1.1版本的开发,V1.1比上一版本的改进在于:
1、jsp中不再用代码段的方式了,而是用JSTL标签,小J学习JSTL的语法,替小P完成View层的活,因为小P实在太忙了。
2、随着用户的增多,不能再随意重启生产服务了,而且应用层也需要高可用。
3、加cache层,降低数据库压力。
3、加了n个新功能...
而架构也改造成如下图:
加入了nginx作为负载均衡和实现前后台tomcat应用的高可用。
读多写少数据取自分布式缓存Reids,并按时间及有变更时主动做淘汰。
为了保证服务无状态,将用户session也统一在Redis中存储。
用户量持续在增长,很快已经突破50万的注册用户了,技术团队的规模也从3个技术人员增长到了6个,其中2个是前端,4个是后端,小P任技术负责人。系统也频繁出现性能问题,各种死锁,慢查询,网络故障困扰着团队,而这些性能问题中99%是低效的sql引起的。小P发现4个后端基本都是1年以内工作经验的,而自己又忙于业务,跟着老板到处出差跟进需求,在短时间内很难提高团队的高性能Mysql知识,至于买的那本《高性能Mysql》自己没时间看,其他三人根本看不懂。老板又不想在这方面花费太多的培训与招聘有经验人士。最终小P做了一个连自己都不能相信的决定:不用Mysql了,改用Oracle!!! 得亏了底层用了ORM框架,改Oracle花费的代码并不太高,同样的sql在Oracle上跑性能好了太多,团队也因此赢得了时间去完成爆炸式增长的需求。当然随着用户的持续增长,对高可用要求也越来越高了,团队为了庆祝这个较大的调整,直接给新版本命名为V1.5,V1.5比V1.1最大改进在于:
1、nginx多台实例,使用DNS解析一个域名配多个ip的方式实现高可用(虽然修改配置后要一段时间才能生效,但可以接受)
2、Oracle一主多从,灾备自动切换,对于实时性要求不高的报表统计、业务监控等从备库查询减少主库压力
3、Redis一主多备,配持久化同步,通过VIP Keepalived实现灾备漂移切换。
4、将定时任务从普通的tomcat应用中剥离,使用Zookeeper实现分布式锁,对于只能单机执行的任务,只有拿到master才执行,master挂了之后,任务会在新选举出来的master机上执行。
时间一晃就是两年过去了,公司也在创业两年时间里积累了200万的注册用户,已经有了稳定的现金流了,前端人员也从原来的2人,扩展到了4个,而后端已经扩展了10个人了,小P也从开发组长升职为技术经理了(有啥区别?),人员越来越多,子系统也随着多了起来,代码之间的耦合问题、前后端未分离带来的扯皮、组员之间的争论也越来越多。主要是碰到了以下问题:
1、到处都是代码的copy,相同的代码,到处都是
2、公共库充斥了业务个性代码,为了业务B修改公共库,影响到了业务A
3、前端的童鞋不愿意继续使用JSTL标签这种偏后端的活
4、环境多了,内部系统间仍以ip互相调用。开发人员抱怨:凭什么换IP的是他,半夜配合上线的人是我?
5、性能问题又开始出现,不时出现慢查询或死锁问题
6、安全问题开始出现,已经有部分用户开始利用系统漏洞盈利
小P经过与团队中的技术骨干商量之后,把系统架构改造成:
注:每个节点都是多点,图上未画出。
前后端彻底分离了,后端纯提供REST接口,小P指定了前端小组经验最丰富的小T为前端组组长。
系统间调用,数据库等配置不再采用IP,而使用内网域名,有变动时直接修改DNS即可。
系统模块化,按模块指定负责人,公共库代码下沉,将与业务相关的代码上浮给相关的模块。模块内公共代码由模块负责人提供,模块内复用。
小P此时已看完《高性能Mysql》,对常见的建索引,sql优化已经得心应手了。
安全问题,基本上是项目组见招拆招,但对审计日志的需求要求有所提高,关键位置都有记录日志了。
Struts 2被暴有安全问题,新人对Hibernate掌握不好,容易踩坑,另外也不需要JSP的View层了,于是SSH也改造成Spring Boot + Mybatis
好了,让我们回顾一下小P团队这两年的架构收获:
高可用:Oracle、Redis、应用、定时任务、nginx都做了高可用
高性能:把Mysql换成了Oracle、读写分离、热点数据Cache、表建相关索引等
可伸缩:应用部分可通过部署多个实例支持更高吞吐,但数据库仍是单库
可扩展:即解耦。通过模块化,不同模块的代码放到各自模块,模块间共用的代码下沉到公共库。前后端分离,私藏配置使用内网域名,不使用IP。
安全性:记录审计日志、用户输入过滤、文件上传控制、短信接口防刷、用户密码加盐加密存储、HTTP换为HTTPS等......
而小P似乎也满足于当前的成就,毕竟公司从当年的用户量为0,成长为今天用户量为200W,这期间虽说是各种问题不断,但总体算支撑起来了,自己也算是小有成就了。而小P也有去各种中小公司面试过,也跟同行交流过发现在广州好多中小公司的架构也不过如此。而此时用户的增长速度也开始放缓了,小P也已经没有足够的动力来升级公司的技术架构了。大家似乎都对现状挺满意,每天都在进行着日常的版本开发及线上运维工作。
直到小P遇上了大神小L......