Published on 2009年09月22日
今天看了twitter关于cache的策略,领略了cache的威力,抒发了一下情感。
Everything runs from memory in Web 2.0.
优化Cache的策略是为了什么,不外乎三点:
- 减少IO,减少传输,减少CPU计算,减少同时工作的服务器的数量。
- 对结果进行共享,比如搜索,通常我们将关键词和结果串化进行Cache,然后在时间范围内使用Cache来对分享服务器工作结果。
- 更快。这永远都是终极的目标。
通常的架构,对于Cache而言,我们有两层,最前端是一个Page Cache,然后是Memcached,最下来就是Data Pool。

这样的架构下我们能够解决大部分的问题,特别是在处理更多常态化的需求时,访问量平稳,数据提交远小于数据读取。但是这么做有瓶颈特别是对于2.0的网站,我们要应付越来越多的用户数据,要不断的缩短Page Cache的有效时间,我们还得应付更多的异常的流量爆发,于是这样的简单的策略就不顶用了。除非我们不计成本的增加我们的服务器,加大我们的带宽,但也许你的老板会说找你还不如请IDC的人吃饭。我们是架构师嘛,为了不让老板这么说,那我们就得找出策略来。
对于无穷无尽的用户数据的提交,我们通常会想到MQ。说说MQ是个什么东西。他是一种消息队列的处理方式,消息列队是分布式应用间交换数据的一种技术,队列被存在磁盘或者RAM里,队列里面是消息,消息直到它被app读走才被删除。这种机制使得app可以独立的运行,它们不必知道各自的位置和状态,执行过程中也不需要等待其他app的响应。
MQ的最上层是一个消息管理器,下面是队列,队列里存放消息。中间是通道,这里是通道是消息传递的管道,是建立在物理网络中的概念,可以说通道MQ整个概念的精华。通道通常被分为三种,消息通道,MQI,Cluster通道。消息通道是一个单向的通道,有Post, Get, Request, Server等不同的类型,一般是建立在MQ服务器与其他事务服务器之间;MQI是建立在app与MQ之间的,是双向的通道;而Cluster通道则是建立在不同的MQ服务器或者同一MQ集群下的不同消息管理器之间。
MQ的工作原理差不多可以来说。

