authors are vetted experts in their fields and write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Michael Truog
验证专家 在工程

Michael是分布式系统和容错专家,曾在AT工作过&T、E*Trade、诺基亚等.

Read More

Expertise

PREVIOUSLY AT

AT&T
Share

什么是遗产现代化?

遗留代码无处不在. 随着代码激增的速度继续呈指数增长, 越来越多的代码被降级为遗留代码. 在许多大型组织中, 遗留系统的维护消耗了90%以上的信息系统资源.

The need to modernize legacy code and systems to meet current performance and processing demands is widespread. 这篇文章提供了使用的案例研究 Erlang 编程语言,以及基于erlang的 CloudI 面向服务架构(SOA), 适应遗留代码——特别是, 一个有几十年历史的C源代码集-到21世纪.

在许多大型组织中, 遗留系统的维护消耗了90%以上的信息系统资源.

杀死源代码之龙

几年前,我是基于文本的多人在线游戏《欧博体育app下载》的忠实粉丝。MUDs). 但它们总是充斥着性能问题. I decided to dive back into a decades-old pile of C source code and see how we could modernize this legacy code and push these early online games to their limits. 在高层次上,这个项目是一个很好的例子 using Erlang 调整遗留软件以满足21世纪的需求.

简要总结:

  • The goal: Take an old 50-player-limited MUD video game and push its source code to support thousands upon thousands of simultaneous connections.
  • The problem遗留的、单线程的C源代码.
  • The solution: CloudI,一种基于erlang的服务,提供 容错性和可伸缩性.

现代化遗留软件:使用Erlang和CloudI的MUD编程

什么是基于文本的MUD?

所有大型多人在线角色扮演游戏(MMORPGs) – like World of Warcraft and EverQuest – have developed features whose early origins can be traced back to older text-based multiplayer online games known as Multi-User Dungeons (MUDs).

第一个MUD是Roy Trubshaw的Essex MUD(或 MUD1),它最初是在1978年使用DEC PDP-10上的MARO-10汇编语言开发的, 但被转化为BCPL, C语言的前身(一直运行到1987年). (正如你所看到的,这些东西比大多数程序员都要老.)

MUDs gradually gained popularity during the late 1980s and early 1990s with various MUD codebases written in C. 例如,DikuMUD代码库被认为是最大的代码库之一的根 trees 的派生MUD源代码, 至少有51个独特的变体,它们都基于相同的DikuMUD源代码. (在这段时间内, incidentally, MUDs became alternatively known as the “Multi-Undergraduate Destroyer” due to the number of college undergraduates that failed out of school due to their obsession with them.)

遗留mud的问题

Historical C MUD source code (including DikuMUD and its variants) is riddled with performance problems due to existing limitations at its time of creation.

缺少穿线

那时,还没有容易访问的线程库. 此外,线程化会使源代码更加难以维护和修改. 因此,这些mud都是单线程的.

每段代码都会减慢单个tick的处理速度. 如果任何计算强迫处理跨越 longer 比起一个tick, MUD滞后,影响每个连接的玩家.

During a single “tick” (an increment of the internal clock that tracks the progression of all game events), MUD源代码必须处理 every 游戏活动 every 连接套接字. 换句话说:每段代码都会减慢单个tick的处理速度. 如果任何计算迫使处理跨越超过一个刻度, the MUD lags, 影响每一个连接的玩家.

有了这种延迟,游戏的吸引力就会立刻降低. 玩家只能眼睁睁地看着自己的角色死去,而自己的命令却没有得到处理.

引入SillyMUD

对于这个遗留应用程序现代化实验的目的,我选择 SillyMUD, a historical derivative of DikuMUD that has influenced modern MMORPGs and the performance problems that they share. 在90年代, 我玩了一个从SillyMUD代码库派生出来的MUD, 所以我知道源代码将是一个有趣的和有点熟悉的起点.

我继承了什么??

The SillyMUD source code is similar to that of other historical C MUDs in that it is limited to roughly 50 concurrent players (64, to be precise, 基于源代码).

然而,我注意到由于性能原因,源代码被修改了.e.,以推动其并发玩家限制). Specifically:

  • 源代码缺少对连接IP地址的域名查找, 由于域名查找强制的延迟而缺席(通常, 旧的MUD想要一个域名查找,以便更容易地禁止恶意用户).
  • The source code had its “donate” command disabled (a bit unusual) due to the possible creation of long linked-lists of donated items which then required processing-intensive list traversals. 这反过来又会影响游戏的表现 all 其他玩家(记住,单线程)?).

引入CloudI

CloudI was 以前讨论的 作为多语言开发的解决方案,因为它提供了容错性和可伸缩性.

CloudI提供了一个服务抽象(以提供面向服务的体系结构)。SOA)) in Erlang, C/C++, Java, Python, and Ruby, 同时将软件故障隔离在CloudI框架内. 通过CloudI的Erlang实现提供了容错功能, 依赖于Erlang的容错特性及其实现 Actor Model. 这种容错是CloudI的Erlang实现的一个关键特性 所有软件都有bug.

