存档

2013年3月 的存档

大型网站运营的技术经验分享

2013年3月28日 没有评论

一、日志系统

对于一个大型网站来说,代码库非常庞大,模块众多。部门协作的人数规模在百人以上,如何跟踪定位问题不像小网站那样容易。而且我们的服务器都是集群化的,动辄几千台。有一套可查询方便使用的日志系统至关重要。

对于日志的使用也有了一定的经验。我们的日志通常会非常详细的记录各种参数,环境变量,HOST等信息,在出现异常的情况下,必须要记录日志。我们使用了MySQL按时间分片的方式来记录日志,所有集群内节点均通过网络方式来写入到中心日志系统。

在管理端我们提供了很方便友好的工具,来查询定位日志,可按用户ID、类型、时间等几种索引方式查询。日志系统帮助我们定位到了很多问题。

二、PHP错误日志收集系统

PHP错误日志是所有PHP程序问题最直接的反馈渠道。通过分析PHP日志可以发现和分析出系统现有的Bug和潜在的问题。我们通过在节点部署监控工具,实时收集PHP错误日志,Fatal Error告警。解决了很多问题

三、数据统计中心

我们有一整套数据上报的系统,系统内各种接口调用、请求响应、错误返回,都会上报到数据统计中心。我们以报表的形式展现出来,可以很方便的看到每个模块,每个接口的可用性,成功率,数据规模。根据数据,我们还做了成功率告警,当接口成功率低于某个数值,比如99.99%时就会发送短信报警。还有历史数据对比报警,当发现今日数据与往期数据差距较大时,可能是系统出现了问题,会及时进行报警。

四、硬件系统报警

我们有一套工具,来监控每个服务器节点的CPU、硬盘、内存、网卡流量信息,以及其他系统关键参数的信息。并以图表方式提供展示,方便了解服务器运行情况。每次新版本,或新功能上线,都通过这些信息来感知访问量变化,以及机器的负载情况。

五、容灾工具

当一组Server中其中一台出现问题时,会及时发现,并踢掉。这个也可以做成自动容灾,不过控制不好会发生雪崩。

分类: PHP 标签:

说说产品驱动型的管理模式

2013年3月28日 1 条评论

很多IT公司都采用产品驱动技术的管理模式,我们腾讯也是如此。身为一个程序员不得不对这种模式做点评价。

不可否认这种模式会比较快得作出产品来,虽然开发出的产品不一定会是最好,最起码不会是最差。另外产品开发的成功率也得到了保证,不至于做了一半不搞了。

但是也顺便讲讲他的坏处吧。产品驱动的开发模式最致命的问题是:会让所有程序员彻底失去积极性。无论多么棒的Idea,多么有意思的Idea,只要用了这种模式,程序员的那种积极性,创新性都将不存在了。逐渐会产生另外一个问题,反正不是我主导的,我不用再思考了,你们怎么说我就怎么做吧。效率越来越差劲。如果军队是参谋指挥将军,打起仗来会怎么样?

谈论下Facebook的管理模式吧。他们也有产品经理,但主要产品的是技术人员而不是产品经理,产品经理负责给技术出谋划策,提供信息帮助技术人员。他们的效率很高。

腾讯也是产品驱动型的管理模式,不过广州研发部是个例外,也正是因为例外,所以他们搞出了QQ邮箱,微信这样的重量级产品来。

分类: 互联网 标签:

腾讯朋友网tp_netclient.php介绍

2013年3月28日 没有评论

一、为什么要开发tp_netclient.php

大家都知道PHP有2套socket的封装:stream扩展和socket扩展。stream系列函数可以直接用fread/fwrite来读写,PHP做了一些封装,使用起来更方便。但从一下几点因素我们基于socket扩展开发了tp_netclient.php

