V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kevinwan
V2EX  ›  推广

我用 go-zero 一周实现了一个中台系统,已开源!

  •  
  •   kevinwan · 352 天前 · 6275 次点击
    这是一个创建于 352 天前的主题,其中的信息可能已经有所发展或是发生改变。

    作者:Jack

    最近发现 golang 社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过 go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc 这些很高大尚,还没有在项目中,真正的玩过,我看了一下官方提供的工具真的很好用,只需要定义好,舒适文件 jia 结构 都生成了,只需要关心业务,加上最近 有个投票的活动,加上最近这几年中台也比较火,所以决定玩一下,

    开源地址: https://github.com/jackluo2012/datacenter

    先聊聊中台架构思路吧:

    img

    中台的概念大概就是把一个一个的 app 统一起来,反正我是这样理解的。

    先聊用户服务吧,现在一个公司有很多的公众号,小程序,微信的,支付宝的,还有 xxx xxx ,很多的平台,每次开发的时候,我们总是需要做用户登陆的服务,不停的复制代码,然后我们就在思考能不能有一套独立的用户服务,只需要告诉我你需要传个你要登陆的平台(比如微信),微信登陆,需要的是客户端返回给服务端一个 code,然后服务端拿着这个 code 去微信获取用户信息,反正大家都明白。

    我们决定,将所有的信息 弄到 配置公共服务中去,里面在存,微信,支付宝,以及其它平台的 appid ,appkey,还有支付的 appid,appkey,这样就写一套。


    最后说说实现吧,整个就一个 repo:

    • 网关,我们用的是: go-zero 的 Api 服务

    • 其它它的是服务,我们就是用的 go-zero 的 rpc 服务

    看下目录结构

    img

    整个项目完成,我一个人操刀, 写了 1 个来星期,我就实现了上面的中台系统。

    datacenter-api 服务

    先看官方文档 https://www.yuque.com/tal-tech/go-zero/yaoehb

    我们先把网关搭建起来:

    ➜ blogs mkdir datacenter && cd datacenter
    ➜ datacenter go mod init datacenter
    go: creating new go.mod: module datacenter
    ➜ datacenter
    

    查看 book 目录:

    ➜  datacenter tree
    .
    └── go.mod
    
    0 directories, 1 file
    

    创建 api 文件

    ➜  datacenter goctl api -o datacenter.api
    Done.
    ➜  datacenter tree
    .
    ├── datacenter.api
    └── go.mod
    

    定义 api 服务

    分别包含了上面的 公共服务用户服务投票活动服务

    详情:https://github.com/jackluo2012/datacenter/blob/main/datacenter.api

    生成 datacenter api 服务

    ➜  datacenter goctl api go -api datacenter.api -dir .
    Done.
    

    我们打开 etc/datacenter-api.yaml 把必要的配置信息加上:datacenter-api.yaml

    上面的 UserRpcCommonRpc ,还有 VotesRpc 这些我先写上,后面再来慢慢加。

    我们先来写 CommonRpc 服务。

    CommonRpc 服务

    新建项目目录

    ➜  datacenter mkdir -p common/rpc && cd common/rpc
    

    直接就新建在了,datacenter 目录中,因为 common 里面,可能以后会不只会提供 rpc 服务,可能还有 api 的服务,所以又加了 rpc 目录

    goctl 创建模板

    ➜  rpc goctl rpc template -o=common.proto
    ➜  rpc ls
    common.proto
    

    往里面填入内容:user.proto

    gotcl 生成 rpc 服务

    ➜  rpc goctl rpc proto -src common.proto -dir .
    protoc  -I=/Users/jackluo/works/blogs/datacenter/common/rpc common.proto --go_out=plugins=grpc:/Users/jackluo/works/blogs/datacenter/common/rpc/common
    Done.
    

    基本上,就把所有的目录规范和结构的东西都生成了,就不用纠结项目目录了,怎么放了,怎么组织了。

    看一下,配置信息,里面可以写入 mysql 和其它 redis 的信息:rpc.yaml

    我们再来加上数据库服务:使用 goctl model 就行

    ➜  rpc cd ..
    ➜  common ls
    rpc
    ➜  common pwd
    /Users/jackluo/works/blogs/datacenter/common
    ➜  common goctl model mysql datasource -url="root:[email protected](127.0.0.1:3306)/datacenter" -table="base_app" -dir ./model -c
    Done.
    

    这样基本的一个 rpc 就写完了,然后我们将 rpc 和 model 还有 api 串连起来,这个官方的文档已经很详细了,这里就只是贴一下代码:

    ➜  common cat rpc/internal/config/config.go
    package config
    
    import (
        "github.com/tal-tech/go-zero/core/stores/cache"
        "github.com/tal-tech/go-zero/zrpc"
    )
    
    type Config struct {
        zrpc.RpcServerConf
        Mysql struct {
            DataSource string
        }
        CacheRedis cache.ClusterConf
    }
    

    再在 svc 中修改:user/rpc/internal/svc/servicecontext.go

    上面的代码已经将 rpcmodel 数据库关联起来了,我们现在再将 rpcapi 关联起来:internal/config/config.go

    加入 svc 服务中:internal/svc/servicecontext.go

    这样基本上,我们就可以在 logic 的文件目录中调用了:internal/logic/common/appinfologic.go

    这样,基本就连接起来了,其它基本上就不用改了,UserRPCVotesRPC 类似,这里就不在写了。

    使用心得

    go-zero 的确香,因为它有一个 goctl 的工具,他可以自动的把代码结构全部的生成好,我们就不再去纠结,目录结构 ,怎么组织,没有个好几年的架构能力是不好实现的,有什么规范那些,并发,熔断,完全不用,考滤其它的,专心的实现业务就好,像微服务,还要有服务发现,一系列的东西,都不用关心,因为 go-zero 内部已经实现了。

    我写代码也写了有 10 多年了,之前一直用的 php,比较出名的就 laravel,thinkphp,基本上就是模块化的,像微服那些实现直来真的有成本,但是你用上 go-zero,你就像调 api 接口一样简单的开发,其它什么服务发现,那些根本就不用关注了,只需要关注业务。

    一个好的语言,框架,他们的底层思维,永远都是效率高,不加班的思想,我相信 go-zero 会提高你和你团队或是公司的效率。go-zero 的作者说,他们有个团队专门整理 go-zero 框架,目的也应该很明显,那就是提高,他们自己的开发效率,流程化,标准化,是提高工作效率的准则,像我们平时遇到了问题,或是遇到了 bug,我第一个想到的不是怎么去解决我的 bug,而是在想我的流程是不是有问题,我的哪个流程会导致 bug,最后我相信 go-zero 能成为 微服务开发 的首选框架。

    最后说说遇到的坑吧:

    • grpc

    grpc 本人第一次用,然后就遇到了,有些字符为空时,字段值不显示的问题:

    通过 grpc 官方库中的 jsonpb 来实现,官方在它的设定中有一个结构体用来实现 protoc buffer 转换为 JSON 结构,并可以根据字段来配置转换的要求。

    • 跨域问题

    go-zero 中设置了,感觉没有效果,大佬说通过 nginx 设置,后面发现还是不行,最近强行弄到了一个域名下,后面有时间再解决。

    • sqlx

    go-zerosqlx 问题,这个真的费了很长的时间:

    time.Time 这个数据结构,数据库中用的是 timestamp 这个 比如我的字段 是 delete_at 默认数库设置的是 null,结果插入的时候,就报了 Incorrect datetime value: '0000-00-00' for column 'deleted_at' at row 1"} 这个错,查询的时候报 deleted_at\": unsupported Scan, storing driver.Value type \u003cnil\u003e into type *time.Time"

    后面果断去掉了这个字段,字段上面加上 .omitempty 这个标签,好像也有用,db:".omitempty"

    其次就是这个 Conversion from collation utf8_general_ci into utf8mb4_unicode_ci,这个导致的大概原因是,现在都喜欢用 emj 表情了,mysql 数据识别不了。

    • 数据连接

    mysql 这边照样按照原始的方式,将配置文件修改编码格式,重新创建数据库,并且设置数据库编码为 utf8mb4,排序规则为 utf8mb4_unicode_ci

    这样的话,所有的表还有 string 字段都是这个编码格式,如果不想所有的都是,可以单独设置,这个不是重点.因为在 navicat 上都好设置,手动点一下就行了

    重点来了:golang 中使用的是 github.com/go-sql-driver/mysql 驱动,将连接 mysqldsn(因为我这使用的是 gorm,所以 dsn 可能跟原生的格式不太一样,不过没关系, 只需要关注 charsetcollation 就行了)

    root:[email protected]/name?parseTime=True&loc=Local&charset=utf8 修改为: root:[email protected]/name?parseTime=True&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci

    go-zero 项目地址

    https://github.com/tal-tech/go-zero

    40 条回复    2020-12-22 07:50:38 +08:00
    lpts007
        1
    lpts007  
       352 天前 via Android   ❤️ 7
    话说用了这个框架的人,发帖格式怎么都一样啊?
    看来是有魔力,我也去用下试试
    kevinwan
        2
    kevinwan  
    OP
       352 天前
    Geekerstar
        3
    Geekerstar  
       352 天前
    @lpts007 hhhh
    zarte
        4
    zarte  
       352 天前
    其实我只想要个 go 写的网关
    putaozhenhaochi
        5
    putaozhenhaochi  
       352 天前
    不是宣传 goctl 吗?
    laminux29
        6
    laminux29  
       352 天前
    ......

    数据中台本质上就是存储数据、统一数据并对外提供数据检索接口,业务没有任何难点,说白了就是 CURD 。但作为胶水特性的系统,最关键是要考虑与其他语言系统的可集成性,以及二开的便捷性。

    因此,数据中台的实现,关键点在于,你用的编程语言,你的编程环境,是否针对集成与二开有帮助。

    而且,这类系统,一般采购方都是体制内的,为了推锅,Oracle 肯定跑不了。

    那么,假设你的用户,现在有烂大街的 java + Oracle 的方案,以及你的 go 方案,你觉得用户会买哪一套?
    bbao
        7
    bbao  
       352 天前
    kevinwan
    大道至简!
    🏢 好未来 / 资深专家

    兄弟,啥也不说了。
    kevinwan
        8
    kevinwan  
    OP
       352 天前
    @laminux29 不管用户买哪一套,开源共享总是鼓励的
    GM
        9
    GM  
       352 天前
    这种事情,一言难尽,我就发个图吧:
    你以为的中台和实际上的中台:

    https://i.loli.net/2020/12/21/ZFm8hxLacClIB2v.png
    ZSeptember
        10
    ZSeptember  
       352 天前
    额,这不就是一个 CRUD 接口吗。
    huskar
        11
    huskar  
       352 天前 via Android
    就这?请移到推广
    kiddingU
        12
    kiddingU  
       352 天前
    哎,我看了作者的一些发帖,感觉略微有点尬....开源这玩意怎么说了,酒香不怕巷子深~~不用特意去太多推广,好东西自然会有人用的
    kevinwan
        13
    kevinwan  
    OP
       352 天前
    @kiddingU 那么用户发的贴,我征得作者同意,转发一下可以的吧,如果这也不行,那这类帖子我就不发了
    yplove156
        14
    yplove156  
       352 天前
    别什么都往中台上套,框架就框架,中台是企业能力的沉淀,是数据能力、技术能力,业务能力的沉淀以达到对需求对快速响应。不是某一套框架、系统就可以说是中台的。
    hinate
        15
    hinate  
       352 天前
    @laminux29 #6 现在都在去 oracle 化了...
    zhaohua
        16
    zhaohua  
       352 天前
    go-zero 也挺香的,但是这玩意叫中台你不觉得丢分吗?
    kevinwan
        17
    kevinwan  
    OP
       352 天前
    @zhaohua 用户这么写的,我只是代发,因为他跟我说上不了 v2ex,让我代他发一下哈,尊重作者原意呢
    kevinwan
        18
    kevinwan  
    OP
       352 天前
    下次不代发,哈哈,我的错
    mrhhsg
        19
    mrhhsg  
       352 天前
    ...楼主你推广就推广呗,推广自己的开源作品这不寒碜
    laminux29
        20
    laminux29  
       352 天前
    @hinate 你和领导讲,用 Oracle 会贵一点,但如果丢数据,不用担责,因为这是世界上最好的数据库,如果它都丢数据了,别的数据库肯定只会更惨。

    但如果去 IOE,不用 Oracle,改用免费数据库比如 mysql,到时候一堆问题,天天丢数据,还要花钱招高价运维,说不定成本更高,丢了数据还要自己担责。

    你觉得领导会选啥?
    salmon5
        21
    salmon5  
       352 天前
    你用一周就用一周呗,标题党,我还用一天呢
    teawithlife
        22
    teawithlife  
       352 天前
    十多年开发,居然连跨域问题就解决不了。。。
    ben1024
        23
    ben1024  
       352 天前
    频繁发就挺烦
    gowk
        24
    gowk  
       352 天前   ❤️ 1
    虽说我喜欢 Go,本来应该不遗余力的 Go 社区的发展壮大,但这么花式的推广,我是没有想到的。。
    noobalex
        25
    noobalex  
       352 天前
    代发文章推广自己的框架 @Livid
    tt2ll
        26
    tt2ll  
       352 天前
    @laminux29 去 ioe,采购 rds,买容器云,用 go 语言,涨工资
    zk123
        27
    zk123  
       352 天前
    vs 和 goland 哪个写起 go 来体验比较好
    sampeng
        28
    sampeng  
       352 天前   ❤️ 1
    麻烦把中台二字去了。这种推广真的丢研发人的脸。
    我不信有企业敢选择这样的设施
    ErwinCheung
        29
    ErwinCheung  
       352 天前   ❤️ 1
    @zk123 goland JB 天下第一
    Numbcoder
        30
    Numbcoder  
       352 天前   ❤️ 2
    go-zero 没用过不做评价。
    但就这几个简单功能,放在我司,交给三年左右经验的开发,用 py/node,最多两天完成,超过两天我都怀疑你在摸鱼
    wellsc
        31
    wellsc  
       352 天前 via iPhone
    @noobalex 没记错的话,楼主已经被降权了
    whimsySun
        32
    whimsySun  
       352 天前
    @Numbcoder 你司开多少钱,这样的人才我司愿意出双倍,你推荐下,给推荐费
    echowuhao
        33
    echowuhao  
       352 天前
    @whimsySun V 站上吹牛逼的太多了。

    v 站上都是 2 天完成一个框架,一周完成 1 个 app 。

    我之前一个 bug 搞了一个星期,老板还说我搞得快。大部分时间,一个 bug,半天就过去了。你们写代码都没有 bug 么。
    echowuhao
        34
    echowuhao  
       352 天前
    我觉得有些人太消极了,你说人家不好,自己弄个好的。
    whimsySun
        35
    whimsySun  
       352 天前
    @echowuhao 哈哈哈,不过文章有点标题党了一些,这几个模块一般不会归类到数据中台。没有用过 go-zero,看 goctl 确实挺方便。
    kevinwan
        36
    kevinwan  
    OP
       352 天前 via iPhone
    @whimsySun 业务中台哈,对中台确实有不同理解和误解,如有不妥,请见谅
    echowuhao
        37
    echowuhao  
       352 天前
    这些概念本来就不是确定的。对于 linus 来讲,写数据库的都是前端。
    msg7086
        38
    msg7086  
       352 天前
    @laminux29 没有人会因为采购 IBM 而被开除.avi
    Livid
        39
    Livid  
    MOD
       352 天前
    @huskar
    @noobalex

    谢谢举报。这个主题已经被移动到 /go/promotions

    @kevinwan 软文只能发到 /go/promotions 如果你继续持续忽略我们的规则,那么我们只能封号了。
    kevinwan
        40
    kevinwan  
    OP
       352 天前 via iPhone
    @Livid 收到,以后不发用户文章,只发技术分享🤝
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3428 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 01:18 · PVG 09:18 · LAX 17:18 · JFK 20:18
    ♥ Do have faith in what you're doing.