集群
集群:同一个业务,部署在多台服务器上,这个就叫做集群。
单机处理到达瓶颈的时候,你就把单机复制几份,这样就构成了一个“集群”。集群中每台服务器就叫做这个集群的一个“节点”,所有节点构成了一个集群。每个节点都提供相同的服务,那么这样系统的处理能力就相当于提升了好几倍(有几个节点就相当于提升了这么多倍)。
集群结构的优势:
集群结构的好处就是系统扩展非常容易。如果随着你们系统业务的发展,当前的系统又支撑不住了,那么给这个集群再增加节点就行了。
集群存在的问题:
当你的业务发展到一定程度的时候,你会发现一个问题——无论怎么增加节点,貌似整个集群性能的提升效果并不明显了。这时候,你就需要使用微服务结构了。
搭建PHP集群的第一步就是设置负载均衡。首先需要三台主机:Nginx负载、PHP应用1、PHP应用2。Nginx中配置proxy和upstream。
负载均衡
负载均衡:把请求均匀的分摊到不同的服务器中,减轻服务器压力,提高服务器的处理速度。
工作原理:内置轮询机制,每隔一段时间轮询每个节点当前状态(内存、cpu),判断哪个节点相对空闲。
用户的请求究竟由哪个节点来处理呢?最好能够让此时此刻负载较小的节点来处理,这样使得每个节点的压力都比较平均。要实现这个功能,就需要在所有节点之前再增加一个负载均衡,用户的所有请求都先交给它,然后它根据当前所有节点的负载情况,决定将这个请求交给哪个节点处理。
分布式
分布式:一个业务被拆成多个子业务,部署在多台服务器上。
当集群无法满足业务需求时,业务耦合度高,需要降低各功能模块的耦合度,因此就对一个大系统进行拆分成小系统,单独部署,易于维护,这就产生了分布式。
分布式结构就是将一个完整的系统,按照业务功能,拆分成一个个独立的子系统,在分布式结构中,每个子系统就被称为“服务”,这些子系统能够独立运行在web容器中。分布式结构其实也是微服务的一种。
分布式里面,每一台服务器实现的功能是有差别的,分布式每台服务器功能加起来,才是完整的业务。
举个例子:
一个电商网站有订单模块,浏览模块,个人资料模块,商品模块这几个模块,我们可以将这些模块分离开来,每个模块在不同的服务器上,这样当需要对某个模块进行维护时,单独维护一个模块就行了,不需要对别的模块进行修改,只需要注意他们之间传递消息不变即可。
分布式架构优势:
1,单个服务宕机不影响别的服务正常运行!
2,单个节点所有的负载分布均衡到了多台服务器上!
3,各服务之间相互透明,实现解耦!
对于开发的新的系统,推荐使用分布式架构,这样能降低后期维护的成本,而对于一些老系统来说,实现分布式架构就要对旧代码进行大量的修改,所以,对于老系统而言,究竟是继续保持集群模式,还是升级成微服务架构,这需要深思熟虑、权衡投入产出比。
消息队列
消息队列:消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。
目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
消息队列在实际应用中常用的使用场景:
异步处理:比如,用户注册后,需要发注册邮件和注册短信,将注册邮件,发送短信写入消息队列异步处理,直接返回注册成功信息。
应用解耦:比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。
削峰填谷:比如,秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉,这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。
消息通讯:消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。
主从复制与读写分离
在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。
主服务器(master):只能提供写操作,复制给从服务器。
从服务器(slave):只能提供读取数据,不能写入,可以有多个。
主从复制用途:
1、实时灾备,用于故障切换
2、读写分离,提供查询服务
3、备份,避免影响业务
主从部署必要条件:
1、主库开启binlog日志(设置log-bin参数)
2、主从server-id不同
3、从库服务器能连通主库
MySQL主从复制原理:
1、从库生成两个线程,一个I/O线程,一个SQL线程;
2、从库I/O线程去请求主库发送binlog里面的更新记录到从库(binlog,主库中保存所有更新事件日志的二进制文件),主库会生成一个binlog输出线程发送binlog内容到从库,从库得到的binlog日志写到relay log(中继日志) 文件中;
3、SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;
MySQL读写分离原理:
读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。
常见的MySQL读写分离:
1、基于程序代码内部实现:在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最广泛的。优点是性能较好,因为程序在代码中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手。
2、基于中间代理层实现:mysql_proxy。实际上是在客户端请求与MySQLServer之间建立了一个连接池。所有客户端请求都是发向MySQLProxy,然后经由MySQLProxy进行相应的分析,判断出是读操作还是写操作,分发至对应的MySQLServer上。对于多节点Slave集群,也可以起做到负载均衡的效果。