CloudI also provides an application server to control the lifetime of service execution and the creation of service processes (either as operating system processes for non-Erlang programming languages or as Erlang processes for services implemented in Erlang) so that service execution occurs without external state impacting reliability. 欲了解更多,请参阅我的 previous post.

CloudI如何使遗留的基于文本的MUD现代化?

The historical C MUD source code provides an interesting opportunity for CloudI integration given its reliability problems:

  • 游戏服务器的稳定性直接影响到任何游戏机制的吸引力.
  • Focusing software development on fixing server stability bugs limits the size and scope of the resulting game.

与CloudI集成, 服务器稳定性错误仍然可以正常修复, but their impact is limited so that the game server’s operation is not always impacted when a previously undiscovered bug causes an internal game system to fail. This provides a great example of the use of Erlang to enforce fault-tolerance in a legacy codebase.

需要进行哪些更改?

The original codebase was written to be both single-threaded and highly dependent on global variables. My goal was to preserve the legacy source code functionality while modernizing it for present day usage.

With CloudI, I was able to keep the source code single-threaded while still providing socket connection scalability.

我的目标是保留遗留源代码的功能,同时使其适应现代使用.

让我们回顾一下必要的更改:

控制台输出

silymud控制台输出的缓冲(终端显示,通常与 Telnet)已经就位, but some direct file descriptor usage did require buffering (so that the console output could become the response to a CloudI service request).

套接字处理

套接字处理在原始源代码中依赖于 select() 检测输入的函数调用, errors, 以及产出的机会, 以及在处理悬而未决的游戏事件之前暂停250毫秒的游戏tick.

The CloudI SillyMUD integration relies on incoming service requests for input while pausing with the C CloudI API’s cloudi_poll 函数(在处理相同的未决游戏事件之前的250毫秒). The SillyMUD source code easily ran within CloudI as a CloudI service after being integrated with the C CloudI API (although CloudI同时提供C和c++ api,使用C API更好地促进了与sliymud的C源代码的集成)。.

Subscriptions

CloudI集成订阅了三种主要的服务名称模式来处理连接, disconnect, 以及游戏事件. 这些名称模式来自C CloudI API调用 subscribe 在集成的源代码. Accordingly, either WebSocket connections or Telnet connections have service name destinations for sending service requests when connections are established.

clouddi中的WebSocket和Telnet支持是由clouddi内部服务(cloudi_service_http_cowboy 用于WebSocket支持和 cloudi_service_tcp 用于Telnet支持). 因为内部CloudI服务是用Erlang编写的, 他们能够利用Erlang的极致可伸缩性, 同时使用CloudI 服务抽象 它提供了CloudI API函数.

Going forward

通过避免套接字处理,可以减少对套接字错误或类似情况的处理 link death (用户与服务器断开连接). 因此,删除低级套接字处理解决了主要的可伸缩性问题.

删除低级套接字处理解决了主要的可伸缩性问题.

但可扩展性问题依然存在. For example, MUD使用文件系统作为静态和动态游戏元素的本地数据库.e.,玩家和他们的进程,以及世界区域,对象和怪物)。. Refactoring the legacy code of the MUD to instead rely on a CloudI service for a database would provide further fault-tolerance. 如果我们使用数据库而不是文件系统, 多个SillyMUD CloudI服务进程可以作为独立的游戏服务器并发使用, 使用户与运行时错误隔离并减少停机时间.

MUD改进了多少?

与CloudI集成, the number of connections scaled by three orders of magnitude while providing fault-tolerance and increasing the efficiency of the same legacy gameplay.

有三个主要的改进领域:

  1. 容错. 与现代化的傻泥云服务集成, the isolation of socket errors and latency from the SillyMUD source code does provide a degree of fault tolerance.
  2. 连接的可伸缩性. With the use of internal CloudI services, the limitation on SillyMUD concurrent users can easily go from 64 (historically) to 16,384 users (with no latency problems!).
  3. 效率和表现. With the 连接处理 在CloudI中完成,而不是单线程的sliymud源代码, the efficiency of the SillyMUD gameplay source code is naturally improved and can handle a higher load.

So, 通过简单的CloudI集成, the number of connections scaled by three orders of magnitude while providing fault-tolerance and increasing the efficiency of the same legacy gameplay.

更大的图景

Erlang提供了99个.9999999%正常运行时间(小于31).(每年536毫秒的停机时间). 有了CloudI,我们将同样的可靠性带到其他编程语言和系统中.

Beyond proving the viability of this approach for improving stagnant legacy game server source code (SillyMUD was last modified over 20 years ago in 1993!), this project demonstrates on a broader level how Erlang and CloudI can be leveraged to modernize legacy applications and provide fault-tolerance, 提升的性能。, 以及总体上的高可用性. These results hold promising potential for adapting legacy code to the 21st century without requiring a major software overhaul.

聘请Toptal这方面的专家.
Hire Now
Michael Truog

Michael Truog

验证专家 在工程

西雅图,华盛顿州,美国

2016年4月4日成为会员

作者简介

Michael是分布式系统和容错专家,曾在AT工作过&T、E*Trade、诺基亚等.

Read More
authors are vetted experts in their fields and write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Expertise

PREVIOUSLY AT

AT&T

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® community.