阿里云栖开发者沙龙PHP技术专场-聊聊服务稳定性保障这些事

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: 摘要:本文主要带大家了解服务稳定性的重要性和相关策略。策略大概分两部分,第一方面从架构层面介绍保障服务稳定性的常见策略(限流,降级,隔离,超时,重试和集群)。第二个方面是从流程方面(code review, 压测,灰度和监控)讲解怎么去保证稳定性。

摘要:本文主要带大家了解服务稳定性的重要性和相关策略。策略大概分两部分,第一方面从架构层面介绍保障服务稳定性的常见策略(限流,降级,隔离,超时,重试和集群)。第二个方面是从流程方面(code review, 压测,灰度和监控)讲解怎么去保证稳定性。

演讲嘉宾简介:
信海龙(花名沧龙),十余年的互联网开发经验,2013年加入阿里巴巴,深耕于电商、社区相关应用开发与架构。同时也是多个开源项目的开发者和维护者。代表开源作品,tclip,基于人脸识别的图片裁剪扩展。

本次直播视频精彩回顾,戳这里!
直播回顾:https://yq.aliyun.com/live/965
PPT分享:https://yq.aliyun.com/download/3530
以下内容根据演讲嘉宾视频和PPT分享整理而成。

本次的分享主要围绕以下三个方面:

  1. 稳定性的重要性
  2. 保障策略架构篇
  3. 保障策略流程篇

稳定性的重要性

对很多企业来说服务稳定性非常重要,首先稳定性问题会对企业带来直接的经济损失。举例来说,亚马逊的“Prime Day”当天出现的一个故障,给亚马逊带来了高达9900万美元的损失。这一个故障损失就可能是其它小公司市值的几倍。所以服务稳定性对公司影响是特别大的。而对于个人来说,服务不稳定性会影响员工的绩效,甚至影响个人前程。

1

保障策略架构篇

从架构层面保障稳定性,常见的策略包括限流,降级,隔离,超时,重试和集群等。

2

1.限流

限流目的
限流的目的主要有两点,第一点是防止系统高负荷运行,第二点是有效利用服务器资源。为什么要做限流?假如不封锁请求,可能会导致服务器报警,如果平时服务器只能处理100个请求,突然多出两个请求服务器或许勉强能够处理,但突然多了500个请求的话,后面的400个请求只处在积压状态,等服务器处理到第500个请求的时候,用户等待时间就会过长,而且最后积压部分的请求可能根本就是无效的处理,因为用户早已流失。
限流算法
常见限流的算法包括漏桶算法和令牌桶算法。漏桶算法如下图,图中的例子有个小桶,桶下面有个孔,每流一滴水就可以认为是一个请求进去。滴水的速率是一样的,孔的高度也是固定的。漏桶算法能保证每个请求的负载时长,即确定每秒能处理的请求数量。

3

漏痛算法实现如下图,可以设定桶的高度是5个,每秒漏两个。执行效果中前面5次结果都是true,之后中间一次结果是false,这说明桶已经装满,之后又漏了两滴水,因为false的时候sleep了一秒,所以下面又有两个true出来。

4
5
令牌桶算法
如下图,令牌桶算法也是有一个桶,但是桶不漏,桶里面放了一些令牌,每来一个请求就在桶里拿一个令牌,如果没有令牌它就可以等待,令牌满了就不再往里面加令牌。这样方法基本上也可以达到一个限流的目的。令牌桶算法和漏桶算法的一个显著区别是漏桶算法在后端取请求量时,基本上漏的速率是一样的,但是令牌桶算法中后端部分可以有突发请求,如果桶满了,可以将桶里所有令牌都拿走。
6
下图是令牌桶算法lua代码实现部分,当然读者还可以使用Nginx,Java脚本或者php脚本来实现。

7

2.降级

