月度归档:2019年01月

HTTP直播HTTP Live Streaming (HLS)

增加EXT-X-MEDIA-SEQUENCE或EXT-X 
      -DISCONTINUITY-SEQUENCE标签的值(第6.2.2节)。

      添加或删除EXT-X-STREAM-INF标签或EXT-XI-FRAME-STREAM-INF 
      标签(第6.2.4节)。请注意,客户端不需要
      重新加载主播放列表文件,因此更改它们可能不会
      立即生效。

      将EXT-X-ENDLIST标记添加到播放列表(第6.2.1节)。

   此外,播放列表文件可以包含EXT-X-PLAYLIST-TYPE标记
   ,其值为EVENT或VOD。如果标签存在且
   值为EVENT,则服务器不得更改或删除任何部分
   播放列表文件(尽管它可以向其添加行)。如果标签
   存在且值为VOD,则播放列表文件不得更改。

   播放列表中的每个媒体片段都必须应用EXTINF标记,以
   指示媒体片段的持续时间。

   媒体播放列表中的每个片段都具有整数不连续
   序列号。
   除了媒体内的时间戳之外,还可以使用不连续序列号来
   跨不同的再现来同步媒体段。Pantos&May将于2014年10月16日到期[第23页]

 
Internet-Draft HTTP Live Streaming 2014年4月

 
   段的不连续序列号是EXT-X 
   -DISCONTINUITY-SEQUENCE标记的值(如果没有,则为零)加上
   URI行之前的播放列表中的EXT-X-DISCONTINUITY标记的数量
   细分市场。

   包含EXT-X-PLAYLIST-TYPE标记的媒体播放列表,其
   值为EVENT或VOD,不得包含EXT-X-DISCONTINUITY- 
   SEQUENCE标记。

   服务器可以
   通过对其应用EXT-X-PROGRAM-DATE-TIME标记将绝对日期和时间与媒体段相关联。这
   定义了(挂钟)日期和时间的信息映射
   由标签指定给段中的第一媒体时间戳,
   其可以用作寻找,显示或用于其他
   目的的基础。如果服务器提供此映射,它应该将
   EXT-X-PROGRAM-DATE-TIME 
   标记应用于应用了EXT-X-DISCONTINUITY标记的每个段。

   如果媒体播放列表包含
   演示文稿的最终媒体段,则播放列表文件必须包含EXT-X-ENDLIST 
   标记。

   如果媒体播放列表不包含EXT-X-ENDLIST标记,则
   服务器必须使新版本的播放列表文件可用,
   其中包含至少一个新媒体段。它必须可用
   相对于以前版本的播放列表文件
   可用的时间:不早于该时间
   之后的目标持续时间的一半,并且不晚于该时间
   之后的目标持续时间的1.5倍。

   如果服务器希望删除整个演示文稿,则必须使
   播放列表文件对客户端不可用。它应该确保
   播放列表文件中的所有媒体段
   至少在删除时播放列表文件的持续时间内仍然可供客户端使用。

6.2.2。现场播放列表

   服务器可以通过
   从播放列表文件中删除媒体段来限制媒体段的可用性(第6.2.1节)。如果
   要删除媒体段,播放列表文件必须只包含
   一个EXT-X-MEDIA-SEQUENCE标记。对于
   从播放列表文件中删除的每个媒体段,其值必须递增1 。

   媒体片段必须按照
   它们在播放列表中出现的顺序从播放列表文件中删除。

   如果
   播放列表文件的持续时间减去段的持续时间
   小于目标持续时间的三倍,则服务器不得从播放列表文件中删除媒体段。

Pantos&May将于2014年10月16日到期[第24页]
 
Internet-Draft HTTP Live Streaming 2014年4月

 
   当服务器从播放列表中删除媒体段时,
   相应的媒体URI应该对客户端保持可用
   的时间段,该时间段等于段的持续时间加上
   分发的最长播放列表文件的持续时间。包含
   该段的服务器。

   如果服务器希望从
   包含EXT-X-DISCONTINUITY标签的媒体播放列表中删除段,则播放列表必须包含
   EXT-X-DISCONTINUITY-SEQUENCE标记。

   如果服务器从媒体
   播放列表中删除EXT-X-DISCONTINUITY标记,它必须增加EXT-X-DISCONTINUITY-的值 –
   SEQUENCE标记,以便
   仍然在播放列表中的段的不连续序列号保持不变。

   如果服务器计划在
   通过HTTP 将媒体段传递给客户端后将其删除,则应该确保HTTP响应包含
   反映计划生存时间的Expires标头。

   实时播放列表不得包含EXT-X-PLAYLIST-TYPE标记。

