用 Go 语言,做 Web 编程开发

人民邮电出版社和实验楼合作的第 15 本书来了!

Web 介绍

Web 应用在我们的生活中无处不在。看看我们日常使用的各个应用程序,它们要么是 Web 应用,要么是移动 App 这类 Web 应用的变种。无论哪一种编程语言,只要它能够开发出与人类交互的软件,它就必然会支持 Web 应用开发。对一门崭新的编程语言来说,它的开发者首先要做的一件事,就是构建与互联网(internet)和万维网(World Wide Web)交互的库(library)和框架,而那些更为成熟的编程语言还会有各种五花八门的 Web 开发工具。

Go 是一门刚开始崭露头角的语言,它是为了让人们能够简单且高效地编写后端系统(back end system)而创建的。这门语言拥有众多先进的特性,并且密切关注程序员的生产力以及各种与速度相关的事项。和其他语言一样,Go 语言也提供了对 Web 编程的支持。

本节实验将列举一些使用 Go 编写 Web 应用的优点,并介绍一些关于 Web 应用的基本知识。

知识点

  • Web 应用的定义
  • 使用 Go 语言编写 Web 应用的优点
  • Web 应用编程的基本知识
  • 使用 Go 语言编写一个极为简单的 Web 应用

使用 Go 语言构建 Web 应用

Go 是一门相对比较年轻的编程语言,它拥有繁荣并且仍在不断成长的社区,并且它也非常适合用来编写那些需要快速运行的服务器端程序。因为 Go 语言提供了很多过程式编程语言的特性,所以拥有过程式编程语言使用经验的程序员对 Go 应该都不会感到陌生,但与此同时,Go 语言也提供了函数式编程方面的特性。除了内置对并发编程的支持之外,Go 语言还拥有现代化的包管理系统、垃圾收集特性以及一系列包罗万象、威力强大的标准库。

虽然 Go 自带的标准库已经非常丰富和宏大了,但 Go 仍然拥有许多质量上乘的开源库,它们可以对标准库不足的地方进行补充。

使用 Go 语言进行 Web 开发正变得日益流行,很多公司都已经开始使用 Go 了,其中包括 Dropbox、SendGrid 这样的基础设施公司,Square 和 Hailo 这样的技术驱动的公司,甚至是 BBC、纽约时报这样的传统公司。

在开发大规模 Web 应用方面,Go 语言提供了一种不同于现有语言和平台但又切实可行的方案。大规模可扩展的 Web 应用通常需要具备以下特质:

  • 可扩展;
  • 模块化;
  • 可维护;
  • 高性能。

可扩展

大规模的 Web 应用应该是可扩展的(scalable),这意味着应用的管理者应该能够简单、快速地提升应用的性能以便处理更多请求。如果一个应用是可扩展的,那么它就是线性的,这意味着应用的管理者可以通过添加更多硬件来获得更强的请求处理能力。

有两种方式可以对性能进行扩展:

  • 垂直扩展(vertical scaling),即提升单台设备的 CPU 数量或者性能;
  • 水平扩展(horizontal scaling),即通过增加计算机的数量来提升性能。

因为 Go 语言拥有非常优异的并发编程支持,所以它在垂直扩展方面拥有不俗的表现:一个 Go Web 应用只需要使用一个操作系统线程(OS thread),就可以通过调度来高效地运行数十万个 goroutine。

跟其他 Web 应用一样,Go 也可以通过在多个 Go Web 应用之上架设代理来进行高效的水平扩展。因为 Go Web 应用都会被编译为不包含任何动态依赖关系的静态二进制文件,所以我们可以把这些文件分发到没有安装 Go 语言的系统里,从而以一种简单且一致的方式部署 Go Web 应用。

模块化

大规模 Web 应用应该由可替换的组件构成,这种做法能够使开发者更容易添加、移除或者修改特性,从而更好地满足程序不断变化的需求。除此之外,这种做法的另一个好处是使开发者可以通过复用模块化的组件来降低软件开发所需的费用。

