背景:这年小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......

小P的架构生活(上)的更多相关文章

  1. 小P的架构生活(下)

    小L强烈建议团队使用微服务,并极力推荐了前公司用的一套分布式事务解决方案. 小P经过反复思考查证并做了大量的尝试后,辨证地对微服务架构做了如下分析: 为什么要用微服务,微服务带来了哪些好处? 1.减少 ...

  2. hdu---(4515)小Q系列故事——世界上最遥远的距离(模拟题)

    小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)T ...

  3. HDU-4515 小Q系列故事——世界上最遥远的距离

    小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) ...

  4. "大中台、小前台”新架构下,阿里大数据接下来怎么玩? (2016-01-05 11:39:50)

    "大中台.小前台”新架构下,阿里大数据接下来怎么玩?_炬鼎力_新浪博客 http://blog.sina.com.cn/s/blog_1427354e00102vzyq.html " ...

  5. 微信架构 & 支付架构(上)

    微信架构 & 支付架构(上) 一. 微信和支付宝对比 这两者现在已经占领了移动支付的90%市场,支付形式也都大抵相同,只是在实现细节上略微不同.这里之所以要专门对比,是因为有些接口的不同在后边 ...

  6. 技术博客——微信小程序的架构与原理

    技术博客--微信小程序的架构与原理 在两个月的微信小程序开发过程中,我曾走了不少弯路,也曾被很多现在看来十分可笑的问题所困扰.这些弯路与困扰,基本上都是由于当时对小程序的架构理解不够充分,对小程序的原 ...

  7. 微信小程序 在canvas画布上划动,页面禁止滑动

    要实现微信小程序 在canvas画布上划动,页面禁止滑动,不仅要设置disable-scroll="true",还要要给canvas绑定一个触摸事件才能生效. <canvas ...

  8. wepy小程序实现列表分页上拉加载(2)

    第一篇:wepy小程序实现列表分页上拉加载(1) 本文接着上一篇内容: 4.优化-添加加载动画 (1)首先写加载动画的结构和样式 打开list.wpy文件 template结构代码: <temp ...

  9. wepy小程序实现列表分页上拉加载(1)

    使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 列表页效果图: 1.新建列表页 (1)在pages里面新建一个list.wpy文件 初始代码 ...

随机推荐

  1. linux常用查看系统操作的linux命令

    系统# uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看CPU信息# hostna ...

  2. LC 789. Escape The Ghosts

    You are playing a simplified Pacman game. You start at the point (0, 0), and your destination is(tar ...

  3. Ubuntu16.04中安装VirtualBox及简单配置

    sudo apt-get -y install virtualbox 注:将该图表拖到桌面上即可 往下的过程都不变..... 将左边的菜单栏移动到下面 打开一个终端输入:gsettings set c ...

  4. delphi中and和or的特殊用法

    1=1 10=2 100=4 1000=8 1 or 2 = 3(11); 1 and 3 = 1; 2 and 3 = 2; 2 or 4 = 6(110); 2 and 6 = 2; 4 and ...

  5. ios8唤不起APP的问题

    https://stackoverflow.com/questions/27526966/ios-8-window-location-href-doesnt-work-with-url-scheme ...

  6. Python 导入文件问题

    1.同级目录下调用 若在程序 testone.py 中导入模块 testtwo.py , 则直接使用 [import testtwo 或 from testtwo  import *] 2.调用子目录 ...

  7. SqlServer:SqlServer(数据库备份,数据文件迁移,增加数据库文件组,递归查询一周报送情况,查询近X天未报送单位,截断数据库日志,复制单个或多个数据库表到另一个数据库 )

    1.数据备份 ) ) ) )),'-','') ) SET @savePath = 'f:/DatabaseBackup/' DECLARE My_Cursor CURSOR FOR ( select ...

  8. 使用gRPC打造服务间通信基础设施

    一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...

  9. RN 图片处理 resizeMode

    Image组件必须在样式中声明图片的宽和高.如果没有声明,则图片将不会被呈现在界面上.    我们一般将Image定义的宽和高乘以当前运行环境的像素密度称为Image的实际宽高. 当Image的实际宽 ...

  10. classmethod自己定制

    # # 利用描述符原理定义一个@classmethod # class ClassMethod: # def __init__(self,func): # self.func = func # def ...