go-zero 成长之路—微服务电商实战系列(二、划分篇)

该系列源码已开源:micro-shop

1. 概述

微服务架构是一种架构风格,它将一个大的系统构建为多个微服务的集合,这些微服务是围绕业务功能构建的,服务关注单一的业务功能,这些服务具有以下特点:

  • 高度可维护和可测试
  • 松散的耦合
  • 可独立部署
  • 围绕业务功能进行构建
  • 由不同的小团队进行维护

微服务架构能够快速、频繁、可靠地交付大型、复杂的应用程序,通过业务拆分实现服务组件化,使用组件进行组合从而快速开发系统。

在这里插入图片描述

2. 服务划分

在实际项目开发中,我们通常采用两种微服务划分策略:

  • 第一种:通过业务职能进行边界进行划分
  • 第二种:通过DDD界限上下文进行边界划分

我们这里采用大家比较容易理解的业务职能的方式进行微服务划分,再次贴上我们电商项目的思维导图:

在这里插入图片描述

从以上思维导图可以看出,我们根据业务职能做如下微服务的划分:

  • 商品服务(product) - 商品的添加、信息查询、库存管理等功能
  • 购物车服务(cart) - 购物车的增删改查、收藏等功能
  • 订单服务(order) - 生成订单,订单管理等功能
  • 支付服务(pay) - 通过调用第三方支付实现支付等功能
  • 账号服务(user) - 用户信息、实名认证、账号设置、地址管理等功能
  • 首页服务(home) - 首页商品推荐、排行榜、限时开抢、banner等功能

每个服务都可以再分为 api 服务和 rpc 服务。

api 服务对外,可提供给 app 调用。

rpc 服务是对内的,可提供给内部 api 服务或者其他 rpc 服务调用。

整个项目服务依赖流程图大致如下:

在这里插入图片描述

3. BFF层

一般对于客户端我们会采用HTTP接口的方式提供服务,以上划分的这些微服务都需要直接提供HTTP接口对外提供服务,当然这样架构整体看起来也会比较简单。

在这里插入图片描述

但是这只是一个相对简单并且没有高并发的系统来。