如何使用FFmpeg连接两个MP4文件

我正在尝试用ffmpeg连接3个MP4文件。我需要这是一个自动的过程,因此我选择了ffmpeg。我正在将这3个文件转换成.ts文件,然后将它们连接起来,然后尝试对连接的.ts文件进行编码。这些文件是H 264和AAC编码的,我希望尽可能保持质量不变或接近原版。

FFmpeg有三种级联方法。

1.级联视频滤波器

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \ -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \ -map "[v]" -map "[a]" output.mkv

请注意,此方法执行重新编码。

2.凹式破碎机

$ cat mylist.txt
file '/path/to/file1' 
file '/path/to/file2' 
file '/path/to/file3' 
$ ffmpeg -f concat -i mylist.txt -c copy output

Windows操作系统:

(echo file ../../../../1.mp4 & echo file ../../../../2.mp4 )>%tmp%/list.txt
ffmpeg -safe 0 -f concat -i %tmp%/list.txt -c copy c:/output.mp4

3.COAT协议

ffmpeg -i "concat:input1|input2" -codec copy output

该方法不适用于许多格式,包括MP4,因为这些格式的性质以及该方法执行的简单级联。

该用哪一个

  • 级联滤波器:如果输入没有相同的参数(宽度、高度等),或者格式/编解码不相同,或者要执行任何筛选,则使用。
  • 凹式破碎机:当想避免重新编码并且你的格式不支持文件级连接时使用(一般用户使用的大多数文件不支持文件级连接)。
  • COAT协议:使用支持文件级连接的格式(MPEG-1,MPEG-2 PS,DV).不要与MP4一起使用。

如果有疑问,可以试试减刑演示程序。

安装Composer PHP Warning: copy(): SSL operation failed with code 1.

报错信息

[root@localhost ~]# php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" PHP Warning:  copy(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in Command line code on line 1 Warning: copy(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in Command line code on line 1 PHP Warning:  copy(): Failed to enable crypto in Command line code on line 1 Warning: copy(): Failed to enable crypto in Command line code on line 1 PHP Warning:  copy(https://install.phpcomposer.com/installer): failed to open stream: operation failed in Command line code on line 1 Warning: copy(https://install.phpcomposer.com/installer): failed to open stream: operation failed in Command line code on line 1

解决方法

  • 应该是CA证书验证失败造成的错误,下载个CA证书
[root@localhost ~]# wget http://curl.haxx.se/ca/cacert.pem [root@localhost ~]# mv cacert.pem /usr/local/openssl/ssl/certs/cacert.pem [root@localhost ~]# vim /yourpath/php.ini
  • 修改cafile路径,保存
