Roger Chen's profileLearningBlogLists Tools Help

Blog


    4/8/2006

    Unix网络编程

    这本书是今年我阅读过的技术书籍中影响我最大的一本:)
     
    我买的是第三版,前两版我没有看过,无法评价。这一版是Bill Fenner和Andrew M.Rudoff执笔,对上一版进行全面修订,加入了IPv6的一些信息和SCTP协议,删除了X/Open传输接口的内容,加入的这些内容很具有实用性。虽然这一版作者的名气比不上前两版大名鼎鼎的W.Richard Stevens,但是我的阅读体验非常好(这既有Stevens的功劳,和译者的努力也是分不开的),内容非常匹配我当前的水平,所以阅读起来非常流畅。不夸张的说,通过阅读这本书,我才迈入了网络编程的大门。
     
    我认为这本书最有价值的地方不在于其描述的套接口编程函数(虽然这些对我这个Unix网络编程的新手来说也是很有价值的),而在于哪些分散在各个章节中对网络编程底层实现细节的注释。你了解各种I/O模型的异同么?知道在在调用某些套接口函数的背后它替你完成了什么工作么?知道SO_LINGER怎么样影响close的行为么?UDP的外出接口是怎么确定的?为什么有时connected udp会返回ICMP异常给客户程序,而普通udp则不会?IPv4和IPv6的服务端和客户端怎么协同工作?
     
    当我看到第八章对connected udp和普通udp的性能比较时,禁不住拍案叫绝(书217页):
    在一个未链接的UDP套接口上给两个数据报调用sendto函数于是涉及内核执行下列6个步骤:
    • 连接套接口;
    • 输出第一个数据报;
    • 断开套接口连接;
    • 连接套接口;
    • 输出第二个数据报;
    • 断开套接口连接。

    另一个考虑是搜索路由表的次数。……

    调用connect后调用两次write涉及内核执行如下步骤:

    • 连接套接口;
    • 输出第一个数据报;
    • 输出第二个数据报。

    在这种情况下,内核只拷贝一次含有宿IP地址和端口号的套接口地址结构,相反当调用两次sendto时,需拷贝两次。[Partridge和Pink 1993]指出,临时连接未连接的UDP套接口将消耗每个UDP传输三分之一的开销。

    目前我只读到第14章,但是我已经准备好在读完后再精读一遍。如果实在要说这本书有什么缺陷的话,那就是它的份量。你知道,长时间捧着一本这么重的书,实在是一件体力活:)

    11/24/2005

    POSA2读书笔记(二)

    呵呵,距离第一篇已经过了半年了……这本书其实翻完已经很久了,但是实践中没有使用到的东西总是一知半解,写出来会误导大众,所以还是不写的好。
     
    今天在为Cindy 3.0a1中并发模型设计头痛的时候,翻了翻这本书中的相关模式,突然有种豁然开朗的感觉:)
     
    Half-Sync/Half-Async:这个模式是从Cindy 1.x一直沿用下来的模式,我估计也是基于NIO的网络应用里面最常用的并发模型。简单的用伪码说:
    while (select() > 0) {
        getReadyEvents();
        deactiveEvents();
        addEventsToQueue();
    }
    网络IO线程不停的select,并把发生的事件添加到某个队列;若干个工作线程并行的从该队列中取的相应的事件,并分发给应用。网络IO线程是串行化的,而工作线程是并行的,所以这个模式就叫半同步/半异步模式。
     
    Leader/Followers:这是今天才豁然开朗的模式:) 在上面的半同步/半异步模式中,瓶颈主要有三处:
    • 动态内存分配。网络IO线程把事件添加到队列,工作线程从队列中取事件,不停的有添加删除操作,队列大小在不停的发生变化。
    • 多同步操作。在对队列进行添加和删除操作时需要对队列进行同步(或者是在队列内部进行同步),同时各个工作线程之间从队列中取相应事件时需要同步。
    • 线程切换:需要不停的在网络IO线程和各工作线程之间做语境切换。比如假设首先所有的工作线程都处于等待状态,这时来了某一个事件,工作线程A被唤醒,去处理该事件;然后又来一个事件,工作线程B被唤醒,去处理该事件;A工作完又回到等待状态,然后又被唤醒……

    那么领导/追随模式是怎么样来避免上面的这三个瓶颈呢?

    首先领导线程在通过select得到了许多的响应事件,然后领导线程把其中一个从selector上移除,并把一个追随线程提升为领导线程,然后自己就变成了工作线程处理该事件,等到事件处理完成后再变成追随线程或领导线程(如果结束时已经没有可用的领导线程的话)。

    这个模式不需要进行动态内存分配,同步操作也比上一个模式少很多,由于领导线程直接变成工作线程处理事件,最大程度的减少了线程切换,所以上面那三个瓶颈都能够得到很好的解决。但是这个模式也有相应的缺点:实现复杂,不像半同步/半异步模式能非常简单的实现。所谓有得必有失呀:)

     

    这里可以做一个简单的比喻为两种模式做一下总结。场景是把一堆书从A地经过B地搬到C地(我想不到其他好的例子)。

    如果是半同步/半异步模型的话,就是有一个人负责把书从A地搬到B地,其余的人在B地等着,一旦B地书来了,就把书再搬到C地。

    如果是领导/追随者模型的话,则是所有的人都在A地排队等待,每个人搬一本送到C地,然后回来排到队伍的最后面。(领导/追随者模型并没有规定次序,所以回来后不一定是排在队伍的最后面,反而是非常有可能排在队伍的第二个位置,这样可以提升系统性能)

     

    10/26/2005

    About SOA

    这期十月份《程序员》杂志的技术专题是关于SOA的,几篇文章看过来,只有Martin Flower那篇《SOA——面向服务的含糊》深得我心。
     
    Service这个词多大呀,把这期杂志《二元文化》里面提到的UNIX命令行程序,套上SOA这种大词,看上去是不是也是像模像样?DCOM看上去是不是也有点像?消息系统看上去是不是也差不多?至于Web Services么,现在都成了宣传SOA的标配。
     
    不知道SOA这个词是谁定义的,简直是天才,定义的实在太出众了,压根没提到实现,听上去又大气,人人都觉得对,足和三个代表有的一拼。唯一不够完美的地方,就是要是当时定义的时候在后面加一小注:本条款解释权归XXX所有,哪有今天这么多的纷争呀。
     
    SOA太大了,咱们还是该干啥干啥去。不过话说回来,咱们现在这个系统,消息服务器、采集服务器、文件服务器……这不就是个现成的SOA嘛,咱们也跟着这个大词占点光也不赖:)
    5/11/2005

    POSA2读书笔记(一)

    POSA2行文过于理论,再加上我C++是毫无基础,理解上有偏差的地方请指正。

    服务访问和配置模式

    对于Java程序员而言,书中列出的4种模式应该是经常看到了,不提了……

    事件处理模式

    • Reactor

    Reactor有什么好处?考虑一下聊天这个场景,大部分情况下,用户只是建立好连接,而什么也不做,偶尔发送了一条消息,服务器处理了这条消息后就继续等待。

    如果服务器单线程轮流执行,则服务器只能处理一个用户,因为该用户始终没有断开连接;如果用传统的一个连接一个线程来实现,则在大部分时间里,服务器的线程只是处在阻塞等待的状态,这无疑是极大的浪费。Reactor就是用于改善这种情景下的一个模式。

    服务器可以采用单线程运行,阻塞在等待用户传递消息的状态。如果B发送了消息,则服务器从阻塞状态恢复,处理B的消息,然后继续阻塞等待;接着A发送了消息,服务器又重复上述步骤……原来一个连接一个线程需要多个线程阻塞等待,而采用了Reactor模式后只需要一个线程等待即可。

    Java NIO中的Selector其实就是运用Reactor模式。将NIO中Selector相关类的设计于书112页的UML图对比:Reactor其实就是Selector类,Synchronous Event Demultiplexer其实就是Selector.select()函数,Handle对应于SelectionKey,EventHandler对于SelectableChannel,Concrete Event Handler A/B这些就对应于SocketChannel/DatagramChannel等等。

    (刚才又仔细看了书,感觉昨天的理解有误,因此对早上写的做了修改)

    5/10/2005

    POSA2

    昨天读到一本好书《面向模式的软件体系结构 卷2:用于并发和网络化对象的模式》,真是太感叹了,如果半年前看到这本书,我也不必为Cindy中的一些设计头痛了。

    不过通过自己的思考和探索后,发现设计和大师们的研究结果相当接近,也蛮不错的:)

    刚好前两个月对Cindy的改进有一些小小的想法,准备读完该书后再做一些实际测量,有必要的话再做一个大版本的更新:)

    3/31/2005

    好文:《我的职场十年》

    链接地址:http://www.blogchina.com/new/member/_%D0%BB%D4%C5

    我经历过的事情没有这么丰富,但是在很多地方还是深有共鸣:)

    3/6/2005

    这个月的阅读计划

    计划这个月阅读完Manning出版的《SWT/JFace In Action》。出于三个原因:一是学习SWT/JFace的使用,我对这个类库是比较感兴趣的;二是想学习SWT/JFace的设计;三是同事对SWT这块比较了解,有问题了还可以请教他,毕竟有一个熟悉的人指导起来学习速度会快不少。

    另外时间充裕的话可以对目前已有的RFID项目做一些了解。Sun在上个月推出了一个RFID的框架,昨天BEA User Group中David也提到ObjectWeb也有一个RFID的项目,但是我去看了一下,目前ObjectWeb的这个项目还没有什么动静。RFID项目仅仅是关注,不会投入太多精力,目前只是雷声比较大,但是如果等到雨点也比较大了才去关注,可能就会丧失一些机会。

    3/1/2005

    李开复给中国学生的第四封信

    连接地址:http://www.kaifulee.com/Articles/Letter4.htm,读读还是觉得很有收获的:)