Go开发者的日常:代码、微服务与生产环境的宁静

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:Go程序员的迷思与现实

\n\n

在IT社区中,关于Go开发者的工作存在两种截然不同的看法。有人说这是完美主义者的天堂:强类型、无类继承、编译速度极快。也有人说这不过是无穷无尽的if err != nil和与泛型的斗争(尽管它们已经被加入)。

\n\n

真相是什么?在一家编写高负载微服务的中型公司里,Go开发者的工作日实际上是如何度过的?今天,我将打开通往我现实世界的大门。没有废话——只有代码、工具和真实案例。

\n\n

我在一家产品公司工作,Golang是我们的主要后端语言。我们的技术栈包括:gRPC、PostgreSQL、Kafka、Kubernetes。这是现代Go开发的典型情况。我们开始吧。

\n\n

08:30 — 早晨:计划与代码审查

\n\n

一天不是从咖啡开始,而是从查看GitLab和Slack的通知开始。趁着大脑清醒,这是审查同事合并请求的最佳时间。

\n\n

早晨例行事务:我首先看什么?

\n
    \n
  • CI/CD中的错误 — 如果构建在夜间失败,这是首要任务。
  • \n
  • 对我代码的评论 — 在Go中,进行详细的审查是惯例。
  • \n
  • 监控图表 — 检查昨天部署后延迟是否增加。
  • \n
\n\n

顺便说一下代码审查。在Go社区中有一条不成文的规定:代码应该简单。如果你编写复杂的“轮子”,审查时会被打回。一个来自资深开发者的典型评论示例:

\n\n
// 不好:过度抽象\ntype Processor interface {\n    Process(ctx context.Context, data []byte) ([]byte, error)\n}\n\n// 好:简单的函数\nfunc Process(ctx context.Context, data []byte) ([]byte, error) {\n    // 逻辑\n}\n
\n\n

在09:00 — 每日站会。我们不会花时间在冗长的叙述上。格式:昨天做了什么,今天要做什么,是否有阻碍。没有“你昨晚过得怎么样”。

\n\n

09:30 — 深入编码:用Go编写微服务

\n\n

今天的计划是完善通知服务。这是一个经典的Go微服务,它从Kafka接收事件并发送邮件/推送通知。任务:添加对模板的支持。

\n\n

首先,我打开项目结构。在Go中,通常采用极简的文件夹树:

\n\n
notifier/\n├── cmd/\n│   └── server/\n│       └── main.go\n├── internal/\n│   ├── handler/\n│   ├── service/\n│   └── repository/\n├── pkg/\n│   └── models/\n└── go.mod\n
\n\n

我从数据模型开始。在Go中,与数据库交互通常使用Go ORM(例如GORM)或通过sqlx使用纯SQL查询。我更喜欢sqlx——更少的魔法,更多的控制。

\n\n
type Template struct {\n    ID      int64  `db:"id"`\n    Name    string `db:"name"`\n    Content string `db:"content"`\n    CreatedAt time.Time `db:"created_at"`\n}\n\nfunc (r *Repository) GetTemplateByName(ctx context.Context, name string) (*Template, error) {\n    var t Template\n    err := r.db.GetContext(ctx, &t, "SELECT * FROM templates WHERE name = $1", name)\n    if err != nil {\n        return nil, fmt.Errorf("get template: %w", err)\n    }\n    return &t, nil\n}\n
\n\n

请注意错误处理。在Golang中没有try-catch。每个函数调用都会检查错误。这不是缺陷,而是特性——代码变得可预测。工作5年来,我从未在生产环境中遇到过意外的空指针。

\n\n

11:00 — 与gRPC集成

\n\n

下一步是为管理后台添加一个gRPC端点。在现代Go开发中,gRPC已成为内部服务的标准。它比REST更快,并且可以自动生成客户端。

\n\n

首先,我描述proto文件:

\n\n
syntax = "proto3";\n\npackage notifier;\n\nservice TemplateService {\n    rpc CreateTemplate (CreateTemplateRequest) returns (TemplateResponse);\                

博客

书籍推荐