[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context ; option.
;openssl.cafile=
openssl.cafile=/usr/local/openssl/ssl/certs/cacert.pem

使用nginx配置多个php-fastcgi负载均衡

配置还是非常简单的,充分体现了nginx的强大与配置的简单。

应用的最前端是一台nginx服务器,所有静态的内容都由nginx来处理,而将所有php的 请求都分摊到下游的若干台

运行PHP fastcgi守护进程的服务器中,这样可以以一种廉价的方案来实现对系统负载的分摊,扩展系统的负载能力。

三台php-fastcgi服务器的ip地址分别为:

          172.16.236.110 ,   172.16.236.111,     172.16.236.112

运行php-fastcgi进程时,需要让php-cgi监听到服务器的局域网地址(分别如上所示),而不是之前一般都是监听的

本地地址(127.0.0.1)。

以 172.16.236.110这台服务器为例:

 
/usr/local/php5/bin/php-cgi -b 172.16.236.110:9000

或许你用spawn-fcgi来启动php-fcgi,那么就是这样(供参考,其实也就是修改监听的地址和端口即可):

 
/usr/local/lighttpd/bin/spawn-fcgi -f /usr/local/php5/bin/php-cgi -a 172.16.236.110 -p 9000

又或许你是用php-fpm来管理php-fcgi,那么你需要修改php-fpm的配置:

 
vim  /usr/local/php5/etc/php-fpm.conf

找到这个配置项(其中的地址可能需要根据你自己环境来调整)



<value< span=”” style=”word-wrap: break-word;”> name=”listen_address“>127.0.0.1:9000>

修改为:

<value< span=”” style=”word-wrap: break-word;”> name=”listen_address>172.16.236.110:9000>



修改完毕后,重启你的php-fpm进程。

然后按照上面的步骤,依次修改其他php fastcgi服务器。

php方面的工作暂时就是这些,下面修改nginx。

 
vim  /usr/local/nginx/conf/nginx.conf

在配置文件的http段内增加类似如下的配置:

1
2
3
4
5
upstream myfastcgi { server 172.16.236.110 weight=1; server 172.16.236.111 weight=1; server 172.16.236.112 weight=1; }

我这里三台php fastcgi服务器的权重是相同的,所以其中的weight值都是1,如果你的php fastcgi服务器需要分主次,那么

可以通过调整其weight值来达到目的。比如以第一台服务器为主,其他两台为辅,则就是这样:

1
2
3
4
5
upstream myfastcgi { server 172.16.236.110 weight=1; server 172.16.236.111 weight=2; server 172.16.236.112 weight=2; }

然后找到原来nginx关于php fastcgi配置的部分,比如:

1
2
3
4
5
6
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }

将其中的fastcgi_pass那一段改为:



fastcgi_pass myfastcgi;

其中的myfastcgi也就是上面刚刚配置的php fastcgi均衡器的名字了。

完了以后,重启nginx即可。

简单吧,就通过这么几个简单的配置,就可以实现一个经济高效的nginx、多php-fcgi的负载均衡解决方案了。

当然了,这样的方案运用到实际项目中 还需要进行一些细化的配置,主要是php方面还需要进一步配置

Google的DevOps理念及实践(上)

SRE(Site Reliability Engineering)是最早由Google提出,又经由Google发展完善的一个崭新运维理念。如今SRE已成为一个涵盖运维理念、思路、组织架构和具体实践的完整体系。数人云推出SRE系列教程,由SRE经验丰富的技术大牛们为大家分享运维一线的独家干货,揭示SRE背后的秘密。

今天为系列教程第一期,我们邀请了前Google SRE、《SRE Google运维解密》的译者孙宇聪与大家进行了线上分享。本文为上篇,讲述了SRE的基本概念和核心原理。与孙老师本人一样风趣幽默的文章,小数希望大家阅读愉快:)

今天与大家分享的内容是关于最近我翻译的这本书,据说反响还不错,今天借这个机会聊一聊书中的内容,并与大家分享一下我回国两年多以来,Google经验在国内的一些思考和落地实践。

什么是SRE?

很多时候国内把DevOps的范围定得有点狭窄, DevOps这件事情在国外更多是整个行业内的一个趋势。DevOps是一种模式,主要是让IT相关的东西与商业结合得更紧密一些,迭代速度变得更快一些,所以它适用于各个行业。今天说的SRE,我认为也是在运维行业上的一部分。

概括来说,我认为《SRE Google运维解密》这本书是一个文集。GoogleSRE全球一千多人,这个组织在公司里相对比较小众,但又是一个比较重要的部门,整个Google所有业务线的运维环境都由SRE来负责。SRE是一个非常分散的组织,每个业务线、每个部门其实都有自己的SRE小团队。这本书里共有一百多个作者联合写成,其中也包括我以前所在的团队,我们做过的一些Project也在书中也有提到,所以它是一本文集。我与原著的三个编辑聊天时,他们说成书最大的难处就是删减内容,当时征集来的内容大概有一千多页,最后删到了五百多页。这也是这本书比较有意思的一个花絮。

回到这本书的宗旨, SRE到底是什么?SRE是Google发明的一个词语或者新定义的一个职业。以前这个运维角色,大家叫运维,美国叫Operation。现在Google把这个职位扩展为SRE,就是用软件工程师的方法和手段,招了一些软件工程师来解决运维的难题,这是SRE的官方定义。

