蘭陵N梓記

一指流沙,程序年华


  • 首页

  • 归档

  • 关于

  • 搜索
close

为什么是Go

时间: 2016-07-23   |   分类: 技术     |   阅读: 3234 字 ~7分钟

HW的执行力就是强,推广Go也是雷力风行,几乎目前是全员皆Go。作为一名其中的参与者,也知目前Go若大规模应用还是有很多的不成熟,风险也非常大。那为什么我司还是选择Go?也来谈谈我个人对为什么选择Go的认识,仅是个人拙见,不代表我司官方的观点。

背景

Go语言主创人员之是C语言与Linux的发明人,所以Go的语法在C的基础之上取众家之精华:

  • 主要继承了C(func, struct,指针)
  • 包管理吸取自Java(package, import)
  • 多态吸取自Python与Ruby(duck type)
  • 并发吸取自Limbo(CSP模型)。

同时是一种多范式的编程语言,集众多编程范式之所长,并以自己独到的方式将它们融合在一起:

  • 面向过程(if,switch,for…)
  • 面向对象(部分支持):封装(struct),继承(匿名组合),多态(隐式Interface,即duck type)
  • 函数式(部分支持):闭包,函数作为参数(入参,返回值)

Go语言打的组合拳:

  • 简单易用 vs Python
  • 机器码性能 vs C/C++
  • 跨平台/标准库 vs Java
  • 并发模型(goroutine/channel)vs Erlang
  • 异步网络 vs Scala/Node.js
  • 动态反射 vs Java
  • 垃圾回收 vs Java

Go语言可能不是每一条都是No.1,但却是目前同时具备上述全部7点特性唯一语言,看似平衡中庸的组合拳往往威力强大。

而我司主要开发语言是C/C++,Java,Python,可以说是若应用Go语言具有广泛的群众基础,同时Go语言兼具他们各自的一些优点,在不同的场景下,能一定的范围内可以代替他们。并且我司的程序员大多较底级,Go语言的简洁与工程化能可能大大提升产品研发效率与降低维护成本。

云计算

我司原是一个设备制造厂商,而不是一个软件开发厂商。但是云计算已正快速改变原有的生态,当软件定义一切,尤其是云计算的全面渗透,计算资源统一X86化。即使传统的网络设备也将网络功能虚拟化(NFV)。NFV化是趋势,若拒绝将是失去未来;只有及时拥抱,才能不被抛弃。

虚拟化/容器化显著的特点:

  • 不再依赖于专用硬件,跨平台跨硬件混合部署:

    如传统的网卡直通,CPU绑定,内核零拷贝将在云计算下无法再发挥优势。而Go语言相比于C/C++天生跨平台,引入内置Runtime,通过它来隔离与不同的系统调用。这让程序迁移到不同的OS或CPU架构成本非常低,程序只需要重新在目标平台上编译而已。

  • 物理资源更细粒度的分割,提高整体资源利用率:

    Go语言相比于Java,在CPU、内存与磁盘大小占用方面相对比较低。尤其当前Docker等容器技术的兴起,细粒度的资源隔离。Go语言相比于Java动则上G的内存占用情况下,在资源上可能通过细粒度逻辑分割而达到充分灵活共享;而Go语言内置并发机制,并且Goroutine调度机制在设计上就充分考虑利用多核,让编写多核并发的程序变得更加的容易。

  • 快速上线开发与部署,缩短上线周期:

    Go语言设计的一个主要目的是降代程序员的心智负担,设计哲学是大道至简,所以一开始就在可读性、模块化、编译速度、适合大型团队(工程优化)和语法简洁上下足了功夫。Go语言相比于Java与C/C++,开发更简洁;内置丰富的标准库也能有效降低代码量。Go程序默认也是编译只是单个文件,减少了部署态的第三方依赖,这让应用上线部署非常容易。

  • 快速伸缩,故障隔离与自愈:

    Go语言相比于Java与Python,不需额外的运行环境,编译为一个独立的执行文件;相对于C/C++没有依赖动态库版本不一致的问题;Go语言程序相对于Java启动速度快,很适合于快速伸缩。而独立进程相比于Java中类Tomcat容器内多WebApp部署方式有更好的故障隔离;Go语言虽有异常(Panic),但可预知的错误建议采用error处理,引入了内置的error类型以及defer关键字来处理异常安全,这让程序员更容易写健壮的代码。

在云计算环境下,只要是适合的场景产品(Go目前还不适合要求低时延,高实时的场景),如在面向管理控制、网络并发等领域,采用Go语言开发,用来代替部分C/C++开发的系统应用;Java开发的网络或后端服务应用;Python开发的管理控制应用;可能极大提升产品的整体竞争力。

微服务

