<?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>I@laoer.com &#187; 构架设计</title>
	<atom:link href="http://i.laoer.com/category/architecture/feed" rel="self" type="application/rss+xml" />
	<link>http://i.laoer.com</link>
	<description>技术、生活、感悟 -- Laoer的博客</description>
	<lastBuildDate>Mon, 15 Feb 2010 08:36:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>GET方式传递中文错误引发的思考</title>
		<link>http://i.laoer.com/think-about-http-get-chinese-encode-error.html</link>
		<comments>http://i.laoer.com/think-about-http-get-chinese-encode-error.html#comments</comments>
		<pubDate>Fri, 24 Apr 2009 08:21:52 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[构架设计]]></category>
		<category><![CDATA[Base64]]></category>
		<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=298</guid>
		<description><![CDATA[今天在“天乙社区”里，网友报了一个BUG，在版区内搜索中文的时候，分页会出现问题，我在社区里试了一下，果然有这样的问题，我记得这个问题在写代码的时候特意注意过，我做了URLEncoder和URLDecoder，但还是有问题，当时可能测试不够，把这个问题漏过了，这个问题出现的原因很简单，就是在GET方式传递中文的时候，由于编码的问题出现了字符的错误，解决的方法也有几种：
第一种，是不采用GET方式，采用POST方式，可以在页面上加入一个隐藏表单，把数据写进去，分页的时候，用JavaScript提交，POST方式发送到服务器，这样的做法可以很好的保护数据完整性，也比较安全，但是对于社区来说需要修改页面，比较麻烦。
第二种，就是将中文内容做一些编码，比如Base64，之后再做一次URLEncoder，这样应该就可以传递正确的信息，我就按照这个方法修改了一下程序，没有问题了。
这时候我突然想起了Taobao的奇怪URL编码方式，比如我在淘宝上搜索“尼康 镜头”，请求到的地址是
http://search1.taobao.com/browse/0/n-g,ytq37njax2243ny&#8212;&#8212;-2&#8212;&#8212;&#8212;40&#8211;commend-0-all-0.htm?at_topsearch=1&#38;ssid=e-p1-s5
注意其中的“ytq37njax2243ny”，在JavaEye里有位高人写了一篇关于淘宝URL编码规则的文章，着实很强，淘宝也用的是Base64，只不过用自己的码表，这样编码出来的字符串就像“ytq37njax2243ny”，乍看上去挺怪异的，但为什么要这么做，我似乎明白了一些，淘宝、阿里巴巴都采用他们自己的Webx框架，在其前端专门有模块是处理URL的，包括URL的生成、解析，其好处有很多，其中一个重要的原因应该是解决编码问题，附件是阿里巴巴webx的一个文档，大家可以看看，有什么启发。
阿里巴巴webx框架资料
]]></description>
			<content:encoded><![CDATA[<p>今天在“<a title="天乙社区" href="http://bbs.laoer.com/main.html" target="_blank">天乙社区</a>”里，网友报了一个BUG，在版区内搜索中文的时候，分页会出现问题，我在社区里试了一下，果然有这样的问题，我记得这个问题在写代码的时候特意注意过，我做了URLEncoder和URLDecoder，但还是有问题，当时可能测试不够，把这个问题漏过了，这个问题出现的原因很简单，就是在GET方式传递中文的时候，由于编码的问题出现了字符的错误，解决的方法也有几种：</p>
<p>第一种，是不采用GET方式，采用POST方式，可以在页面上加入一个隐藏表单，把数据写进去，分页的时候，用JavaScript提交，POST方式发送到服务器，这样的做法可以很好的保护数据完整性，也比较安全，但是对于社区来说需要修改页面，比较麻烦。</p>
<p>第二种，就是将中文内容做一些编码，比如Base64，之后再做一次URLEncoder，这样应该就可以传递正确的信息，我就按照这个方法修改了一下程序，没有问题了。</p>
<p>这时候我突然想起了Taobao的奇怪URL编码方式，比如我在淘宝上搜索“尼康 镜头”，请求到的地址是</p>
<p>http://search1.taobao.com/browse/0/n-g,ytq37njax2243ny&#8212;&#8212;-2&#8212;&#8212;&#8212;40&#8211;commend-0-all-0.htm?at_topsearch=1&amp;ssid=e-p1-s5</p>
<p>注意其中的“ytq37njax2243ny”，在JavaEye里有位高人写了一篇<a href="http://www.javaeye.com/topic/286240" target="_blank">关于淘宝URL编码规则的文章</a>，着实很强，淘宝也用的是Base64，只不过用自己的码表，这样编码出来的字符串就像“ytq37njax2243ny”，乍看上去挺怪异的，但为什么要这么做，我似乎明白了一些，淘宝、阿里巴巴都采用他们自己的Webx框架，在其前端专门有模块是处理URL的，包括URL的生成、解析，其好处有很多，其中一个重要的原因应该是解决编码问题，附件是阿里巴巴webx的一个文档，大家可以看看，有什么启发。</p>
<p><a href="http://i.laoer.com/wp-content/uploads/2009/04/webx.rar">阿里巴巴webx框架资料</a></p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/think-about-http-get-chinese-encode-error.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SNS中好友动态功能的设计思路</title>
		<link>http://i.laoer.com/sns-news-feed-design.html</link>
		<comments>http://i.laoer.com/sns-news-feed-design.html#comments</comments>
		<pubDate>Tue, 17 Mar 2009 10:28:20 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[构架设计]]></category>
		<category><![CDATA[SNS]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=171</guid>
		<description><![CDATA[现在大部分SNS网站都有一个功能，就是显示好友的活动状态，比如你的好友上传了一张照片、分享了一篇文章等等动作，都可以显示在你的页面里，这样大大增强了社区的互动性，也成为现在SNS网站的主要特征，对于这样一个功能，从设计角度，还是值得思考的，并不简单，特别是用户越来越多，信息海量增长的时候，我未必能提出十全十美的方案，但我们可以由简如繁梳理一下思路。
首先我们要定义用户的活动消息，也可以理解为一个事件，就是我们举的例子：用户上传照片、与别人结为好友、修改了个人资料等等，动作各有不同，但需要在结构上通用，我们先设计一个
ID //消息ID
UserID //用户ID
MsgType //消息类型，比如加好友、上传照片等不同的类型
EventMsg //消息的内容，这里我们可以用Json的数据格式来描述出不同的活动内容
CreateTime //消息创建时间
这个结构也是个数据库的结构，当用户做个一个动作之后，就会创建这样一个消息，并保存在数据库中，当显示好友的活动信息时，就从这张表里查询自己好友id的数据，并按时间显示，这个做法是一个最简单的实现，但会出现一些问题，当你与一个用户成为好友之后，该好友之前发生的动作会显示出来，而不是在成为好友时点之后的动作，同样，切断好友关系之后也有类似的问题，如果从业务角度和用户体验上可以接受的话，也没什么，但由于信息是按时间排序，有时候会给用户错乱的感觉，还有，这个信息不能删除，如果删除了所有好友就看不到这条信息了，但在Facebook里是则是可以删除好友的动作信息的，这个方法还有一个问题是，所有信息都放在一张大表里，在信息爆炸增长，个人好友也很多的情况下，查询效率会非常低，产生严重的性能障碍，如果对这张表做水平切分，则在实现上复杂了许多，性能也未必好很多，接下来我们再思考是否有更好的解决办法。
在SNS的理论里，个人好友的合理数量在150个左右（最近有文章说Facebook的人均好友数是120人），SNS网站应该是有好友数量的限制的，我们就按人均150个好友来设想，是否可以在用户发生某些动作之后，针对他的所有好友都写入一条信息，所能解决的是，信息是在用户成为好友时点之后写入，用户可以删除好友的活动信息，不影响其他用户的显示，在显示时查询效率要高很多，但是负面效应也十分明显，一个用户的动作有平均150个写入，对于数据库来说开销也非常大，我们想想在这样的设计下，是否可以提高性能。
首先看数据库设计，我们要把信息表和信息与用户的对应表分开，我们上面定义的数据结构保留，我们定义它的表名为Event，我们再新建一张表EventUser，结构如下
ID  //主键
EventID //Event表的ID
FriendUserID //好友的ID
CreateTime //消息创建时间
对FriendUserID做索引，当用户发生动作时，首先将动作信息写入Event表，之后查找用户的所有好友，将EventID、好友ID逐条写入EventUser表，当要显示自己的好友活动信息是，查询EventUser中FriendUserID等于自己ID的信息，并和Event表做一个Join查询就可以了。
进一步提升性能的方法，将Event里的信息缓存，比如用Memcached，EventID做为Key，内容做为Value，这样，查询EventUser是就不用Join Event表，而是从缓存里读取，由于要记录给每个好友的信息，所以EventUser会变得非常大，平均要比我们最初设计的数据容量大150倍，我们对EventUser表做水平切分，根据用户ID做Hash算法，基本上能均匀的分配到所有的表中，至于EventUser水平切分的算法还有多种，根据实际情况来定，总的来说就是把数据分摊掉，同时EventUser里的数据可以不永久保存，做定期删除，可以保持数据容量在一个合理的范围内。
对于用户动作之后的数据写入，可以采用异步的方法，在发生动作时，抛出一个消息，由另外一个线程在做写入操作，如果对每个动作平均150次的写入仍存顾虑，我们可以针对每个用户开出一块内存空间，或是缓存，里面保存最后50条最新的好友动作，并在每条记录里做一个持久化标志，当有50条信息都标志是“未持久化”时，做一次数据库的写入，然后把信息置为“已持久化”，这种非实时写入的方式，可以提高一定的数据库效率，显示时，先从内存中取出，再查数据库。
还有一些问题，对不不同消息类型的处理方式不同，比如用户修改个人资料，并不是每次发生这样的动作都要做一次给朋友做一次“群发”的操作，如果遇到这个人在短时间内做了多次修改个人资料的操作，就给朋友发出多个消息，会产生垃圾信息，让人觉得很怪异，所以对于这样的操作会有一定的时效性，比如在一天之内的修改个人资料，就是一个消息，这时候的处理是更新，而不是插入。
以上是我对SNS中好友动态功能的设计思路，可能还有一些未想到的问题，还需要认真思考。
]]></description>
			<content:encoded><![CDATA[<p>现在大部分SNS网站都有一个功能，就是显示好友的活动状态，比如你的好友上传了一张照片、分享了一篇文章等等动作，都可以显示在你的页面里，这样大大增强了社区的互动性，也成为现在SNS网站的主要特征，对于这样一个功能，从设计角度，还是值得思考的，并不简单，特别是用户越来越多，信息海量增长的时候，我未必能提出十全十美的方案，但我们可以由简如繁梳理一下思路。</p>
<p>首先我们要定义用户的活动消息，也可以理解为一个事件，就是我们举的例子：用户上传照片、与别人结为好友、修改了个人资料等等，动作各有不同，但需要在结构上通用，我们先设计一个</p>
<p>ID //消息ID<br />
UserID //用户ID<br />
MsgType //消息类型，比如加好友、上传照片等不同的类型<br />
EventMsg //消息的内容，这里我们可以用Json的数据格式来描述出不同的活动内容<br />
CreateTime //消息创建时间</p>
<p>这个结构也是个数据库的结构，当用户做个一个动作之后，就会创建这样一个消息，并保存在数据库中，当显示好友的活动信息时，就从这张表里查询自己好友id的数据，并按时间显示，这个做法是一个最简单的实现，但会出现一些问题，当你与一个用户成为好友之后，该好友之前发生的动作会显示出来，而不是在成为好友时点之后的动作，同样，切断好友关系之后也有类似的问题，如果从业务角度和用户体验上可以接受的话，也没什么，但由于信息是按时间排序，有时候会给用户错乱的感觉，还有，这个信息不能删除，如果删除了所有好友就看不到这条信息了，但在Facebook里是则是可以删除好友的动作信息的，这个方法还有一个问题是，所有信息都放在一张大表里，在信息爆炸增长，个人好友也很多的情况下，查询效率会非常低，产生严重的性能障碍，如果对这张表做水平切分，则在实现上复杂了许多，性能也未必好很多，接下来我们再思考是否有更好的解决办法。</p>
<p>在SNS的理论里，个人好友的合理数量在150个左右（<a href="http://tech.sina.com.cn/i/2009-03-02/07232868882.shtml" target="_blank">最近有文章说Facebook的人均好友数是120人</a>），SNS网站应该是有好友数量的限制的，我们就按人均150个好友来设想，是否可以在用户发生某些动作之后，针对他的所有好友都写入一条信息，所能解决的是，信息是在用户成为好友时点之后写入，用户可以删除好友的活动信息，不影响其他用户的显示，在显示时查询效率要高很多，但是负面效应也十分明显，一个用户的动作有平均150个写入，对于数据库来说开销也非常大，我们想想在这样的设计下，是否可以提高性能。</p>
<p>首先看数据库设计，我们要把信息表和信息与用户的对应表分开，我们上面定义的数据结构保留，我们定义它的表名为Event，我们再新建一张表EventUser，结构如下</p>
<p>ID  //主键<br />
EventID //Event表的ID<br />
FriendUserID //好友的ID<br />
CreateTime //消息创建时间</p>
<p>对FriendUserID做索引，当用户发生动作时，首先将动作信息写入Event表，之后查找用户的所有好友，将EventID、好友ID逐条写入EventUser表，当要显示自己的好友活动信息是，查询EventUser中FriendUserID等于自己ID的信息，并和Event表做一个Join查询就可以了。</p>
<p>进一步提升性能的方法，将Event里的信息缓存，比如用Memcached，EventID做为Key，内容做为Value，这样，查询EventUser是就不用Join Event表，而是从缓存里读取，由于要记录给每个好友的信息，所以EventUser会变得非常大，平均要比我们最初设计的数据容量大150倍，我们对EventUser表做水平切分，根据用户ID做Hash算法，基本上能均匀的分配到所有的表中，至于EventUser水平切分的算法还有多种，根据实际情况来定，总的来说就是把数据分摊掉，同时EventUser里的数据可以不永久保存，做定期删除，可以保持数据容量在一个合理的范围内。</p>
<p>对于用户动作之后的数据写入，可以采用异步的方法，在发生动作时，抛出一个消息，由另外一个线程在做写入操作，如果对每个动作平均150次的写入仍存顾虑，我们可以针对每个用户开出一块内存空间，或是缓存，里面保存最后50条最新的好友动作，并在每条记录里做一个持久化标志，当有50条信息都标志是“未持久化”时，做一次数据库的写入，然后把信息置为“已持久化”，这种非实时写入的方式，可以提高一定的数据库效率，显示时，先从内存中取出，再查数据库。</p>
<p>还有一些问题，对不不同消息类型的处理方式不同，比如用户修改个人资料，并不是每次发生这样的动作都要做一次给朋友做一次“群发”的操作，如果遇到这个人在短时间内做了多次修改个人资料的操作，就给朋友发出多个消息，会产生垃圾信息，让人觉得很怪异，所以对于这样的操作会有一定的时效性，比如在一天之内的修改个人资料，就是一个消息，这时候的处理是更新，而不是插入。</p>
<p>以上是我对SNS中好友动态功能的设计思路，可能还有一些未想到的问题，还需要认真思考。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/sns-news-feed-design.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