传统运维模式的弱点

现在传统的计算机行业的运维方式,大部分都是采用系统管理员的模式。大家最熟悉的运维方式是这样:招聘一些系统管理员,他们有负责采购机器的,有负责维护数据中心的,也有专门维护数据库的等等。系统管理员模式有几个特点,他们只是把一些现成的组件组装起来,并不会自己开发和创造新的系统,比如拿了MySQL把它跑起来,或是研发部门开发出来的新代码组装成之后提供这样一个服务。这是运维部门的一个特色,负责把这个东西运行好。

举一个例子,在美国的时候我们经常自嘲,说自己是流水线上的工人。因为这个流水线实际上是别人设计出来的,总得有人去操作这个机器,而我们就是一线的操作流水线的工人。又比如,我们好像是发电站里的工作人员,又或者是飞机驾驶员。飞机驾驶员就是开别人造出来的飞机,这和运维部门的职责很像。

那么这样一个运维部门的职责包括哪些呢?首先最重要的是应急事件的处理,这是重中之重,也是最唯一的职责。其次是常规更新,现在的业务发展越来越快,每周都有新的东西上线,比如说今天要买新机器,明天要改IP地址,大家可能80%的投入都是在这些事上,这就是系统管理员或者是现在运维行业的工作模式。

但是系统管理员模式有一个最大的弊端,按照传统的组织架构模式或者是这种运维模式运行会导致这个团队持续扩张,业务越来越多,需要不停的招人去应付各种各样的事。刚开始接手生产的时候,也许一周就出一次事或者是需要更新一次。因为人的沟通能力总是有限的,招了五个人之后,这五个人之间的传达问题就形成了一个困难。当你把一个精神传达给这五个人,他们事后执行出来的结果都不一样,这就是传统模型一直想要解决的问题。但是这种模型也有好处,就是市场招聘比较容易。

Google有几个比较重要的特点,首先它的部署规模非常大。Google到今天已经十八年了,刚开始前几年公司所有的人平时写代码,周末去机房接机器。因为它扩展速度特别快,部署规模非常大。如果按照传统的系统管理员的那种模式操作,这个机柜归你,这个机柜归他,再下一个归另外一个人,那么Google招人的速度一定赶不上机器增加的速度,所以Google是被逼迫创造了这样的职位,因为没有办法安排团队做如此大规模的运维。

传统的运维模式还有一个更大的问题,它过于强调专业化。比如一个人是做网络的,他只做网络其他都不管,全公司可能只有他懂网络,因为他不停的在网络上投入时间,集中力气把这个事情做好。这样一个结果就是会发现运维部门没人能休假,一出事只有一个人能解决问题。不仅仅是网络,特殊硬件、一些第三方服务都存在这个问题。这就导致了知识没法共享,人灵活性受到限制,整个组织的灵活性也受限制。这个问题,我认为它最终形成了一个负反馈的循环,每个人之间越是互相隔离,越是没有办法提高,导致服务质量上不去。最大的问题是,招来更多的人其实也不解决问题,因为这个部署规模不断扩大,人之间的知识不能共享,所以招来的人只能运维新的设备,旧的设备还是这些人在做。

这是一个怪圈。回国之后我与很多公司的朋友都聊过这个问题。以前大家讲Oracle这样的公司存在老DBA,说老DBA都是难得一见的,深居简出,但是你有什么问题,只有他能解决,其实这在Google这个语境里这是一个比较不健康的状态。SRE的一大特点就是想请假的时候随时请假,每一个人都可以请假;当出现紧急情况的时候,当天值班的人真的可以处理他负责的这个服务所有的问题。

Google SRE的起源与特点

