阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

阿列克谢·奈德诺夫,首席执行官 ITooLabs,讲述了用Go(Golang)编程语言为电信运营商开发电信平台。 Alexey还分享了他在亚洲最大的电信运营商之一部署和运营该平台的经验,该运营商使用该平台提供语音邮件(VoiceMail)和虚拟PBX(Cloud PBX)服务。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

阿列克谢·奈德诺夫(Alexey Naydenov)(以下简称“AN”): - 大家好! 我叫阿列克谢·奈德诺夫。 我是 ITooLabs 的总监。 首先,我想回答一下我在这里做什么以及我是如何来到这里的。

如果您查看 Bitrix24 市场(“电话”部分),那么那里有 14 个应用程序和 36 个应用程序 (40%) 是我们:

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

更准确地说,这些是我们的合作伙伴运营商,但这一切的背后是我们的平台(平台即服务)——我们花一点钱卖给他们。 其实我想谈谈这个平台的发展以及我们是如何来到Go的。

现在我们平台的人数是:

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

44 家合作运营商,包括 MegaFon。 一般来说,我们喜欢冒险,实际上我们在俄罗斯拥有 100 家运营商的 44 亿用户。 因此,如果有人有一些商业想法,我们总是很乐意倾听他们的意见。

  • 5000家用户企业。
  • 共有 20 名订阅者。 这都是 B000B——我们只与公司合作。
  • 白天每分钟 300 个呼叫。
  • 去年通话时间达到 100 亿分钟(我们庆祝了)。 这没有考虑我们平台上的内部谈判。

它是如何开始的?

合适的人如何开始创建自己的平台? 还应该考虑到,我们有“硬核企业”的发展历史,甚至是在一年中最准确的企业时间! 当你走到客户面前并说:“我们需要更多服务器时,那是一段快乐的时光。” 顾客:“是的,毫无疑问! 我们的架子上有十个。

所以我们使用了 Oracle、Java、WebSphere、Db2 等等。 因此,我们当然采用了最好的供应商解决方案,将它们集成并尝试利用它来起飞。 他们自己玩。 这将是一个内部启动。

这一切都要从2009年开始。 自 2006 年以来,我们一直以某种方式密切参与运营商的决策。 我们制作了几个定制的虚拟 PBX(就像我们现在订购的那样):我们看了看,认为它很好,并决定发起内部启动。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

以VMWare为例。 由于我们是自己走,所以我们不得不立即放弃酷炫的供应商存储。 我们都知道:承诺应该除以3,成本应该乘以10。因此,我们做了DirDB等等。

然后它开始生长。 由于平台无法再应对,因此添加了计费服务。 然后计费服务器从 MySQL 迁移到 Mongo。 结果,我们得到了一个有效的解决方案,可以处理所有到达那里的调用:

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

但在内部的某个地方,同一个供应商的产品正在旋转——我们曾经使用过的主要核心产品。 大约到 2011 年底,我们自己意识到,我们的主要瓶颈当然是这个特定的产品 - 我们会遇到它。 我们看到前面有一堵墙,随着顾客的走动,我们全速冲向墙。
因此,我们必须做点什么。 当然,我们对各种产品进行了大量研究——包括开源产品和供应商产品。 我现在不会详述这一点——这不是重点。 我们想到的最后一个退路是创建我们自己的平台。

最终,我们做出了这个选择。 为什么? 因为所有供应商和开源产品都是为了解决 10 年前的问题而设计的。 好吧,如果是10岁,还有更多! 选择对我们来说已经变得显而易见:要么放弃理想服务(为合作伙伴、运营商和我们自己)的伟大想法,要么做一些我们自己的事情。

我们决定做一些不同的事情!

平台要求

如果你做了一件事情很长时间(你利用别人的产品),那么这个想法就会慢慢地在你的脑海中形成:我自己该怎么做? 由于我们在公司都是程序员(除了卖家,没有非程序员),所以我们的需求已经形成很长时间了,而且很明确:

  1. 发展速度高。 供应商的产品折磨了我们,一开始就不适合我们,因为一切都需要很长时间才能解决。 我们想要快——我们有很多想法! 我们仍然有很多想法,但想法清单看起来像是提前了十年。 现在只剩一年了。
  2. 最大限度地利用多芯铁。 这对我们来说也很重要,因为我们看到只会有越来越多的核心。
  3. 高可靠性。 那个我们也哭过的。
  4. 高容错性。
  5. 我们希望以每日发布流程结束。 为此,我们需要选择语言。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

