当前位置:首页 > 技术分析 > 正文内容

关于我的Go语言Web开发心得与笔记

ruisui882个月前 (03-07)技术分析10


去年我曾经用Go语言开发过一个网站。尽管这个网站可能永远不会面世,但我在此过程中收获颇丰,现在想与大家分享我的一些心得与笔记。

一、Go 1.22:路由支持的新飞跃

我一直对Go语言的路由库(如gorilla/mux、chi等)持观望态度,更倾向于手动实现路由。例如:

// DELETE /records 请求处理  
case r.Method == "DELETE" && n == 1 && p[0] == "records":  
    if !requireLogin(username, r.URL.Path, r, w) {  
       return  
    }  
    deleteAllRecords(ctx, username, rs, w, r)  
// POST /records/ 请求处理  
case r.Method == "POST" && n == 2 && p[0] == "records" && len(p[1]) > 0:  
    if !requireLogin(username, r.URL.Path, r, w) {  
       return  
    }  
    updateRecord(ctx, username, p[1], rs, w, r)

然而,从Go 1.22版本开始,标准库对路由的支持有了显著提升,代码得以简化为:

mux.HandleFunc("DELETE /records/", app.deleteAllRecords)  
mux.HandleFunc("POST /records/{record_id}", app.updateRecord)

当然,我们还需要一个登录中间件,可以像这样使用requireLogin:

mux.Handle("DELETE /records/", requireLogin(http.HandlerFunc(app.deleteAllRecords)))

二、内置路由的陷阱:尾随斜杠的重定向

在使用内置路由时,我遇到了一个棘手的问题:为/records/设置路由后,对/records的请求会被重定向到/records/。这导致POST请求被错误地转换为GET请求,因为请求体在重定向过程中被丢弃。幸运的是,Xe Iaso的一篇博客文章为我提供了解决这一问题的线索。

我认为,避免这个问题的最佳方法是使用POST /records这样的API端点,而不是POST /records/,这看起来也更符合常规设计。

三、sqlc:自动生成数据库查询代码的神器

编写大量的SQL查询样板代码让我感到厌倦,但我又不想使用ORM,因为我喜欢直接控制SQL查询。这时,我发现了sqlc这个工具。它可以将SQL查询:

-- name: GetVariant :one  
SELECT *  
FROM variants  
WHERE id = ?;

编译成Go代码:

const getVariant = `-- name: GetVariant :one  
SELECT id, created_at, updated_at, disabled, product_name, variant_name  
FROM variants  
WHERE id = ?  
`  
  
func (q *Queries) GetVariant(ctx context.Context, id int64) (Variant, error) {  
    row := q.db.QueryRowContext(ctx, getVariant, id)  
    var i Variant  
    err := row.Scan(  
       &i.ID,  
       &i.CreatedAt,  
       &i.UpdatedAt,  
       &i.Disabled,  
       &i.ProductName,  
       &i.VariantName,  
    )  
    return i, err  
}

我喜欢sqlc的原因是,它可以根据我编写的SQL查询自动生成Go代码,让我无需在ORM文档中苦苦寻找如何构造所需的SQL查询。

四、SQLite技巧分享

在Mastodon上,我读到了一篇名为《为服务器优化SQLite》的文章。虽然我的项目规模较小,对性能要求不高,但这篇文章仍然给了我很多启发:

  1. 我创建了一个专门用于写入数据库的对象,并设置了db.SetMaxOpenConns(1)。我发现,如果不这样做,当两个线程同时尝试写入数据库时,我会遇到SQLITE_BUSY错误。
  2. 为了提高读取速度,我考虑使用两个独立的数据库对象,一个用于写入,一个用于读取。

文章中提到的其他技巧也很有用(如优化COUNT查询、使用STRICT表等),但我还没有尝试过。

另外,如果我有两个表且永远不会进行JOIN操作,我会将它们放在单独的数据库中,以便独立连接。

五、Go 1.19:设置GC内存限制的新方法

我在内存有限的虚拟机(如256MB或512MB)上运行Go项目时,遇到了应用程序因内存不足而被杀死的问题。经过调查,我发现这可能是由于垃圾回收器配置不当导致的。

