我像“小马过河”一样升级了我的开源系统

开源
我也在社区中和大家沟通了升级问题:有的大佬表示自己是新开一个项目用V2重写的;有的大佬表示升级很简单,就是目录变更一下,业务逻辑还是可以用的,费不了多长时间。​

前言

我在升级之前做了比较充分的准备工作,深入研究了GoFrame V2新特性才决定升级的,并且总结了一篇文章:# ​​站在开发者的角度理解框架的设计思想​​。

区别于官方文档,我是站在开发者的角度,总结分享了V2版本相比于V1版本的优势,实践了我的有着130多个接口的# ​​开源电商项目的升级踩坑之旅​​,希望对大家有帮助。

目前开源电商系统V2版正在开发中,欢迎Star:https://github.com/wangzhongyang007/goframe-shop-v2

基于Gin+Gorm+VUE的集五福营销裂变项目也在脱敏中,后面会开源出来供大家学习使用。

先说结论

我决定用我的开源项目# ​​开源电商前后台API系统 实践升级之旅​​。

这是一个单体项目,适合新手入门,开发了超过了130个接口,不管是新手入门还是实践升级之旅都比较有代表性:包括了传统电商需要的基本功能,也有进阶高并发的解决方案。

欢迎Star:https://github.com/wangzhongyang007/goframe-shop

图片

我最终结合自己的项目情况,决定用V2重写开源项目,而不是用V1升级到V2,因为我的工程设计思想和V2建议的工程结构差别很大。

经过仔细考量后,我认为V2的工程架构更好,虽然门槛稍高一点,但是在项目后期更易于维护。

实践出真知

我调研实操的经历,还是非常有参考价值的,我的项目不适合从V1升级到V2,而是用V2重写,并不代表你的项目不适合。这个经历真的就像“小马过河”一样。

升级之旅

下面就介绍一下我的升级之旅:

1. 首先查看之前的版本:

图片

2. 替换依赖库

在工程文件中进行替换,把所有的:github.com/gogf/gf/ 全部替换为:github.com/gogf/gf/v2/

图片

3.按提示解决错误

替换之后尝试运行,肯定会出错,但是没关系,提示什么错误就解决什么错误嘛:

图片

我尝试根据提示执行 go get 相关依赖,但是并没有生效。

4.升级框架和CLI工具

突然想到我只是替换了项目中的依赖包,但是并没有更新GoFrame框架和GoFrame CLI工具。

而且通过查阅官方文档得知:GoFrame是支持v1和v2同时使用的,但是官方并不建议,因为同时使用会导致维护成本很高。

注意:框架是框架,cli是cli,两者不要混淆在一起。官方文档有详细介绍,不再重复阐述:官方文档[1]

在升级CLI工具时踩了很多坑,因为通过查阅官方文档,发现了很多种升级方式,但我在实践中前几种均未生效,最终是通过下面的方式升级成功的。

wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH) && chmod +x gf && ./gf install -y && rm ./gf

注意:如果是MacOS下使用zsh的小伙伴可能会遇到别名冲突问题,可以通过alias gf=gf来解决,运行一次之后gf工具会自动修改profile中的别名设置,用户重新登录(或者重开终端)就好了。

5. CLI升级成功

CLI升级安装成功的示例图:

图片

查看gf cli版本 已经更新到了v2.2.0 最新版:

图片

6.及时备份

因为升级CLI我花了好长时间,做了各种尝试,所以我决定及时提交git做好备份,养成好习惯:

图片

在解决了CLI升级问题之后,我真的长舒了一口气。准备迎接新的挑战吧:

7.gtoken升级

解决gtoken的问题还是很简单的,升级gtoken就可以了,正如官方文档所说gtoken已经全面拥抱GoFrame V2版本了:

图片

安装升级gtoken的教程如下:

  • gopath模式:go get github.com/goflyfox/gtoken
  • 使用go.mod添加:require github.com/goflyfox/gtoken latest

图片

我是使用gopath模式安装的,很顺利;我们再继续解决新的报错:

8.gmvc问题

图片

通过查阅文档得知,gmvc已经废除,以后也不再支持了:

图片

9.最新版的gf CLI生成dao

准备迎接新的挑战吧,用最新版的gf CLI生成dao:

图片

并没有迎接到暴风雨, 而是卡住了。

原因是这样的,正如我开篇说的:

V2版本的工程目录做了调整,官方说:如果你的V1项目使用的是GoFrame官方推荐的工程目录结构,可以参考最新的工程目录结构手动调整即可:工程目录设计[2]。

需要注意的是,最新的cli工具不再支持旧版工程目录的项目创建。

10.调整项目的目录结构

我们需要调整项目的目录结构,参考链接如下:https://GoFrame.org/pages/viewpage.action?pageId=30740166

我在项目根目录下,新建internal目录,然后执行 gf gen dao 还是很丝滑的。

图片

11.分析V2的gf gen dao

我发现v2版本的cli不仅给我们生成了dao层,在model层中还细分了do层和entity层。

为什么这么设计,大家有时间可以看官方文档:https://GoFrame.org/pages/viewpage.action?pageId=30740166

