本文概述
- 什么是旧式现代化?
- 杀死源代码龙
- 什么是基于文本的MUD?
- 旧版MUD的问题
- 介绍SillyMUD
- CloudI简介
- CloudI如何使基于文本的旧版MUD现代化?
- 需要哪些更改?
- 向前走
- MUD改善了多少?
- 总结
什么是旧式现代化?
旧版代码无处不在。随着代码的扩散速度呈指数级增长, 越来越多的代码被降级为遗留状态。在许多大型组织中, 旧系统的维护消耗了90%以上的信息系统资源。
现代化传统代码和系统以满足当前性能和处理需求的需求已广泛存在。这篇文章提供了使用Erlang编程语言和基于Erlang的CloudI Service Oriented Architecture(SOA)的案例研究, 以使遗留代码(尤其是数十年的C源代码集合)适应21世纪。 。
在许多大型组织中, 旧系统的维护消耗了90%以上的信息系统资源。
杀死源代码龙
几年前, 我非常喜欢基于文本的多人在线游戏, 称为多用户地下城(MUD)。但是他们总是充满性能问题。我决定重新探究已有数十年历史的C源代码, 并看看我们如何使这些旧代码现代化, 并将这些早期的在线游戏推向极限。从较高的角度来看, 该项目是使用Erlang调整旧版软件以满足21世纪需求的一个很好的例子。
简短摘要:
- 我们的目标是:开发一款拥有50个玩家限制的老式MUD视频游戏, 并推送其源代码以支持成千上万的同时连接。
- 问题:旧版单线程C源代码。
- 解决方案:CloudI, 一种基于Erlang的服务, 可提供容错和可伸缩性。
什么是基于文本的MUD?
所有大型多人在线角色扮演游戏(MMORPG)(如《魔兽世界》和EverQuest)都开发了功能, 其起源可以追溯到称为多用户龙与地下城(MUD)的较早的基于文本的多人在线游戏。
第一个MUD是Roy Trubshaw的Essex MUD(或MUD1), 它最初于1978年在DEC PDP-10上使用MARO-10汇编语言开发, 但后来转换为BCPL(C编程语言的前身), 并且一直运行到1987)。 (如你所见, 这些东西比大多数程序员都要老。)
MUD在1980年代末和1990年代初逐渐流行起来, 各种C语言编写的MUD代码库。例如, DikuMUD代码库被称为派生MUD源代码最大树之一的根, 至少有51种独特变体基于相同的DikuMUD源代码。 (顺便提一下, 在这个时间范围内, MUD被称为”多本科生驱逐舰”, 原因是由于迷恋大专生而无法从学校毕业的人数)。
旧版MUD的问题
由于创建时存在的局限性, 历史C MUD源代码(包括DikuMUD及其变体)充满了性能问题。
缺乏穿线
那时, 还没有易于访问的线程库。而且, 线程化将使源代码更加难以维护和修改。结果, 这些MUD都是单线程的。
每段代码都会减慢单个刻度的处理速度。而且, 如果有任何计算迫使处理跨度超过单个刻度, 则MUD会滞后, 从而影响每个连接的参与者。
在一个”滴答”中(跟踪所有游戏事件进程的内部时钟增量), MUD源代码必须为每个连接的套接字处理每个游戏事件。换句话说:每段代码都会减慢单个刻度的处理速度。而且, 如果有任何计算迫使处理跨度超过单个刻度, 则MUD会滞后, 从而影响每个连接的参与者。
有了这个滞后, 游戏立即变得不那么吸引人了。角色死亡时, 玩家会无助地注视着自己, 而自己的命令仍未处理。
介绍SillyMUD
出于此遗留应用程序现代化实验的目的, 我选择了DikuMUD的历史衍生产品SillyMUD, 它影响了现代MMORPG及其共享的性能问题。在1990年代, 我玩过一个源自SillyMUD代码库的MUD, 所以我知道源代码将是一个有趣且有点熟悉的起点。
我继承了什么?
SillyMUD源代码与其他历史C MUD的源代码相似, 因为它被限制为大约50个并发播放器(根据源代码, 确切地说是64个播放器)。
但是, 我注意到出于性能方面的原因(即为了限制其并发播放器的限制)已对源代码进行了修改。特别:
- 源代码缺少在连接IP地址上的域名查找, 这是由于域名查找所引起的延迟而导致的(通常, 较旧的MUD希望通过域名查找来更轻松地禁止恶意用户)。
- 由于可能创建捐赠项目的长链接列表, 因此源代码的”捐赠”命令被禁用(有点不寻常), 然后需要处理大量的列表遍历。这些反过来损害了所有其他玩家的游戏性能(单线程, 还记得吗?)。
CloudI简介
由于CloudI提供的容错性和可伸缩性, 以前曾讨论过将其作为多语言开发的解决方案。
CloudI以Erlang, C / C ++, Java, Python和Ruby提供服务抽象(以提供面向服务的体系结构(SOA)), 同时将软件故障隔离在CloudI框架内。容错是通过CloudI的Erlang实施提供的, 它依赖于Erlang的容错功能及其Actor模型的实施。这种容错性是CloudI Erlang实施的一项关键功能, 因为所有软件均包含错误。
CloudI还提供了一个应用程序服务器来控制服务执行的生命周期和服务进程的创建(作为非Erlang编程语言的操作系统进程或Erlang中实现的服务的Erlang进程), 以便在不影响外部状态的情况下进行服务执行可靠性。有关更多信息, 请参见我以前的文章。
CloudI如何使基于文本的旧版MUD现代化?
鉴于其可靠性问题, 历史悠久的C MUD源代码为CloudI集成提供了一个有趣的机会:
- 游戏服务器的稳定性直接影响任何游戏机制的吸引力。
- 将软件开发重点放在修复服务器稳定性错误上会限制所产生游戏的大小和范围。
通过CloudI集成, 服务器稳定性错误仍然可以正常修复, 但是它们的影响是有限的, 因此当以前未发现的错误导致内部游戏系统出现故障时, 游戏服务器的操作不会总是受到影响。这提供了一个很好的示例, 说明了如何使用Erlang在旧版代码库中实施容错功能。
需要哪些更改?
原始代码库被编写为单线程并且高度依赖全局变量。我的目标是保留旧的源代码功能, 同时对其进行现代化更新以用于当今的使用。
使用CloudI, 我能够保持源代码为单线程, 同时仍提供套接字连接可伸缩性。
我的目标是保留原有的源代码功能, 同时使其适应现代用途。
让我们查看必要的更改:
控制台输出
SillyMUD控制台输出(通常与Telnet连接的终端显示器)的缓冲已经到位, 但是某些直接文件描述符的使用确实需要缓冲(以便控制台输出可以成为对CloudI服务请求的响应)。
套接字处理
原始源代码中的套接字处理依赖于select()函数调用来检测输入, 错误和输出机会, 以及在处理未决的游戏事件之前暂停250毫秒的游戏滴答声。
CloudI SillyMUD集成依赖于传入的服务请求进行输入, 同时暂停C CloudI API的cloudi_poll函数(处理相同的未决游戏事件之前需要250毫秒)。与C CloudI API集成后, SillyMUD源代码可以很容易地在CloudI中作为CloudI服务运行(尽管CloudI提供了C和C ++ API, 使用C API可以更好地促进与SillyMUD的C源代码集成)。
订阅内容
CloudI集成预订了三种主要的服务名称模式, 以处理连接, 断开连接和游戏事件。这些名称模式来自C CloudI API调用, 该调用在集成源代码中进行订阅。因此, WebSocket连接或Telnet连接都具有服务名称目的地, 用于在建立连接时发送服务请求。
CloudI中的WebSocket和Telnet支持由内部CloudI服务提供(Cloudi_service_http_cowboy用于WebSocket支持, 而cloudi_service_tcp用于Telnet支持)。由于内部CloudI服务是用Erlang编写的, 因此它们能够利用Erlang的极高可扩展性, 同时使用提供CloudI API功能的CloudI服务抽象。
向前走
通过避免套接字处理, 在套接字错误或链路中断(用户与服务器断开连接)之类的情况下, 可以减少处理。因此, 删除底层套接字处理解决了主要的可伸缩性问题。
删除低级套接字处理解决了主要的可伸缩性问题。
但是可伸缩性问题仍然存在。例如, MUD将文件系统用作静态和动态游戏元素(即玩家及其进度以及世界区域, 对象和怪物)的本地数据库。重构MUD的旧代码以改为依赖CloudI服务访问数据库将提供进一步的容错能力。如果我们使用数据库而不是文件系统, 则可以同时使用多个SillyMUD CloudI服务进程作为单独的游戏服务器, 从而使用户与运行时错误保持隔离, 并减少停机时间。
MUD改善了多少?
借助CloudI集成, 连接数量可按三个数量级扩展, 同时提供容错能力并提高相同旧游戏的效率。
有三个主要方面的改进:
- 容错能力。借助现代化的SillyMUD CloudI服务集成, 将套接字错误和延迟与SillyMUD源代码隔离开来, 确实可以提供一定程度的容错能力。
- 连接可伸缩性。通过使用内部CloudI服务, 对SillyMUD并发用户的限制可以轻松地从64个(历史上)增加到16, 384个用户(没有延迟问题!)。
- 效率和性能。通过在CloudI而不是单线程SillyMUD源代码中完成连接处理, SillyMUD游戏性源代码的效率自然得到提高, 可以处理更高的负载。
因此, 通过简单的CloudI集成, 连接数量可按三个数量级扩展, 同时提供容错能力并提高相同传统游戏的效率。
总结
Erlang为生产系统提供了99.9999999%的正常运行时间(每年少于31.536毫秒的停机时间)。借助CloudI, 我们为其他编程语言和系统带来了相同的可靠性。
除了证明这种方法可以改善停滞的旧版游戏服务器源代码(SillyMUD于20年前于1993年进行了最后一次修改!)之外, 该项目还更广泛地展示了如何利用Erlang和CloudI来使旧版应用程序现代化并提供故障。容忍度, 提高的性能和总体上的高可用性。这些结果具有使遗留代码适应21世纪而无需进行重大软件改造的潜力。
评论前必须登录!
注册