前言
说在最前面,我是一个外表谦让,内心狂热,外表斯文,内心贪玩的一个普通人。我的职业是程序员,是一个 golang 语言爱好者,一半是因为 golang 好用,一半是因为其他语言学不好。我是从 phper 转为 gopher 的,写 php 的时候我认识了互联网软件,写 go 的时候感觉自己终于在编程。
初见 golang
我大学专业是软件。第一门编程语言是 C++,知道了指针,知道了加减乘除,知道了编程去控制软硬件。后来选修了 java,被 ssh 框架戏耍了一个暑假。再后来进入了一个社团技术部,再被 html/css/js 打击了自己信心。高中年级总能排名前几的我,真的开始怀疑人生了。再再后来进入了一家游戏平台公司,开始了 php 的编写之旅。“噢!”,终于,我知道了什么是互联网,折磨我的编程语言 c++/java/html/css,原来还可以这样子 “变现”。
刚入门了互联网的我,心里是真的喜悦。不过,重复的东西做多了,总是少不了厌倦。每天都是写 php,都是那些增删改查,都是修改数据表,增加字段,增加临时表。真的,开始腻了。“听说最近公司在用新的编程语言 golang”,我,想去试试。但,我不敢,心里有对自己和对 golang 的怀疑,因此我不是第一个去拜师的。当 golang 在公司流行了两个月,我的 leader 让我去用一下 golang。终于,我师出有名了。浅尝了一周的 golang 之后,我!!发现!!
golang 是有指针的,这不是大学熟悉的 C++ 那样的指针吗
golang 是编译语言,原来客户端的 “打包、打包”,原来是这么一回事
golang 是可以做定时器的,换用 php 该怎么搞啊?很麻烦的吧。
golang 不用写分号,不用写括号,看起来很简单啊,性能又很好啊!
golang 原生支持 web 服务,原来不用 nginx 也可以起一个 web 服务啊
……. 还有很多很多
喜欢 golang
尝试了 golang 之后,我发现我喜欢上了 golang 了。
golang 严谨
golang 中不提倡多余的变量。gopher 都知道,golang 变量不使用,直接会报编译错误!这让我刮目相看!在我看来,是把严谨提升了一个阶段,只要你是 gopher,就会强迫你变得严谨。golang 变量这个属性,秉承了 golang 的设计理念,严谨这个理念贯穿了 golang 的各处。
曾经有一个 CTO 跟我说,定义的每一个变量、每一个字段,都应该有它的作用。多余的代码,多余的变量,多余的字段,除了误导别人,弄脏代码,别无他用。我,表示绝对赞同!
golang 性能好
单单靠 golang 的简单、严谨,当然上不了程序员的舞台。可恨的是,golang 性能还很好!比 C++ 要差点,但是就 web 应用的并发、资源占用来说,比 java、python、php、nodejs 都是要优秀的。具体数据大家上网一搜比比皆是。一个语法简单、性能又好、入门只需一周的语言,反正我是入坑了。
有段时间,我太热爱 golang 了导致认为 golang 可以做任何事情。不过慢慢,我理性了。做 web 应用,首选 golang。做数据分析、爬虫、图片处理还是 python 吧。但要是有人说用 java 去写 web 后台,cms 类型还好,要是面向市场用户的,spring boot 那套,spring cloud 那套,我觉得,远远远远远远远比不上用 golang 相关的框架,java 还是去做那些单体应用吧。
golang 轻量
golang 还有另外一个属性,就是 “轻”,有多轻?对比一下 java 的 jvm 那套容器,你就知道有多轻了。几行代码就能实现一个原生 web 服务了,docker 这个跨时代的产物就是 golang 写的。etcd 这个分布式基石也是 golang 写的,云原生这个跨时代的名词,很多组件都是 golang 贡献的。“微服务” 这个面试必问的名词,golang 可以对它做最好的诠释。
go-zero 一见如故
后来我进入了一家直播公司,刚好遇到了公司的波动,让我有了停下来自省的时间。其间,喜欢逛逛 github,稍有目的去逛一下 golang 的开源项目。比如 gin,iris,go-micro,go-zero,sentinel-golang,gin-vue-admin 等等等啦。一开始,go-zero 并不是特别吸引我,可能是博客 /github 布局不够亮眼吧。但是,当我哪天沉下来看 go-zero 的文档,开始敲起第一个 goctl 的命令,我好像,好像!已经停不下来。
go-zero,用起来,真的很舒服!
我刚在游戏平台公司实习转正的时候,也是可以带一两个实习生的。当时我就有个想法,“如何让员工都敲出规范、高效的代码”。当时想了下用 go-template,但是因为学艺未精,推进不下去。时隔几年,当我接触到 go-zero 的 goctl 后,发现,居然有大佬实现了当年我的想法!虽然我技术不大行,但是梦想还是要有的,go-zero 对我来说太亲切了。搞!肝!!
一周时间,过完了 go-zero 的 github 文档以及语雀文档,中途也自己练手了几个 demo。可真是越敲越舒服。迫不及待地用想找个实际项目投入生产!果真不久有个机会来了,公司想做一个简单的 app 做投放调研,允许重新搭建一个新的后台 web 项目,我!go-zero!义不容辞,开干。又花了两周时间,写完了一个后台 web 服务,里面有下面板块
用户板块
咨询板块
报告板块
支付板块
广告板块
截个图看看我的项目结构,由于还是公司项目,暂时不会开源啦,不过凡是 go-zeroer 都能看懂
简单说明一下:
api 目录,就是 http1.1 的 web 服务,跟前端对接
rpc 目录,rpc 服务,基本和 api 一一对应
enum 目录,枚举目录,里面存放的是各种各样的枚举值,我把它提到一等公民了
model 目录,数据库 model,目前都是用 goctl 根据 mysql 生成的 model
utils 目录,这里主要存放我的一些小工具包,例如 int/string/time 的一些操作,参考了下 go-zero 的命名方法,子目录一般会以 x 结尾,例如 intx,timex,stringx 等等
worker 目录,主要是做一些消费者模型的消费者,例如 kafka 的消费者,google 订阅通知的消费者等等
ws 目录,存放 websocket 相关的服务,例如私聊
感谢下 go-zero,让我对项目的组织结构有了一个简单的标准。worker、ws 等服务,以前的项目结构都杂乱无章,目前都是参考 go-zero 生成 api 的目录结构了:
main.go 入口
etc 存放配置,
internal 内部目录
config:配置
handler:处理器
logic:逻辑处理
types:中间类型
go-zero 理念
“工具大于约定和文档”,这,就是 go-zero 的理念。我,表示极度赞同!
go-zero 的最大特点,就是 goctl。goctl 是什么?就是能根据协议文档,生成代码的一个神器。例如
定了 a.proto 文件,goctl rpc proto a.proto -dir . 即可生成 rpc 服务
定了 b.sql 文件,goctl model mysql ddl -c -src b.sql -dir . 即可生成模板 model 文件
定了 c.api 文件(go-zero 出品),goctl api go -api ad-api.api -dir . 即可生成 api 文件
再配合上 golang 的 jb IDE,代码提醒,代码格式化,一个 go-zero 的生态,就出来了。一个字:舒服!!
go-zero 小工具
除了 goctl 神器,另外一个让我拜服的点是,go-zero 的一些小工具。
流数据处理利器:fx。听说 java8 的 lambda 很炫酷,go-zero 也有了!fx.Filter ().Sort ().Head () ,让数组的复杂处理变得简单
mapReduce 降低服务相应时间:mr.Finish (), mr.Map ().Reduce (), 跟并发处理 waitGroup 说拜拜!
etcd 服务发现的集成:p2c 的算法发现服务,免却了开发们点对点或 nginx 的转发服务,安装一个 etcd 就完事了
jwt 集成 api:轻松拥有一个 jwt 的后台服务
集成 Prometheus:轻松拥有一个带监控的 golang 后台服务
等等等
二次感谢 go-zero,还有很多小工具,等待我去看源码,时间轮 / 调度器等等啦。go-zero 有点像我学习的导师一样。
go-zero 拓展
go-zero 为小白如我的 gopher 们,提供了一个功能完备、性能可观、开发迅速的 web 框架。然而,它不像其他框架那样约束着我,我还是能里面做很多发挥的。虽然不是大牛级别的发挥,但是,个性化操作还是支持的:
model 层,完全可以接入 gorm 代替掉内置的 sqlx,虽然就没了大佬辛苦做的缓存击穿等防护的功能。当然也可以两者并存。
rpc 层,不必约定要 api 层去调用。例如我上面截图的 worker/ws 层去调用完全没问题。
api 层自己生成的 middleware,可以抽离出到公共目录,那就可以多个 api 目录使用同一个 middlerware 了。
等等等啦
go-zero 很轻量、很便捷、很博学。里面蕴藏的着很多知识以及理念。目前我只是用了皮毛,go-zero 的 k8s 部署,目前我没开始接入。继续努力努力学习啦!