背景:这年小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. 二、Spring Boot 中maven中dependencies所有的jar包都报红,install报错(https://repo.maven.apache.org/maven2): Not authorized , ReasonPhrase:Authorizatio

    问题一:现象:打开SpringBoot项目后,所有依赖包都报红色波浪线 1.install报错(https://repo.maven.apache.org/maven2): Not authorize ...

  2. leetcode324 摆动排序II

      1. 首先考虑排序后交替插入 首尾交替插入,这种方法对于有重复数字的数组不可行: class Solution { public: void wiggleSort(vector<int> ...

  3. Node fs 创建多层文件夹

    一.dirname()方法 1. 获得路径当中最后一段文件或文件夹所在的路径.多次调用path.dirname将会逐层返回上级目录 var path=require("path") ...

  4. 2018年第一记:EDM策略分享-EDM营销的策略分析

    很久没有上博客园来更新下文章了,一则因为工作繁忙,二则对技术方面的研究时间花的少了,目前主要侧重于EDM营销方面的策略制定.很多人跟我说,做EDM营销都茫然无头绪,那么做EDM到底有什么策略呢?下面博 ...

  5. 能否保证service不被杀死?

    Service设置成START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样 提升service优先级 在AndroidManifest.xml文件中对于in ...

  6. 【.NET】ASP.Net IE10+ SCRIPT:XXX_doPostBack 未定义

    问题描述 GridView中分页控件,点击分页无反应,Linkbutton点击无反应,打开Web控制台,发现如下错误:SCRIPTXXX:_doPostBack 未定义:查询后得知,是由于.NET F ...

  7. Matlab中的eig函数和Opecv中eigen()函数的区别

    奇异值分解的理论参见下面的链接 http://www.cnblogs.com/pinard/p/6251584.html https://blog.csdn.net/shenziheng1/artic ...

  8. python 将分词结果写入txt文件

    首先我运用的分词工具是结巴分词 import jieba  然后调用jieba.cut( )  但是jieba.cut 返回的是一个generator的迭代器 他可以显示分词结果 但是无法将结果写入t ...

  9. 【神经网络与深度学习】GLog使用笔记

    环境: XPsp3 vs2005 glog-0.3.3 http://download.csdn.net/detail/chenguangxing3/6661667 编译: glog-0.3.3里面有 ...

  10. 【Python开发】PyQt5应用与实践

    一个典型的GUI应用程序可以抽象为:主界面(菜单栏.工具栏.状态栏.内容区域),二级界面(模态.非模态),信息提示(Tooltip),程序图标等组成.本篇根据作者使用PyQt5编写的一个工具,介绍如何 ...