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

2020 年 12 月 2 日 InfoQ
作者 | 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 👇
登录查看更多
0

相关内容

JSON( Java Script Object Notation)是一种轻量级的资料交换语言,以文字为基础,且易于让人阅读。尽管 JSON 是在 JavaScript 的一個子集,但 JSON 是独立于语言的文本格式,並且采用了类似于 C 语言家族的一些习惯。
专知会员服务
91+阅读 · 2020年12月26日
【干货书】'Mastering Go 第二版中文版',143页pdf
专知会员服务
47+阅读 · 2020年11月1日
【2020干货书】Python3基础导论介绍,98页pdf
专知会员服务
100+阅读 · 2020年10月11日
【2020新书】现代C++初学者指南,301页pdf
专知会员服务
159+阅读 · 2020年7月24日
渗透某德棋牌游戏
黑白之道
12+阅读 · 2019年5月17日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
自己动手撸一个分布式IM(即时通讯) 系统
51CTO博客
13+阅读 · 2019年3月20日
如何编写完美的 Python 命令行程序?
CSDN
5+阅读 · 2019年1月19日
Go存储怎么写?深度解析etcd存储设计
高可用架构
4+阅读 · 2019年1月16日
号称“开发者神器”的GitHub,到底该怎么用?
算法与数据结构
4+阅读 · 2018年3月29日
快乐的迁移到 Python3
Python程序员
5+阅读 · 2018年3月25日
码农日常工具推荐
架构文摘
4+阅读 · 2017年9月26日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
Arxiv
0+阅读 · 2021年1月23日
VIP会员
相关VIP内容
专知会员服务
91+阅读 · 2020年12月26日
【干货书】'Mastering Go 第二版中文版',143页pdf
专知会员服务
47+阅读 · 2020年11月1日
【2020干货书】Python3基础导论介绍,98页pdf
专知会员服务
100+阅读 · 2020年10月11日
【2020新书】现代C++初学者指南,301页pdf
专知会员服务
159+阅读 · 2020年7月24日
相关资讯
渗透某德棋牌游戏
黑白之道
12+阅读 · 2019年5月17日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
自己动手撸一个分布式IM(即时通讯) 系统
51CTO博客
13+阅读 · 2019年3月20日
如何编写完美的 Python 命令行程序?
CSDN
5+阅读 · 2019年1月19日
Go存储怎么写?深度解析etcd存储设计
高可用架构
4+阅读 · 2019年1月16日
号称“开发者神器”的GitHub,到底该怎么用?
算法与数据结构
4+阅读 · 2018年3月29日
快乐的迁移到 Python3
Python程序员
5+阅读 · 2018年3月25日
码农日常工具推荐
架构文摘
4+阅读 · 2017年9月26日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
Top
微信扫码咨询专知VIP会员