在这里我只说结论:

  1. dao层用于数据访问,这是一层抽象对象,用于和底层数据库交互,仅包含最基础的 CURD 方法
  2. model层是结构模型,是数据结构管理模块,管理数据实体对象,以及输入与输出数据结构定义。

model中的do是领域对象,用于dao数据操作中业务模型与实例模型转换,由工具维护,用户不能修改。

model中的entity是数据模型,数据模型是模型与数据集合的一对一关系,由工具维护,用户不能修改。

图片

12.再次备份

为了方便找回资料,我在修改目录结构之前也在本地做了备份,方便我一会复制粘贴代码,小伙伴们也可以借鉴一下。

图片

13.调整目录结构

图片

官方建议的工程目录

目录/文件名称

说明

描述

api

对外接口

对外提供服务的输入/输出数据结构定义。考虑到版本管理需要,往往以api/v1...存在。

hack

工具脚本

存放项目开发工具、脚本等内容。例如,CLI工具的配置,各种shell/bat脚本等文件。

internal

内部逻辑

业务逻辑存放目录。通过Golang internal特性对外部隐藏可见性。

- cmd

入口指令

命令行管理目录。可以管理维护多个命令行。

- consts

常量定义

项目所有常量定义。

- controller

接口处理

接收/解析用户输入参数的入口/接口层。

- dao

数据访问

数据访问对象,这是一层抽象对象,用于和底层数据库交互,仅包含最基础的 CURD 方法

- logic

业务封装

业务逻辑封装管理,特定的业务逻辑实现和封装。往往是项目中最复杂的部分。

- model

结构模型

数据结构管理模块,管理数据实体对象,以及输入与输出数据结构定义。

- do

领域对象

用于dao数据操作中业务模型与实例模型转换,由工具维护,用户不能修改。

- entity

数据模型

数据模型是模型与数据集合的一对一关系,由工具维护,用户不能修改。

- service

业务接口

用于业务模块解耦的接口定义层。具体的接口实现在logic中进行注入。

manifest

交付清单

包含程序编译、部署、运行、配置的文件。常见内容如下:

- config

配置管理

配置文件存放目录。

- docker

镜像文件

Docker镜像相关依赖文件,脚本文件等等。

- deploy

部署文件

部署相关的文件。默认提供了Kubernetes集群化部署的Yaml模板,通过kustomize管理。

resource

静态资源

静态资源文件。这些文件往往可以通过 资源打包/镜像编译 的形式注入到发布文件中。

go.mod

依赖管理

使用Go Module包管理的依赖描述文件。

main.go

入口文件

程序入口文件。

因为我之前的目录结构也不是严格按照goFrame v1.xx示例设计的,而是根据项目的前后端需求自定义设计的。

所以意识到了:要想顺利升级,工作量还是非常大的,应该需要修改很多代码。

我参考文档修改了自己项目的目录:

13.1 迁移api层

我把之前写的对外接口相关的代码放到api层:

图片

13.2 替换dao和model被引用的路径

迁移之后遇到了新问题:

图片

咱们来分析一下,目前做的操作只是:

  1. 通过最新的gf cli工具在项目根目录的internal目录下生成了新的dao和model层;
  2. 删除了之前app目录下的dao层和model层。

那咱们全局替换一下imports的目录不就行了:

全局替换dao和model的目录:

  • 把shop/app/dao替换为:shop/internal/dao
  • 把shop/app/model替换为:shop/internal/model

OK,顺利的解决了上面的问题。

14.解决神奇的问题

又遇到了新的问题:提示我 xxx is not in GOROOT。

图片

我尝试通过用goland打开我的go/src目录,而不是直接打开shop工程目录,来解决问题:

这招比较好用,项目的依赖不再全部飘红,并且goland也给出了提示:

图片

图片

15.解决构建约束问题

分析一下原因:新的工程目录使用了internal目录,进行了约束。意思也就是除了对外暴露接口的方法放在api目录,其他不需要对外的逻辑都要放在internal中:

图片

好吧,啥也别说了,继续修改:

我将之前处理业务逻辑的app目录中的文件迁移到internal目录中。

温馨提示:你的项目是哪个目录不重要,总之,按照GoFrame V2的原则,只有api目录用于暴露给外部,不需要暴露给外部的逻辑全部放在internal目录中:

图片

16.项目工程目录和V2建议的工程目录统一

我结合自己的项目情况,移动和重命名了业务逻辑文件和目录,整体还是很顺滑的:

我之前的项目以library作为公共程序包,官方建议使用utility目录,还是以官方为准吧,这样以后在社区中沟通也能降低理解难度:

图片

经过目录调整,修改后的目录结构和官方建议的目录结构基本一致了:

图片

然后继续各种运行,报错,解决错误,整体上都比较好解决,就不做记录了。

值得分享的经验就是:不要怕报错多,整体看一遍,找找共同特点。绝大多数都是可以根据提示顺利解决的问题。

17.迁移业务逻辑

在迁移业务逻辑时发现了新问题:

我通过研究V2的官方示例得知,service层内部每个文件都以接口的方式定义,且service层是能够通过代码自动生产的:

