??xml version="1.0" encoding="utf-8" standalone="yes"?>91精品日韩人妻无码久久不卡,国产99久久久久久免费看,亚洲欧美一区二区三区久久http://www.shnenglu.com/yangsf5/category/20468.htmlkeep thinking keep coding.zh-cnTue, 12 Jul 2016 18:54:24 GMTTue, 12 Jul 2016 18:54:24 GMT60诅RMysql性能调优与架构设计》笔?/title><link>http://www.shnenglu.com/yangsf5/archive/2014/05/04/206818.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Sun, 04 May 2014 10:38:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2014/05/04/206818.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/206818.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2014/05/04/206818.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/206818.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/206818.html</trackback:ping><description><![CDATA[<div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div><div style="orphans: 2; text-align: -webkit-auto; widows: 2;"><div></div><fieldset><legend><span style="color: #ff0000; line-height: normal;">2016-07-12 日更?nbsp;</span></legend><div><span style="line-height:normal;color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?br /></span><div></div></div><a ><div><div><span style="color:red;">http://blog.clawz.me/2014/05/04/14-note-of-mysql-book/</span></div></div></a></fieldset><a ><div><div></div></div></a><br /><font face="微Y雅黑" size="3"><span style="line-height: normal;">一、背?/span></font></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     q几天在review公司目mysqlq块的架构,|上google出来的东西大多是皮毛Q特别一些中文站炚w的,英文的话阅读和消化都比较慢,除非不得ԌQ有些还明显有些错误?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     之前看《Http权威指南》的甜头q在Q加上有些积累现在看技术书速度也快了)Q所以赶紧找些质量高的mysql斚w的书看,扑ֈ一本阿里h写的《Mysql性能调优与架构设计》,Fenng也有做序推荐?nbsp;    </div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     正文部分为阅ȝ记?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><span style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">二、硬件关键指?/span><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     下边列出是常见性能指标Q具体指标的取舍也要看具体应用场景。具体设计时再回头参考书里里讲的例子?br /><div>1.IO性能高的部g主要q盘和内存Q各U与IO相关的板卡相兟?/div><div>     IO性能分ؓ和IOPSQ每U可提供的IO讉Kơ数Q和每秒的IOL量(IO吞吐量)?/div><div>2.CPUQSQL parse和优化)Qƈ发高的时候CPU每秒需要处理的h高Q相应CPU处理能力需要比较强劌Ӏ?/div><div>3.|络讑֤</div></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">二、性能优化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q一Q商业需求合理化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     书里例子Q实时更C个论坛帖子总量的统计?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     select count(*)语句单,但是Innodb引擎q是耗时间。而这个需求的强实时更新没多少用户真正兛_q个。定时更新可提高很大的性能?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     q条自己已经知道了?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q二Q系l架构最优化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q有几类数据不适合存到数据库中Q?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     1.二进制多媒体数据Q图片、音频、视频等Q,q类数据Ҏ据库I间资源耗费非常严重Q且q些数据的数据存储很消耗数据库L的CPU资源?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     2.水队列数据Q支持事务的存储引擎Z事务安全性和可恢复性,需要记录所有变更的日志信息Q而流水队列数据会不断的被INSERT\UPDATE\DELETEQ导致日志量很大。用成熟的W三斚w列Y件处理,性能会成倍提升?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     3.大文本数据Q从5.0.3开始,VARCHARQ实际数据小?55字节Ӟ实际存储I间和实际数据长度一P可一旦长度超q?55字节之后Q所占用存储I间是实际数据长度的两倍。不光性能低下Q还是浪费空间?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q是否合理利用了应用层的cache?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q数据层的存取实现都是最_的吗。在E序里不要过度依赖面向对象思想?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q过度依赖数据库SQL语句的功能造成数据库操作效率低下?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     量减少与mysql的交互次数和SQL复杂度。不要对可扩展性过度追求,Dpȝ设计时开分太李三Q导致需要大量Join语句?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q重复执行相同的SQL造成资源费?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q三Q逻辑实现_?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q四Q硬件设施理性化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">三、合理利用锁机制来优化mysql</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">四、Query优化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     主要优化思\和原则:</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q优化更需要优化的Query?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q定位优化对象的性能瓉?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q明的优化目标?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q从explain入手?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q多使用profile?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q永q用结果集驱动大的l果集?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q尽可能在烦引中完成排序?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q只取出自己需要的columns?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q仅仅用最有效的过滤条件?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?0Q尽可能避免复杂的join和子查询?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">五、Schema设计的性能优化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q一Q高校的模型设计</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q不一定要q求范式</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q适度冗余——让query量减少join?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q大字段垂直分拆</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     字段特别大,讉K频率又很低的字段拆出厅R因录存储是一条一条的存放Q查询某些数据时Q也会读取到q个讉K不高的大字段Q比较浪费IO资源?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q大表水q_?#8212;—Zcd的分拆优?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     把少量访问频率极高的记录水^拆分出去。例如论坛里的置帖子从普通讨里分拆出Mؓ单独的表?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q统计表——准实时优?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q二Q合适的数据cd</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     选择更小的数据类型,可以降低IO消耗。另外不同数据类型的CPU处理方式也不一栗例如通过整数cd代替点数或者字W类型?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q三Q规范的对象命名</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     q条Ҏ能没啥影响Q但是对数据库的l护影响非常大。库的字D越来越?#8230;…</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">六、mysql server性能优化</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">七、存储引擎优?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">八、架构设?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q一Q可扩展设计的基本原?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q二Qmysql replication</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q三Q数据切?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     水^切分和垂直切分,之前目里做架构时已基本了解?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q四Qcache和search的利?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     cache是memcache之类的。search主要用来做全文检索?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q五Qmysql cluster</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q六Q高可用设计之思\及方?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q七Q高可用设计之mysql监控</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"><hr />      看完上边后又在看《高性能mysql》第三版2013q初版的Q美国h写的Q这本是mysql的经怹作,比上辚w本更好吧。就是内容详l,啥都有。详l的基准试Ҏ、特性细节(原理Q、架构考虑Q这几年mysql升的特性(如分区等Q,讲述的mysql版本已经新到5.5~E许5.6前瞻。还有作者都是相关经验很多年的大ѝ内容写的也不枯燥,很向那些~程斚w的经怹的书写风根{?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     旉宝贵Q推荐看《高性能mysql》这本就行了?/div></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.shnenglu.com/yangsf5/aggbug/206818.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2014-05-04 18:38 <a href="http://www.shnenglu.com/yangsf5/archive/2014/05/04/206818.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>控制反{http://www.shnenglu.com/yangsf5/archive/2014/04/14/206573.htmlSheppard YSheppard YMon, 14 Apr 2014 03:10:00 GMThttp://www.shnenglu.com/yangsf5/archive/2014/04/14/206573.htmlhttp://www.shnenglu.com/yangsf5/comments/206573.htmlhttp://www.shnenglu.com/yangsf5/archive/2014/04/14/206573.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/206573.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/206573.html
2016-07-12 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2014/04/14/14-ioc/

一、概?/span>
     从酷客看?/span>《需求变化与IoC?/a>Q里边讲的东西挺形象的?/span>
     用户需求是一直变的,如果一直根据用h做,E序员会累死?/div>
     控制反{的比较Ş象的例子QPC机的架构都是设计好的Q用h要什么样的,再去l装配置。而不是用戯惌什么功能,每个用户去设计一套PC架构Q这样厂商就会篏死,而且成本非常高?/div>
二、拓?/div>
     不被多变的需求牵Ӟ做好自己的h生架构设计?/div>
     不因为某某小事而去花大_֊去钻研没用的东西Q要专注自己喜欢的技能?/div>
     q没仔细想玩?/div>


Sheppard Y 2014-04-14 11:10 发表评论
]]>claw设计草稿http://www.shnenglu.com/yangsf5/archive/2014/03/31/206404.htmlSheppard YSheppard YMon, 31 Mar 2014 03:09:00 GMThttp://www.shnenglu.com/yangsf5/archive/2014/03/31/206404.htmlhttp://www.shnenglu.com/yangsf5/comments/206404.htmlhttp://www.shnenglu.com/yangsf5/archive/2014/03/31/206404.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/206404.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/206404.html
2016-07-12 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?br />
http://blog.clawz.me/2014/03/31/14-claw-design/

一、目?/span>
     参考云风skynetQ实现go版本的开源服务器引擎?/div>
二、细?/div>
Q一Q服?/div>
     按服务来拆模块的好处不说了。只说go来的实现方式。go里有channel和goroutine。消息队列和轻量U线E都天然解决了?/div>
Q二Q服务间的通信
     同进E内的服务之间通信Q直接往Ҏchannel发消息即可。不同进E里靠各q程自己的harbor服务来{发。harbor服务来负责集间的通信?/div>
     集群里设|一个master服务来做全局的名字服务,主要用于登记和同步集里各个q程开启的各个服务。所有harbor启动后向master注册自己Qmaster向所有harborq播同步新加入的q个机器?/div>
Q三Q组?/div>
     l常需要向某几个服务广播一个消息,l播问题。multicast服务来管理组播?/div>
Q四Q日?/div>
     使用glog?/div>
三、已实现的服?/div>
Q一Qmaster和harbor
     暂时master做ؓharbor的中心控制器的。后l会改进Q做成harbor之间两两通信Q减对master的单点依赖?/div>
Q二Qgate
     gate用来做通常的网l监听用。目前的很简单,用户需要向q个服务器注册自q包解析和处理器?/div>
Q三Qweb
     web负责http的监听,template的加载cacheQ几个通用函数的提取?/div>
四、ps
     目地址Q?a >https://github.com/yangsf5/claw


Sheppard Y 2014-03-31 11:09 发表评论
]]>了解云风的skynethttp://www.shnenglu.com/yangsf5/archive/2014/01/16/205413.htmlSheppard YSheppard YThu, 16 Jan 2014 03:25:00 GMThttp://www.shnenglu.com/yangsf5/archive/2014/01/16/205413.htmlhttp://www.shnenglu.com/yangsf5/comments/205413.htmlhttp://www.shnenglu.com/yangsf5/archive/2014/01/16/205413.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/205413.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/205413.html
2016-07-11 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2014/01/16/14-cloudwu-skynet-research/



QPS开始应用《暗旉》里提到的理论,skynet用自q话来ȝq写下来Q这栯充分思考ƈ转述q记忆U烦Q?/p>


一、skynet设计的理?/p>

Q一Q单个skynet节点

Q?Q愿?/p>

    充分利用多核。最初想法是多进E。像׃nodejs里多核就只能是多q程了,因ؓ每个nodejsq程是单U程的?br />

    多进E是遵@unix设计哲学Q工具链形式Q分拆进E的形式来分拆模块,减少复杂度和耦合性,方便~程及维护?br />

    后来云风他们发现lua做ؓ嵌入式脚本,写逻辑时很好用的,反正如何都要用luaQ而且lua提供了沙盒,q样多进E可以变为单q程多个沙盒Q这L合了多进E和单进E多U程的优ѝ多U程里共享资源,在同一q程地址I间Q访问更高效?br />


Q?Q核心功能(门房Q)

    很精Q仅解决一个问题?/p>

    skynet里不实现具体游戏逻辑Q后者些攑ֈ一个一个动态库里(so文gQ。skynet这些so注册到自己里边,每个so一个永不重复的idQ类g数据库的autoincreament。看描述q个id是skynet自己q行时当ơ维护的Q而不是模块配|好ln的id。模块的怹有效唯一标示为名字,skynet提供了名字服务,可以l每个模块取一个易ȝ名字?br />


Q?Q核心不解决什么问?/p>

    skynetd所有服务在同一OSq程协作完成。核心里没跨机通讯Q单个服务的崩溃和重启也没管Q云风表C些应该由上层处理Q他有责L露错误,而不是隐藏?br />

    q个设计的原因,游戏和操作系l不一P操作pȝ默认不信MQ何进E,各进E崩溃什么的不应影响其他q程Q所以某个进E挂了,他就安葬它,而其他进E美好的生活。单游戏是ؓ玩家服务的,某个环节出错都有可能造成玩家利益混ؕQ所以那里错了就整个程Q服务器Q挂掉吧。没有必要让出错模块被隔dQ而其他模块却l箋提供服务导出未预知行为?br />

    上边说的东西应该上层考虑Q用lua的沙盒就能做{略隔离?br />


Q?Qskynetq行旉辑?/p>

    skynet负责且只负责一个数据包从一个服务发送到同一q程的另一个服务里。发送服务直接调发送APIQskynet收到数据包后Q调用接受者服务的注册的callbackQ即发给了接受者服务?br />

    skynet保证在各模块初始化时、每个独立的callback调用Ӟ都是怺U程安全的。这L写服务的人就不需要考虑多线E的M问题了,只需专心处理l他的一个个数据包?/p>

    PSQ天龙的场景lua有点像这里的单个服务。不知天龙的跨线E切场景情况在这里也可以l简化ؓ单线E?Q回头看源码再研I这个问题)


Q?Q消息调?/p>

TODO


Q?Qgate和connection

TODO


Q二Qskynet集群

    集群里最多支?55个skynet节点Q每个skynet节点有一个idQ成为harbor id。这个id是集层面指定,可以Zؓ分配Q也可以׃个中央服务器协调分配?/p>

Q?Q集间通信

    skynet核心层纸负责在往外发消息时在source字段上加上自qharbor id。而集间的通信Q是由单独的harbor服务来做的。skynet是往集群其他节点发的消息Q就转发到harbor内。harbor会跟集群内跟自己l识的skynet的harbor历tcp链接。harbor把消息发l目标harbor?br />

    harbor间的通信为单向的tcp道?br />

    master服务来同步全局的名字服务。每个skynet都会知道其他节点上装配了哪些服务Q好路由q去?br />


Q?Q组?/p>

    TODO



Sheppard Y 2014-01-16 11:25 发表评论
]]>集群实现l节Q?Q?登陆程修改http://www.shnenglu.com/yangsf5/archive/2013/12/16/204821.htmlSheppard YSheppard YMon, 16 Dec 2013 02:44:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/12/16/204821.htmlhttp://www.shnenglu.com/yangsf5/comments/204821.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/12/16/204821.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/204821.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/204821.html
2016-07-11 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2013/12/16/13-game-cluster-design-detail-5/

 



一、回?/p>

    之前的登陆流E在q篇?/a>。之前的登陆程qͼ

Q?Q先查是否同服已登陆Q是则两个链接都t掉Q否则进入下步;

Q?Q判断是否异服已登陆Q是则告诉异服踢老链接,随后t自p的新链接。否则进入下步;

Q?Q当前服务器登陆相关程走完后,向玩家在U列表汇报(写入q个玩家登陆的服务器id为我Q。这时的汇报写入为redis的CAS操作Qؓ了检查是否发生了那篇里介l的同̎L间多L陆事件。CAS操作成功Q本服链接登陆完成,做后l操作。否则CAS操作p|Q表C瞬时登陆的异服同̎L另一个链接的登陆程走的快,已经完成整个程Q包括汇报进在线列表。这时的处理只用慢拍的本服链接关闭p了?/p>

 

二、存储架构变为redis+mysql后的问题

    现在玩家上线旉要从mysql加蝲玩家ȝ数据到redisQ需要考虑q个数据加蝲攑ֈ上边登陆程哪一步里?/p>

    首先数据加蝲有可能会p|Q如果数据加载出问题Q就不能让该玩家登陆?/p>

    如果攑ֈQ?Q(3Q之_是redis的CAS之前Q这L间同一账号多v登陆都有可能开始进行加载数据步骤,而处理的快的那个客户端就有可能汇报登陆完成之后立即玩游戏q更C自己在redis里的数据Q处理的慢的客户端还q时q在mysql的数据往redis的加载,会覆盖快的客L更新的数据?/p>

    如果攑ֈQ?Q里redis的CAS之后Q数据加载失败,需要回退CAS的操作?/p>

    可见W二U至可以保证数据正性。这U情冉|象下Q就是第一U里没有提供事务操作的回滚(慢客L覆盖数据后发现干了坏事却不方便回滚自q破坏Q?/p>

    Q?Q这个操作当时是Z区分异服登陆q玩游戏很久了和瞬间多v登陆q两U情늚。现在想惌两种情况的处理统一为直接踢掉新旧两个链接也没什么,毕竟瞬时登陆的情况不多?/p>

 

三、新程

    Ҏ上边的结论,新的程为:

Q?Q先查是否同服已登陆Q是则两个链接都t掉Q否则进入下步;

Q?Q向玩家在线列表CAS报告自己登陆。如果失败告诉异服踢掉该账号老链接,自己q边t掉该̎h链接卛_。成功则q入下步Q?/p>

Q?Q加载数据,成功p入正常游戏流E。加载失败,去在线列表里清掉自己?/p>

Sheppard Y 2013-12-16 10:44 发表评论
]]>集群实现l节Q?Q?L数据划分及同?/title><link>http://www.shnenglu.com/yangsf5/archive/2013/12/13/204771.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Fri, 13 Dec 2013 07:58:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2013/12/13/204771.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/204771.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2013/12/13/204771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/204771.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/204771.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-11 日更?nbsp;</span></legend><div><span style="color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span></div><div></div><a ><div><span style="color:red;">http://blog.clawz.me/2013/12/13/13-game-cluster-design-detail-4/</span></div></a></fieldset><a ><div></div><p> </p></a><p><br /> </p><div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">一、玩家数据在redis与mysql之间的同?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    ׃redis操作可以保证多个q程d同一个玩家数据时的原子性。所以之前多个逻辑服务器读写同一玩家数据时没有什么问题,但是现在redis和mysql之间需要同步玩家的数据Q例如定时将redis里的在线玩家数据刯mysql里做持久化)。这个同步的逻辑代码攑֓呢?</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    观察需求特性,玩家上线加蝲到redis做cache、定时更新持久层、玩家离U时清掉cacheq更新到持久层,都是redis和mysql之间的数据交互。这些可以放C个服务里Q单q程实现Q或者集成到现在的逻辑服务器里?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    方便实现Q做下限制。玩家登陆的逻辑服务器记Z的owner服务器,每个玩家数据的redis/mysql同步只由他owner来做?nbsp;q样问题q化了?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    q里有些做法是突然想到的Q就像《暗旉》里提到的联惛_的,而不是归Uxl的。最q在看《暗旉》,好书Q里边就提到边写Ҏ考,思考时“大脑内存”有上限的Q边写就能把部分思考分支换出笔记这U?#8220;盘”上,然后大脑专心思考其中一两个分支Q想的差不多Q再回过头将“W记盘”上的数据换入“大脑内存”……正在思考的东西写博客的习惯已经形成一D|间了Q看了书后,更深切体会到q种好处?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    如果逻辑服务器宕机,它上边的玩家掉U了Q而这台逻辑服务器是不能对这些玩家做ȝ数据持久化的。这U情况需要进一步思考TODO。另外之前这U玩家怎么标记为离U,需要再想一遍,也TODO了?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">二、从本质出发review我们的存储架?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    不要走的太远而忘了ؓ什么出发,从本质上思考,弃掉那些不必要的思考分支,化问题?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    本质我们的架构是为实现游戏的玩法目标来做的,另一斚w我们考虑开发成本、维护成本、机器成本。好的架构是权衡目标实现E度和这些成本的耗费?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    目标是实现同一国家的玩家不分区分服。之前缓存和持久化都是用redis来做Q开发成本和l护成本都挺低的。但是需要很多机器。现在控制机器成本,所以需要分析我们数据的特点Q将h据放到mysqlq种机器需求量的数据库。具体到表的分析q里׃方便贴了。说下大概分c:</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q离U玩家的h据,ȝ玩家的私人数据,不需也不能与别h交互的;</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q离U玩家的热数据,例如名字Q好友是想看到离U好友的名字的;</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q在U玩家的一直更新的数据Q例如经验|游戏货币{;</div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Q?Q在U玩家的到强实时玩法时才更新的数据?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    Q?Q里的数据无疑问攑֜mysql里。(2Q里的数据还得根据情늜是否一致放在redis里,即离U的玩家q部分数据也攑֜redis里。(3Q里的数据无疑问在线是放到redis里。(4Q里的数据可以根据情况考虑下gq加载什么的Q即玩家上线时这部分数据不马上加载到redisQ而是{玩家开始这个玩法时才从mysql里加载到redis里。这个需要考虑q个玩法的数据量以及是否玩家参与度高?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">三、扩?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    先了解mysql单表数据上限、然后mysql单库上限。这里的上限指不影响效率的上限,而不是物理上限。拿C限数据后Q做预分库分表。分库分表也要好好想惟?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     查了下,mysql 5.1里InnoDB引擎表空间最大容量ؓ64TB。在查我们公司服务器配置表里盘Q最低有100G的,最?00多G的?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     初步定mysql的sharding和partitionP不同物理Z间的sharding为分个大的idD,单个物理Z卛_库内的如果表q是很大做自己的partition。最l看上线怎么定,再定q个跨机sharding的idD长度,至于单机的partitionQ对代码来说是不需要管的,q维Ҏ性能搞就行了?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">     先简单算下,每h100kQ?00wZ个shardingQ需要大U?00GI间?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">四、其他架构展?/div><div style="font-family: 微Y雅黑; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">    有单机内容;需要联|时才联|;p|时p|,强实时时做强实时联网。一直纠l这个会不会影响现在的存储架构,但是想了下,不大影响Q变的只是链接Ş式,玩家数据处理q是一L?/div></div><p> </p><img src ="http://www.shnenglu.com/yangsf5/aggbug/204771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-12-13 15:58 <a href="http://www.shnenglu.com/yangsf5/archive/2013/12/13/204771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>集群实现l节Q?Q?DB集群http://www.shnenglu.com/yangsf5/archive/2013/12/06/204628.htmlSheppard YSheppard YFri, 06 Dec 2013 08:53:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/12/06/204628.htmlhttp://www.shnenglu.com/yangsf5/comments/204628.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/12/06/204628.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/204628.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/204628.html
2016-07-11 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2013/12/06/13-game-cluster-design-detail-3/

 

 

一、纯redis集群

    如果redis不止做cacheQ也做持久化Q那得好好算我们的业务规模需要多台机器来支撑?000w注册玩家Q每台机?6G内存Qؓ了保证效率取3/4为可用,?2GQ?/p>

    如果每个玩家1M数据Qȝ9765GQ不热备,需?14台机器。每台机器存?.2w人?/p>

    如果每个玩家16k数据Qȝ153GQ不热备,需?3台机器。每台机器存?7w人?/p>

    如果每个玩家1k数据ȝ9.5GQ不热备,需?台机器。每台机器存?000w人?/p>

    注册玩家会越来越多的……

 

二、mysql做持久化Qredis做cache

    只说存储Q一个mysql支持几T数据没什么问题。例如上?000w注册玩家Q每个玩?M数据QL据近9.5TQ存一个mysql_。但是如果高峰在U玩家ƈ发到100wQ需要将大部分操作规划到redisq个cache上。否则mysql仍然因磁盘IO太多吃不消?/p>

 

Q一Q与Uredis集群相比的劣?/p>

Q?Q好友需要看ȝ玩家的信息,而离U玩家在mysql里,如果频繁Q?/p>

    把离U玩家可能被别h查看的信息不存mysql了,改用redis做持久化?/p>

Q?QGM工具改玩家消息,需要改mysql和redis的cache里。会不会Ҏ出问题?

 

Q二Q优?/p>

Q?Qredis只做cache集群了,用twemproxy理p了。如果redis做持久化Q还是需要自己来分片Q且早期p规划好?/p>

Q?Q单个玩家的数据涨到1M的时候,ȝh?000w~3000wQ再加两个mysql?/p>

 

三、redis做cache+热数据持久化Qmysql做冷数据持久?/p>

    q里其实是二里边的每个玩家的部分很热的数据从mysqlUdredis里做持久化。但是玩家在U时Q他的数据基本都是热的。所以这个方案不是很好设计?/p>

 

 

最后、参?/p>

1. redis官方关于分片的文章:http://redis.io/topics/partitioning

2. twemproxy文章Q?a _>http://antirez.com/news/44

 

 



Sheppard Y 2013-12-06 16:53 发表评论
]]>休闲游戏q_架构http://www.shnenglu.com/yangsf5/archive/2013/10/31/204033.htmlSheppard YSheppard YThu, 31 Oct 2013 15:15:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/10/31/204033.htmlhttp://www.shnenglu.com/yangsf5/comments/204033.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/10/31/204033.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/204033.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/204033.html
2016-07-11 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2013/10/31/13-game-platform/

 


一、背景和目标

    当年大三的时候写了个五子世界,是qq game那种大厅-戉K-桌子Q我只有单逻辑的五子棋Q。毕业后一直想找个旉来重构它Q后来有ơ下军_看了下代码,有点儿不知所措,你懂的,QDQ还不如重写?/p>

    现在对go很感兴趣Q准备用go来实C前的开源梦。就先已以前的五子棋世界那种休闲游戏q_来开始练手吧?/p>

    目标暂时不定的太大,基本实现大厅-戉K-桌子-游戏p了,慢慢重构慢慢完善?/p>

 

二、服务器架构

    基本架构参照之前l公叔R目做?a title="" href="http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html" target="_self" _href="http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html" data_ue_src="http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html">架构。当架构有改变时Q及时修改这博客,或者新博客与这相互引用和注解?/p>

    不同的部分,加个大厅Q大厅里昄戉K状态,q样玩家p己选择闲的戉KȝQ这样就不需要做负蝲均衡的算法了?/p>

 

Q一Q̎Ll?/p>

    游戏自n不做账号密码q种用户pȝQ只用第三方的̎P如微博̎L来连接到我们游戏。或者更单点Q这块儿只模拟下微博{第三方用户pȝ的登陆了?/p>

    W三方̎戯接到我们游戏Q我们本地只p增长的uid生成器来生成一个int的uid卛_Q将W三方的platformUid和我们的localUid做个兌映射?/p>

 

Q二Q大?/p>

    大厅可以做成短连接,玩家选择游戏及房间的时候才d厅刷C当前的各戉K负蝲情况?/p>

 

二、客L

    用walk。(待详l规划)



Sheppard Y 2013-10-31 23:15 发表评论
]]>集群实现l节Q?Q?玩家在线状态箋http://www.shnenglu.com/yangsf5/archive/2013/10/19/203811.htmlSheppard YSheppard YSat, 19 Oct 2013 01:41:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/10/19/203811.htmlhttp://www.shnenglu.com/yangsf5/comments/203811.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/10/19/203811.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/203811.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/203811.html
2016-07-11 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2013/10/19/13-game-cluster-design-detail-2/

 


 

一、玩家离U?/p>

    ׃ȝ的状况多Q常见的玩家自己拿自q账号的离U,也有自己的̎号在多个讑֤来挤掉线Q还有就是被非法的h使用时的挤掉Uѝ这里应该将玩家理解Z个̎P下边量用̎h表述?/p>

Q一Q网l断开或者主动离开游戏

    q时玩家所在的服务器在玩家net.close时加入向通信redis汇报的逻辑Q即通信redis里删除这个玩家的在线U录?/p>

 

Q二Q同服重复登陆时的kick

    首先肯定要踢掉之前登陆的链接。因为同服时新旧链接都在q个服务器上Q逻辑上简单,允许新链接的登陆比较好处理,但是后边有其他考虑?/p>

 

Q三Q异服登陆时的kick

    首先也是t掉之前的登陆。需要在之前登陆到的服务器将该̎L链接断开q整理数据存储之后,才能允许在新的服务器登陆?/p>

    旧服务器清理完该玩家后,向通信redis报告删除该̎L在线状态。新服务器需要知道玩家已l在旧服被kick完了才可以让玩家登陆。刚才同服时提到的允许新链接立刻登陆的问题,q里变的比较不可控了。美好的q程是,新链接接入后挂v在新服,{异服踢完后Ql做新链接的登陆操作。但是这需要新旧服之间的同步逻辑Q需要将新服玩家做个状态机为维护这U挂hl箋登陆状态。另外还要考虑q个期间玩家又在另一个服登陆。要考虑的东西很?#8230;…

    q有一U有问题的处理方式,x服只是向老服发送踢人指令,新服自己却马上进入新链接的登陆操作。这L问题是,即业务逻辑单到不会发生数据不同步问题,但登陆操作不会一定成功。新服登陆完向通信redis报告玩家在线Q旧服踢完要向通信redis报告玩家ȝ。这两个操作异步Ӟ如果旧服的离U报告在后,通信redis上就会错误的记录账号当前不在U?#8230;…

 

Q四Qȝ

    最l重复登陆问题简单处理方法:账号登陆Ӟ只要到该̎号同服或异服已登陆,先将旧链接踢掉,再将新链接断开。就l玩家一个提C?#8220;账号已登录,L后重?#8221;Q让玩家自己来多操作几次Q直到旧链接被踢完?/p>

    

二、同一账号的同瞬间多v登陆事g

    ​上边重复登陆的检查还有一U情况不能防止,是瞬间的多个客L用同一账号登陆。同服时׃nodejs的异步,异服时由于天然异步,查该账号是否已登陆与当前链接成功登陆ƈ向通信redis报告q些操作不具原子性?/p>

    ​所以在最后向通信redis写入上线状态时再次判断是否已登陆(卛_断是否被瞬时q发的另一个客L的登陆给标记为已上线了)。redis里用hsetnx代替hsetQ前者在数据已经被设|时操作p|?/p>

PSQ?/p>

    刚接触不久或者本w逻辑复杂的东西Q例如分布式Q很多思考的l果不及时记录的话,后边Ҏ忘记当初的理由,D需要冗余的重复思考。所以现在博客写琐碎些,记蝲些细节的思考?/p>

 

 



Sheppard Y 2013-10-19 09:41 发表评论
]]>集群实现l节Q?Q?异服通信和压?/title><link>http://www.shnenglu.com/yangsf5/archive/2013/10/17/203784.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Thu, 17 Oct 2013 06:45:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2013/10/17/203784.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/203784.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2013/10/17/203784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/203784.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/203784.html</trackback:ping><description><![CDATA[<p> </p><fieldset><legend><span style="color: #ff0000;"> 2016-07-11 日更?nbsp;</span></legend><div><span style="color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span></div><div></div><a ><div><span style="color:red;">http://blog.clawz.me/2013/10/17/13-game-cluster-design-detail-1/</span></div></a></fieldset><a ><div></div><p> </p></a><p><br /></p><p>一、背?/p> <p>    目开始后Q先敲定了大体可横向扩展的集架构(q是个美好的期望Q,然后开始编写单q程的服务器底层和逻辑Q让前边几个q代周期的逻辑内容配合客户端跑h了?/p> <p>    接着是单q程的架构扩展v来,设计上细化下架构的扩展。已写在前篇《休闲手游服务器集群扩展思考》里。最q的两周在将之前单进E的服务器架构里部分模块扩展为支持这随W里提到的集架构?/p> <p>    实现的过E中到的一些需要仔l设计的l节Q原则上q是K.I.S.S?/p> <p> </p> <p>二、全服玩家在U状?/p> <p>    逻辑服务器集的负蝲均衡法q没实现。先只扩展玩安的同服通信为异服通信Q通过redis的pub/subQ以下将q个用于通信转发的redisUCؓ通信redisQ?/p> <p>    问题链:Q?#8220;-->>”引出的下个问题被当前问题所依赖Q?/p> <p>        通信发v斚w要知道目标方在逻辑集群里的哪个服务器上 -->></p> <p>        玩家登陆和退出时往通信redis报告 -->></p> <p>        登陆时检查̎h否注册到我们的游戏,否就注册 -->></p> <p>        </p> <p>Q一Q登陆和注册</p> <p>    玩家拿到用户pȝ的̎h登陆我们游戏服务器。游戏服务器拿clientl的q个code再去用户pȝ服务器做验证Q通过后l?/p> <p>    查̎h否在我们游戏注册Q如果没有则注册上,映射出游戏服务器上的一个local uid。这里需要检查玩家是否在游戏注册了,所以需要一个platform uid与local uid的映表。这个映之前单q程服务器时与其他角色数据放在相同redis上的Q现在移到全局cȝredis上(以下U全局redisQ暂时是通信redis和全局redis放一LQ等以后看压和U上反馈再做演变Q。另外用来本地注册生成local uid的自增长id也移C全局redis上?/p> <p>    ​查完注册Q得到local uidQ先看是否在本服务器登陆了,否则再向通信redis查看是否登陆在其他服务器。如果已登陆Q则t掉之前的登陆。之前单q程只有同服重复登陆thQ现在多个异服重复登陆的th操作?/p> <p>    登陆成功向通信redis报告local uid和所在的q个logic服务器的server id。另外退出时也向通信redis报告Q注销掉这条记录?/p> <p> </p> <p>Q二Q异服通信</p> <p>    每个逻辑服务器都与通信redis建立用于pub/sub的链接,各逻辑服务器有自己的频道?/p> <p>    异服上的玩家通信Ӟ从通信redis拿到目标玩家所在server idQ让后向目标server所对应的专有频道pub数据卛_?/p> <p>    </p> <p>三、压工?/p> <p>    加了q个集群扩展后,底层试只是单元试是不够的。反正要压力试工具q早要写Q就先写了简单版的压工P来做异服通信的自动化试?/p> <p>    压测工具开始的x挺多的,后来抛弃了一些短期不好实现的x。现在就单的Q一个client一个Client structQ这个处理client的通信发送接收。做相同动作的clientZ个Group struct。每个动作ؓ一个Rule structQ里边组合好收到什么包后做什么事情,或者直接发些什么包?/p> <p>    c++端游压测的每个Rule动作一般用lua来写的,比较方便Q我们这个压工Lgo写,rule暂时也用go写,也不ȝ?/p> <p>    感慨下,q种q行的应用场景,go的编E思维与具体写法比node.js更适合c/c++n的程序员?/p><p> </p><img src ="http://www.shnenglu.com/yangsf5/aggbug/203784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-10-17 14:45 <a href="http://www.shnenglu.com/yangsf5/archive/2013/10/17/203784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>休闲手游服务器集扩展思?/title><link>http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Mon, 30 Sep 2013 02:46:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/203500.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/203500.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/203500.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-11 日更?nbsp;</span></legend><div><span style="color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span></div><div></div><a ><div><span style="color:red;">http://blog.clawz.me/2013/09/30/13-mobile-game-cluster-design/</span></div></a></fieldset><a ><div></div><p> </p></a><p><br />一、目?/p> <p>    能横向扩展,架构要简单,能做到负载均衡,避免单节点负载太ȝ资源费?/p> <p> </p> <p>二、数据存储的DB集群</p> <p>    ​数据存储cd有多U?/p> <p>Q一Q非交互性的个h数据</p> <p>    ​可通过单的id分段。id?~10000的玩家个人数据存储在db1Qid?0001~20000的玩家个人数据存储在db2Q以此类推?/p> <p> </p> <p>Q二Q交互性数?/p> <p>    ​如好友关pȝ?/p> <p>Q?Q如果好友关pd以ؓ单向Q那么可以将关系存到个h数据里?/p> <p>Q?Q如果好友关pM能ؓ单向Q那么需要保证每条关pM持在要么没有Q要么两人都认同Q记数据上一_互相有关pR那么需要保证相关的关系操作的一致性。这样可能只保存一份每两个Z间的关系Qk-v存储旉要方向查找,不知是否能实现?/p> <p> </p> <p>Q三Q全局数据</p> <p>    ​如全局排行榜之cȝ。这U放在单独的库里里,专门做全局数据的存储。当C定规模时Q按全局数据的类型再分库?/p> <p>    ​家族、帮会等Q也攑֍独的库里。如果需要扩展,再按家族id、帮会id来分库?/p> <p> </p> <p>三、逻辑服务器集对DB集群的访?/p> <p>    ​DB集群的\p则配|到逻辑服务器的config里。当需要热扩展DBӞ启动新DB后,l各logic服务器发送GM指定Qreload路由规则的config?/p> <p>    ​DB集群路由规则的configQ可以放在一个公共地方,各logic服务器接到GM指o后,d共地Ҏ取新的config然会reload?/p> <p> </p> <p>四、逻辑服务器集?/p> <p>    ​Z架构的简单,可以每个逻辑服务器进E上都有所有逻辑Q扩展时Q以扩展逻辑服务器进E数量来辑ֈ?/p> <p>Q一Q各逻辑服务器上玩家分配</p> <p>    ​逻辑服务器集之间的交互。如果逻辑服务器的使用Q也像个人数据存储的DB那样id分段——只让1~10000的玩家登陆logic1Q?0001~20000的玩家登陆logic2Ӟq很单,但各id断的玩家z跃度不定的Q做不到负蝲均衡啊?/p> <p>    ​所以是Ҏ当时的负载情况,来推荐玩家登陆闲的逻辑服务器的。这样需要有个全局映射Q知道哪个玩家登陆在哪个服务器上。可以将玩家当前所在的服务器id记录在该玩家的个人数据所在的db里?/p> <p>Q二Q逻辑服务器间的通信</p> <p>    ​目前目持久化用redisQ最快出东西Q就先考虑redis的优ѝ?/p> <p>    ​逻辑服务器间的通信Q通过全局数据存储的redis来做pub/sub转发吧?/p> <p>    ​redis的pub和sub的实时性不够时Q?#8203;有实时性需求的玩家都{C个专门做强实时性的Ҏ逻辑服务器?/p> <p> </p> <p>五、PS</p> <p>    ​公司的项目是Node.js+RedisQ业余时间打用Go写个服务器引擎?/p> <p>    ​q篇考虑发到_֍区,可以得到很多的批评徏议?/p><img src ="http://www.shnenglu.com/yangsf5/aggbug/203500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-09-30 10:46 <a href="http://www.shnenglu.com/yangsf5/archive/2013/09/30/203500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>node.js手游服务器调?/title><link>http://www.shnenglu.com/yangsf5/archive/2013/08/12/202497.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Mon, 12 Aug 2013 09:21:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2013/08/12/202497.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/202497.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2013/08/12/202497.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/202497.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/202497.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更?nbsp;</span></legend><div><span style="color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span></div><div></div><a ><div><span style="color:red;">http://blog.clawz.me/2013/08/12/13-nodejs-mobile-game-server-research/</span></div></a></fieldset><a ><div></div><p> </p></a><p><br />一、node.js能做?/p> <p>    <a _>http://www.infoq.com/cn/articles/what-is-nodejs</a></p> <p> </p> <p>二、杂w?/p> <p>1. http的长q接是不是也是只能req/rep模式Q能实现服务器端push吗?</p> <p>    http的长q接即HTTP keep-aliveQHTTP1.1里加入)Q这个原生的只是Z更少的徏立和关闭tcp链接Q可以减网l流量;因ؓ已徏立的tcp握手Q减后l请求的延时{。这个http长连接不支持全双工通信?/p> <p>    http实现“服务器推”的技术,一是借助客户端Flash XMLSocket或者Java Applet套接口来实现Q另一U是comet技术。(q有一U遭|的客户端以一定间隔向服务器发求的轮询׃提了Q?/p> <p>    comet有两U:</p> <p>        Q?Q基于AJAX的长轮询Qlong-polling技术)</p> <p>        Q?Q基?Iframe ?htmlfile 的流QstreamingQ方?/p> <p>    q两U方式看描述已经L游服务器差远了,׃L惹它们了吧?/p> <p> </p> <p>2. 大规模网站的架构Q怎么做到水^扩展的?</p> <p>    |站的需求跟游戏不一P|站都是http够了,req/rep卛_Q没有交互等q播同步之类的复杂状态?/p> <p>    Qpomelo里表C游戏的业务模型很难做到传统|站那种无限水^扩展Q?/p> <p> </p> <p>3. websocekt是什么?</p> <p>    html5开始提供的Qؓ了ɋ览器和服务器间q行全双工通讯的长链接协议。websocket协议本质上是一个基于TCP的长q接协议。与传统C/S长连接的区别在于Qwebsocket链接开始时的握手协议,客户端首先要向服务器发v一个HTTP骑牛Q这个请求和通常的HTTPh不同Q包含了一个附加信?Upgrade:WebSocket"表明甌协议升Q服务器回应后,x手完成,websocket链接建立hQ双方自由通信Q直C方关闭链接?/p> <p>    websocket相对于http的优点,除了全双工通讯Q还有服务器与客L交换的header信息很小?/p> <p>    websocket与传lsocket的区别,前者有帧协议,不需要上层做拼包了?/p> <p> </p> <p>4. redis可以直接搞集吗Q?/p> <p>    数据量太大时Qredis的持久化会媄响性能Q解x案时用个slave专职做持久化。另外redis容灾和传lweb应用的减压,开多个slaveQ用于分担读的压力?/p> <p>    当库C定数量时Q可以用分库分表来水qx展?nbsp;</p> <p> </p> <p>5. node.js能用c++扩展吗?</p> <p>    v8和node都是c++写的?/p> <p> </p> <p>三、网易pomelo能干些啥</p> <p>    分布式服务器Q方便扩展。另外实C很多游戏常用模块Q如aoi{?/p> <p> </p> <p>四、公司的node.js框架有哪些不能做?/p> <p>1. websocket实现了吗Q?/p> <p>    实现中?/p> <p>2. 方便分布式扩展吗Q?/p> <p>    貌似没有pomelo那么方便?nbsp;</p> <p> </p> <p>五、ȝ</p> <p>    ​node.js做手游服务器的开发还是挺方便的,pomelo已经做很多事?#8230;…</p> <p> </p> <p>N、参?/p> <p>1. CometQ基?HTTP 长连接的“服务器推”技术:<a _>http://www.ibm.com/developerworks/cn/web/wa-lo-comet/</a></p> <p>2. WebSocketQ?a _>http://zh.wikipedia.org/wiki/WebSocket</a></p> <p>3. 使用 HTML5 WebSocket 构徏实时 Web 应用Q?a _>http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/</a></p> <p>4. pomeloQ?a _>https://github.com/NetEase/pomelo</a></p> <p>5. HTTP长连接:<a _>http://www.blogjava.net/xjacker/articles/334709.html</a></p> <p>6. Redis复制与可扩展集群搭徏Q?a _>http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster</a></p><img src ="http://www.shnenglu.com/yangsf5/aggbug/202497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-08-12 17:21 <a href="http://www.shnenglu.com/yangsf5/archive/2013/08/12/202497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>X目C++服务器(1Q? M构想http://www.shnenglu.com/yangsf5/archive/2013/04/25/199704.htmlSheppard YSheppard YThu, 25 Apr 2013 06:52:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/04/25/199704.htmlhttp://www.shnenglu.com/yangsf5/comments/199704.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/04/25/199704.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/199704.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/199704.html
2016-07-08 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>

 