因此,从我们为自己提出的产品需求来看,对语言的需求以清晰的逻辑方式增长。

  1. 如果我们想要支持多核系统,那么我们需要支持并行执行。
  2. 如果我们需要开发速度,我们就需要一种支持竞争性开发、竞争性编程的语言。 如果有人没有遇到过差异,那么它非常简单:
    • 并行编程是关于两个不同的线程如何在不同的内核上运行;
    • 并发执行,更具体地说是并发支持,是关于语言(或运行时,等等)如何帮助隐藏并行执行带来的所有复杂性。
  3. 稳定性高。 显然,我们需要一个集群,它比我们在供应商产品上拥有的集群更好。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

如果你还记得的话,我们实际上没有太多选择。 首先,Erlang——我们喜欢它并且知道它,它是我个人的最爱。 其次,Java甚至不是Java,而是特指Scala。 第三,当时我们根本不懂的语言——Go。 当时它刚刚出现,更准确地说,已经存在了两年左右,但还没有发布。

击败Go!

围棋的历史

我们在上面做了一个平台。 我会尝试解释原因。

Go 简史。 2007年开始,2009年开通,2012年发布第一个版本(也就是说,我们在第一个版本发布之前就开始工作了)。 发起者是 Google,我怀疑它想要取代 Java。

作者非常有名:

  • Ken Thomson,Unix 的创始人,发明了 UTF-8,参与了 Plan 9 系统的开发;
  • Rob Pike 与 Ken 一起设计了 UTF-8,还在贝尔实验室参与了 Plan 9、Inferno、Limbo 的工作;
  • Robert Gizmer,我们因发明 Java HotSpot 编译器和开发 V8(Google 的 Javascript 解释器)生成器而认识并喜爱他;
  • 还有超过 700 名贡献者,包括我们的一些补丁。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

走过去一看

我们看到语言或多或少是简单易懂的。 我们有明显的类型:在某些情况下需要声明它们,而在其他情况下则不需要(意味着无论如何都会推断出类型)。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

可见,描述结构已成为一种时尚。 可见我们有了指针的概念(星号所在的地方)。 可以看出,对声明数组和关联数组的初始化有特殊的支持。

大致可以理解——你可以活下去。 尝试写你好,世界:

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

我们看到了什么? 这是类似 C 的语法,分号是可选的。 它可以是两行的分隔符,但前提是这两个结构完全位于同一行。

我们看到控制结构中的括号(第 14 行)是可选的,但大括号始终是必需的。 我们看到打字是静态的。 大多数情况下都会显示 Tim。 这个例子比通常的Hello, world稍微复杂一些——只是为了表明有一个库。

我们还看到什么重要的事情? 代码被组织成包。 为了在您自己的代码中使用该包,您需要使用 import 指令导入它 - 这也很重要。 我们开始——它有效。 伟大的!

让我们尝试一些更复杂的东西:Hello, world, 但现在它是一个 http 服务器。 我们在这里看到什么有趣的事情?

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

首先,函数充当参数。 这意味着我们拥有的函数是“一等公民”,您可以用函数式风格用它做很多有趣的事情。 接下来我们会看到意想不到的情况:导入指令直接引用 GitHub 存储库。 没错,就是这样——而且,更应该这样。

在 Go 中,包的通用标识符是其存储库的 url。 有一个特殊的 Goget 实用程序,可以处理所有依赖项、下载它们、安装它们、编译它们,并在必要时准备它们以供使用。 同时,Goget 了解 html-meta。 因此,您可以保留一个 http 目录,其中包含指向您的特定存储库的链接(例如我们所做的)。

我们还看到什么? 常规库中的Http和Json。 显然,有内省-反射,应该在encoding/json中使用它,因为我们只是用一些任意对象来代替它。

我们运行它,看到有 20 行有用的代码,它们可以编译、运行并给出机器(在运行它的机器上)的当前平均负载。
从这里我们可以立即看到还有什么重要的事情? 它编译成一个静态二进制文件(buinary)。 这个二进制文件根本没有依赖项,没有库! 它可以复制到任何系统,立即运行,并且可以正常工作。

我们继续前进。

Go:方法和接口

