手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

基本实现 phprpc_client For SAE

Tags: phprpc, sae

简单的PHP类,判断远程地址状态

Tags: http, remote, http_code

常用http code

Tags: http, rfc

利用SAE监控网站

SAE是Sina App Engine(新浪应用引擎)的缩写,SAE是一个分布式web应用开发运行的服务平台,其不仅仅包含创建、部署web应用的简单交互,更涉及一整套大规 模分布式服务的解决方案。用户通过SAE可以方便的创建web应用、定制web应用、开发web应用、部署web应用、切换线上版本、删除应用,大大节省 了开发者的开发成本和运维成本。

作为大规模的分布式服务,云服务是未来的趋势,我们立志于走在云计算领域的研究开发前列,为广大web开发者提供基于云计算的更方便、快捷、可靠、节省的 应用开发运行平台,同时SAE也着眼解决新浪公司内部的资源冗余问题,为公司内部大量的web应用提供可靠的运行平台。

上面这段内容来自于SAE官方网站。云服务云服务,当然是用云来服务。GAE其实也是一个类似的玩意,其实SAE是在GAE出来了几年后才发展起来的东西,相比于GAE来说,功能是要差了一点,不过他是目前为止支持PHP最好的云。要知道google的GAE只支持java和python,虽然通过各种各样的扩展可以使得他支持jRuby,jphp之类的,但毕竟不是原生支持,而SAE才是

开通后做了一个小东西。就是PING自己的博客,当发现取不到meta数据时,就发封邮件给我。因为监控宝是半小时,我在SAE上可以跑5分钟一次。呵呵(既能刷PV,又能监控,多好啊。)

代码很简单。

PHP代码
  1. $url = 'http://www.neatstudio.com';  
  2. $tags = @get_meta_tags( $url );  
  3. if(isSet( $tags['generator'] ) && trim($tags['generator']) == 'gouki,editplus'){  
  4.     //..do nothing  
  5. }else{  
  6.     require_once'saemail.class.php' );  
  7.     $smail = new saemail();  
  8.     $title = sprintf("[%s]无法访问",date'Y-m-d H:i:s' ));  
  9.     $smail->quickSend( '13800138000@139.com' , $title , '无内容' , '******@sina.com' , '******' );  
  10. }  
然后修改config.yaml,増加cron(其实原来的config.yaml已经有cron了,只是注释掉了)

修改后,为了防止被WEB访问,再加一个

XML/HTML代码
  1. handle:  
  2.  - hostaccess: if(path ~ "/cron目录/") allow "10.0.0.0/8"  
表明只允许内网访问,不允许WEB访问,现在直接访问的时候就是403了。HOHO

过了半小时,收到了一封MAIL(因为在测试的时候,我是成功就发)

一切就是这样简单

Tags: sae, php, cron

WEB异步?

网上闲逛的时候看到两篇文章,有点小意思。一个是mikespook 写的关于Web编程异步模型的白日梦,还有一个是【FarmVille(美版开心农场)谈架构:所有模块都是一个可降级的服务】,都谈到了异步。

贴上上面两篇文章,这样可以做一个比较。

先来:【关于WEB编辑异步模型的白日梦】

在地铁上被前前后后那些特种男女逼到车角,无奈。又想起早上那个白日梦,遂上网搜索了一番。得老赵的佳作一篇《F# 与ASP.NET(1):基于事件的异步模式与异步Action》。之前看过,由于对微软无爱,未能 细品。今日一读,如醍醐灌顶,豁然开朗。

遂整理思路如下,以待后用。

在说异步模型之前,先说说最常见的同步模型吧。例如下面的 PHP 代码:

PHP代码
  1. // 获取数据  
  2. $userInfo = getUserInfo();  
  3. $newsList = getNewsList();  
  4. $topRateNewsList = getNewsList('DESC `rate`');  
  5. // 创建模板,绑定变量  
  6. $tmp = CreateTemplate();  
  7. $tmp->bind('userInfo'$userInfo);  
  8. $tmp->bind('newsList'$newsList);  
  9. $tmp->bind('topRateNewsList'$topRateNewsList);  
  10. // 渲染模板,输出  
  11. $tmp->render();  
  12. echo $tmp;  

在这段代码中,所有调用都是顺序的。也就是说,如果 getUserInfo($userId) 没有返回用户信息的话,getNewsList(5) 永远都不会被调用。实际情况,可能是用户信息是从用户库取数据,新闻是从新闻库取数据。假设新闻库运行良好,而由于某种原因用户库宕机了,那么这次请求也 就废掉了。故障也从一个库的宕机扩散到整个站点。

现在,我白日做梦的创建一种新语言 go-php,引入 go-lang 的关键字 go 到 php 中:

PHP代码
  1. // 创建一个数据通道  
  2. $chan = CreateChan();  
  3. // 获取数据,并放到数据通道上去  
  4. go getUserInfo($chan);  
  5. go getNewsList($chan);  
  6. $params = array('DESC `rate`');  
  7. go getNewsList($chan$params);  
  8. // 创建模板  
  9. $tmp = CreateTemplate();  
  10. // 从通道上取数据  
  11. while($d = $chan->read()) {  
  12.     if ($d['error']) {  
  13.         // 数据有错误 ……处理一下吧  
  14.     } else {  
  15.         $tmp->bind($d['key'], $d['data']);  
  16.     }  
  17. }  
  18. // 渲染模板,输出  
  19. $tmp->render();  
  20. echo $tmp;  

 