回到最开始,Google SRE的VP叫Ben Treynor,他是一个资深的软件开发经理。2003年他加入公司第一个任务,是组建一个7人的“生产运维小组”。很快他发现如果想把这件事情做好,也就是把搜索服务运维好的话,按照Google机器增加的速度,传统的模式绝对是不可能的。机器增加的速度,系统复杂度增加的速度远比人增加的速度要多得多。所以他组建的团队有以下三个特点,注意,这里我认为其实更多的是事后的总结。首先,他的执行方式是像组建一个研发团队一样来组建这个运维团队。他招了很多他熟悉的研发工程师,这些研发工程师从开发能力上没有任何问题,用现在流行的话就是全栈工程师,什么都会做。第二点,这些人对系统管理比较有热情,懂一些Linux内核知识、网络层的知识。第三点,最关键的是这些人鄙视重复性劳动,码农最痛恨的是什么事,就是反复做同一件事。他把这些人聚到一块,然后让他们执行以前传统公司运维人员来做的事情,很自然这些人不愿意手动干,于是就写程序干。多快好省,同时写程序还有一个好处,就是可以把一些最佳实践、方式、流程、方法都固化成代码,用这种方式去应对规模性的扩张,去应对复杂度的上升。

这些是SRE跟传统的运维模式最不同的一点,就是招的人研发为主,做的事也是以研发为主。这是当时SRE成立背后的故事,这些年来我认为他们做得最好的一点是一直在维持了一种平衡。将运维部门从传统执行部门往上提升,打破了传统的界限。就像刚才说的DevOps,很多人理解为就是让研发部门做运维的事,或者运维部门做研发的事情,但实际上DevOps在国外的定义更宽泛一点。DevOps的思想更多的是说把整个开发流程的界限打通,产品有的时候也要干一些研发的事,研发有时候把这个信息要很快的反馈给这个产品,开发和运维或者QA和运维之间的界限也打通。所以现在去搜DevOps的图片,会发现IBM这些人都在讲圈圈,说以前是产品研发都是一条线直着来,而现在都是转圈的,这就是DevOps理论。

按照这个理论来说,SRE就是DevOps的思想在开发和运维之间的一个平衡。

SRE的工作职责

这个图是我发明的,书中没有提到。书里大概有二十多章的内容是在讲SRE的各种日常工作,简单提了一下它的金字塔模型,于是我归纳总结了一下。这里是由下至上,下面的事份额比较大一点,上面的事份额比较小一点,分了三类。第一类,运维部门最重要的是应急响应这个问题,因为业务越来越大,与运营的结合越来越紧密,很多时候要处理的事情更多的是商业和运营上的事,也包括软件上的问题,这个部门最特殊或者最唯一的职责就是应急响应。之上是日常运维,保证机器能够正常更新、快速迭代。再往上是输出一些工程研发,无论是做工具,还是做高可用架构、提高可靠性,这些都是最上层的东西,只有把底下全部做好了才能说到上面。

应急响应

应急响应是运维部门在公司最独特的一点,表现为当公司出现问题时,应该找谁或者流程应该是怎样的。我回国之后见了不少初创企业,他们网站出问题了,往往是CEO先发现,CEO打电话“哎,这个到底是怎么回事啊”,然后每一个人都说“不知道啊,不是我负责呀,我得找谁谁”。不管多大一件事都得传遍整个公司,整个效率非常混乱。

我在Google待了八年时间,这样的流程也经历过,但是最近这几年Google非常重视这一点,建立了一整套应急事件处理方式。首先要有全面监控,监控这件事情是持久不断的,重中之重。SRE所有人都要非常了解整个监控系统在所有业务中的部署实施,其实这是我们平时花精力最多的地方。监控系统里面对整个系统所有方面都有监控,不光包括业务指标,也包括性能指标、效率指标。监控应该平台化、系统化,不停的往上积累,多做一些模板,同质化的系统就可以用同样的方法去做监控。

第二点是应急事务处理,应急事务处理分两部分,第一部分是演习,另外一部分是真正的处理流程。如何把它做好?实际上就是要不停的去演习、去做这个事情。像刚才举的例子,网站挂了,首先不应该CEO先发现,而应该是监控系统或者报警系统先告警,在发现之前就很应该明确这个东西应该谁排查,谁处理,这个信息应该早就发给合适的人去处理,甚至他应该早就在做了。如果发生特别大的,需要跨部门之间协作的问题,那不应该只是领导现场调配,而是整个组织每个人都明白这个流程应该是怎么样的,直接就做。Google甚至可以做到在一次事故中间两地交班,某个团队处理一半,然后我交接给另外一边团队,就下班回家了,持续不停的有人继续跟踪处理这件事情,而不会出现问题。这样一个模式是我觉得非常值得我们思考的。