现在的应用程序规模越来越庞大,逻辑处理也是越来越复杂。在我司的电信领域,一个产品的研发也是动则几百号人的团队一起开发;系统上处理的数据规模,与接入的用户请求数也是几何级增加,在吞吐量、稳定性都会面临着极大的挑战;当前的业务尤其是面向移动终端用户的业务,需求变化快,业务不断推出与消亡,传统的单体架构根本无法适合频繁的变更,系统的可扩展性、定制性尤显得重要。当功能繁杂,结构混乱,以及人员变化等因素影响下,要解决这些问题,不得不在交付中不断地制定策略,演进架构:

随着云计算应用经验的不断积累,以及相关的工具链不断成熟,也伴随着微服务架构的出现。它通过将功能分解成多个独立的服务,以实现对解决方案或者复杂系统的解耦。微服务的诞生并非偶然:

  • 领域驱动设计指导我们如何分析并模型化复杂的业务;
  • 敏捷方法论帮助我们消除浪费,快速反馈;持续交付促使我们构建更快、更可靠、更频繁的软件部署和交付能力;
  • 虚拟化和基础设施自动化( Infrastructure As Code)则帮助我们简化环境的创建、安装;
  • DevOps文化的流行以及特性团队的出现,使得小团队更加全功能化。这些都是推动微服务诞生的重要因素。

微服务通常有如下几个特征,也是与Go语言特征不谋而合:

  • 小:专注于做一件事情

    小即是极多,这与Go语言遵循设计原则。保持简单性的方法就是:每种特性仅提供一种方法,减少重复、冗余,只提供一种方法做事情,把事情做到极致,这就是Go语言的原则。而微服务通常讲是两个Pizza能吃饱的团队来共用维护一个服务的代码。与”单一职责原则”类似,每个服务只做一件事情,并且把它做好。Go语言在语法特性简洁处理,编写相同的功能,相比于其它语言代码量很少。同时它提供高质量的标准库,让程序员减少对第三方框架选择与熟悉难题,让程序员更多的精力放在业务本身的逻辑上。

  • 独:运行在独立的进程中

    当初接触Go语言时,发现它既然支持与C的调用,一直不太理解它为何不支持动态库(1.5版本部分支持)。但事实上,Go语言认为如果一项特性不带来显著的有益,那就不提供。其实动态库的版本当编译与运行时不一致导致程序崩溃一直是C/C++开发的噩梦。Go编译单一执行文件,能一定程度缓和这个问题。另外Go一直追求生成代码优化,执行文件最小化。这也方便程序部署在Docker容器中,运行在一个独立的操作系统进程,拥有更好的故障隔离。

  • 轻:轻量级的通信机制

    服务和服务之间通过轻量级的机制实现彼此间的通信。所谓轻量级通信机制,通常指基于语言无关、平台无关的这类协议,例如XML、JSON。Go语言的主要发力点之一就是网络编程,标准库内置了HTTP协议框架,同时也提供了对JSON、XML的序列化与序列化支持,结合它的Goroutine并发机制,开发一个Rest服务只须很少的代码。

  • 松:部署态与运行态松耦合

    Go语言是一个强类型静态语言,可以把代码编译为本地机器指令。它的RUNTIME是会在编译时一起链接到执行文件中,这也就意味着我们不需要像JAVA那样装一个JVM。而且编译出的执行文件本身不依赖于其他动态库,完全可以做到轻松的发布。Go语言基于Channel来通讯,也会带来一定程序代码结构上的松耦合。

当产品架构朝微服务架构演进时,Go语言语言特征与微服务不谋而合,采用Go语言在一定程度上会助力微服务架构实施与落地。单体应用拆分成众多微服务时,服务之间从传统的插件机制来获得扩展性,转化成分布式多进程通讯来扩展。Go语言在网络并发上的优势,使得微服务开发变得更为简单,性能上更有优势。

参考:
[1] 基于微服务架构,改造企业核心系统之实践
[2] Go在谷歌:以软件工程为目的的语言设计
[3] Why Go is not Good
[4] 说说Golang的使用心得
[5] go语言设计哲学
[6] 少即是极多 - Go 语言设计理念

#go# #cloud#
理解Go Context机制
Go语言不足
微信扫一扫交流

标题:为什么是Go
作者:兰陵子
关注:lanlingthink(览聆时刻)
声明:自由转载-非商用-非衍生-保持署名(创作共享3.0许可证)

  • 文章目录
  • 站点概览
兰陵子

兰陵子

Programmer & Architect

164 日志
4 分类
57 标签
GitHub 知乎
    • 背景
    • 云计算
    • 微服务
© 2009 - 2022 蘭陵N梓記
Powered by - Hugo v0.101.0
Theme by - NexT
0%