Go 有方法。 您可以为任何自定义类型声明方法。 而且,这不一定是一个结构体,而可能是某种类型的别名。 您可以为 N32 声明一个别名并为其编写方法来执行一些有用的操作。

这就是我们第一次陷入昏迷的地方……事实证明,Go 没有这样的类。 了解Go的人可能会说有类型包含,但这是完全不同的。 开发人员越早停止将其视为继承越好。 Go 中没有类,也没有继承。

问题! 以谷歌为首的作家公司给了我们什么来展示世界的复杂性? 我们已经获得了接口!

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

接口是一种特殊类型,允许您编写简单的方法、方法签名。 此外,存在(执行)这些方法的任何类型都将对应于该接口。 这意味着您可以简单地为一种类型编写相应的函数,为另一种类型(对应于该接口类型)编写相应的函数。 接下来,声明该接口类型的变量并将这些对象中的任何一个分配给它。

对于铁杆粉丝来说,我可以说这个变量实际上包含两个指针:一个指向数据,另一个指向特定于该特定类型的特殊描述符表,指向该类型的接口。 也就是说,编译器在链接时制作这样的描述符表。

当然,Go 中也有指向 void 的指针。 单词interface{}(带有两个大括号)是一个变量,原则上允许您指向任何对象。
到目前为止,一切都井然有序,一切都很熟悉。 没什么奇怪的。

Go:goroutine

现在我们来谈谈我们感兴趣的:轻量级进程——Go 术语中的 goroutine(协程)。

阿列克谢·奈德诺夫。 ITooLabs。 Go(Golang)手机平台的开发案例。 第1部分

  1. 首先,它们非常轻量(小于 2 Kb)。
  2. 其次,创建这样一个 goroutine 的成本可以忽略不计:你可以每秒创建一千个 goroutine - 什么也不会发生。
  3. 它们由自己的调度程序提供服务,该调度程序只是将控制权从一个 Goroutine 转移到另一个 Goroutine。
  4. 在这种情况下,控制权在以下情况下转移:
    • 如果遇到 go 语句(如果 goroutine 启动下一个 goroutine);
    • 是否启用了阻塞输入/输出调用;
    • 是否触发垃圾收集;
    • 如果开始一些通道操作。

也就是说,每当 Go 程序在计算机上运行时,它都会检测系统中的核心数量,并根据需要启动尽可能多的线程(系统中有多少个核心,或者您告诉它多少个)。 因此,调度程序将在每个核心中的所有这些操作系统线程上运行这些轻量级执行线程。

应该指出的是,这是利用铁最有效的方法。 除了我们已经展示的内容之外,我们还做了更多的事情。 例如,我们制造的 DPI 系统允许在一台设备中提供 40 GB 服务(取决于这些线路中发生的情况)。

甚至在 Go 之前,我们也出于这个原因使用了完全相同的方案:因为它允许您保存处理器缓存的局部性,显着减少操作系统上下文切换的次数(这也需要很长时间)。 我再说一遍:这是利用铁最有效的方法。

这个简单的 21 行示例是一个简单执行 echo-server 的示例。 同时请注意,serve 函数极其简单,它是线性的。 没有回调,无需费心和思考...您只需阅读和编写即可!

同时,如果您读取和写入,它实际上应该阻塞 - 这个 goroutine 只是简单地排队,并在再次可以执行时由调度程序获取。 也就是说,这个简单的代码可以充当本机操作系统允许的尽可能多连接的回显服务器。

很快就会继续...

一些广告🙂

感谢您与我们在一起。 你喜欢我们的文章吗? 想看更多有趣的内容? 通过下订单或推荐给朋友来支持我们, 面向开发人员的云 VPS,4.99 美元起, 我们为您发明的入门级服务器的独特模拟: VPS (KVM) E5-2697 v3(6 核)10​​4GB DDR480 1GB SSD 19Gbps XNUMX 美元或如何共享服务器的全部真相? (适用于 RAID1 和 RAID10,最多 24 个内核和最多 40GB DDR4)。

Dell R730xd 在阿姆斯特丹的 Equinix Tier IV 数据中心便宜 2 倍? 只有这里 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 电视低至 199 美元 在荷兰! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - 99 美元起! 阅读 如何建设基础设施公司同级使用价值730欧元的Dell R5xd E2650-4 v9000服务器一分钱?

来源: habr.com

添加评论