分类: TechNote

  • Capture Time To First Byte using curl

    From: http://www.pinoytux.com/linux/capture-time-to-first-byte-using-curl

    Working with websites is equivalent to non-ending website testing. Checking the speed of the site itself is not a new thing to check when doing performance diagnostics. And I found out that curl can calculate the speed of a website, from the initial connection time, to the time the first byte is downloaded, up to the total time the site has finished loading.

    Here is a sample command using curl:

    curl -o /dev/null -w “Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n” http://inserturl.here

    This command will output this:

    [root@rai01 ~]# curl -o /dev/null -w “Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n” http://pinoytux.com
    % Total % Received % Xferd Average Speed Time Time Time Current
    Dload Upload Total Spent Left Speed
    0 0 0 0 0 0 0 0 –:–:– 0:00:01 –:–:– 0
    Connect: 0.268 TTFB: 1.528 Total time: 1.528

    Looks like my website is fast 🙂

    The first data is the Connect time, which means this is how long it took for the curl to connect to the website.
    Connect: 0.268

    The second data is time when the first byte was received, Time To First Byte (TTFB).
    TTFB: 1.528

    The last data is the total time for the site to finish loading.
    Total time: 1.528

    You can also turn off the progress bar by adding the -s switch to the command.

    From: http://www.unquietdesperation.com/2009/03/19/time-to-first-byte-with-curl/

  • Gephi

    http://gephi.org/

    Gephi is an interactive visualization and exploration platform for all kinds of networks and complex systems, dynamic and hierarchical graphs.

  • 有关Linode优惠码以及10%优惠购买链接

    今天登入到Linode管理面板发现自己用Linode已经快两年半了:

    “Your account has been active since January 05, 2010”

    Linode应该是目前美国最好的VPS了,速度快,最重要的是很稳定,被多人推荐(云风、Fenng等等大牛都在用),尤其是其强大的管理面板,客服回复ticket时间基本在10分钟以内。

    Linode目前有6个数据中心可以选择:

    Tokyo, JP (日本东京)
    London, GB, UK (英国伦敦)
    Newark, NJ, USA (美国新泽西州内华达)
    Atlanta, GA, USA (美国佐治亚州亚特兰大)
    Dallas, TX, USA (美国特克萨斯州达拉斯)
    Fremont, CA, USA (美国加州弗里蒙特)

    位于美国西海岸的Fremont的he机房,作为大陆地区访问最快的机房一度成为国人的首选。

    但在Linode推出东京机房之后,提供了不亚于国内主机的速度(上海电信ping延迟在70ms左右),国人纷纷迁入东京机房,大量涌入的悲剧就是造成东京机房晚上访问速度惨不忍睹(ping基本在300ms+)。

    我自己选择留在Fremont。

    由于Linode VPS优秀的品质,越来越多的人选择Linode VPS,有不少同学都在搜Linode优惠码,希望在购买时能够获得优惠,不过遗憾的是,Linode官方没有提供优惠码,网络上也没有优惠码。

    一些网站发布的所谓的优惠码,都是骗人的,其实是他们的推荐码。

    Linode提供的推荐码,如果有人通过推荐码注册够买并且使用超过三个月以上,则在半年后返一部分推荐费用给推荐者,当然此费用只能用于购买Linode VPS,不能提现。

    如果购买的时候想要获得优惠, 在 referral code 栏中填写 e572f5c67c4a4429dd8aeb987e00aeb4fe02d25c ,并选择选择一次性年付,则可以获得10%的优惠。

    年付10%优惠购买链接: http://www.linode.com/?r=e572f5c67c4a4429dd8aeb987e00aeb4fe02d25c

    如果你希望获得返佣,可以通过上面我的推荐链接购买,在达到条件之后可以联系我,我会返还推荐费的一半给你:)

  • nginx-discovery

    http://www.nginx-discovery.com/

  • 转载:Ring Buffer 和 Memory Poll

    原文链接:http://blog.ddup.us/?p=241
    —————————————————————————-
    那天看到微博上看到讨论如何设计网络程序Buffer(链接)。其中@简悦风云 给出个使用Ring Buffer的思路同时也顺带着嘲讽了一下C++和STL(链接),结果引出混战。本文不关心事件,纯粹讨论其中的两个技术点——RingBuffer和Memory Poll。

    两者都是内存管理中比较常用的技术。我们知道C语言中使用malloc/free库函数来申请/释放内存,C++中对应的是new/delete,终归也是调用malloc/free。有些程序会非常频繁的申请/释放内存,这就导致内存碎片的产生,进而引起性能下降甚至内存分配失败。像Memcached这种内存kv数据库为了解决这种问题都是在应用层自己又实现了一套内存管理模块。Redis早期版本直接使用malloc/free库函数,后来忍受不了其性能,在后续版本中使用freebsd中的内存管理算法jemalloc来代替。所以在高性能程序中,优良的内存管理算法至关重要。

    Ring Buffer

    Ring Buffer也叫Circular Buffer,是一种缓冲区数据结构,一般用于生产者-消费者模式的程序中,一个或多个生产者不停产生数据,同时一个或多个消费者使用数据,数据使用完这块缓冲区就可以释放了。简单的Ring Buffer其实就是基于连续内存地址的循环队列,稍有不同的是当队列满时,某些Ring Buffer应用场景可以直接覆盖掉队尾的数据。风云给出的socket连接例子(链接)就是这种情况。建立Ring Buffer首先就是先malloc出一大块连续内存空间,然后遵循先入先出FIFO原则申请释放内存,后续的内存操作都在这块实现开辟的内存区域完成,这也就省去了每来一条数据就申请一次内存的开销。可见不仅是从执行时间上还是从减少内存碎片角度看,这种方法都比原生的malloc要好。

    但是这种方式的缺点也是显而易见的:1)只适用于数据是FIFO的这种情况,一旦数据不是按照先申请先释放原则进行,那内存碎片问题还是解决不了。2)需要预估缓冲区大小,因为缓冲区一次申请完毕,后续调整代价比较大,所以需要预估大小。3)队列管理,这其实是数据结构与算法的问题。不过一旦其中存放时的变长数据的话,解决起来要稍稍复杂一些。

    摘一段Wikipedia上的简单Ring Buffer代码:

    /* Circular buffer example, keeps one slot open */
    #include
    #include

    /* Opaque buffer element type. This would be defined by the application. */
    typedef struct{int value;} ElemType;

    /* Circular buffer object */
    typedefstruct{
    int size; /* maximum number of elements */
    int start; /* index of oldest element */
    int end; /* index at which to write new element */
    ElemType *elems; /* vector of elements */
    } CircularBuffer;

    void cbInit(CircularBuffer *cb,int size){
    cb->size = size +1;/* include empty elem */
    cb->start =0;
    cb->end =0;
    cb->elems =(ElemType *)calloc(cb->size,sizeof(ElemType));
    }

    void cbFree(CircularBuffer *cb){
    free(cb->elems);/* OK if null */
    }

    int cbIsFull(CircularBuffer *cb){
    return(cb->end +1)% cb->size == cb->start;
    }

    int cbIsEmpty(CircularBuffer *cb){
    return cb->end == cb->start;
    }

    /* Write an element, overwriting oldest element if buffer is full. App can
    choose to avoid the overwrite by checking cbIsFull(). */
    void cbWrite(CircularBuffer *cb, ElemType *elem){
    cb->elems[cb->end]=*elem;
    cb->end =(cb->end +1)% cb->size;
    if(cb->end == cb->start)
    cb->start =(cb->start +1)% cb->size;/* full, overwrite */
    }

    /* Read oldest element. App must ensure !cbIsEmpty() first. */
    void cbRead(CircularBuffer *cb, ElemType *elem){
    *elem = cb->elems[cb->start];
    cb->start =(cb->start +1)% cb->size;
    }

    int main(int argc,char**argv){
    CircularBuffer cb;
    ElemType elem ={0};

    int testBufferSize =10;/* arbitrary size */
    cbInit(&cb, testBufferSize);

    /* Fill buffer with test elements 3 times */
    for(elem.value=0; elem.value<3* testBufferSize;++ elem.value) cbWrite(&cb,&elem); /* Remove and print all elements */ while(!cbIsEmpty(&cb)){ cbRead(&cb,&elem); printf("%d\n", elem.value); } cbFree(&cb); return0; }

    Memory Poll

    内存池技术更是由来已久,以至于基本上遇到内存管理一般人首先想到的就是这个。的确不管是在操作系统内核中还是在应用层程序中,内存池技术广泛的应用。之前说的memcached就是自己在应用层实现了一套内存池。另外SGI版本的STL中为了应对频繁申请/释放小内存块产生的内存碎片问题,同样用到了内存池技术。

    SGI版本的STL中默认的内存分配是通过std::alloc完成的,其中将内存分配划分为两级:小于等于128B的在第一级中分配;大于128B的在第二级中分配。第二级内存分配就是简单的调用operator new完成。第一级实际是一个内存池:其中有11个slot,每个slot对应一个同样大小空闲块链表。块从8B开始,按照8B的倍数递增直到128。这样在分配小内存时,显示将请求的容量向上按8的倍数取整,然后从空闲链表中拿一个空闲区块出来。回收的时候采用类似的方法,将空闲块归还到空闲链表中。这样就能有效避免频繁分配释放小内存块。

    可见内存池技术相对于上边的Ringbuffer的优点是:不用关心内存申请释放的顺序。缺点是:1)数据结构更复杂;2)按照固定大小的块划分存在内存浪费。这种浪费是不能避免的,但是可以通过合理的选择块的大小,尽量减少浪费。Memcached提供了可以根据用户自定义的递增因子设置间隔slot中块的增长量。这样就可以针对特定业务做特定优化。

    参考

    http://en.wikipedia.org/wiki/Circular_buffer

    http://blog.codingnow.com/2012/02/ring_buffer.html

    《STL源码详解》

  • 两个pub/sub客户端

    Faye : http://faye.jcoglan.com/ Faye还有一个服务端。

    https://gist.github.com/661855

  • PHP妖孽

    PHP要时时注意编码问题的坑。

  • 各种妖孽

    php cURL模拟POST请求,碰到这样的错误:

    HTTP/1.0 417 Expectation failed
    Server: squid
    Date: Fri, 02 Mar 2012 16:08:46 GMT
    Content-Type: text/html
    Content-Length: 1563
    X-Squid-Error: ERR_INVALID_REQ 0
    X-Cache: MISS from none.net
    Via: 1.0 none.net:80 (squid)
    Connection: close

    请求头
    POST /abc.php HTTP/1.1
    User-Agent: Internal Callback
    Host: www.abc.com
    Accept: */*
    Content-Length: 14598
    Content-Type: application/x-www-form-urlencoded
    Expect: 100-continue

    解决方案:设置CURLOPT_HTTPHEADER为array(‘Expect:’)

    参考链接:
    http://chrismckee.co.uk/curl-http-417-expectation-failed/
    http://www.shesek.info/php/http-error-417-with-php-curl

  • Tornado实时行情报价

    用Tornado实现了一个实时行情报价系统,长轮询,一个简单的应用,从看文档查资料到实现。
    花了大概两个小时。
    好惊讶。

    继续玩python:)

    接下来要做点其他好玩的东西了。

  • 三个HTML代码清理工具

    Tidy
    htmLawed
    HTML Purifier