1、超时设置的问题。调用fread读取socket时,如果没有显式设置超时那么将会取默认的socket超时值75秒。另外即使显式设置了超时,代码中如果调用了stream_socket_recvfrom,还会取默认的75秒超时(这是PHP stream_socket_recvfrom函数的bug)。一旦server端无响应,75秒的超时会使当前进程长时间阻塞。PWS,PSF,SAPS都将无法相应新的请求,造成严重的后果。tp_netclient.php默认设置了100ms,就算没接收到数据,也只会阻塞100ms,之后进程会继续处理新的请求。

2、fread有8192长度限制,一旦读到8192字节,此函数就会返回。TCP可以循环读取, UDP包就会被丢弃。这样如果用UDP协议,就不能处理超过8192字节的包。tp_netclient.php使用了socket扩展,可以支持到UDP包的最大长度65535,不存在此问题。

3、stream的socket不能设置socket option。很多有用的socket option,如SO_REUSEADDR、TCP_NODELAY都不能支持。tp_netclient.php基于socket扩展,可以很方便设置各种socket option。

4、tp_netclient.php支持waitall,在知道包长度的情况下可以一次取完,不必循环取。

5、tp_netclient.php支持UDP connect,解决了UDP串包问题

6、stream扩展是2层封装的,而socket扩展是原生socket函数的封装,性能更好。

二、tp_netclient.php如何使用

目前在朋友网系统消息模块中已广泛使用,在生产环境安全可靠无问题。

示例代码:


$client = new TP_NetClient_TCP;

if($client->connect('10.6.207.204', 19003 ,0.5))
{
   $data = 'GET /default.php HTTP/1.1\r\nHost: www.pengyou.com\r\n\r\n';
   $client->send($data);
   $cnt = $client->recv(65535);
   echo 'succ:',$cnt,'\n';
}
else
{
   echo 'faile:';
   echo $client->code;
   echo $client->msg;
}

注:此代码是私有的,大家可以直接使用swoole扩展提供的client封装。使用方法基本相同。
https://github.com/matyhtf/php_swoole/blob/master/examples/client.php

分类: PHP 标签:

PHP-AOP扩展介绍

2013年3月8日 1 条评论

项目地址:http://pecl.php.net/package/AOP

首先介绍下AOP编程,也叫做面向切面编程,是一种非倾入式编程的方法,采用外部注入的方式来取代嵌入代码。可以实现非常好的模块低耦合。

假设你的框架有一个 Frameworkd::init方法,功能是初始化框架资源。现在有db,template的初始化也需要在这个阶段执行,传统的做法就是只能修改 Frameworkd::init在里面加入 db,template的方法调用。未来如果增加了新的模块,比如cache。那就需要修改Frameworkd::init的代码。这种做法显然是侵入性的。

当然也可以用hook list的方式来实现。在需要外部注入的地方加入一个hook list,遍历执行外部注入的接口。但远没有AOP强大,而且还需要不断加入hook list的遍历点。

如果AOP编程的话,只需要外部注入一个函数,执行 Frameworkd::init时,就会执行指定的代码。


<?php
class MyServices
{
        public function doAdminStuff1 ()
        {
                //some stuff only the admin should do
                echo "Calling doAdminStuff1\n";
        }

        public function doAdminStuff2 ()
        {
                //some stuff only the admin should do
                echo "Calling doAdminStuff2\n";
        }
}

function adviceForDoAdmin ()
{
        echo "AOP[1] Run\n";
}

function adviceForDoAdmin2 ()
{
        echo "AOP[2] Run\n";
}
aop_add_after('MyServices->doAdmin*()', 'adviceForDoAdmin');
aop_add_after('MyServices->doAdmin*()', 'adviceForDoAdmin2');
$o = new MyServices;
$o->doAdminStuff1();
$o->doAdminStuff2();

执行结果:

Calling doAdminStuff1
AOP[2] Run
AOP[1] Run
Calling doAdminStuff2
AOP[2] Run
AOP[1] Run
分类: PHP 标签: