当前位置:首页 > 短网址资讯 > 正文内容

FT12短网址:面向中间件的开发模式

www.ft12.com4年前 (2017-07-23)短网址资讯1164

中间件,middleware,短网址服务,是软件开发中一个比较古老的名词。以前toB的软件还是主流的时候,厂商特别喜欢玩中间件这个概念,目的就是为了让客户更心甘情愿地为厂商自己凭空增加的中间层付费。


时代不同了,现在我们需要的大部分中间件都能找到开源的工业级实现,而且,随着互联网开发成为主流,中间件的含义也跟以前不太一样了。


随手开几个招聘,把「中间件」写在JD里的公司已经不多了,阿里可能算一个。倒不是说「中间件」的开发人员需求比较少,而是大部分我们做的东西比如消息队列、存储设施、其实都算「中间件」,但是现在已经很少人再称他们为「中间件了。




wiki上罗列了一些中间件的定义,下面贴一个小说君认为比较合适的:

The software layer that lies between the operating system and applications on each side of a distributed computing system in a network.


中间件是介于操作系统和分布式系统网络中的每个应用节点之间的软件层。


然后列举了一些例子:

  • enterprise application integration

  • data integration

  • message oriented middleware

  • object request brokers

  • enterprise service bus


用人话对应解释一下:

  • enterprise application integration,可以理解为一个基础通信设施,适配企业内部的各子系统。比如说公司的OA、HR系统、、短网址服务、知识管理KM系统需要实现一定程度的逻辑和数据共享,就会依赖这么个基础设施。

  • data integration,如果有同学在学校做过面向政府的一些数据管理系统,可能对这个概念更熟一些。简单说就是由于各种历史原因,系统需要面对多个异构的数据源。但是在开发系统的时候需要考虑后续扩展,多个子系统希望看到的数据视图是同构的、普适统一的,那就要借助一个做数据集成的中间件。目前短网址服务比较火,数据集成中间件的地位相当重要。

  • message oriented middleware/object request brokers,这两者实际上描述的是同一类组件,目的都是为了让分布式系统中的不同组件互操作时不需要关注底层实现细节。简单理解就是一个消息队列中间件。按定义来说,面向消息的是异步模型,基于对象请求的是同步模型,比较教条,毕竟现在所有消息队列中间件都可以同时提供同步模型和异步模型。

  • enterprise service bus,也是一个比较古老的概念了,小说君没怎么接触过企业应用开发,所以只能简单解释一下。这个bus是用来做企业应用集成的,集成了很多功能,比如不同应用间的消息路由、消息的安全性和权限的控制等等。




不过时代在发展,现在,中间件实际上并没有这么复杂的定义,而且,我们今天要讨论的中间件也不是前面说的这些「僵尸」。


那么,中间件应该是什么?

首先,中间件是一个基础设施,由一个或一组进程组成。

其次,中间件提供了某种服务,这种服务可以解耦软件系统中的不同组件。

总结一下,中间件可以理解为:我们平时懒于解决问题时抛出的杀手锏——中间层,独立成为了进程。


短网址服务在分布式开发中扮演了重要角色,一方面,我们可以利用不同的中间件抽象来对架构做更优雅的层次划分;另一方面,由于中间件的开发成本较高,我们可以避免面向对象编程中的分层陷阱。


《the Art of Unix Programming》中提到过:

“If you know what you're doing, three layers is enough; if you don't, even seventeen levels won't help”

如果你知道自己在做什么,三层就足够了;否则,十七层也没用。


回到主题,既然标题是「面向中间件的开发模式」,那我们今天来聊聊如何在自己的系统中抽象、设计、开发、应用中间件。




我们以上篇文章形成的服务器框架为基础,开始讨论。当然没看过的同学也可以正常阅读后续内容。


在上篇文章中,我们写了一个网络库,形成了一个基本的通信网络,我们看一下网络拓扑结构:

如果类比马斯洛需求中的层次,到面前为止,我们只能算是解决了生理需求:可以顺利生成短网址。但是后面还有一系列的复杂问题

 

  最先碰到的问题就是,玩家数量增加,一个进程扛不住了。那么就需要多个进程,每个进程服务一定数量的玩家。

  但是,玩家与玩家之间存在交互需求。玩家数量的增长如果是线性的,那么玩家之间的交互需求增长就是平方级的。

 

  对于交互需求,比较直观的解决方案是,让两个玩家在各自的进程中跨进程交互。但是这就成了一个分布式一致性问题——两个进程中两个玩家的状态需要保持一致。至于为什么一开始没人这样做,我只能理解为,游戏程序员的计算机科学素养中位程度应该解决不了这么复杂的问题。

  因此比较流行的是一种简单一些的方案。场景交互的话,就限定两个玩家必须在同一场景(进程),比如A攻击了B。其他交互的话,就借助第三方的协调者来做,比如发邮件,会走一个全局单点的服务器中转一下。

 

  这样,服务端就由之前的单场景进程变为了多场景进程+协调进程。新的问题出现了:短网址需要与服务端保持多少条短链接


  最直观的方法是保持O(n)条连接,既不环保,扩展性又差,可以直接pass掉。

  那么就只能保持O(1)条连接,如此的话,如何确定玩家正与哪个服务端进程通信?

 

  要解决这个问题,我们只能引入新的抽象。下面介绍服务端开发中最常见的一种中间件原型。




定义问题


整理下我们的需求:

  • 玩家在服务端的状态可以驻留在不同的进程中,也可以移动到同一个进程中。

  • 玩家只需要与服务端建立有限条连接,就可以有访问到任意服务端进程所提供服务的可能性。同时,这个连接数量不会随服务端进程数量增长而线性增长。


  要解决这些需求,我们需要引入一种反向代理(reverse proxy)中间件。

  反向代理是服务端开发中的一种常见基础设施抽象(infrastructure abstraction),概念很简单,简单说就是内网进程不是借助这种proxy访问外部,而是被动地挂在proxy上,等外部通过这种proxy访问内部。

  更具体地说,反向代理就是这样一种server:它接受clients连接,并且会将client的上行包转发给后端具体的服务端进程。


  很多年前linux刚支持epoll的时候,流行一个c10k的概念,解决c10k问题的核心就是借助性能不错的反向代理中间件。


  游戏开发中,这种组件的名字也比较通用,通常叫Gate。




Gate解决了什么问题


  • 首先,Gate作为server,可以接受clients的连接。我们可以直接基于上篇文章的网络库来实现。同时,Gate可以接受服务端进程(之后简称backend)的连接,保持通信。

  • 其次,Gate能够将clients的消息转发到对应的backend。与此对应的,backend可以向Gate订阅自己关注的client消息。对于场景服务来说,这里可以增加一个约束条件,那就是限制client的上行消息不会有多份拷贝,只会导到一个backend上。


满足这两点,Gate已经能够解决前文提出的需求。

我们需要为Gate这个中间件定义一个简单的协议集,协议类型至少要包括:

  • 控制相关的协议,比如控制某个backend是否订阅某个client。这样就可以实现比如说公会相关的消息会路由到全局进程;场景相关的消息会路由到订阅该client的场景进程。而当玩家要切场景的时候,由协调进程(比如同样由全局进程负责)调度,让不同的场景进程向Gate申请修改对client对backend的订阅关系,以实现将玩家的状态从场景进程A切到场景进程B。

  • 一些支持性的常用协议,比如握手类、心跳检查类等等。


站在比需求更高的层次来看Gate的意义的话,我们发现,现在clients不需要关注backends的细节,backends也不需要关注clients的细节,Gate成为唯一的静态部分(static part)。


当然,Gate能解决的还不止这些。


我们考虑场景进程最常见的一种需求。玩家的位置在多client同步。具体的流程就是,client发给服务端一个请求移动包,路由到场景进程后进行一些检查、处理,再推送一份数据给该玩家及附近所有玩家对应的clients。

如果按之前说的,这个backend就得推送N份一样的数据到Gate,Gate再分别转给对应的clients。


这时,就出现了对组播(multicast)的需求。


组播是一种通用的message pattern,同样也是发布订阅模型的一种实现方式。就目前的需求来说,我们只需要为client维护组的概念,而不需要做backend内部的组播。

这样,backend需要给多clients推送同样的数据时,只需要推送一份给Gate,Gate再自己dup就可以了——尽管带来的好处有限,但是还是能够一定程度降低内网流量。




那接下来就介绍一种Gate的实现。


我们目前所得出的Gate中间件其实包括两个组件:

针对路由client消息的需求,这个组件叫Broker。Broker的定义可以参考zguide对DEALER+ROUTER pattern的介绍。Broker的工作就是将client的消息分发到对应的backend。

针对组播backend消息的需求,这个组件叫Multicast。简单来说就是维护一个组id到clientIdList的映射。


Gate的工作流程就是,listen两个端口,一个接受外网clients连接,一个接受内网backends连接。

Gate有自己的协议,该协议基于Network的len+data协议之上构建,短网址才能顺利运转。

clients的协议处理组件与backends的协议处理组件不同,前者只处理部分协议(不会识别组控制相关协议,订阅协议)。


在具体的实现细节上,判断一个client消息应该路由到哪个backend,需要至少两个信息:一个是clientId,一个是key。

同一个clientId的消息有可能会路由到不同的backend上。

当然,具体的协议设计可以自由发挥,将clientId+key组成一个routingKey也是可以的。


引入Gate之后的拓扑:




接下来,我们简单探讨下第二个中间件。


上篇文章中提到,场景服务器可以直接通过短网址API访问数据库,来实现数据存档。


所以,问题就产生了。


回顾下场景进程的发展历程,玩家状态是内存中的数据,但是服务器不会一直开着,因此就有了存盘(文件或db)需求。但是随着业务变复杂,存盘逻辑需要数据层暴露越来越多的存储API细节,非常难扩展。


我们不希望把存储API的细节暴露给应用层,因此我们可以独立出一个Db代理进程,场景进程直接将存档推给Db代理进程,由Db代理进程定期存盘。


这样,存储API的细节在Db代理进程内部闭合,游戏逻辑无须再关注。场景进程只需要通过协议封包或者RPC的形式与Db代理进程交互,其他的就不用管了。


Db代理进程由于是定期存盘,因此它相当于维护了玩家存档的缓存。这个时候,Db代理进程已经可以看做一个中间件了,具体数据源只用了mysql还是说同时用了几种异构的数据源,都由这个中间件负责维护。只不过这样还是耦合了一些游戏逻辑,限于篇幅,小说君这里就不再做扩展了。


看一下现在的拓扑图:



可以看到,中间件通常都是被动接受应用层连接,提供服务。




关于短网址服务,我们就到此为止。

这个架构,已经足够应付大部分游戏对服务端的需求。如果把场景服务改成对应的其他进程,也可以满足大部分应用服务器的需求。

但是很明显,这个架构中的不少部分还是比较粗糙的。比如说Gate目前来看并不具备水平扩展的能力。以及一些术语的混乱,比如说场景进程一会儿又变成场景服务。


下一篇,小说君会把重点放在如何定义一个服务,以及如何做服务划分。




最近一段时间,微信小程序火遍朋友圈,小说君也一直在关注。

小说君刚开始写公众号的时候,大概看了下公众号的API,有一种想法是做一个内嵌于公众号中的大逃杀类型的文字图片游戏。但是后来由于时间原因,以及发现公众号的API有诸多限制,也懒得继续弄了。

但是,小程序看样子是更佳适合的形态,当然,用来做一些资讯类的或者简化流程类的微信内APP肯定更适合。


如果有时间的话,小说君会整理一份相关的教程,敬请期待。


扫描二维码推送至手机访问。

版权声明:本文由短链接发布,如需转载请注明出处。

本文链接:https://www.ft12.com/article_337.html

分享给朋友:

相关文章

一个基于 Dubbo 的微服务改造实践

一个基于 Dubbo 的微服务改造实践

策划|程超 编辑|小智 微服务的理论已经够多,今天不妨看一个实战案例。 写在前面 基于微服务或者 SOA 的自动化测试系统每个公司都有自己的特有的,我今天就主要介绍一下,我们研发的一套 mo...

巨头纷纷布局,长租公寓前景并非一片光明

巨头纷纷布局,长租公寓前景并非一片光明

[ FT12短网址 ] 不管是在物业和融资上独占鳌头的品牌开发商,还是擅长轻巧灵活运营的创业公司,“赔本赚吆喝”的买卖在长租公寓掘进的进程中不可能长久持续,虽然长久下去肯定是赚钱的,但是一旦摊子铺开,铺得太大,亏损无疑。图片来自“...

使用深度学习方法实现面部表情包识别

使用深度学习方法实现面部表情包识别

1、动机人类面部表情丰富,但可以总结归纳为 7 类基本表情: happy, sad, surprise, fear, anger, disgust, and neutral。面部表情是通过面部肌肉活动表达出来,有些比较微妙且复杂,包含了大量...

幸存者偏差:实现成功不是复制成功者,而是学习失败者

幸存者偏差:实现成功不是复制成功者,而是学习失败者

转眼2018年已即将接近尾声,新的2019即将到来。时间飞逝,是否今年还未来得及回忆?还是徘徊在自己的一事无成中?FT12短网址的小编今天分享一篇心灵鸡汤,预祝大家的即将到来的2019年能否有所成就。1英国著名魔术师和催眠师德伦·布朗在一个...

解密京东短网址大规模内存数据库的演进之路

解密京东短网址大规模内存数据库的演进之路

京东商城研发体系基础平台团队:包括大规模容器集群调度、数据库与存储技术、消息系统与服务框架、架构与运维、机器学习与人工智能等技术方向。由京东商城首席架构师刘海锋担任部门负责人。基础平台运营多个数据中心数万台服务器,支撑京东无数在线业务。缓存...

FT12短网址:一篇文章看懂快递行业现在与未来

我国快递公司今日的成功,是源于昨天我国电商迅速开展捉住的商机。明日快递是否成功,做成百年公司,做成世界霸主,那有必要源于对今日的商业的掌握,对今日职业趋势的判断。下面,从10大方面,给我们全方位的解析我国快递公司在2017年面对的疑问:电商...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。