尽管 Go 是一门静态类型语言,但用户可以通过它的接口机制对行为进行描述,以此来实现动态类型匹配(dynamic typing)。Go 语言的函数可以接受接口作为参数,这意味着用户只要实现了接口所需的方法,就可以在继续使用现有代码的同时向系统中引入新的代码。与此同时,因为 Go 语言的所有类型都实现了空接口,所以用户只需要创建出一个接受空接口作为参数的函数,就可以把任何类型的值用作该函数的实际参数。此外,Go 语言还实现了一些在函数式编程中非常常见的特性,其中包括函数类型、使用函数作为值以及闭包,这些特性允许用户使用已有的函数来构建新的函数,从而帮助用户构建出更为模块化的代码。

Go 语言也经常会被用于创建微服务(microservice)。在微服务架构中,大型应用通常由多个规模较小的独立服务组合而成,这些独立服务通常可以相互替换,并根据它们各自的功能进行组织。比如,日志记录服务会被归类为系统级服务,而开具账单、风险分析这样的服务则会被归类为应用级服务。创建多个规模较小的 Go 服务并将它们组合为单个 Web 应用,这种做法使得我们可以在有需要的时候对应用中的服务进行替换,而整个 Web 应用也会因此变得更加模块化。

可维护

和其他庞大而复杂的应用一样,拥有一个易于维护的代码库(codebase)对大规模的 Web 应用来说也是非常重要的。这是因为大规模的应用通常都会不断地成长和演化,所以开发者需要经常性地回顾并修改代码,而修改难懂、笨拙的代码需要花费大量的时间,并且隐含着可能会造成某些功能无法正常运作的风险。因此,确保源代码能够以适当的方式组织起来并且具有良好的可维护性对开发者来说就显得至关重要了。

Go 语言的设计鼓励良好的软件工程实践,它拥有简洁且极具可读性的语法以及灵活且清晰的包管理系统。除此之外,Go 语言还有一整套优秀的工具,它们不仅可以增强程序员的开发体验,还能够帮助他们写出更具可读性的代码,比如以标准化方式对 Go 代码进行格式化的源代码格式化程序 gofmt 就是其中一个例子。

因为 Go 语言希望文档可以和代码一同演进,所以它的文档工具 godoc 会对 Go 源代码及其注释进行语法分析,然后以 HTML、纯文本或者其他多种格式创建出相应的文档。godoc 的使用方法非常简单,开发者只需要把文档写到源代码里面,godoc 就会把这些文档以及与之相关联的代码提取出来,生成相应的文档文件。

除此之外,Go 还内置了对测试的支持:gotest 工具会自动寻找与源代码处于同一个包(package)之内的测试代码,并运行其中的功能测试和性能测试。Go 语言也提供了 Web 应用测试工具,这些工具可以模拟出一个 Web 服务器,并对该服务器生成的响应(response)进行记录。

高性能

高性能不仅意味着能够在短时间内处理大量请求,还意味着服务器能够快速地对客户端进行响应,并让终端用户(end user)能够快速地执行操作。

Go 语言的一个设计目标就是提供接近于 C 语言的性能,尽管这个目标目前尚未达成,但 Go 语言现在的性能已经非常具有竞争力:Go 程序会被编译为本地码(native code),这一般意味着 Go 程序可以运行得比解释型语言的程序要快,并且就像前面说过的那样,Go 语言的 goroutine 对并发编程提供了非常好的支持,这使得 Go 应用可以同时处理多个请求。

希望以上介绍能够引起你对使用 Go 语言及其平台进行 Web 开发的兴趣。但是在学习如何使用 Go 进行 Web 开发之前,我们需要先来了解一下什么是 Web 应用,以及它们的工作原理是什么,这会给我们学习之后的内容带来非常大的帮助。

以上内容来自《Web 编程》第一章,点击链接即可免费试学前两章!

推荐阅读更多精彩内容