0%

模板能够分离数据和逻辑,使得逻辑变得简洁清晰,同时提高复用率。

模板引擎结构图

模板引擎按照功能可以划分为两种类型:

  • 无逻辑模板引擎:此类模板引擎只进行字符串的替换,无其它逻辑;
  • 嵌入逻辑模板引擎:此类模板引擎可以在模板中嵌入逻辑,实现流程控制/循环等。

这两类模板引擎都比较极端。无逻辑模板引擎需要在处理器中额外添加很多逻辑用于生成替换的文本。而嵌入逻辑模板引擎则在模板中混入了大量逻辑,导致维护性较差。实用的模板引擎一般介于这两者之间。

阅读全文 »

gomock 是 Go 官方的模拟框架,可以与 go 的 test 很好的集成。在实际项目中,当需要进行单元测试时,往往会有很多的依赖项,有些依赖可能还没有办法直接进行创建,例如数据库连接,文件 I/O 等。此时通过使用 go mock 可以模拟依赖项,简化测试。

阅读全文 »

for 和 range

循环是几乎所有编程语言都具有的控制结构,也是编程语言中常用的控制结构,Go 语言除了使用经典的三段式循环之外,还引入了另一个关键字 range 用于快速遍历数组、哈希表以及 Channel 等元素。

这里主要记录 Go 语言中的两种不同循环,也就是经典的 for 循环和 for…range 循环,分析这两种循环在运行时的结构以及它们的实现原理。

for 循环和 for…range 循环的形式分别如下:

func main() {
    // for 循环
    for i := 0; i < 10; i++ {
        println(i)
    }
    
    // for range 循环
    arr := []int{1, 2, 3}
    for i, _ := range arr {
        println(i)
    }
}

在汇编语言中,无论是经典的 for 循环还是 for-range 循环都会使用 JMP 等命令跳回循环体的开始位置复用代码,所以使用 for…range 语法的控制结构最终应该也会被 Go 语言的编译器转换成普通的 for 循环

接下来将逐个分析每一种循环的场景。

阅读全文 »

validator 库用于对数据进行校验。在 Web 开发中,对用户传过来的数据我们都需要进行严格校验,防止用户的恶意请求。例如日期格式,用户年龄,性别等必须是正常的值,不能随意设置。使用 validdator 库可以很方便的进行很多的校验,避免自己编写大量的格式检验代码。

阅读全文 »

因为最近快入职了,正好在公众号看到推广,就在拉勾教育上购买了一套 MySQL 实战教程:《姜承尧的MySQL实战宝典》,重新温习一下 MySQL,这篇文章主要记录通过这个课程学习到的一些 MySQL 使用技巧。

这里附上课程链接:拉勾教育——MySQL实战宝典

阅读全文 »

Go module 是 Go1.11 版本之后推出的模块管理工具,从1.13开始为默认的依赖管理工具。在没有 Go module 之前,对于导入依赖的管理都是通过 GOPATH 来指定在工程中使用哪些源文件和模块。项目的代码只能放到 GOPATH/src 目录下,依赖的各种源文件也都只能加入到 src 目录下才可以运行使用。

阅读全文 »

日志级别

通常,日志的级别分这几种:TRACE,DEBUG,INFO,WARN,ERROR,FATAL。其含义分别如下:

  • FATAL:表示需要立即被处理的系统级错误。当该错误发生时,表示服务已经出现了某种程度的不可用,系统管理员需要立即介入。这属于最严重的日志级别,因此该日志级别必须慎用,如果这种级别的日志经常出现,则该日志也失去了意义。通常情况下,一个进程的生命周期中应该只记录一次FATAL级别的日志,即该进程遇到无法恢复的错误而退出时。当然,如果某个系统的子系统遇到了不可恢复的错误,那该子系统的调用方也可以记入FATAL级别日志,以便通过日志报警提醒系统管理员修复;
  • ERROR:该级别的错误也需要马上被处理,但是紧急程度要低于FATAL级别。当ERROR错误发生时,已经影响了用户的正常访问。从该意义上来说,实际上ERROR错误和FATAL错误对用户的影响是相当的。FATAL相当于服务已经挂了,而ERROR相当于好死不如赖活着,然而活着却无法提供正常的服务,只能不断地打印ERROR日志。特别需要注意的是,ERROR和FATAL都属于服务器自己的异常,是需要马上得到人工介入并处理的。而对于用户自己操作不当,如请求参数错误等等,是绝对不应该记为ERROR日志的
  • WARN:该日志表示系统可能出现问题,也可能没有,这种情况如网络的波动等。对于那些目前还不是错误,然而不及时处理也会变为错误的情况,也可以记为WARN日志,例如一个存储系统的磁盘使用量超过阀值,或者系统中某个用户的存储配额快用完等等。对于WARN级别的日志,虽然不需要系统管理员马上处理,也是需要及时查看并处理的。因此此种级别的日志也不应太多,能不打WARN级别的日志,就尽量不要打;
  • INFO: 该种日志记录系统的正常运行状态,例如某个子系统的初始化,某个请求的成功执行等等。通过查看INFO级别的日志,可以很快地对系统中出现的 WARN,ERROR,FATAL错误进行定位。INFO日志不宜过多,通常情况下,INFO级别的日志应该不大于TRACE日志的10%;
  • EEBUG or TRACE:这两种日志具体的规范应该由项目组自己定义,该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。通过该种日志,可以查看某一个操作每一步的执行过程,可以准确定位是何种操作,何种参数,何种顺序导致了某种错误的发生。可以保证在不重现错误的情况下,也可以通过DEBUG(或TRACE)级别的日志对问题进行诊断。需要注意的是,DEBUG日志也需要规范日志格式,应该保证除了记录日志的开发人员自己外,其他的如运维,测试人员等也可以通过 DEBUG(或TRACE)日志来定位问题

参考文章

最佳日志实践(v2.0)

OpenTracing 简介

OpenTracing 是一个中立的(厂商无关、平台无关)分布式追踪的 API 规范,提供了统一接口方便开发者在自己的服务中集成一种或者多种分布式追踪的实现。

OpenTracing 诞生的背景

开发和工程团队因为系统组件水平扩展、开发团队小型化、敏捷开发、CD(持续集成)、解耦等各种需求,开始使用微服务的架构取代以前好的单机系统。 也就是说,当一个生产系统面对真正的高并发,或者解耦成大量微服务时,以前很容易实现的重点任务变得困难了。过程中需要面临一系列问题:用户体验优化、后台真是错误原因分析,分布式系统内各组件的调用情况等。随着服务数量的增多和内部调用链的复杂化,仅凭借日志和性能监控很难做到 “See the Whole Picture”,在进行问题排查或是性能分析的时候,无异于盲人摸象。

阅读全文 »

time 包中的类型

time 包中定义了以下时间类型:

time.Time{}

时间类型,包含了秒和纳秒以及 Location:

type Time struct {
    wall uint64 // 秒
    ext  int64  // 纳秒
    loc *Location
}
阅读全文 »