前言
五年前,我在CNBLOG写的一篇文章,《php+mysql下,对网站架构方面的一些认识(以我维护的站点为例)》,当然,整套架构不是做的,而是配合当初的运维部门,共同完成。那个时候我从入行PHP两年,对所谓的“架构”也是懵懂。只觉得很深奥,很高大上。那时候,架构师,那简直就是神一般的职位。
当时,这篇文章被很多站点收录,诸如:51CTO、CSDN等这样的大站,也有很多小站。不过文章中,我已经去掉了很多的配图,因为可能涉及到安全因素。在当时看,架构还是蛮不错的。但是也存在较多问题。
放眼现在,我们可以重新整理这套架构
找到可以优化的地方
找到替代的方案
需要思考地方
我们先来看下架构图:
从上图,我们分两大部分,分析:
左侧的程序代码同步
右侧的架构
如何优化
现有做法:
从版本管理工具拉取最新代码,除去.svn标记等文件,同步到生产环境
svn拉取最新代码 -> 测试服务器 -->rsync同步--> 生产环境
存在的问题:
1、采用svn进行版本管理,不利于团队协作开发;经常会出现修改的文件又被之前的覆盖了,白做了
2、在项目较大的情况下,所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,这个.svn文件会巨大,
svn是按照文件进行比较的,会占用很大资源
进一步优化:
使用SVN进行版本管理,和程序发布,不方便进行测试环境和生产环境的代码区分,麻烦点,可以解决
trunk->tag
trunk的发布到测试环境
tag的发布到生产环境
tag的程序均是经过测试通过的,由trunk合并过来的
最优方案:
采用git版本管理工具
svn 与 git 的区别
最核心的区别Git是分布式的,而Svn不是分布的。svn必须联网进行操作。好处是跟其他同事不会有太多的冲突,自己写的代码放在自己电脑上,一段时间后再提交、合并,也可以不用联网在本地提交。
GIT把内容按元数据方式存储,而SVN是按文件。你会发现有个.svn 这个文件会越来越大。
GIT分支和SVN的分支不同。分支在svn中并不突出。常见的就是branch,它是一个完整的目录。而git的特征就是分支。
SVN的特点是简单,使用一个中央版本库。
Git的对分支和合并有更好的支持,这是开发者最关心的。
具体做法:
1、建立两个分支:master 和 develop
2、master用于生产环境,develop用户测试环境。
3、master分支禁止被提交(commit、push),只准从develop或hotfix(线上bug)合并而来。
4、服务器上写一个shell脚本,用来做两件事,一是拉取最新代码,而是rsync同步代码
剩下的是团队成员开发协作、以及发布流程相关问题。
1、如何协作开发?参考这篇文章 Git 在团队中的最佳实践--如何正确使用Git Flow,写的很不错。很多公司在此基础上进行优化和改进
2、发布流程,我这里草拟了一份,增加了一个pre_product预发布分支。可能在你公司就不适合,请酌情调整。
我们用的是Teambition项目管理工具,可以新建个TAB,如:opend、working on、pull request、review、
merged、done。任务有技术负责人下发,成员认领开发。
代码审查
你Google一下Code Reivew这个关键词,你就会发现Code Review的好处基本上是不存在争议的,有很多很多的文章和博文都在说Code Review的重要性,怎么做会更好,而且很多公司在面试过程中会加入“Code Review”的问题。
但是,我们经常会遇到这种情况:
1)工期压得太紧,时间连coding都不够,以上线为目的,
2)需求老变,代码的生命周期太短。所以,写好的代码没有任何意义,烂就烂吧,反正与绩效无关。
其实,我认为这是很不负责任的。后面,我们会用大量时间来解决之前本不该发生的问题。
架构优化
LVS部分可以使用nginx的反向代理去实现,道理与LVS相同。用户请求到代理服务器,nginx代理服务器分发请求到后端WEB,我找了个图,方便大家去理解
nginx特点
nginx性能好,承担高的负载压力且稳定,可以负载超过1万的并发。
工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构;
Nginx对网络的依赖比较小;
Nginx安装和配置比较简单,测试起来比较方便;
Nginx对请求的异步处理可以帮助节点服务器减轻负载;
LVS的特点
抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生;
配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;
工作稳定,自身有完整的双机热备方案;
无流量,保证了均衡器IO的性能不会收到大流量的影响;
LVS需要向IDC多申请一个IP来做Visual IP,因此需要一定的网络知识,所以对操作人的要求比较高;
具体看你的业务情况,使用nginx或者lvs。当初公司的日均PV均超过100W,所以采用的是LVS方案+双机热备
集群优化
架构图上是两主两从MMM (Master-Masterreplication manager for MySQL)。其实很长情况下,是一主三从模式。只有在master1宕机的情况下,才启用master2。
主从复制
MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。
每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。
从架构图中我们可以分析,在大并发量较大的情况下,会出现主从复制延迟这种问题,如何解决?目前已经有了比较成熟的方案。
主从复制原理图:
步骤1: 所有数据更新都会被主库记录到主库的二进制日志。
步骤2: 与此同时从库的IO线程会从主库上读取二进制日志,写入到从库的中继日志上。
步骤3: 从库的SQL线程读取中继日志上的内容来更新从库。
造成延迟的原因
1、并发较大的情况下,master产生的DDL和DML数量大于salve的可接受数。从库的Slave_SQL_Running是单线程作业,不能并发执行,所以当主库的TPS并发较高时,就容易产生延迟。
2、slave将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺序的,成本高很多,还可能可slave上的其他查询产生lock争用,所以一个DDL卡主了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时
如何解决
1、减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行
2、主库写对数据安全性较高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以将sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率
3、使用比主库更好的硬件设备作为slave
4、使用mysql5.7 参看 《MySQL 5.7 并行复制实现原理与调优》
分库分表
这篇文章写的很好,需要好好拜读
http://www.cnblogs.com/hackxh...
以上是对几年前的架构进行可以优化的地方
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。