处理完问题之后,要总结。之前听过的一个故事是,某公司业务出现了一个事故,大家加班加点,十几个小时没睡觉把这事搞定,然后领导过来就说了一句“大家辛苦了,回家睡觉吧”。但是,其实在这个时候我要说,领导光说这个其实恰恰是不够的。领导在这里应该问:为什么加班啊?这个事情为什么会发生啊,下次能不能不发生,大家能不能不加班,能不能不熬夜?这样才对, 能做到事后总结这个事情很难,但只有把这个做好了,才能降低以后问题发生的几率。

日常运维

日常运维做得最多的可能是变更管理。业务现在发展非常快,迭代速度、迭代周期非常快。其实这件事情能做好,能够做到无缝、安全、不停的变更管理,是运维部门能给公司做的最大贡献。

第二个,容量规划,当规模大到一定程度的时候,就需要有人来回答这个问题——到底要买多少新机器,能否保证明年的性能、效率,那谁来负责这件事呢?SRE部门提出这些方案,然后要确保这些指标、这些东西是有数据支撑的,确实能解决问题的。

工程研发

工程研发虽然做得少,但是工作很关键。SRE在工程研发上主要的工作,首先是帮产品部门确定一个SLO。SLO是一个服务指标,每一个产品都有一个服务指标。任何系统都不可能是百分之百可靠的,也没有必要做到百分之百可靠。这里得有一个目标,比如说可以每个月中断几分钟。这件事情是要产品部门考虑清楚的。比如我之前在YouTube做视频存储、视频点播的时候,要考虑每个视频到底是存一份还是存两份的问题,将这种问题放到一个非常大的部署规模里面的时候,只有产品部门能够拍板。说到底是要不要花这个预算,要不要花这么多钱去提高0.1%的可靠性或者0.01%的可靠性。

另外一点是无人化运维。大家都看过《黑客帝国》吧?一醒来发现大家都是电池,都是为机器服务的。其实把这个比喻放在运维部门非常合适。因为如果不停的开发出需要人来操作运维的系统,结果大家最后都是电池,明显是不可持续的。如果不停的产生这种需要人来操作的东西,不停的招人,最后就变成不停的运维这个东西。把整个流程自动化,建立一个能够应对复杂业务的平台,这就是工程研发上最需要的东西。

SRE模型成功的关键要素

SRE在Google有十几年的历史了。这个模型是如何成功的?我总结如下几点:

职业化

运维行业从来都说不清楚自己是干嘛的,这是不对的。很多人认为会操作Linux,或者是DBA、会配网络,就算运维了。实际上运维的范围要比这个大得多。运维应该是负责公司业务正常运转的角色,这才是真正的运维。在出问题的时候能解决问题,保障业务连续性,甚至避免问题发生,这才是运维职业的定义。

具体如何做呢?推演和演习。

推演是给你一套系统,你要分析出来它会有什么样的失败模式。我们当时经常在黑板上画系统图,大家一起讨论如果这个组件出问题了会发生什么情况,用户到底还能不能看视频了,用户购买流程还能不能走通。实际上这些过程很多时候软件开发是不考虑的,但是如何拆分、如何去保证每个环节的可靠,这才反是运维这个行业最关键的一点,所以一定要做这种推演。只有这种推演才能输出改变,让系统更可靠。

第二点是演习。我们当时每周都会进行一次小型灾难演习,例如把以前出现的问题拿出来一个,让新加入团队的人去演习,所有其他的人也都要去参加。这里主要是观察新人到底是怎么思考这个系统的,新人做出的决定到底是不是正确的。因为一个人做出的决定是不是正确的实际上取决于系统给的反馈到底是不是对的。Google认为运维复杂系统不是一个靠智商和记忆力就能解决的问题,不能依赖人一定要知道这段话或这个知识点,而是要知道一种方法,知道如何去排除问题或排查问题。运维系统应该提供足够的信息,让轮值的人能够用正确的方法去处理问题。这很像是背英语辞典和会用英语聊天的区别,你再怎么背辞典关键时刻也是要查辞典的,但是真正能运用这些信息解决问题,是比较难的。