http://blog.clawz.me/2013/04/25/13-x-cpp-server/ 

 

 

一、简?/p>

    q个目刚v步,来有可能会演变为公司的服务器框架。博客里暂且U呼为X目?/p>

    语言为c++Q之后将此服务器的设计演变尽量记录下来,Z个系列,?#8220;X目C++服务?#8221;为统一标题开头?/p>

 

二、架构设?/p>

Q一Q多q程通信Ҏ

    zeromq

Q二Q协议方?/p>

    protobuf 

Q三Q存?/p>

    redis

Q四Q脚?/p>

    luaplus

Q五Q日?/p>

    glog

 

三、自动构建部|?/p>

    自动构徏{ؓ敏捷开发提供保障?/p>

    之前l历的那些项目(其中包括业内比较有名?个大型项目)在自动构建部|方面基本ؓ0Q开发效率不高,q次新项目准备从一开始就做这斚w的准备?/p>

Q一Q单?/p>

    单测框架考虑google的gtest?/p>

 



Sheppard Y 2013-04-25 14:52 发表评论
]]>PHP/Java Bridge的?/title><link>http://www.shnenglu.com/yangsf5/archive/2013/04/08/199230.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Mon, 08 Apr 2013 10:20:00 GMT</pubDate><guid>http://www.shnenglu.com/yangsf5/archive/2013/04/08/199230.html</guid><wfw:comment>http://www.shnenglu.com/yangsf5/comments/199230.html</wfw:comment><comments>http://www.shnenglu.com/yangsf5/archive/2013/04/08/199230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/yangsf5/comments/commentRss/199230.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/yangsf5/services/trackbacks/199230.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-06 日更?nbsp;</span></legend><div><span style="color:red;">此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span></div><div></div><a ><div><span style="color:red;">http://blog.clawz.me/2013/01/18/13-php-java-bridge/</span></div></a></fieldset><a ><div></div><p> </p></a><p><br />一、需求背?/p> <p>    之前介绍q我们项目的架构Q由于历史原因,架构演变成as<-->java<-->phpq样Qjava与as通过tcp长连接通信Qjava与php通过两条http通道来通信Qjava与php各自有个http serverQƈ各自作ؓҎ的http clientQjava转发as以前的postlphpQphp需要跨session推送或者广播时变ؓhttp client向java的http server做postQ?/p> <p>    q之前的架构是as的功能逻辑大部分直接与phpq行http通信?/p> <p>    目的目标是慢慢php部分写的p糕的已有逻辑Q例如帮z这U交互和q播同步比较多的Q改到java服务器上。项目h员配备跟不上Q所以不能一下子全{了?/p> <p>    如果用之前的两条http通道来小步快跑式的移逻辑Q就需要再装q两个通道之间的通信Q费旉q不一定好使,所以我们需要一个java直接调用php的技术?/p> <p>    goole了解后,最l决定用PHP/Java Bridge?nbsp;</p> <p> </p> <p>二、PHP/Java Bridge</p> <p>Q一Q示?/p> <p>CallPhp.java<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <span style="color: #0000FF; ">package</span> me.sheppardy.study;<br /><span style="color: #008080; "> 2</span> <br /><span style="color: #008080; "> 3</span> <span style="color: #0000FF; ">import</span> java.io.ByteArrayOutputStream;<br /><span style="color: #008080; "> 4</span> <span style="color: #0000FF; ">import</span> java.io.FileReader;<br /><span style="color: #008080; "> 5</span> <br /><span style="color: #008080; "> 6</span> <span style="color: #0000FF; ">import</span> javax.script.ScriptEngine;<br /><span style="color: #008080; "> 7</span> <span style="color: #0000FF; ">import</span> javax.script.ScriptEngineManager;<br /><span style="color: #008080; "> 8</span> <br /><span style="color: #008080; "> 9</span> <span style="color: #008000; ">/**</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">10</span> <span style="color: #008000; "> * <br /></span><span style="color: #008080; ">11</span> <span style="color: #008000; "> * PHP/Java Bridge, example<br /></span><span style="color: #008080; ">12</span> <span style="color: #008000; "> * </span><span style="color: #808080; ">@author</span><span style="color: #008000; "> sheppard(ysf1026@gmail.com) 2013-01-18<br /></span><span style="color: #008080; ">13</span> <span style="color: #008000; "> *<br /></span><span style="color: #008080; ">14</span> <span style="color: #008000; "> </span><span style="color: #008000; ">*/</span><br /><span style="color: #008080; ">15</span> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> CallPhp<br /><span style="color: #008080; ">16</span> {<br /><span style="color: #008080; ">17</span>         <br /><span style="color: #008080; ">18</span>         <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> main(String[] args) <span style="color: #0000FF; ">throws</span> Exception<br /><span style="color: #008080; ">19</span>         {<br /><span style="color: #008080; ">20</span>                 test(1104);<br /><span style="color: #008080; ">21</span>                 test(531);<br /><span style="color: #008080; ">22</span>                 test(1221);<br /><span style="color: #008080; ">23</span>                 test(110);<br /><span style="color: #008080; ">24</span>         }<br /><span style="color: #008080; ">25</span>         <br /><span style="color: #008080; ">26</span>         <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> test(<span style="color: #0000FF; ">int</span> id) <span style="color: #0000FF; ">throws</span> Exception<br /><span style="color: #008080; ">27</span>         {<br /><span style="color: #008080; ">28</span>                 Response rep = <span style="color: #0000FF; ">new</span> Response();<br /><span style="color: #008080; ">29</span>                 call(<span style="color: #0000FF; ">new</span> Request(id), rep);<br /><span style="color: #008080; ">30</span>                 System.out.println("CallPhp.test, id=" + id + " message=" + rep.message);<br /><span style="color: #008080; ">31</span>         }<br /><span style="color: #008080; ">32</span>         <br /><span style="color: #008080; ">33</span>         <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> call(Request req, Response rep) <span style="color: #0000FF; ">throws</span> Exception<br /><span style="color: #008080; ">34</span>         {<br /><span style="color: #008080; ">35</span>                 ScriptEngineManager engineManager = <span style="color: #0000FF; ">new</span> ScriptEngineManager();<br /><span style="color: #008080; ">36</span>                 ScriptEngine engine = engineManager.getEngineByName("php-invocable");<br /><span style="color: #008080; ">37</span> <br /><span style="color: #008080; ">38</span>                 ByteArrayOutputStream log = <span style="color: #0000FF; ">new</span> ByteArrayOutputStream();<br /><span style="color: #008080; ">39</span> <br /><span style="color: #008080; ">40</span>                 <span style="color: #0000FF; ">try</span><br /><span style="color: #008080; ">41</span>                 {<br /><span style="color: #008080; ">42</span>                         engine.put("phpRootDir", "data/php");<br /><span style="color: #008080; ">43</span>                         engine.put("log", log);<br /><span style="color: #008080; ">44</span>                         engine.put("req", req);<br /><span style="color: #008080; ">45</span>                         engine.put("rep", rep);<br /><span style="color: #008080; ">46</span>                         FileReader reader = <span style="color: #0000FF; ">new</span> FileReader("data/php/gate.php");<br /><span style="color: #008080; ">47</span>                         engine.eval(reader);<br /><span style="color: #008080; ">48</span>                         System.out.println("CallPhp.call phpLog=" + log.toString());<br /><span style="color: #008080; ">49</span>                 }<br /><span style="color: #008080; ">50</span>                 <span style="color: #0000FF; ">catch</span>(Exception e)<br /><span style="color: #008080; ">51</span>                 {<br /><span style="color: #008080; ">52</span>                         System.out.println("CallPhp.call phpLog=" + log.toString());<br /><span style="color: #008080; ">53</span>                         <span style="color: #0000FF; ">throw</span> e;<br /><span style="color: #008080; ">54</span>                 }<br /><span style="color: #008080; ">55</span>         }<br /><span style="color: #008080; ">56</span> }<br /><span style="color: #008080; ">57</span> <br /><span style="color: #008080; ">58</span> <span style="color: #0000FF; ">class</span> Request<br /><span style="color: #008080; ">59</span> {<br /><span style="color: #008080; ">60</span>         <span style="color: #0000FF; ">public</span> Request(<span style="color: #0000FF; ">int</span> id)<br /><span style="color: #008080; ">61</span>         {<br /><span style="color: #008080; ">62</span>                 <span style="color: #0000FF; ">this</span>.id = id;<br /><span style="color: #008080; ">63</span>         }<br /><span style="color: #008080; ">64</span>         <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">int</span> id;<br /><span style="color: #008080; ">65</span> }<br /><span style="color: #008080; ">66</span> <br /><span style="color: #008080; ">67</span> <span style="color: #0000FF; ">class</span> Response<br /><span style="color: #008080; ">68</span> {<br /><span style="color: #008080; ">69</span>         <span style="color: #0000FF; ">public</span> String message;<br /><span style="color: #008080; ">70</span> }</div><p>java-bin/data/php/gate.php<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <?php<br /><span style="color: #008080; "> 2</span> <br /><span style="color: #008080; "> 3</span> <span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br /></span><span style="color: #008080; "> 4</span> <span style="color: #008000; "> *<br /></span><span style="color: #008080; "> 5</span> <span style="color: #008000; "> * 脚本l一入口<br /></span><span style="color: #008080; "> 6</span> <span style="color: #008000; "> * @author sheppard(ysf1026@gmail.com) 2013-01-18<br /></span><span style="color: #008080; "> 7</span> <span style="color: #008000; "> *<br /></span><span style="color: #008080; "> 8</span> <span style="color: #008000; "> </span><span style="color: #008000; ">*/</span><br /><span style="color: #008080; "> 9</span> <br /><span style="color: #008080; ">10</span> <span style="color: #008080; ">define</span>('PHP_ROOT_DIR', java_context()->get('phpRootDir'));<br /><span style="color: #008080; ">11</span> <span style="color: #800080; ">$log</span> = java_context()->get('log');<br /><span style="color: #008080; ">12</span> <span style="color: #800080; ">$log</span>->write("\n\tjava give phpRootDir is " . PHP_ROOT_DIR);<br /><span style="color: #008080; ">13</span> <br /><span style="color: #008080; ">14</span> <span style="color: #0000FF; ">require_once</span>(PHP_ROOT_DIR . '/function.php');<br /><span style="color: #008080; ">15</span> <br /><span style="color: #008080; ">16</span> <span style="color: #800080; ">$log</span>->write(getDoomsday());<br /><span style="color: #008080; ">17</span> <br /><span style="color: #008080; ">18</span> <span style="color: #800080; ">$rep</span> = java_context()->get('rep');<br /><span style="color: #008080; ">19</span> <span style="color: #800080; ">$rep</span>->message = handle(java_context()->get('req'), <span style="color: #800080; ">$log</span>);<br /><span style="color: #008080; ">20</span> <br /><span style="color: #008080; ">21</span> ?></div><p> </p><p>java-bin/data/php/function.php<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <?php<br /><span style="color: #008080; "> 2</span> <br /><span style="color: #008080; "> 3</span> <span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br /></span><span style="color: #008080; "> 4</span> <span style="color: #008000; "> *<br /></span><span style="color: #008080; "> 5</span> <span style="color: #008000; "> * 具体功能举例<br /></span><span style="color: #008080; "> 6</span> <span style="color: #008000; "> * @author sheppard(ysf1026@gmail.com) 2013-01-18<br /></span><span style="color: #008080; "> 7</span> <span style="color: #008000; "> *<br /></span><span style="color: #008080; "> 8</span> <span style="color: #008000; "> </span><span style="color: #008000; ">*/</span><br /><span style="color: #008080; "> 9</span> <br /><span style="color: #008080; ">10</span> <span style="color: #0000FF; ">function</span> getDoomsday()<br /><span style="color: #008080; ">11</span> {<br /><span style="color: #008080; ">12</span>         <span style="color: #0000FF; ">return</span> "\n\tdoomsday is 20121221";      <br /><span style="color: #008080; ">13</span> }<br /><span style="color: #008080; ">14</span> <br /><span style="color: #008080; ">15</span> <span style="color: #0000FF; ">function</span> handle(<span style="color: #800080; ">$req</span>, <span style="color: #800080; ">$log</span>)<br /><span style="color: #008080; ">16</span> {<br /><span style="color: #008080; ">17</span>         <span style="color: #800080; ">$id</span> = <span style="color: #800080; ">$req</span>->id;<br /><span style="color: #008080; ">18</span>         <span style="color: #800080; ">$log</span>->write("\n\tfunction.php handle id=$id");<br /><span style="color: #008080; ">19</span>         <span style="color: #0000FF; ">if</span>('1104' == <span style="color: #800080; ">$id</span>)<br /><span style="color: #008080; ">20</span>                 <span style="color: #0000FF; ">return</span> 'guess?';<br /><span style="color: #008080; ">21</span>         <span style="color: #0000FF; ">else</span> <span style="color: #0000FF; ">if</span>('531' == <span style="color: #800080; ">$id</span>)<br /><span style="color: #008080; ">22</span>                 <span style="color: #0000FF; ">return</span> 'score';<br /><span style="color: #008080; ">23</span>         <span style="color: #0000FF; ">else</span> <span style="color: #0000FF; ">if</span>('1221' == <span style="color: #800080; ">$id</span>)<br /><span style="color: #008080; ">24</span>                 <span style="color: #0000FF; ">return</span> 'maybe doomsday';<br /><span style="color: #008080; ">25</span>         <span style="color: #0000FF; ">else</span><br /><span style="color: #008080; ">26</span>                 <span style="color: #0000FF; ">return</span> '404 not found';<br /><span style="color: #008080; ">27</span> }<br /><span style="color: #008080; ">28</span> <br /><span style="color: #008080; ">29</span> ?></div><p> </p><p>output<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> CallPhp.call phpLog=<br /><span style="color: #008080; "> 2</span> java give phpRootDir is data/php<br /><span style="color: #008080; "> 3</span> doomsday is 20121221<br /><span style="color: #008080; "> 4</span> <span style="color: #0000FF; ">function</span>.php handle id=1104<br /><span style="color: #008080; "> 5</span> CallPhp.test, id=1104 message=guess?<br /><span style="color: #008080; "> 6</span> CallPhp.call phpLog=<br /><span style="color: #008080; "> 7</span> java give phpRootDir is data/php<br /><span style="color: #008080; "> 8</span> doomsday is 20121221<br /><span style="color: #008080; "> 9</span> <span style="color: #0000FF; ">function</span>.php handle id=531<br /><span style="color: #008080; ">10</span> CallPhp.test, id=531 message=score<br /><span style="color: #008080; ">11</span> CallPhp.call phpLog=<br /><span style="color: #008080; ">12</span> java give phpRootDir is data/php<br /><span style="color: #008080; ">13</span> doomsday is 20121221<br /><span style="color: #008080; ">14</span> <span style="color: #0000FF; ">function</span>.php handle id=1221<br /><span style="color: #008080; ">15</span> CallPhp.test, id=1221 message=maybe doomsday<br /><span style="color: #008080; ">16</span> CallPhp.call phpLog=<br /><span style="color: #008080; ">17</span> java give phpRootDir is data/php<br /><span style="color: #008080; ">18</span> doomsday is 20121221<br /><span style="color: #008080; ">19</span> <span style="color: #0000FF; ">function</span>.php handle id=110<br /><span style="color: #008080; ">20</span> CallPhp.test, id=110 message=404 not found</div><br /><p> </p><p>Q二Q注意事?/p> <p>1. ׃是java调用的phpQ所以php里当前工作\径变成了java的?/p> <p>2. FileReader加蝲*.php文g之后ScriptEngine.evel(FileReader)的耗时大概?30+msQStringReader时ؓ180+msQ速度都不咋滴Q但是这不是我们目急着考虑的问题,之前的http方式也好不到哪去Q优化留C后再说?/p> <p>3. php的解释器q行路径配置Q?Dphp.java.bridge.php_exec=?/p> <p> </p> <p>三、相兌?/p> <p>1. 官网Q?a data_ue_src="http://php-java-bridge.sourceforge.net/pjb/">http://php-java-bridge.sourceforge.net/pjb/</a></p> <p>2. W合java调脚本标准的调phpCZQ?a data_ue_src="http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=PhpThreads.java">http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=PhpThreads.java<br /><br /><br /></a>psQ?013q??8日我在CU的博?/p><p> </p><p> </p><p> </p><p> </p><img src ="http://www.shnenglu.com/yangsf5/aggbug/199230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-04-08 18:20 <a href="http://www.shnenglu.com/yangsf5/archive/2013/04/08/199230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>redis调研http://www.shnenglu.com/yangsf5/archive/2013/04/08/199228.htmlSheppard YSheppard YMon, 08 Apr 2013 10:09:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/04/08/199228.htmlhttp://www.shnenglu.com/yangsf5/comments/199228.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/04/08/199228.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/199228.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/199228.html
2016-07-06 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>


