在生产环境用了一个月Go语言,我有4点体会

2020年12月1日 236点热度 0人点赞 0条评论
图片
作者 | Dominik Tarnowski
译者 | 张健欣
策划 | 万佳

最近,我获得了一份 DevOps 工作,工作内容主要涉及用 Go 完全从头开始编写一个新的后端系统。此前,我从未在生产环境使用过 Go,从个人项目中有过了解。

1 你(可能)应该使用一个 Web 框架

一开始,我们决定只使用 Go 的 http 库和一个简单的路由库——mux。

然而,我很快就遇到了现实生活中的生产问题:

恢复中间件——用来日志打印和静默处理程序代码中的死机。

日志——我想要某个方案,可以打印每个请求的信息,包含 body params、auth tokens 等等(用于调试目的)。

更好的错误处理——我希望错误仍然是带有错误信息和代码的 JSON 响应。

其它常用的中间件——包含 JWT 验证和 CORS。

我有两个选择:自己实现上述问题的解决方案,针对每个问题使用不同的第三方库,或者选择一个 Web 框架,基本上已经做了大部分(如果不是全部)这些事情。

我最终决定使用 Echo 这个 Web 框架。据悉,它在 GitHub 上有近 2 万个点赞,有一个非常活跃的社区,还有很棒的文档。我认为它是完成这份工作的一个很棒的工具。

图片

我还发现,用 echo 编写应用程序时有一些比较精简的样板(主要是解析 json body、编写 errors 以及手动设置 headers 等),让代码的可读性有所提高。

图片

然而,当你有一些比较复杂的端点时,你就会注意到生产率的真正差异。你经常会遇到需要验证某些 JSON 字段的情况,并且需要有意义的错误信息来描述错误。如果你想要在不使用任何库的情况下完成这些,你的代码将很快变得很难阅读:

图片

2 你需要一个好的代码结构

Go 的 Web 框架(或者一般的 go 项目)不强制任何特定的文件结构。如果你使用过 ASP.NET/ASP.NET Core 之类的东西,当我说一些框架是紧密结构的,而且很多事情都是通过约定而不是显式指定来完成的时,你就会知道我在说什么。

关于 Go 的问题是,你很容易跳过关于构建代码结构的学习,使得代码很难阅读和维护。如果你还不知道我在说什么,下面是我不久前写的一个(糟糕的)Go 端点例子:

图片

你明白我的意思吗?在添加了所有的 CreateUser 和 CreateAgency 方法后,“更好的”方法很可能会包含更多的行,但是... 它以后会非常容易理解、重用、调试和修改,因为每个方法都有单独的用途。如果你还没有明白,我强烈建议你看一看下面关于良好代码结构的资源:

https://github.com/ribice/gorsk- 基础 REST API 的良好例子

https://github.com/bxcodec/go-clean-arch- 也是一个 REST API 例子,但是更严格地遵循“Clean Architecture”理念

一般来说,这个理念很简单。你应该将与数据库通信的代码与实际的应用程序逻辑本身分开,而且应用逻辑也应该与传输 / 端点逻辑(在本例中是 HTTP 端点)分开。

3 明智地选择你的 SQL driver

当我第一次用 Go 开始编程时,我希望尽可能使用最新的库,因此我选择使用 database/sql 包(使用 Postgres)。虽然这个体验还可以,但在查询数据时,我遇到很多样本,特别是不得不使用 Scan 语法。这导致我有下面 2 个选项:

sqlx-  一个基于 database/sql 的轻量包装器,做了一些扩展,使得做查询更容易。

gorm-  一个针对 Go 的 ORM(Object-Relational Mapping,对象 - 关系映射)库,根据你的 Go models 生成 SQL models 和查询。

我不认为有一个明确的“更好的”库,最终取决于使用场景和个人偏好。

gorm 可能会让你轻松一些,特别是如果你经常在修改数据库之后忘记在查询中增加字段的话(因为在 gorm 中,你根本不需要做这些)。

另一方面,sqlx 更以 SQL 为中心,它更像是写 Go 代码来调用 SQL 接口,而不是 gorm 方案那样根据 Go 代码生成 SQL。如果你喜欢完全掌控 SQL 并且不必学习 GORM 的新语法,那么这是一个不错的方案。

4 Docker

我遇到的一个挑战是配置这个项目的生产环境。开发环境和生产环境总会有一些差别,例如这个应用程序在哪个端口上运行、数据库的主机和凭证,等等。

我见过有人通过 JSON、YAML 甚至 git 忽略的.go 文件来配置应用程序变量。我个人发现 env 文件最好用,特别是配合 docker-compose 使用:

图片图片

我通常将这些与以下实用的函数结合使用:

图片

用 Go 构建 Docker 镜像也超级简单:

图片

5 其它?

我还想到了其它一些东西,但我不认为它们值得单独用章节来讨论:

  • Named returns in Go

  • Effective Go

  • Go Modules

原文链接:

https://tdom.dev/go-in-production

今日荐文

点击下方图片即可阅读

图片

京东单方面辞退 38 岁 P7 员工三次败诉;小米高管因错误言论致歉请辞;腾讯向抖音发 300 封律师函 | Q 资讯


每周精要上线移动端,立刻订阅,你将获得
InfoQ 用户每周必看的精华内容集合:
资深技术编辑撰写或编译的全球 IT 要闻
一线技术专家撰写的实操技术案例
InfoQ 出品的课程技术活动报名通道;
“码”上关注,订阅每周新鲜资讯
图片

点个在看少个 bug?
5820在生产环境用了一个月Go语言,我有4点体会

root

这个人很懒,什么都没留下

文章评论