小P的架构生活(上)
背景:这年小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的架构生活(上)的更多相关文章
- 小P的架构生活(下)
小L强烈建议团队使用微服务,并极力推荐了前公司用的一套分布式事务解决方案. 小P经过反复思考查证并做了大量的尝试后,辨证地对微服务架构做了如下分析: 为什么要用微服务,微服务带来了哪些好处? 1.减少 ...
- hdu---(4515)小Q系列故事——世界上最遥远的距离(模拟题)
小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)T ...
- HDU-4515 小Q系列故事——世界上最遥远的距离
小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) ...
- "大中台、小前台”新架构下,阿里大数据接下来怎么玩? (2016-01-05 11:39:50)
"大中台.小前台”新架构下,阿里大数据接下来怎么玩?_炬鼎力_新浪博客 http://blog.sina.com.cn/s/blog_1427354e00102vzyq.html " ...
- 微信架构 & 支付架构(上)
微信架构 & 支付架构(上) 一. 微信和支付宝对比 这两者现在已经占领了移动支付的90%市场,支付形式也都大抵相同,只是在实现细节上略微不同.这里之所以要专门对比,是因为有些接口的不同在后边 ...
- 技术博客——微信小程序的架构与原理
技术博客--微信小程序的架构与原理 在两个月的微信小程序开发过程中,我曾走了不少弯路,也曾被很多现在看来十分可笑的问题所困扰.这些弯路与困扰,基本上都是由于当时对小程序的架构理解不够充分,对小程序的原 ...
- 微信小程序 在canvas画布上划动,页面禁止滑动
要实现微信小程序 在canvas画布上划动,页面禁止滑动,不仅要设置disable-scroll="true",还要要给canvas绑定一个触摸事件才能生效. <canvas ...
- wepy小程序实现列表分页上拉加载(2)
第一篇:wepy小程序实现列表分页上拉加载(1) 本文接着上一篇内容: 4.优化-添加加载动画 (1)首先写加载动画的结构和样式 打开list.wpy文件 template结构代码: <temp ...
- wepy小程序实现列表分页上拉加载(1)
使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 列表页效果图: 1.新建列表页 (1)在pages里面新建一个list.wpy文件 初始代码 ...
随机推荐
- yum源问题
配置本地yum源 1.使用工具将iso文件上传到操作系统,或者直接挂载iso文件 2.配置yum #cd /etc/yum.repos.d/ 删除多余的repo文件 # vi /etc/yum.rep ...
- 【转】composer proc_open(NUL)报错问题
composer 执行的时候报错错误信息如下: [ErrorException] proc_open(NUL): failed to open stream: No such file or dir ...
- 转: Android 设备的远程调试入门
从 Windows.Mac 或 Linux 计算机远程调试 Android 设备上的实时内容. 本教程将向您展示如何: 设置您的 Android 设备进行远程调试,并从开发计算机上发现设备. 从您的开 ...
- Python 正则表达式【二】
关于前向,后向,匹配,非匹配 Matches if ... matches next, but doesn’t consume any of the string. This is called a ...
- 国内npm源
永久使用lnpm config set registry https://registry.npm.taobao.org // 配置后可通过下面方式来验证是否成功 npm config get reg ...
- 机器学习:gensim之Word2Vec 详解
一 前言 Word2Vec是同上一篇提及的PageRank一样,都是Google的工程师和机器学习专家所提出的的:在学习这些算法.模型的时候,最好优先去看Google提出者的原汁Paper和Proje ...
- CornerNet-Lite算法笔记
论文名称:CornerNet-Lite: Efficient Keypoint Based Object Detection 论文链接:https://arxiv.org/abs/1904.08900 ...
- spring @valid 注解
用于验证注解是否符合要求,直接加在变量之前,在变量中添加验证信息的要求,当不符合要求时就会在方法中返回message 的错误提示信息. @PostMapping public User create ...
- 【OpenGL】初识OpenGL4.0
目录(?)[-] 什么是GLSL GLEW 安装GLEW 使用GLEW 其他库 使用GLM库进行数学运算 安装GLM 使用GLM 使用GLM作为OpenGL的输入 使用GLFW进行窗口管理 这篇文章主 ...
- 在C语言中函数及其调用过程
目录 函数 C语言中的变参函数 函数的本质是什么 内存区域的区分技巧 函数的调用过程 栈帧的概念 调用过程细节 按照约定传参 函数 如果一个函数有声明没实现,那么就会出现链接错误: 以上代码会出现链接 ...