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

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

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

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

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

  • 恢复中间件——用来日志打印和静默处理程序代码中的死机。
  • 日志——我想要某个方案,可以打印每个请求的信息,包含body params、auth tokens等等(用于调试目的)。
  • 更好的错误处理——我希望错误仍然是带有错误信息和代码的JSON响应。
  • 其它常用的中间件——包含JWT验证和CORS。

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

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

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

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

你需要一个好的代码结构

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

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

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

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

明智地选择你的 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 的新语法,那么这是一个不错的方案。

Docker

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

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

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

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

其它?

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

原文链接:

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

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/qrl4pWMiR7T1l5mtevxI
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券