使用GO的workspace工作区配合私有库重构多端非微服务项目

367 阅读3分钟

前言

今天我们讲一下在不使用微服务的情况下,如何使用GO的workspace(中文应该是叫工作区)配合私有库来重构多端非微服务项目。

前提

现在有一个项目,代码分成了商户端biz和管理端admin。分别提交到不同的git代码库中。两个项目连接的数据库是同一个。整个项目没有微服务化。

问题

但现在商户端和管理端有很多业务逻辑很类似。比如查看商户余额,可能商户端和管理端都需要调用一个接口叫 balance.Get(merchantId int),粗暴的做法是把这个方法在bizadmin两个git仓库里都写一份。

随着代码量增加,这个balance.Get接口将会不断迭代。这时候需要把两边的代码同步修改一份。

唔,闻到代码的臭味了。

方案

微服务

一种方法是把bizadmin项目重构为微服务项目,新增一个balance的微服务,bizadmin通过RPC调用来获得数据。此后balance内部业务更新只需要关注自身即可。

但这个方法需要对bizadmin项目进行微服务改造,项目时间上不允许。暂时不使用此方法

私有库

可以将balance的业务方法封装进另一个service私有库,然后使用私有库的方法进行开发。在bizadmingo.mod文件中设置好replace后,再调用service库中的方法。此后service库即可以独立迭代。不需要在biz/admin中反复修改。

但这个方法的问题在于go.mod文件中的replace中需要指定开发者的本地路径,而在多人开发的情况下,这个本地路径每人不同,提交上去后会污染其它开发者的开发环境。不是最佳解决方案。

workspace方案

GO 1.18中引入了workspace,可以将不同目录的项目编排在一起。

bizadmin放在同一个目录下,创建service项目,创建go.work文件。

workspaceDir
├── biz
│   ├── .git
│   ├── go.mod      // biz项目
│   └── main.go
├── admin
│   ├── .git
│   ├── go.mod      // admin项目
│   └── main.go
├── service
│   ├── .git
│   ├── go.mod      // service项目
│   └── main.go
├── go.work         // 工作区

go.work文件内容如下

go 1.18

use (
    ./biz 
    ./admin
    ./service
)

在工作区目录下执行go work sync之后,此时在 bizadmin中就可以方便地调用service包里的方法了。

比如在biz项目中可以直接使用如下的use

use "service/sdk/balance"

main() {
    balance.Get(1)
}

workspace的方案已经避免了前个方案在go.mod中使用 replace 导致污染的问题。并且各端都可以独立提交git仓库。

workspace + 私有库

如果再优化一点,将service库当作内部独立库提交到私有库中。那么最终的调用方式会是这样的:

use "git.mydomain.com/team/service/sdk/balance"

main() {
    balance.Get(1)
}

当 service 进入相对稳定状态时,就可以这么干了。这样万一有新的仓库不需要加入workspace的时候,就可以直接使用私有库。

后记

这样拆分后代码比较干净,也相对好维护,团队切换成本低。未来如果需要切换成微服务的话也有基础。

希望大家好运。