Go语言编程笔记12:web基础
开一个新坑,用Go来做web开发。虽然已经从事多年基于LAMP的web开发,但最近学习了Go编程,所以打算借着学习《Go Web 编程》一书的同时撰写笔记,算是对web开发的复习和回顾。
《Go Web 编程》作者为新加坡人,从事编程相关教学工作,此书主要内容为使用Go的标准库实现一个web应用,并借此阐述HTTP和web开发的相关理念和技能。
本篇笔记的大纲是我用幕布编写的思维导图,可以在这里查看。
Go开发web的优势
虽然说任何一门编程语言都可以在几乎所有的领域使用,但依然存在某些领域偏爱某种编程语言的现象。
比如Java多用于大型企业的商业应用,PHP多用于中小企业建站,Python用于科学计算、人工智能、数据分析,而Go常用于游戏服务器和实时通信等。
这种现象是由语言特性决定的,比如PHP在LAMP环境下易于部署、开发、维护,对于人力资源紧张的中小企业友好,而Python的list
、set
、map
等数据结构设计的相当好用,且语言本身的简单易学,再加上繁荣的第三方库,就造成了其在科学领域的广泛使用。
而Go的优点在于标准库本身支持了处理HTTP响应和请求的组件,可以让Go开发的web应用无需借助额外的Apache等Web service实现web服务。这样做的好处一是web请求无需经过web service转发,执行效率高。二是可以定制化地实现web请求处理和线程调度,比如通过线程池保持长连接的web请求,以实现游戏服务器等需要长连接情景下的高效web服务。
此外,Go语言的另一优势是语言本身是编译型语言,执行效率高。
执行效率的高低是相对而言的,一般来说C>Go>PHP>Python,但各种语言也在采用各种手段来提高执行效率,比如PHP使用C编写的库作为标准组件,Python之父加入微软后也在推进Python效率的提升。总之一门主流的语言在效率方面都是合格的,它们之间的执行效率只会在某些个别应用场景下被方大,需要注意,大部分时间都是无需在意的。
上面是从语言本身的特性评价Go在Web开发上的优势,下面用一般性的Web应用需要满足的特征进行评价:
- 可扩展
- 模块化
- 可维护
Web应用的可扩展性包含两个方面:纵向和横向。纵向扩展指要能通过增加单台服务器的性能(CPU的数量和主频)提高应用的性能。横向扩展指要能通过增加服务器的数量提升应用的性能。
Go开发的Web应用在纵向可扩展性上的优势在于其支持的goroutine实现的并发,可以很好的在单个或者多个CPU线程上实现不错的调度,以实现一个不错的并发性能。横向可扩展性上的优势在于,Go开发的程序都是一个单独的包含了所需要的库的二进制文件,这意味着可以无需考虑部署所依赖的外部环境,可以简单地通过拷贝二进制文件的方式在多台服务器上部署同样的应用。
Web应用的模块化体现在将一个大型应用拆分为多个小应用,应用之间使用数据库、消息队列等方式进行通信,以便于进行维护。在近些年这样的做法也叫做“微服务”,可以让小型应用之间通过网络进行通信,以灵活地组成完整的可以服务的Web应用。
在这方面Go并没有单独的优势,大多数后台开发语言都具有相同的能力。
Web应用的可维护性体现在代码结构清晰、可读性强。这点对所有的编程语言的要求是相同的,不同的是Go非常独特的理念:提供一致性的语法格式化工具go fmt
以及定义严格(甚至可以说苛刻)的语法。这点在主流编程语言中非常罕见,一些其他语言转过来的开发者(包括我)一开始可能很难适应。但就多人协同开发而言,这样做无疑是有益的,可以带来一致性的代码风格,对提升代码的可维护性是有帮助的。
HTTP
Web开发中,HTTP协议是基础。对于HTTP协议而言,最基础的定义是:这是一个纯文本的无状态的请求-响应协议。
除此以外我们还需要了解HTTP的主要版本:
- HTTP 0.9,这是一个早期版本,应用于基本都是静态网站的互联网上古时期。
- HTTP 1.0,这是一个已经相当晚上的版本。
- HTTP 1.1,在HTTP1.0基础上推进的版本,也是目前普遍使用的版本。
- HTTP 2.0,也称为HTTP/2,在保持HTTP基本语法不变的基础上,提升了传输性能。
更多HTTP不同版本之间的差异,请阅读HTTP协议几个版本的比较。
Web应用历史
在Web应用的发展史中,有两个技术相当关键:
CGI
CGI的全称是Common Gateway Interface(通用网关接口)。
最原始的Web应用只能提供一种服务,即将请求的文件内容原样返回。所以早期的互联网上的网站都是静态的,只能展示服务器上的文档。
CGI提供了一种可能:即通过这种CGI定义的接口,可以让Web应用和服务器上的其它本地应用进行“交互”,以提供额外的服务。
图源:《HTTP权威指南》
SSI
SSI全称Server Side Iclude(服务端嵌入)。
虽然通过CGI技术可以扩展Web服务器的功能,但其对于Web服务器的主业(展示HTML页面)并无多大帮助,依然只能展示内容固定的静态HTML页面。这时候就有了SSI技术,该技术的要点在于可以在HTML页面中嵌入“模版语言”,通过执行模版语言后用执行结果替换HTML中的相应标签来展示一个“动态页面”。
PHP就是从一门模版语言基础上发展而来的。
HTTP请求
HTTP的核心就是“请求”和“响应”,它们的具体都是以“报文”的形式存在。
一个HTTP报文包含这几部分:
- 首行
- 报文头
- 空白行
- 报文体
具体的定义中,请求和响应报文略有区别。
这里以https://blog.icexmoon.xyz/
请求的报文头进行说明:
GET / HTTP/1.1
Host: blog.icexmoon.xyz
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
...
Upgrade-Insecure-Reque