一、优?/p>

Q一Q相对于其他k-v数据库的优势

1. 包含复杂数据cdQ例如Strings\Lists\Hashes\Sets\Sorted sets{?/p>

    q些复杂数据cd的操作提供了原子操作Q不用考虑锁?/p>

2. 内存中运行;可以持久化?/p>

3. 相关|站Q?/p>

http://redis.io/

http://www.slideshare.net/hitkidnil/memcached-vs-redis

http://www.itlearner.com/article/4890

http://timyang.net/data/redis-misunderstanding/

http://stackoverflow.com/questions/2873249/is-memcached-a-dinosaur-in-comparison-to-redis

 

二、缺?/p>

    官方不支持windows版,有非官方的。这个不是太大问题?/p>

 

三、性能

1. 内存数据库,性能非常高?/p>

2. 与memcache的性能比较Qredis作者给的回{,数据的存储redis占优Q大?00k的memcache占优Q但ȝ来说Q一般项目用时都还不够D虑q里的瓶颈?/p>

 

四、用者及口碑

    暴雪、stackoverflow、github、flickr{等在用redis。业内口非常好?/p>

    http://redis.io/topics/whos-using-redis

 

五、结合我们项目?/p>

    ׃历史原因Q数据库我们先后使用了兄弟公司的k-v数据库,和之后的mysql?/p>

    换数据库Q是׃之前的k-v数据库只支持key-value对的存储Qvalue里以json串来存储。这L存储方式不支持单个字D늚更新以及高效的频J排序等功能法需求。而游戏编E很需要这些,所以花大气力I补以前决{的pQDB换成了mysql?/p>

    目架构也在调整Qphp通过handlersocket与mysqlq行交互Q之前的java只做单的同步Q没有db操作。现在ؓ了性能考虑Q在慢慢Ҏ玩家频繁交互的功能和部分别的新功能写在java。这样java必Mdb交互?/p>

    之前Z快速P代,java与mysql的交互,是java通过http来post存储h到phpQphp接到requestq卛_储。phpq边有老php写的逻辑更新了db字段Ӟ再post一个request到javaQjava做了个http serverQ,java更新自己的内存?/p>

    q样有两个问题?/p>

1. 所有与db的操作,cache的地方在handlersocketQ(据说有ƈ发写入性能问题——待进一步考证Q?/p>

2. php与java都要更新db数据Ӟ两个独立的http通道Q很诡异Q很低效?/p>

    现在有了redisQpub/sub很方便做cachepȝ?/p>

    一斚wphp与java怺通知数据更新Ӟ通过redis卛_。目前我们先应用急需的这块。当前项目php里用memcache做交互时存储以及部分用于加锁的逻辑可以考虑用redis慢慢取代?/p>

    另一斚wQ以后可以很方便的用redis做我们应用程序与mysql的cache?br />

psQ?012q?2?0日我在CU的博?/p>

Sheppard Y 2013-04-08 18:09 发表评论
]]>|络通信序列化协议的选择http://www.shnenglu.com/yangsf5/archive/2013/04/08/199223.htmlSheppard YSheppard YMon, 08 Apr 2013 09:56:00 GMThttp://www.shnenglu.com/yangsf5/archive/2013/04/08/199223.htmlhttp://www.shnenglu.com/yangsf5/comments/199223.htmlhttp://www.shnenglu.com/yangsf5/archive/2013/04/08/199223.html#Feedback0http://www.shnenglu.com/yangsf5/comments/commentRss/199223.htmlhttp://www.shnenglu.com/yangsf5/services/trackbacks/199223.html
2016-07-03 日更?nbsp;
此篇博客已经q移到新博客Qƈ做行文检查和优化排版Q?/span>
http://blog.clawz.me/2012/09/21/12-chose-protobuf/

 



一、背景介l?/p>

    ׃历史原因Q用了兄弟公司的框ӞD之前的通信序列化协议强制用的JSON。我们项目ؓ一个web目Q前端asQ后端php+javaQ一开始只有as与php短连接,后来Z一些逻辑的实时消息,加了java来另作的长连接?/p>

    as与php都是q型的语言Q用JSON来序列化Q网l通信逻辑可以写的很随意,q导致我们现在查问题非常手。另外JSON也浪费了些流量。现在项目在扩展手机前端Q对量的要求更苛刻。ؓ了新老问题的选择Q我们就要换掉JSON?/p>

 

二、序列化协议选择的考虑

    手机前端使用C++写的逻辑Q我们协议的要求语言、跨q_、体U小、序列化和反序列化快?/p>

    可供选择的协议有protobuf/thrift/messagepack{?/p>

1. thrift的学习成本貌似比protobuf高些Q另外先看的protobufQ感觉两U协议差不多Q就懒的l箋研究thrift了?/p>

2. protobuf和messagepack的取舍:

    两种皆是开源项目?/p>

Q?Qprotobuf是googleL的,已经被google自己和业内大规模使用了,证明是可靠的Q而messagepack貌似出来的比较晚Q还没被大规模用?/p>

Q?Q语a支持Qprotobuf官方原生支持C++、Java、pythonQ其他均为第三方扩展Qmessagepack官方支持C++、Java、phpQ不支持asQ但支持js?/p>

Q?Qprotobuf有个~译器可以自动生成各语言对应版本的协议类Qmessagepack在强cd如java和C++里就需要自己写各个语言版本的了?/p>

Q?Q体U方面,messagepack的体U应该比protobufE大?/p>

Q?Q速度斚wQmessagepack官方说速度是protobuf?倍,但是看他的测试只是一U语a的序列化试?/p>

Q?Q其他,messagepack也支持key-value方式的序列化Q号UCU小的JSON。这虽很ҎUL以前的协议,Z快速出demoQ我也都准备用messagepack先期试改了,但是猛然发现每个语言q是得写各自的,而且现在涉及CU不同前端,一D늚修改q需及时通知另一前端做相应修攏V这U太难控制了Q没有protobuf的proto文g那种的一致性保证?/p>

 

三、最l选择

    l合以上的比较,最后选择了protobuf来作为我们项目新的网l通信序列化协议?br />
psQ?012q??1日我在CU上的博文



Sheppard Y 2013-04-08 17:56 发表评论
]]> ޹Ʒþþ| žžƷ99þþ㽶| ˺ݺۺϾþ88| þˬˬAV| AŮAVۺϾþþ| žžþþƷ| 99þۺϹƷ| 99þþƷһѿ| 91ɫۺϾþѷ| Ʒþһ| 99þ99ֻѵľƷ| ƷҹþøƬ| þۺϺݺɫۺ| 㽶97þ| þþƷƷƾ| ĻӰӾþþѹۿ| þһѵ | һɫþ88ۺպƷ | ݹƷþ| ƷžžþƵ | ëƬþþþþùëƬ | þ99ƷСѼ| 99þһa| 91ƷѾþþþþþþ| þƵ| ޾Ʒþ| ƷѾþþþõӰ| þþ뾫Ʒҹ| þþƷAV鶹վ | þþƷվ| ձvaĻþ| ˾þô߽ۺĻ| ŷպþþƷ| AVݺɫۺϾþ| һ97ձ˾þۺӰԺ| þ66͵Ʒ9| þþƵ| ˾þô߽槼| þþþþùƷŮ| ˾þۺ2020| þþƷ}Ů|