《PHP 进阶之路 – 亿级 pv 网站架构的技术细节与套路》观后有感

最近在研究如何把自己的网站服务做得更加稳健,学习更多的网站架构知识,而且在 SegmentFault 上也看到很多大佬的经验和讲座,便在其中选了一个相关的讲座( 周梦康 / PHP 进阶之路 – 亿级 pv 网站架构的技术细节与套路 )来看,并且感觉学到了不少新的概念,也确定了新的学习方向。

便在读后有少些的体会,便写下这篇文章来总结一下。

 

提升网站服务的健壮性在周梦康大佬总结时有以下几点:

  • 服务解耦
  • 后端采用负载均衡、动静分离、读写分离、缓存、分布式等策略
  • 服务治理
  • 日志收集
  • 计划任务的分布式和管理
  • 流量压测和估算
  • 完善的监控系统
  • 轻巧的发布系统

 

下面是对讲座内容的个人笔记和总结

1.服务解耦

解耦,顾名思义就是要讲各个服务相互之间的影响性(藕丝)降低,将系统各个部分的职能切割以便能在在服务遇到故障时能及时排查、在日后便于维护,并且让各个系统组件使用标准化的接口协作。此举是为了降低由于系统的部分组件(模块)的故障导致的整个系统的可用性大幅度降低,通俗来讲就是避免牵一发而动全身。

常见的服务解耦有:前后端的解耦、后端模块之间的解耦等

在这个讲座中,老周提到的是各个web服务之间的解耦。

举个例子,在一个web服务中,会有不同功能的服务存在一个系统里,简单的有:web内容服务、登录授权服务、附件上传服务。

在这个例子的三个服务中,他们所占用的IO需求都是不一样的,而且附件上传的服务可能会导致服务器的IO阻塞,如果让他们放在一起就有可能互相之间有影响,例如A用户在登录时,有很多的用户在进行文件上下传,如果服务都放在同一台服务器上,IO随时可能被挤爆了,就有可能导致A用户登录不上去了/加载很慢。

于是就可以让web内容服务器、登录授权服务器、附件上传等的服务分开,然后加一层NGINX的负载均衡来怼各个服务进行隔离。这样每个服务之间不收影响,一旦其中一个服务阻塞或者故障了,其他仍可继续运行。

下面是老周在讲座里说的一个例子,即通过redis进行SESSION共享的方法对web内容服务、登录授权服务、和附件上传服务进行隔离。

 

2.后端采用负载均衡、动静分离、读写分离、缓存、分布式等策略

此次的分离可以分为三个小点:动静分离读写分离业务分离

读写分离:

简单的数据库优化可以在以下几点进行

  1. 读写分离:在数据库中配置主从数据库服务器,各职能为:写表直接写入主库、读表在从库里读取。并为读写操作分别配置不同的账户及其不同的权限以达到在账户级别的读写分离;在后端访问数据库时加入一个中间层,对提交的sql语句进行检测分类,就可以方便地把写库和读库的操作分开。
  2. 负载均衡:可以简单通过PHP的配置文件实现,例如在配置文件中分开读写操作用的数据库账户,把账户信息写进一个数组,让PHP在建立连接时随机取出服务器、账户进行数据库连接。这样就可以简单的把数据库读写压力分摊到各个数据库节点。
  3. 更高级的负载均衡可以实时读取各节点间的负载(CPU,内存,IO,数据库连接数等),以自动地更改各个服务器在随机抽取时候的权重,这样可以做到一个简单的、稍微高级一点的负载均衡服务器。

动静分离:

  • 在web服务中,动静分离可以是动态的页面和静态的资源(CSS、图片等)之间的分离。在这里主要还是依赖于CDN
  • 用户通过访问CDN的边缘节点(靠近用户的节点)获取这些静态资源,边缘节点镜像服务商的二级缓存,再由服务商的二级缓存(中间源)访问自己服务的分布式存储回源,采用服务商二级缓存(中间源)可以有效减低回源的压力。
  • CDN切片存储
  • 采用多个CDN域名,防止浏览器的访问阻塞、降低故障时,更换内容时的回源压力。因为很多浏览器对同一域名的并发会有限制,所以采用多个CDN域名首先可以一定程度上缓解这个限制。

一些主流浏览器对 HTTP 1.1 和 HTTP 1.0 的最大并发连接数目,可以参考如下表格:

Browser

HTTP/1.1

HTTP/1.0

IE 11

6

6

IE 10

6

6

IE 9

10

10

IE 8

6

6

IE 6,7

2

4

Firefox

6

6

Safari 3,4

4

4

Chrome 4+

6

6

Opera   9.63,10.00alpha

4

4

Opera 10.51+

8

?

iPhone 2

4

?

iPhone 3

6

?

iPhone 4

4

?

iPhone 5

6

?

Android2-4

4

?

  • 同时,采用多个CDN域名可以在清除缓存,缓存预热时降低回源压力(分批内容清除)

业务分离:

涉及使用NGINX的动态web集群等,也可参照上文的服务解耦部分的内容

3.服务治理:

在我们的服务中,通常可以分为很多的服务模块。各个模块可以交由不同的人去开发、运维,而在此中间便缺少不了跨模块、跨部门的交流。如何把交流的成本降低和正确性的提高?就是把这些交流的内容用规则去标准化、自动化处理。

在此种情况下就提出“服务治理”的概念,旨在把各个服务交由一个控制中心管控以节省交流成本。

各个服务向同一的管控中心注册自己的服务,例如向管控中心提供自己服务的服务器的IP地址等,让别的服务在调用这个服务时候可以向管控中心申请这个服务的请求地址等。

在这里老周提到一个YAR的远程调用。

客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

选自 周梦康 / PHP 教父鸟哥 Yar 的原理分析

远程调用可以将业务逻辑和模块之间的耦合度再降低。

 

笔记先记到这里,明天再更新剩下的内容

分享到:

3 条评论

昵称

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. xtlsoft

    跟我想象的架构差不多。

    Worker01 Worker02 Worker03 Worker04 Worker…
    WaitQueue(Not Alive) Register GatewayServer <— If down, enable WaitQueue
    Business01 Business02 Business03
    Tengine Balancer
    Both out with Squid Cache.
    Nginx Static Server 01 Nginx Static Server 02

  2. ⑨BIE

    _(:з」∠)_这种问题,对于我这种访问量属于二项分布的人完全不用担心,不知道是该高兴还是该哭23333

    1. 很懒的樱花

      233🙈访问+1,具体还是学技术和架构能力吧,服务治理那个概念挺好的