社区降级案例
一般情况下,系统上线之后总会遇到一些不稳定情况,比如redis挂掉,甚至后端数据库My SQL挂掉。当出现不稳定情况之后,系统如何保证继续提供这些服务。以社区案例为例,即便是My SQL挂掉,也要能够保证社区为用户提供基本的可读服务。其中一个策略是将一些热点数据,即用户经常浏览的信息或者最新的信息缓存起来,当后端服务不可用的时候,把这些数据展现给用户。大概流程如下图,数据存储部分后端会有一个脚本去分析Nginx里面的日志,然后去请求Vanish,Vanish再去请求后端,这样的话Vanish会有一个有效期,能够保证Vanish存进去的数据都是用户经常访问的一些数据。第二步,如何保证后端数据库挂掉的数据时候能迁过去?下图可以看到,Nginx中使用lua脚本进行实现,它会检测后端服务返回的一些状态,使用计数器计算失败次数,如果频繁的达到一定程度的失败次数,就切换到从Vanish获取数据,最后推送给用户。这样能保证即便是后端的数据库挂掉,甚至即便所有的php进程都挂掉的时候,社区也能给用户提供一些基本的服务。

8
降级目的
降级的目的比较简单,第一个是保障服务器基本可用,第二个是保障服务的核心服务可用。降级是怎么一个思路呢?一般降级的每个策略都是针对一个场景,预想特定场景下需要要解决什么问题;然后再梳理在这个场景下需要保留哪些核心基本服务;最后才选定技术方案,系统化的进行实现。简单讲就是先确定需要达到什么目的,再去了解是什么样的情况,最后制定策略或者计划。比如,系统会调用第三方服务,而第三方服务有可能挂掉,这是一种典型的场景。再比如,系统本身调用推荐服务,但是推荐服务也会挂掉,这种场景下不能够因为没有推荐数据就不显示数据,还是需要展示一些数据,这是一种基本的核心服务。每年的双11或者一些大型活动中基本都会存在降级。降级不仅仅是存在于资源故障场景下,资源不够用时也可能会需要降级,因为资源不够用需要关注重点。如大促活动中,需要先保证交易服务正常运行,其它消耗资源的服务(如对账)可以后续再去处理。
9

3.超时

超时案例
社区对外提供接口服务,对方的反馈是接口服务较慢。接口部分流程是查一段数据,然后将数据反映过去,其问题点在于系统中超时时间设置过长。比如调用Memcache,但是Memcache已经挂掉,由于超时设置过长,数据需要等到超时时间结束以后再返回,导致接口一直在等待。那如何设置超时时间才合理?要注意超时时间并不是固定的值,而是需要针对整个业务,根据特定场景设置超时时间值。
10
如何设置超时时间
大体的思路如下图。第一步,识别业务需要的服务响应时间。比如,需要100毫秒去响应数据,之后统计业务里面可能需要调多少服务。第二步,统计服务日常的响应时间。第三步,分清主次,即分出哪些是核心服务。因为核心服务一旦失败,整个链路便不可用,所以可以对核心服务的时间设置的宽松一些。如果一些服务调不通,但又不影响整个链路,可以对它的时间设置的相对严格。
11
设置完超时之后需要验证,借助模拟手段封端口(如下图),模拟故障,然后检查数据返回时间是否在指定的时间内。

12

4.隔离

隔离案例
下2013年左右,手机客户端开始逐渐升级起来,很多项目既有PC端也有客户端,所以同一个服务即要为PC端又要为客户端提供API接口。一旦遇到大型活动或者需要手机推送,服务会遇到不稳定情况,服务的不稳定会导致PC端也受影响,所以需要将服务进行物理隔离,从原先耦合到一块的服务器分到不同的机器组。隔离目的非常简单,要限制住不稳定因素导致的风险,停止传播。
隔离形式
隔离的常见形式包括几种。第一是秒杀场景,秒杀场景一个高并发的场景,可能带来的问题也比较多,在高并发场景下秒杀的时候,需要和一些正常的业务区分开来,不建议一台机器既提供秒杀也提供进程服务。另外,秒杀的时候会产生热点数据,如售卖数据。数据库更新比较频繁,从数据库层面也可以进行隔离,将热点部分和正常服务部分从资源上隔离。第二个场景是慢SQL隔离,一个资源隔离。一条慢SQL会导致整个服务不稳定。每请求一次线程,慢SQL会一直耗着当前线程,所以资源占用非常大。第三个场景是机房隔离。一般大公司都会做多机房部署,其目的就是确保稳定性。确保稳定性时不要做跨机房调用,否则耦合度会比较高,假如A调B,B挂掉,A服务也会受影响。一般确保稳定性都是做本机房的调用。而且本机房的调用性能也比较快。最后一个场景是进程隔离,因为进程比线程更加稳定。

13

5.集群

对小公司而言,一台机器就提供一个服务,如果机器挂掉服务恢复就会成为一个问题。一般解决方法是做一个集群,从原来的一台机器提供服务变为可以用多台机器提供服务。集群的目的是为了解决单点的问题。集群的形式主要有主备,即同时只有一台机器提供整个服务,可以有一台或者多台提供备份,备份不仅要包含代码层面,整个服务运行所依赖的资源都要有备份。另外一个形式是主从。主是提供一个完整的服务,从是提供部分的服务。还有一种是多主,多主指的是每一台机器的决策是对等的,都会对外提供一些服务。随着集群形式的不同,对代码编写的并发性上有一定要求。主备只需要考虑单机的并发控制,主从是考虑同时提供服务的部分。比如加锁,主备上只要加一个本地的技能锁就可以,主从或者多主则需要加分布式锁。

14

保证策略流程篇

保证稳定性策略的流程方面上分为下图中四个点,code review, 压测,灰度和监控。
15

1.Code review

code review目的是在项目上线前及时发现一些问题。经验比较丰富的人可以将经验进行分享。code review基本经过三个阶段。第一个阶段是头脑风暴式,一群开发人员围着代码做code review,虽然时间成本较高,效果也不太理想,但是这种方式也有好处,在前期可以将大家的意见进行整理,制定code review的规范。第二种code review形式是演讲式,专家事先把代码做一下review,整理一些点,然后进行分享。演讲式可以按照轮岗制,相对头脑风暴式大大节约了时间。目前常见的code review 形式是结对式,由一个或者两个专家结对,相互review,时间上比较灵活,也不需要占据会议室资源。

2.压测

压测目的
压测的目的,第一是保证系统稳定性。在高并发的时候,检测系统是否稳定,因为一些问题在流量比较低的时候发现不了,只有在高并发的时候才能发现这个问题。第二是检测性能的抗压能力,检查系统能承受多大的QPS。
压测关注点
首先,压测机器和被压测服务在同一网段,尽量避免因为网络原因导致压测的结果不准确。第二点是关注服务器的负载,注意不要把服务器压到100%,服务器快要崩的时候,得到的值意义不大。应该是服务器负载达到60%~70%的时候,看QPS是多少。另外,压测并发数据是逐步递增的过程,到一个点的时候,并发数据越多代表QPS越低。最后,根据测试环境的压测结果估算线上的承载能力。估算的公式是线上QPS = 单机QPS 机器数 0.7。后面会乘以一个系数(0.7)是因为线上put上去的时候总会存在一些损耗。

16
全链路压测
但有一些测试在测试环境下无法实现压测,所以现在发展成了全链路压测。全链路压测大概分成三个核心关注点。第一个是数据模型的构造。全链路压测是模拟线上真正的数据模型,比如说访问详情页的人数,下单的人数,人数比例,登陆人数等等参数,尽量按照真实数据模拟,构建仿真模型,这样才能真正的发现线上的一些问题。注意全链路压测不是在测试环境下实现,而是在线上压测。第二个是压测工具构建。可以是借助开源的压测工具,阿里自建了压测平台,根据数据模型提升流量。第三点是流量的隔离。对流量增加标识,保证不影响线上的数据,将全链路测试流量放到测试的存储中。比如生成一个订单order表,同时也会生成一个影子表test_order。如果发现是来自于全链路压测的流量,就把这个数据写到影子表test_order里面,这样能够保证存储。无论是缓存还是数据库存储都能够进行流量隔离。

17

3.灰度

