<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tim[后端技术] &#187; network</title>
	<atom:link href="http://timyang.net/tag/network/feed/" rel="self" type="application/rss+xml" />
	<link>http://timyang.net</link>
	<description>Tim&#039;s blog, 关于后端架构、互联网技术、分布式、大型网络应用、NoSQL、Key Value等</description>
	<lastBuildDate>Mon, 02 Aug 2010 15:34:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>多服务器通讯层应该如何设计—一次code review小记</title>
		<link>http://timyang.net/architecture/communication-code-review/</link>
		<comments>http://timyang.net/architecture/communication-code-review/#comments</comments>
		<pubDate>Thu, 21 May 2009 16:16:41 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[架构]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[network]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=207</guid>
		<description><![CDATA[大型的网络应用服务器(比如即时通讯及游戏服务器等)通常有大量的服务器内部数据通讯需求，几个月前曾经介绍过通讯层的实现再谈点对点通讯模块的故障问题，目前这个程序已经经历了数个版本的重构。今天进行了一次小组code review，讨论了当前版本的一些问题。
I. Background
我们为什么需要一个独立的通讯层
对于服务器内部的通讯功能，已经有TCP提供可靠传输，已经有类似Apache MINA这样的框架来提供上层的封装，业务逻辑代码完全可以直接基于socket或MINA这样的框架来直接传送数据，我们为什么还需要包装一个独立的通讯层？
目前考虑到的原因有

Connection pool作用。为了节点间更高的throughput, 通常两节点之间会使用n个固定连接来传输。n可设为CPU内核数大小。
多节点互相连接的处理。一个节点需要连接n个节点发送信息。如果这部分逻辑放在业务调用层来实现，业务层会变得臃肿。
处理自动重连逻辑，单个节点可以停用并重新启用。将这部分逻辑封装到通讯层，上层调用会更优雅。
服务器之间通讯很短时间内不稳定(比如10s左右的中断)的处理。如果IDC内部或IDC之间通讯不稳定会造成这种现象。我们希望这种短暂的中断，不要引起业务逻辑重新选择节点，造成大量数据迁移及cache重构带来的内部振荡。
海量数据传输最优化，大部分时间单个节点单向传输会&#62;10k个数据包/s，独立的通讯层容易测试观察该环节是否存在瓶颈。

通讯层不做什么

序列化/反序列化，这个通常使用其他的框架或技术来做，比如protocol buffers, json等
RPC, 我们不做rpc的事情，已有的各种RPC技术已经做得足够好了，如果有RPC需求，我们会使用其他现有的技术。

II. Code Review过程
逻辑介绍
首先由主程介绍了目前的数据流程，架构图及核心代码片断。比较核心的重发机制图示意如下

(Figure 1: 重发的流程)
过程说明：

每个数据包有个TTL值，TTL&#62;0之前会一直重试发给同一节点。这主要避免短期网络中断带来集群内振荡。
如果正常的节点投递失败，则继续投递到backup节点。Backup节点由调用方在投递时候指定。类似在邮政寄快递，需要填写如果投递不到收件人怎么处理。通讯层只是根据投递地址表(list)来进行二次投递。
如果backup也失败，则返回调用方的callback FailureHandler。这点有点类似Erlang里面失败处理的思路。

听众提出的问题

重发那一段流程是否必要，因为TCP本身已经有重发逻辑。应用层再加上一层重发处理，原理上可以应付短暂的网络中断，但是实际运行过程中能否真正有很大效果。(目前运行的情况也没有很明确的数据来支持这一点)
目前一个节点需要连接的多个节点是静态配置的，即由程序启动时候决定，没有做自动发现及删除。目标节点是否可用由发送方自行判断。因此提出一个问题，backup节点选择由调用方来指定是否最佳？可否让通讯层自动协商，内部选择另一个同一类型的节点来做替代节点？但实现通讯层节点自动协商机制会增加程序复杂度。毕竟我们不是P2P程序，节点故障发生的情况很少。因此需要综合来权衡。
目前的结构处理几十到上百个节点的集群问题不大，如果要用在上千个节点的场合，有哪些环节需要调整？

其他提出的一些问题是针对具体代码写法的，由于不具有广泛借鉴意义，就不一一赘述。
Similar Posts:某分布式应用实践一致性哈希的一些问题

多IDC的数据分布设计(一)

降低应用latency方法谈

参加Erlang开发者大会一些记录

Java垃圾回收调优
]]></description>
			<content:encoded><![CDATA[<p>大型的网络应用服务器(比如即时通讯及游戏服务器等)通常有大量的服务器内部数据通讯需求，几个月前曾经介绍过通讯层的实现再谈<a href="http://hi.baidu.com/jabber/blog/item/757873f447d100def2d3851c.html">点对点通讯模块的故障问题</a>，目前这个程序已经经历了数个版本的重构。今天进行了一次小组code review，讨论了当前版本的一些问题。</p>
<h1>I. Background</h1>
<h2>我们为什么需要一个独立的通讯层</h2>
<p>对于服务器内部的通讯功能，已经有TCP提供可靠传输，已经有类似Apache MINA这样的框架来提供上层的封装，业务逻辑代码完全可以直接基于socket或MINA这样的框架来直接传送数据，我们为什么还需要包装一个独立的通讯层？</p>
<p>目前考虑到的原因有</p>
<ul>
<li>Connection pool作用。为了节点间更高的throughput, 通常两节点之间会使用n个固定连接来传输。n可设为CPU内核数大小。</li>
<li>多节点互相连接的处理。一个节点需要连接n个节点发送信息。如果这部分逻辑放在业务调用层来实现，业务层会变得臃肿。</li>
<li>处理自动重连逻辑，单个节点可以停用并重新启用。将这部分逻辑封装到通讯层，上层调用会更优雅。</li>
<li>服务器之间通讯很短时间内不稳定(比如10s左右的中断)的处理。如果IDC内部或IDC之间通讯不稳定会造成这种现象。我们希望这种短暂的中断，不要引起业务逻辑重新选择节点，造成大量数据迁移及cache重构带来的内部振荡。</li>
<li>海量数据传输最优化，大部分时间单个节点单向传输会&gt;10k个数据包/s，独立的通讯层容易测试观察该环节是否存在瓶颈。</li>
</ul>
<h2>通讯层不做什么</h2>
<ul>
<li>序列化/反序列化，这个通常使用其他的框架或技术来做，比如protocol buffers, json等</li>
<li>RPC, 我们不做rpc的事情，已有的各种RPC技术已经做得足够好了，如果有RPC需求，我们会使用其他现有的技术。</li>
</ul>
<h1>II. Code Review过程</h1>
<h2>逻辑介绍</h2>
<p>首先由主程介绍了目前的数据流程，架构图及核心代码片断。比较核心的重发机制图示意如下</p>
<p><img class="alignnone size-full wp-image-210" title="comm" src="http://timyang.net/blog/wp-content/uploads/2009/05/comm.gif" alt="comm" width="378" height="372" /></p>
<p>(Figure 1: 重发的流程)</p>
<p>过程说明：</p>
<ul>
<li>每个数据包有个TTL值，TTL&gt;0之前会一直重试发给同一节点。这主要避免短期网络中断带来集群内振荡。</li>
<li>如果正常的节点投递失败，则继续投递到backup节点。Backup节点由调用方在投递时候指定。类似在邮政寄快递，需要填写如果投递不到收件人怎么处理。通讯层只是根据投递地址表(list)来进行二次投递。</li>
<li>如果backup也失败，则返回调用方的callback FailureHandler。这点有点类似Erlang里面失败处理的思路。</li>
</ul>
<h2>听众提出的问题</h2>
<ul>
<li>重发那一段流程是否必要，因为TCP本身已经有重发逻辑。应用层再加上一层重发处理，原理上可以应付短暂的网络中断，但是实际运行过程中能否真正有很大效果。(目前运行的情况也没有很明确的数据来支持这一点)</li>
<li>目前一个节点需要连接的多个节点是静态配置的，即由程序启动时候决定，没有做自动发现及删除。目标节点是否可用由发送方自行判断。因此提出一个问题，backup节点选择由调用方来指定是否最佳？可否让通讯层自动协商，内部选择另一个同一类型的节点来做替代节点？但实现通讯层节点自动协商机制会增加程序复杂度。毕竟我们不是P2P程序，节点故障发生的情况很少。因此需要综合来权衡。</li>
<li>目前的结构处理几十到上百个节点的集群问题不大，如果要用在上千个节点的场合，有哪些环节需要调整？</li>
</ul>
<p>其他提出的一些问题是针对具体代码写法的，由于不具有广泛借鉴意义，就不一一赘述。</p>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/consistent-hashing-practice/" rel="bookmark" title="September 6, 2009">某分布式应用实践一致性哈希的一些问题</a></li>

<li><a href="http://timyang.net/distributed/multi-idc-consensus/" rel="bookmark" title="February 2, 2010">多IDC的数据分布设计(一)</a></li>

<li><a href="http://timyang.net/architecture/web-latency-tools/" rel="bookmark" title="August 2, 2010">降低应用latency方法谈</a></li>

<li><a href="http://timyang.net/erlang/cn-erlounge-iii/" rel="bookmark" title="December 26, 2008">参加Erlang开发者大会一些记录</a></li>

<li><a href="http://timyang.net/java/java_gc_tunning/" rel="bookmark" title="January 7, 2009">Java垃圾回收调优</a></li>
</ul><!-- Similar Posts took 20.459 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/architecture/communication-code-review/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