此外,要区分责任和指责。责任和指责是两个事情,但是很多公司的运维经常分不清楚。什么叫责任,就是这个事到底谁负责。但是指责是另外一回事。例如一个员工敲错了一个命令,大家说 “都是因为他的错,给他扣工资、扣奖金,让他三天不吃饭”,但这其实并不真正解决问题。再例如,比如说一个系统设计电源插座,没有仔细考虑,很容易被人踢到,结果有人真踢到了,整个机房断电了出了很大的事故。那么从Google的理念来说这里不是人的问题,而是系统设计的问题。这里是不是应该有两套电源,是不是应该有保护?只有从系统设计问题的角度出发才能真正解决问题,而指责这个踢到插座的人,让他一个月不上班,甚至当时开除也并不能解决系统的设计问题,下回总会还有人踢到。

说一个故事,故事的内容是一个事故。某个数据中心有一排机器要断电,数据中心的人发了一个工单告诉操作员要把这个开关给关了。然后这个操作员去关,他关掉了开关,但是发现这一排机器的灯没灭,另外一排的灯却灭了——按错开关了。他检查一下发现按错了,“啪”把另外一个开关也关了,然后再把这一排机器给启动,结果由于启动时候过载导致整个数据中心都断电了,扩大了问题。如果单纯只是指责,这个人肯定完了,起码奖金没有了,能不能保证工作都不知道。但是Google 更关注的是这个东西为什么会容易出错,要么是开关颜色不对,要么是相同机器的操作方式靠得太近了,会让人产生这种错误的判断。所以你看Google的机房里都是五颜六色的,因为这样确实有用,比如热水管是红色的,制冷管是蓝色的,所以查起来很容易,区分起来很容易,尽量减少了这个问题。这个设计的思想在SRE日常工作里贯彻得非常深,每人在流程或工作的时候都要考虑到有没有被误用的可能,然后如何避免误用。

专业化

专业化体现在什么程度呢?要真正的去写代码,要能给业务系统或者给研发写的东西挑出问题,提高可靠性。

第一,减少琐事。运维中有很多虚假的工作。每天很忙,然而又不解决问题,做了很多假的工作。大家看起来好像很忙,一个屏幕上十几个窗口,各种刷屏,但完全不解决问题。更好的方式是用自动化、系统化、工具化的方式去消除这种琐事的存在。如果永远靠人工,那永远都闲不下来。

第二,回到SRE,SRE制度里有一条红线,运维的人只能把一半的时间花在运维上,另外一半的时间必须搞工程上、研发上的东西。研发可以是写工具,可以是参与系统设计,参与可靠性的提高,但是要保证运维不能只干运维。

第三点,我认为也是比较缺少的,运维部门光有责任没有决策权,所以大家都说一出事故,运维就背黑锅。怎么不背黑锅呢?说改这儿、改那儿,然后发现没有人批准改动,这是最大的问题。SRE做的最好的一点是管理层对SRE的工作方式非常认可、非常支持,他们认为服务质量是服务的一个重要指标。一旦上升到这个高度,SRE部门提出一些要求就比较容易理解,得到支持,因为他们是有事实根据的。当GoogleSRE发现生产出现问题的时候,标准的解决办法就是暂停所有更新,确保业务稳定。举个比较极端的例子,像刚才说的如果发现线上系统有问题的情况下,SRE是有权利拒绝接受业务更新的,只允许研发部门修bug,不允许加新功能。这个争议我在过去八年见过为数不多的几次,开发可以一直闹到 VP,SVP 这个级别。每一次都是听SRE的。

打通与产品团队的反馈回路

所有东西不都是百分之百稳定的,稳定性的提高要消耗成本,要增加更多的冗余,更多的容量,甚至只能花钱解决。运维部门的任务就是提供这些数据和方案。比如搞三个9、四个9,要如何达到,这在投入和系统设计上有很大区别。这个部分公司里没有其他人可以提出,必须要由运维部门提出。如果没有这个反馈回路的话,你会发现大家都很痛苦,很多时候做出的决定都是违背自然规律的。我看过很多这样的案例,上面拍脑门决定某个业务要100%稳定,完全不管下面怎么搞,由于反馈回路不存在或者这个反馈回路的信息流动不够顺畅,导致了这个东西最终实际做不好,这是SRE模型相当关键的一个地方。