好了,这其实不是什么新奇创造,这只是一个二段式异步调用(Begin/End)。这有点像大宗采购,采购商并 不一件一件的商品进行采购,而是拿着清单说:“好了,兄弟,这是我要的货,你们帮我找齐,放到码头406号仓库去……”,然后他就在 406 号仓库等着点货了。这段代码还可以改进,就像采购清单一样,将这个清单推到数据层,数据层把数据返回到数据通道上去。恩,应该不少人在自己的应用中使用 MQ,Memcache 甚至 pipe 实现了这种异步了吧。

再来看另外一段 go-php 代码:

PHP代码
  1. /** 
  2.  * 回调函数 
  3.  * @param $tmp 模板 
  4.  * @param $d 返回的数据 
  5.  */  
  6. function callbackBind($tmp$d) {  
  7.     if ($d['error']) {  
  8.         // 数据有错误 ……处理一下吧  
  9.     } else {  
  10.         $tmp->bind($d['key'], $d['data']);  
  11.     }  
  12. }  
  13. // 创建模板  
  14. $tmp = CreateTemplate();  
  15. // 获取数据,并设置数据回调  
  16. go getUserInfo(callbackBind, $tmp);  
  17. go getNewsList(callbackBind, $tmp);  
  18. $params = array('DESC `rate`');  
  19. go getNewsList(callbackBind, $tmp$params);  
  20. // 如果不是所有数据都回调了,则阻塞  
  21. $tmp->wait();  
  22. // 渲染模板,输出  
  23. $tmp->render();  
  24. echo $tmp;  

这就是老赵的事件回调的异步处理的 go-php 版本。这有点像渠道商订货(或者淘宝上的无货代理?):“我需要XXXX,你帮我送到XXXX去”。然后坐等,所有的内容都送到了,就收钱走人。

对于数据读取的错误,只要处理得当也不是致命的。最多在渲染页面的时候,少某块数据,用户只会奇怪:“这次怎么打开没有新闻那部分的内容了呢……刷 新一下看看……”。而不会说:“烂网站,又打不开了……”用户体验直线上升啊!

好了,梦就做到这里。相信这两种方式其实已经有实际案例了。我比较孤陋寡闻一些,了解的不多。而且有的东西,未经许可也不好多说……大家私下打听 吧。

总之呢,两种异步模型各自有各自的好处。并行的数据存取,提高 I/O 利用率是其本质。王道啊……

-----------------------------------------------------------------------------------------

开始【FarmVille(美版开心农场)谈架构:所有模块都是一个可降级的服务

所有模块都是一个可降级的服务

    For any web application, high latency kills your app and highly variable latency eventually kills your app.

    由于大型的网络应用需要依赖各种底层及内部服务,但是服务调用的高延迟是各种应用的最大问题,在竞争激烈的SNS app领域更是如此。解决此问题的方法是将所有的模块设计成一种可降级的服务,包括Memcache, Database, REST API等。将所有可能会发生大延迟的服务进行隔离。这可以通过控制调用超时时间来控制,另外还可以通过应用中的一些开关来关闭某些某些功能避免服务降级造 成的影响。

    上面这点我也有一些教训,曾碰到过由于依赖的一些模块阻塞造成服务不稳定的现象。

    1. 某Socket Server使用了ThreadPool来处理所有核心业务。

    2. 不少业务需要访问内网的一个远程的User Service(RPC)来获取用户信息。

    3. User Service需要访问数据库。

    4. 数据库有时候会变慢,一些大查询需要10秒以上才能完成。

    结果4造成3很多调用很久才能执行完,3造成2的RPC调用阻塞,2造成1的ThreadPool堵塞,ThreadPool不断有新任务 加入,但是老的任务迟迟不能完成。因此对于最终用户的表现是很多请求没有响应。部分用户认为是网络原因会手工重复提交请求,这样会造成状况并进一步恶化。上 面的问题根本是没有意识到远程服务可能会超时或失败,把远程服务RPC调用当成一个本地调用来执行。

    解决思路一:RPC增加Timeout

    解决思路二:将RPC改成异步调用。

    另一分布式大牛James Hamilton谈 到(2)上面这种做法就是他论文Designing and Deploying Internet-Scale Services中的graceful degradation mode(优雅降级)。

FarmVille其他数据

FarmVille基于LAMP架构,运行在EC2上。读写比例是3:1。使用开源工具来做运维监控,如 nagios报警,munin监控,puppet配置。另外还开发了很多内部的程序来监控Facebook DB, Memcache等。到Facebook接口的流量峰值达到3Gb/s,同时内部的cache还承担了1.5Gb/s。另外可动态调整到Facebook 与Cache之间的流量,Facebook接口变慢时,可以利用cache数据直接返回,终极目的是不管发生了那个环节的故障,能够让用户继续游戏。

小结

    尽管FarmVille公布了上面一些技术资料,凭借上面这些资料无法全部了解FarmVille的架构。但是所有模块都是一个可降级服务 的概念值得设计大规模应用的同行参考。

-------------------OVER-----------------

 

上面两篇都讲到了一个顺序执行所导致的问题,所以才想到是采用异步,瀑布型的网页架构事实上本来就会造成当一小部分没正常取出或堵塞时,影响整个网站的运行,异步是否真的必要?如果真有必要,我们的PHP在没有线程、没有进程等的处理状态下,是否能够完美实现?我这只是记录一点资料,请不要尝试与我讨论。我自己也处于迷惘中

Tags: 异步, web, rpc