我们先看看单个系统的情况。app1发送一条消息到MQ,并告诉它消息属于队列1,于是MQ则将消息放到队列1里面,app2便可以读取这个消息然后MQ等待app2读取后把这条消息del掉。
下面这个便要复杂一些。app1发送一条消息到MQ,并告诉它消息属于队列2,然而MQ将消息放到队列2之后发现,这个队列其实是在sysB里面的,这时候MQ会把消息放到一个特殊的传输队列中,然后我们建立一个cluster通道,这个通道更像是一个代理app,这个代理app读到数据并传输到sysB,而在确认sysB真正获取到消息之后MQ才释放掉这条消息。在这里我们意识到MQ在确保消息的准确传输,并且一条消息只有一次这样的传输。
移步:缓存,缓存,缓存(二)—— 言归正传说twitter
Published on 2009年08月10日
当我们需要在不同服务器或者不同的语言之间做数据交换,我们有一种方法是用Socket做数据代理。Socket是源于UNIX的套接字,基于TCP/IP协议,是从UNIX早期的命令集中演化而来的,基础的模式是“连接-读写-关闭”。Socket可以应用于B/S和C/S两种不同的网络软件架构上,现在已经被广泛的引用。
php的Socket模块虽然相对比较简陋,一些复杂的应用会出现一些莫名奇妙的问题,但是单单作为基础的数据代理来讲还是经受了人们的检验。
一、Socket传输的是什么
Socket传输的是字节流,没有定义边界。只是通过调节缓冲区的大小来完成流的截断,当然设置缓冲区的大小都是必须的,否则Socket也许会一直工作下去。Socket传输的数据很容易被截取并且会直接展示出来,所以你通常需要对你的数据进行加密,比如AES,就是很好的加密算法,不要用MD5这样的散列表,否则你会死得很惨。
PHP似乎想要get字节流加上边界,在它的socket_write这个函数中声明的三个参数,它的文档里面说如果你将第三个参数设置为PHP_NORMAL_READ,那么将会读取到/r或者/n,可惜,当我这样做的时候,程序溢出了。原因至今不明。
二、用php做一个SocketServer
我们先抛弃类,这篇将没有一个类定义出现。
前面我们已经说了Socket的工作模式是“连接-读写-关闭”。作为服务器,我们要做的事情是建立一个socket,绑定一个端口,然后监视每一个连接,读取他们传来的消息,并给予他们反馈,然后将这个连接毙掉。现在我们开始
< ?php
//===================
//SockServ.php
//===================
define('SOCKIP', 'localhost');
define('SOCKPORT', '12345');
/**
* Set up our socket
*/
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //创建一个socket
printf("Socket created.\r\n");
socket_bind($sock, SOCKIP, SOCKPORT); //绑定一个端口
socket_listen($sock); //开始监视了
printf("Socket has set up.\r\n\r\n");
while(true) {
$conn = socket_accept($sock); //抓到一个,允许它的连接
if ($conn) {
printf("==========================================\r\n");
printf("Socket connected.\r\n");
while($data = socket_read($conn, 1024)) {
//千万不能加上PHP_NORMAL_READ啊
$buffer = $data;
printf("Data Received.\r\n");
print_r("Buffer: ".$buffer."\r\n");
socket_write($conn, "OK"); //告诉客户端,OK,我收到了
printf("Successed!\r\n");
}
socket_close($conn); //工作完成,你可以去了
printf("Closed the socket\r\n");
printf("==========================================\r\n\r\n");
}
}
?>
上面这段程序,你最好别用浏览器来跑,你可能会得到一个超时,你应该在命令行里面跑。在服务器上,让它跑在后台,然后就让它呆在那里吧,没事的。
三、还有客户端呢
我们当然还需要一个客户端,不然你执行上面程序时会一直停在“Socket has set up.”。客户端的任务就是在浏览器里打开一张页面程序,向服务器端发送那么一个字符串,然后接受服务器返回的“OK”。我们开始吧
< ?php
//===================
//SockClient.php
//===================
define('SOCKIP', 'localhost');
define('SOCKPORT', '12345');
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //创建一个socket
$connStat = socket_connect($sock, SOCKIP, SOCKPORT); //连接到服务器
if ($connStat) { //连接成功
echo '<p>连接成功!';
$buffer = 'Hi, Server!';
socket_write($sock, $buffer);
while($data = socket_read($sock, 1024)) {
//依然切记不要PHP_NORMAL_READ
if ($data == 'OK') echo '<p>OK,搞定!</p>';
}
socket_close($sock); //你可以安心的去了
} else { //连接失败啦
echo '<p>连接居然失败了,是不是服务器没开啊!</p>';
}
?>
这个程序是跑在浏览器上面的,通常呢,我们会写成一个类这个类独立在系统的架构之外,将这个类文件交给负责不同app的程序员,让他们来调用,从而实现和服务器的通信。
四、当然这是个很简单的例子
实际上,我们通常有更复杂的事情去做,但是并不代表对于socket来说我们要做更多的事情,我们只需要在客户端的数据开源(现在是直接定义的),服务器端的数据处理(现在只是打印到屏幕上),还有服务器根据客户端数据进行不同的反馈以及客户端对反馈的处理,这几个方面进行扩展,便可以完成几乎所有的需求。
Socket作为一种有效的数据代理方式,还能够为更好的程序架构提供帮助,比如我们提供更多的服务器数据交换来降低前段服务器的计算压力,Socket本身有很好的栈策略也能在服务器的部署上带来帮助。
Published on 2009年07月30日
好久没写了,这里换了一个主机空间,免费的还是不靠谱说停就停了。回来这么久,还算是安定了下来。先说件很无奈的事情,我离开北京之后,Eason又去开了一场演唱会,还有过段时间的张北草原音乐节,张悬、Tizzy Bac,真是早不来晚不来,呆在北京真好。
和在北京时不一样,回到重庆,我们考虑得更多的是怎么为重庆本地市场做互联网,这段时间说到一个很多的问题是互联网应用的本地化应该怎么来做,谈得太多了,所以我决定写下来。
一、什么样的应用需要本地化
在回答这个问题之前我们要弄明白本地化的优势在哪里。当我们在一个地区拥有一定影响力的时候,我们能更好的吸引当地用户的目光,能够更好的了解当地用户的习惯,能够对地方性事件作出最快的反应,能够更好的聚集当地用户,另外我们能够更好的进行与当地商家的商务合作。不管怎么说,其实本地化的优势一句话表达就是我们在这里,我们能够激发各方面的地域感情。所以如果你有大量的用户来源,并且你致力于做一个地方性站点,那么你是存在优势的,而且这种优势在一些方面将会表现得很突出。
那么我们现在来回答什么样的应用需要本地化。或者说是回答什么样的应用做本地化是在浪费时间和金钱。互联网和网站一直在为了消除地域限制而努力,并在这个基础上建立起了不少成功的产品。
- 比如各种网上购物,在消除地域限制之后为用户带来了真正的便利而且拓宽了用户的需求。
- 再比如一些类型的社区,这些社区里面我们尽可能的希望和更多的来源更广泛的用户进行交流,在这样的社区里面我们发现仅仅是一个地区的人是不够的,这样的社区比如豆瓣,虾米,twitter…等等。
- 还有一种不适合用来做本地化的产品就是产品本身已经形成了一个个相对封闭的团体,本地化可能只是这个产品的一个部分,这样的产品做本地化优势是不明显的,比如facebook似的SNS,必须要针对一个更大的群体再将群体细分才有可能增强群体与群体之间的联系。
当然还有一些,本地化可能本身就是打破互联网的一个更自由更开放的性质。但还有有一些产品具有本地化的价值:
- 本地化资讯快报,因为我们在当地能对当地事件作出最快速的反应。在这一点上和其他的本地媒体的性质是一样的。当然互联网媒体相较于传统媒体的优势在何处,而资讯的长尾在哪里这是另一个问题,是如何做互联网新闻媒体的问题。
- 当地生活指南,结合我们的商业优势和我们对当地用户以及当地情况的了解来做地域性的生活指南。这是一个具有商业价值并且能够为用户创造更多的价值,能够最终提高网站在当地的影响力。
- 本地化社区,这种社区和上述的一些类型的社区刚好相反,这种社区的讨论更具有地方性,更能聚集地域情感,更容易讲线上活动转移到线下,能够增强用户之前的情感因素。
还有更多产品需要我们不断去寻找。
二、本地化要怎么做
本地化要怎么做才能做好,还是一句话,如何更好的提现我们的优势就是最好方法。
- 内容应该更加本地,更加纯粹。
- 加强商务合作,做本地用户与本地商家之间的杠杆。
- 强调地域性,增强基于地域的情感价值。
- 产品线要向用户的本地价值倾斜,将资源集中到更能体现我们价值的地方。