UDP Jitter测试

UDP Jitter测试是以UDP报文为承载,通过记录在报文中的时间戳信息来统计时延、抖动、单向丢包的一种测试方法。Jitter(抖动时间)是指相邻两个报文的接收时间间隔减去这两个报文的发送时间间隔的差值。

图1 UDP Jitter测试原理图 

图1所示,UDP Jitter测试的过程如下:

  1. 源端(ME60A)向目的端(ME60B)发送数据包。发送时,在报文中记录时间戳t1。

  2. 目的端(ME60B)收到报文后,在报文中记录时间戳t1’。

  3. 目的端(ME60B)将收到的报文发回到源端,在报文中记录时间戳t2’。

  4. 源端(ME60A)收到报文,在报文中记录时间戳t2。

从源端接收到的信息中计算出:

  • 数据包从源端到目的端和从目的端到源端的最大抖动时间、最小抖动时间及平均抖动时间。

  • 从目的端到源端或从源端到目的端的最大单向延时。

从而清晰的反映出网络状况。

双向时延:RTT=(t2-t1)-(t2′- t1’)

当双向时延>用户配置的超时时间时,表示网络不畅通。此时,报文将被统计为丢包。

丢包率=丢包个数/发送报文总数

UDP Jitter测试可以测试2个方向的抖动(Jitter)值:

  • SD(源到目的)方向:Jitter=(t3’-t1’)-(t3-t1)

    计算出来的结果,如果大于0,则统计为正向抖动值;如果小于0,则统计为负向抖动值。

  • DS(目的到源)方向:Jitter=(t4-t2)-(t4’-t2’)

    计算出来的结果,如果大于0,则统计为正向抖动值;如果小于0,则统计为负向抖动值。

UDP Jitter测试例还支持统计单向丢包。

图2 UDP Jitter测试统计单向丢包原理图 

图2所示,在Server(ME60B)端会统计收到报文的个数,当Client(ME60A)端口收到的报文个数与从报文中获取的Server(ME60B)端收到报文的个数不同时,会自动发起单向丢包查询,获取Server(ME60B)端接收报文的个数:

Packet Loss SD是源到目的的丢包

Packet Loss SD=Client(ME60A)端发送的报文个数-Server(ME60B)接收报文个数

Packet Loss DS是目的到源的丢包

Packet Loss DS=Server(ME60B)接收报文的个数-Client(ME60A)接收报文的个数

Client(ME60A)端收不到查询报文时,会将丢包记录到Packet Loss Unknown。

php连接mysql是否应该使用存储过程以及优劣势和使用场景

利弊是相对的,使用存储过程来实现不一定是什么“滔天大罪”,这完全取决于系统的规模,扩展性以及产品的发展方向。
通常情况来说,把业务逻辑写到存储过程中不利于系统分层设计和维护,更不利于数据库的迁移(当然没有谁总想着换个数据库玩儿玩儿),这么做的原因很可能是他认为可以提高性能(存储过程的性能确实优于SQL访问的性能),不过为了解决性能问题有很多种方案,这种方式可能会差一些。

先说一下优劣势,再说一下使用场景吧

1、存储过程的优势

(1)、减少连接数

(2)、调用相对程序方比较简单,由DB管理员加,程序方只是需要传递参数即可

(3)、方便DBA查看

2.使用存储过程的劣势

(1)、程序极大耦合,业务一旦更改,需要都进行更改

(2)、牵扯到复杂计算的情况下,需要数据库进行运算,而数据库的优势是存取,循环等逻辑判断服务的情况是数据库的一个硬伤

(3)、调试困难,无法知道运行sql的情况,尤其是数据库有专门DBA的情况

(4)、主从分离的情况无法使用

(5)、无法适应数据库的切割(水平或垂直切割)。数据库切割之后,存储过程并不清楚数据存储在哪个数据库中。

3、使用场景

存储过程只是适用在php和mysql都是同一个人管理的不太进行业务变更的小网站上。稍微复杂一点的网站并不适合存储过程