在Go 1.19中,我们可以设置GC内存限制来避免这种情况。我将GC内存限制设置为250MB后,应用程序因内存不足而被杀死的情况大大减少:

export GOMEMLIMIT=250MiB 

六、我为何偏爱用Go语言制作网站

我之所以对Go语言情有独钟,尤其在网站开发领域,主要得益于以下几个方面的优势:

  • 部署高效便捷:Go语言的部署过程极为简便,只需一个静态二进制文件即可完成。更令人惊喜的是,通过embed功能,静态资源也能轻松嵌入到二进制文件中,进一步简化了部署流程。
  • 内置强大的Web服务器:Go语言内置了功能完善的Web服务器,直接适用于生产环境,无需额外配置WSGI或其他中间件,从而大大提高了开发效率和灵活性。
  • 工具链安装简便:Go语言的工具链安装过程同样简便快捷,只需执行如apt-get install golang-go的命令,随后使用go build即可轻松构建项目,无需复杂的配置过程。
  • HTTP响应处理简洁:借助Serve(w http.ResponseWriter, r *http.Request)函数,Go语言能够轻松读取HTTP请求并发送响应,大大简化了Web开发的复杂度,提高了开发效率。
  • 标准库支持丰富:net/http包作为Go语言的标准库之一,无需额外安装任何第三方库,即可直接用于网站开发,为开发者提供了极大的便利。
  • 系统级编程能力强大:作为系统级语言,Go在处理如ioctl等底层命令时同样表现出色,展现了其强大的跨领域应用能力。

总的来说,Go语言不仅让我在短时间内迅速开发出功能完善的网站,即便在长时间搁置后,也能轻松回归并继续开发。相比之下,我曾尝试学习Rails,但总是感到困惑和挫败。而对于充满重复样板代码的Go项目,我反而觉得更加容易理解和维护。这无疑是Go语言在网站开发领域中的独特魅力所在。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/2585.html

标签: go embed
分享给朋友:

“关于我的Go语言Web开发心得与笔记” 的相关文章

7种超轻量级的Linux发行版,能够帮助你找到适合自己的操作系统

Linux是一种非常受欢迎的开源操作系统,而且有许多版本可以选择。有时候,你需要一种超轻量级的Linux发行版,它可以在资源有限的设备上运行,并且能够快速启动。本文将介绍7种超轻量级的Linux发行版,希望能够帮助你找到适合自己的操作系统。1. Tiny Core LinuxTiny Core Li...

总结了Vue3的七种组件通信方式,别再说不会组件通信了

写在前面本篇文章是全部采用的<script setup>这种组合式API写法,相对于选项式来说,组合式API这种写法更加自由,具体可以参考Vue文档对两种方式的描述。本篇文章将介绍如下七种组件通信方式:propsemitv-modelrefsprovide/injecteventBusv...

gitlab简单搭建与应用

一、gitlab1、简介GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。与Github类似,GitLab能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历...

编码 10000 个小时后,开发者悟了:“不要急于发布!”

【CSDN 编者按】在软件开发的道路上,时间是最好的老师。根据“一万小时定律”,要成为某个领域的专家,通常需要大约一万小时的刻意练习。本文作者身为一名程序员,也经历了一万小时的编程,最终悟出了一个道理:慢即是快,重视架构设计和代码质量,确保每一行代码都经得起时间的考验。作者 | Sotiris Ko...

美国民众负债累累 但今年假期消费者支出仍将创下新高

智通财经APP获悉,在迎接假期之际,许多美国人已经背负了创纪录的信用卡债务。然而,今年假期消费者支出仍将创下新高。根据美国零售联合会(NRF)上周发布的报告,预计今年11月1日至12月31日期间的消费总额将达到创纪录的9795亿至9890亿美元之间。NRF首席经济学家Jack Kleinhenz表示...

HTML5学习笔记三:HTML5语法规则

1.标签要小写2.属性值可加可不加””或”3.可以省略某些标签 html body head tbody4.可以省略某些结束标签 tr td li例:显示效果:5.单标签不用加结束标签img input6.废除的标签font center big7.新添加的标签将在下一HTML5学习笔记中重点阐述。...