如何预定义接口需要实现的方法呢?

图片

答案是:在logic层编写代码,通过工具生成对应的service文件;在logic层的init()方法中调用service层的RegisterXXX()方法进行服务注册,由此可见复杂的逻辑都是在logic层处理的。

图片

18. 通过CLI生成service

通过cli生成service是非常重要的操作,因为这部分代码必须工具生成,所以我们要先了解这个知识点,先说我的结论:

  1. 业务模块之间的依赖通过接口化解耦,将原有的service分类调整为接口目录。这样每个业务模块将会各自维护、更加灵活。
  2. 该命令通过分析给定的logic业务逻辑模块目录下的代码,自动生成service目录接口代码。
  3. 生成接口及服务注册文件

更多介绍可以查看官方文档:接口维护-gen service[3]

19. 反思

写到这里,目前的心得体会是一定要搞清楚v2版本的设计思想,再从v1升级到v2,否则升级到一半会导致无从下手。

因为通过V2版本的CLI工具生成的dao、model 和v1版本版本是不一致的。

同时V2版本也支持gf gen service的方式,统一我们的接口维护方式。

再次强烈大家看我这篇文章:# 站在开发者的角度理解框架的设计思想

从框架开发者和使用者两个角度去学习升级V2的知识点。

20.“分水岭”问题

到这里是一个重要的分水岭了:是升级迁移,还是直接用V2重写,这个没有标准答案,咱们应该在吃透了V2新特性和工程设计思想后,结合已有的项目特点去决定。

我结合自己的项目特点,经过仔细分析,再加上和GoFrame社区大佬们的沟通,我决定用GoFrame V2版本直接重写,而不是在已有项目上做迁移。

因为我的项目结构和v2的设计思想差别太大了,升级无异于重写,甚至可能花费的精力更多。

我开源项目的工程设计是这样的:

  1. 首先在app目录新建了system目录,用于管理多个终端:

backend对应电商平台的后台接口

frontend对应电商平台的前台接口。

  1. 在每个终端下又都是按照功能模块做了区分,每个功能模块都会创建一个单独的目录。我们以admin目录举例:
  • admin.go:定义请求和响应的结构体
  • admin_api.go:定义了对外api的方法,调用下方admin_service.go中封装的逻辑
  • admin_service.go:编写业务逻辑,通过dao操作DB

图片

显然,我的架构设计和GoFrame V2的工程设计思路差别是很大的,经过慎重思考,我决定基于V2最新版本重写开源项目,也欢迎小伙们加入我们。

总结

在遇到“分水岭”问题之前,GoFrame从v1升级到v2的过程还是比较顺滑的。

我也在社区中和大家沟通了升级问题:有的大佬表示自己是新开一个项目用V2重写的;有的大佬表示升级很简单,就是目录变更一下,业务逻辑还是可以用的,费不了多长时间。

这个问题就像“小马过河”的故事一样,大家还是要结合自己的项目情况:

  1. 如果你是按照V1版本建议的工程目录或者你的设计思想本身就和V2版本比较契合,那就直接升级。
  2. 如果你像我一样,已有项目的工程目录和设计思路和V2版本有较大区别,并且在认真学习v2版本的工程实践和新特性之后,觉得V2版本更适合你项目的后期维护迭代,那就抓紧用V2直接重写项目吧。

相关资料

[1] 官方文档: https://GoFrame.org/pages/viewpage.action?pageId=1115790

[2] 工程目录设计: https://GoFrame.org/pages/viewpage.action?pageId=30740166

[3] 接口维护-gen service: https://GoFrame.org/pages/viewpage.action?pageId=49770772

[4] Go开源电商项目教程-教程大纲+开源地址: https://b23.tv/hdOpOTp

本文转载自微信公众号「 程序员升级打怪之旅」,作者「王中阳Go」,可以通过以下二维码关注。

转载本文请联系「 程序员升级打怪之旅」公众号。

责任编辑:武晓燕 来源: 程序员升职加薪之旅
相关推荐

2012-03-07 17:24:10

戴尔咨询

2011-02-28 10:38:13

Windows 8

2012-12-20 10:17:32

IT运维

2023-10-30 13:17:10

开源软件

2023-09-04 14:28:33

FlarumDiscourse开源

2009-06-12 15:26:02

2015-08-25 09:52:36

云计算云计算产业云计算政策

2013-01-11 18:10:56

软件

2022-09-23 15:23:08

webpack5改变代码

2019-06-27 09:05:29

操作系统Android 华为

2022-04-14 19:39:39

Java线程安全

2019-03-19 09:34:41

离职跳槽月薪

2010-07-07 14:37:40

MeeGo英特尔

2024-04-03 13:50:00

开源模型

2020-02-14 14:36:23

DevOps落地认知

2017-05-25 15:02:46

联宇益通SD-WAN

2021-06-28 10:06:21

开源文本识别pyWhat

2015-10-19 12:33:01

华三/新IT

2016-05-09 18:40:26

VIP客户缉拿

2021-07-23 09:50:12

程序员技能开发者
点赞
收藏

51CTO技术栈公众号