前言五年前,我在CNBLOG上写了一篇文章,《php+mysql下,对网站架构方面的一些认识(以我维护的站点为例)》,当然整个架构并没有做完,但是和原来的运维部一起完成了。那时我接触PHP已经两年了,对所谓的“架构”也是一窍不通。我只是觉得它非常深刻和崇高。在那个时候,架构师简直就是神一般的职位。当时这篇文章被很多站点收录,比如:51CTO,CSDN等,也有很多小站点。不过在文章中,我去掉了很多图片,因为可能涉及到安全因素。当时,结构非常好。但是也存在很多问题。看现在,我们可以重新梳理这个架构,找到可以优化的地方,找到需要考虑的备选方案。我们先来看架构图:从上图可以分为两部分。分析:左边的程序代码是右边同步的如何优化现有做法:从版本管理工具中拉取最新代码,去除.svn标记等文件,同步到生产环境svn拉取最新代码->测试服务器->rsync同步->生产环境问题:1、使用svn进行版本管理,不利于团队协作开发;通常,修改后的文件会被以前的文件覆盖,这是没有用的。2.在大型项目的情况下,所有的资源控制系统都使用文件元信息隐藏在一个类似于.svn的文件中。这个.svn文件会很大,svn是根据文件比较的,会占用很多资源。进一步优化:使用SVN进行版本管理和程序发布,不方便测试环境和生产环境的代码区分是比较麻烦的一点,可以解决trunk->tagtrunk到测试环境的问题。标签发布到生产环境。tag的程序已经通过测试,从trunk中合并。与git的区别最核心的区别是Git是分布式的,而Svn不是。svn必须联网才能运行。好处是不会和其他同事发生太多的矛盾。我写的代码放在我的电脑上,过一段时间再提交合并,或者在没有联网的情况下本地提交。GIT将内容存储为元数据,而SVN将其存储为文件。你会发现有一个.svn文件会越来越大。GIT分支不同于SVN分支。分支在svn中并不突出。常见的是branch,就是一个完整的目录。git的特点是分支。SVN的特点是简单,使用中央存储库。Git对分支和合并有更好的支持,这是开发者最关心的。具体方法:1.建立两个分支:master和develop2。master用于生产环境,开发用户用于测试环境。3、master分支禁止提交(commit、push),只能从develop或hotfix(在线bug)合并。4、在服务器上写一个shell脚本,做两件事。一种是拉取最新的代码,但是用rsync同步代码。剩下的就是团队成员的开发和协作以及与发布过程相关的问题。1、如何协同发展?参考这篇Git在团队中的最佳实践——如何正确使用GitFlow,写的很好。很多公司都在这个基础上优化改进。2.发布过程。我在这里起草了一个副本,并添加了一个pre_product预发布分支。它可能不适合您的公司,请酌情调整。我们使用Teambition项目管理工具,可以新建一个TAB,如:opend、workingon、pullrequest、review、merged、done。任务由技术负责人发布,成员认领开发。对于codereview,Google一下关键字CodeReivew,你会发现CodeReview的好处基本上是没有争议的。有很多很多文章和博文都在谈论CodeReview的重要性,如何做得更好,并且很多公司会在面试过程中添加“CodeReview”问题。但是,我们经常会遇到这种情况:1)工期太紧,coding的时间不够,目的就是上线;2)需求在变,代码生命周期太短。因此,编写良好的代码是没有意义的。坏了就坏了。无论如何,它与性能无关。其实我觉得这是很不负责任的。后面我们会花很多时间去解决以前不应该发生的问题。架构优化的LVS部分可以使用nginx的反向代理来实现,这一点和LVS是一样的。用户向代理服务器请求,nginx代理服务器将请求分发给后端WEB。找了一张图,方便大家了解nginx的特点。Nginx性能好,负载压力大,稳定。工作在网络的第7层,可以对http应用做一些分流策略,比如域名,目录结构;Nginx对网络的依赖性小;Nginx安装配置比较简单,测试起来也比较方便;异步处理可以帮助节点服务器减轻负载;LVS具有抗负载能力强的特点,工作在网络第4层,只做分发,不产生流量;配置比较低,这是缺点也是优点,因为可以配置的东西不多,所以不需要太多的接触,大大减少了人为出错的机会;工作稳定,拥有完善的双机热备方案;无流量,保证均衡器IO的性能不会因为大流量的影响而降低;LVS需要向IDC额外申请一个IP成为VisualIP,需要一定的网络知识,所以对运营商的要求比较高;根据你的业务情况,使用nginx或者lvs。一开始公司日均PV超过100W,所以采用了两主两从MMM(Master-MasterreplicationmanagerforMySQL)的LVS方案+双机热备集群优化架构图。其实长期以来都是一主三从的模式。只有当master1宕机时,master2才会启用。主从复制MySQL复制是基于主服务器在二进制日志中跟踪对数据库的所有更改(更新、删除等)。因此,要进行复制,必须在主服务器上启用二进制日志记录。每个slave从master接收到master记录到其二进制日志中的已保存更新,以便slave可以对其数据副本执行相同的更新。从架构图中我们可以分析出在并发量大的情况下,会出现主从复制延迟的问题。如何解决?目前已经有比较成熟的方案。主从复制示意图:第一步:所有的数据更新都会被主库记录到主库的二进制日志中。第二步:同时,从库的IO线程会从主库读取二进制日志,写入从库的中继日志。第三步:从库的SQL线程读取relaylog的内容,更新从库。延迟的原因1.在大并发的情况下,master产生的DDL和DML数量大于salve可接受的数量。从库的Slave_SQL_Running是单线程作业,不能并发执行。所以当主库TPS并发高的时候,很容易出现延迟。2、slave在slave上实现主库的DDL和DML操作。DML和DDL的IO操作是随机的,不是顺序的,成本要高很多。也可能造成slave上其他查询的锁争用,所以一个DDL卡主需要执行10分钟,之后所有的DDL都会等待。这个DDL执行完还会继续执行,这就导致了怎么解决延迟。1.减少从库同步延迟的解决方案是优化架构,尽量让主库的DDL执行的快。2.主库写入数据安全性更高,比如sync_binlog=1,innodb_flush_log_at_trx_commit=1等设置,但是slave不需要这么高的数据安全性,可以设置sync_binlog为0或者关闭binlog,innodb_flushlog也可以设置为0提高SQL的执行效率3.使用比主库更好的硬件设备作为slave4,使用mysql5.7。见《MySQL 5.7 并行复制实现原理与调优》分库分表。.以上是几年前的架构可以优化的地方