灰度目的是小范围试错,尽量发现问题。灰度的策略大概有以下几种,第一个策略是只让某一个地区的人先访问最新的特性,遇到问题的话用户及时反馈,问题也只会影响特定地区。另外一个策略是基于用户属性,如一个推荐系统,请求过来的时候能区分新老用户,它对新老用户的推荐的策略可能是不一样的,从而来验证策略的准确性和有效性。第三种策略是基于数据,从一批用户中选取几个用户进行处理。比如,对供应链的供应商的数据做处理,但是一般情况下不敢保证代码上线之后100%没问题。这时先选择一个供应商处理,验证数据,确保没问题再全量处理所有的供应商。最后是基于平台,一般都发生在客户端场景下。客户端与服务端不同,服务端一般是针对这个平台,先指挥这个平台先发布新版本,反馈不错再推到整个全面平台。对于客户端的灰度技术的实现如下图,给客户端集中一个Cookie,请求到了之后在Nginx中去检查Cookie,根据不同的Cookie把情趣转到不同的组。比如组A有新特性,组B是老版本,根据不同的Cookie转到不同组,保证只有一部分人可以看到新的特性。

18
19

4.监控

监控注意点
监控的目的是可以自动化及时发现问题。监控需要注意几点问题,第一是全方面监控,系统和服务全部都要监控。第二是报警分级,监控报警的系数设置的要合理。最后一点是在真实环境下做数据收集。比如,A和B服务器,只在B服务器做监控。如果A服务器My SQL数据库网络出问题后,因为在监控上B服务器是正常的,监控不会报警。所以要在应用服务器上做监控才会报警具体哪台机器哪个服务出现故障等信息。

20
自研监控系统
下图是阿里自研的监控系统。首先确定对哪些指标进行监控。将整个指标的数据绘制出来,查看指标数据波动。一旦遇到问题,可以很方便的进行对比。另外要确定影响,将所有相关的指标聚合起来。比如供应商的团队操控系统经常会发生仓库操作卡顿,有很多因素都会导致卡顿,如PC端调用其它接口较慢,服务器load比较高等。仓库人员无法关注具体的细节,他们在影响界面查看指标影响值,一眼就可以知道是哪项指标不合格导致的卡顿。之后对造成的影响进行相应的处理,目前一般的行为有效报警或短信报警。
21
22

技术交流

欢迎同学入群与专家实时技术交流

点击链接入群 https://c.tb.cn/F3.ZR58nS

或扫码入群

php

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性本文旨在探讨PHP中常见的设计模式及其应用,帮助开发者编写出更加灵活、可维护和易于扩展的代码。通过深入浅出的解释和实例演示,我们将了解如何使用设计模式解决实际开发中的问题,并提升代码质量。
在软件开发过程中,设计模式是一套经过验证的解决方案模板,用于处理常见的软件设计问题。PHP作为流行的服务器端脚本语言,也有其特定的设计模式应用。本文将重点介绍几种PHP中常用的设计模式,包括单例模式、工厂模式和策略模式,并通过实际代码示例展示它们的具体用法。同时,我们还将讨论如何在实际项目中合理选择和应用这些设计模式,以提升代码的可维护性和扩展性。
61 4
|
5天前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
17 4
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
46 2
|
2月前
|
缓存 程序员 PHP
为什么说 Swoole 是 PHP 程序员技术水平的分水岭?
【9月更文挑战第8天】Swoole 被视为 PHP 程序员技术水平的分水岭,因为它要求程序员深入理解底层原理(如网络编程、异步和并发模型),具备性能优化能力(如高效服务器开发、数据库连接池管理),拥有架构设计能力(如微服务架构、项目复杂度管理),并具备持续学习和自我提升意识。熟练掌握 Swoole 的程序员在技术能力和综合素质方面更具优势。
|
2月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
96 3
|
2月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
2月前
|
缓存 网络协议 程序员
为什么说 Swoole 是 PHP 程序员技术水平的分水岭?
【9月更文挑战第7天】Swoole 因其异步非阻塞编程模式、高性能服务器开发能力、性能优化工具及拓展技术视野等特点,被视为 PHP 程序员技术水平的分水岭。它要求程序员掌握异步编程、协程、网络协议等知识,并具备性能优化和系统管理能力,从而全面提升技术水平。
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
下一篇
无影云桌面