对于一个复杂的高并发系统来讲,我们需要处理各种异常场景,比如:

  • 某些页面需要依赖多个微服务提供数据,为了避免串行请求导致耗时过长。一般会采用并行请求多个微服务,这个时候其中某一个服务请求异常或宕机,那我们可能需要做一些特殊的处理,比如数据降级等

  • 某些页面需要组合多个微服务的数据满足业务需求时,如果每个微服务都提供HTTP对外接口,那这些复杂数据组合和异常处理都要在客户端完成,大家都知道客户端是不宜做复杂业务逻辑的,它的重点在与做交互体验,所以我们的架构组要做到前轻后重(即客户端逻辑尽量少而把比较重的业务处理逻辑下沉到服务端,而服务端又根据业务职能拆分成了不同的微服务,这些微服务只关注单一的业务

那么这些面向业务场景的复杂逻辑的处理应该放到哪里呢?

我们的解决方案就是加一层,即BFF层,通过BFF对外提供HTTP接口,客户端只与BFF进行交互。

在这里插入图片描述

BFF层的引入解决了我们上面遇到的问题,但增加一层就会增加架构的复杂度,所以如果你的服务是一个单体应用的话,那么BFF是不必要的,引入它不会增加任何价值。

对于我们当前项目来说,应用程序依赖于微服务,同时需要面向业务功能提供HTTP接口和要保证接口的高可用,所以BFF对于当前项目来说是一个合适的选择。

BFF在这里不做太多说明。具体可以自行百度搜索。

4. 服务实现

  • 用户服务 user
api服务端口:9001rpc服务端口:8080
login用户登录接口login用户登录接口
register用户注册接口register用户注册接口
userinfo用户信息接口userinfo用户信息接口
  • 首页服务 home
api服务端口:9002rpc服务端口:8081
banner首页Banner接口banner首页Banner接口
recommend人气推荐接口recommend人气推荐接口
ranking-list排行榜接口ranking-list排行榜接口
  • 产品服务 product
api服务端口:9004rpc服务端口:8083
detail商品详情接口detail商品详情接口
lists商品列表接口lists商品列表接口
stock商品库存接口stock商品库存接口
cate-lists分类列表接口cate-lists分类列表接口
search搜索接口search搜索接口
  • 订单服务 order
api服务端口:9003rpc服务端口:8082
create-order创建订单接口create-order创建订单接口
order-detail订单详情接口order-detail订单详情接口
order-list订单列表接口order-list订单列表接口
order-cancel订单取消接口order-cancel订单取消接口
  • 支付服务 pay
api服务端口:9004rpc服务端口:8083
pay-order订单支付接口pay-order订单支付接口
pay-callback支付回调接口pay-callback支付回调接口
  • 购物车服务 cart
api服务端口:9004rpc服务端口:8083
cart-add添加购物车接口cart-add添加购物车接口
cart-edit编辑购物车接口cart-edit编辑购物车接口
cart-del删除购物车接口cart-del删除购物车接口
cart-edit-num购物车数量变更接口cart-edit-num购物车数量变更接口

5. 目录结构

创建目录结构

microShop
├── cart             // 购物车服务
│   ├── api          
│   └── rpc          
├── home             // 首页服务
│   ├── api
│   └── rpc
├── order            // 订单服务
│   ├── api
│   └── rpc
├── pay              // 支付服务
│   ├── api
│   └── rpc
├── product          // 产品服务
│   ├── api
│   └── rpc
└── user             // 用户服务
    ├── api
    └── rpc
...
...

以上就是咱们这次要实现服务的大体目录结构。

初始化目录

规划好服务目录结构后,咱么要进行开发离不来一个重要的环节:初始化go-zero 如何初始化呢?

还记得上一章节 4小节说的吗? 如果不记得请看:go-zero 成长之路—微服务电商实战系列(一、需求篇)4小节:需要使用到的命令和工具。

上一章节咱们提到过:goctl,这个工具就是go-zero用来快捷开发的一个服务生成工具。

具体的使用命令呢,可以去 go-zero 官方文档中查看。在这里咱们不过多介绍。

接下来咱们就来直接使用,以 user服务为例:

  • 构建 API 服务,有两种构建方式:
// 方式1:一键初始化api服务
goctl api new user

// 方式2:通过 编写的 user.api 文件进行生成, api.api 文件语法,参考 go-zero 官方文档
goctl api go -api user.api -dir . -style go-zero  

构建后的目录结构如下:

├── api.api
├── etc
│   └── user-api.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── handler
│   │   ├── handlers.go
│   │   └── routes.go
│   ├── logic
│   │   ├── login-logic.go
│   │   └── register-logic.go
│   ├── svc
│   │   └── service-context.go
│   └── types
│       └── types.go
├── model
│   ├── user_model.go
│   ├── user_model_gen.go
│   ├── user_receive_address_model.go
│   ├── user_receive_address_model_gen.go
│   └── vars.go
├── sql
│   └── user.sql
└── user.go

构建后怎么进行启动呢?通过go run 具体参考 go-zero 官方文档

go run user.go -f etc/user-api.yaml
  • 构建 RPC 服务:
// 首先先创建 proto 文件
touch account.proto

// 书写proto文件配置, 具体参考 `go-zero` 官方文档

// 根据proto 文件生成RPC服务
goctl rpc protoc account.proto --go_out=./types --go-grpc_out=./types --zrpc_out=. -style go-zero 

构建后的目录结构如下:

├── account.go
├── account.proto
├── etc
│   └── account.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── logic
│   │   ├── login-logic.go
│   │   └── register-logic.go
│   ├── server
│   │   └── user-server.go
│   └── svc
│       └── service-context.go
├── model
│   ├── user_model.go
│   ├── user_model_gen.go
│   ├── user_receive_address_model.go
│   ├── user_receive_address_model_gen.go
│   └── vars.go
├── types
│   └── account
│       ├── account.pb.go
│       └── account_grpc.pb.go
└── user
    └── user.go

启动方式 同上

go run account.go -f etc/account.yaml
  • 构建 model 模型,有两种构建方式,具体参考 go-zero 官方文档
// 首先 先导出 sql 文件
// 其次通过sql文件的方式进行生成,也就是 ddl 方式
goctl model mysql ddl -src="*.sql" -dir="." -c -style go-zero

// 通过资源句柄链接方式进行生成
goctl model mysql datasource -url="user:password@tcp(127.0.0.1:3306)/database" -table="*"  -dir="./model"

到这里user服务的代码初始化已经完成,其他服务和user服务类似,这里就不再多说了。

6. 结束语

本篇我们讲解了微服务的定义,微服务是围绕业务功能构建的,服务关注单一的业务,服务间采用轻量级的通讯机制,每个微服务都可以独立的部署和测试。

我们根据商城功能进行了微服务的拆分,主要拆分了购物车订单支付商品首页推荐用户等服务,然后我们又说明了为什么需要引入BFF服务,BFF本质上是一个用于做数据组装的服务,对外提供面向业务功能的或者说面向客户端UI的HTTP接口。

接着我们定义了我们这个工程的目录结构,主要分为apirpc等服务,不同服务的职责不同,api对外提供HTTP接口,rpc对内提供RPC接口。

最后我们通过goctl对项目做了初始化,使用goctl可一键生成项目框架代码,大大提供了生产力。

希望本篇文章对你有所帮助,谢谢。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码一行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值