go-zero 微服务实战系列(二、服务拆分)

简介: go-zero 微服务实战系列(二、服务拆分)

微服务概述

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

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

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

服务划分

我们首先进行微服务的划分,在实际的项目开发中,我们通常采用两种微服务划分策略,第一种方式是通过业务职能进行微服务边界的划分,第二种方式是通过DDD的界限上下文进行微服务边界的划分,我们这里采用大家比较容易理解的业务职能的方式进行微服务划分,再次贴上我们电商项目的思维导图:

从以上思维导图可以看出整个电商系统功能还是比较多的,我们根据业务职能做如下微服务的划分:

  • 商品服务(product) - 商品的添加、信息查询、库存管理等功能
  • 购物车服务(cart) - 购物车的增删改查
  • 订单服务(order) - 生成订单,订单管理
  • 支付服务(pay) - 通过调用第三方支付实现支付功能
  • 账号服务(user) - 用户信息、等级、封禁、地址管理
  • 推荐服务(recommend) - 首页商品推荐
  • 评论服务(reply) - 商品的评论功能、评论的回复功能

BFF层

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

但对于一个复杂的高并发的系统来说,我们需要处理各种异常的场景,比如某个页面需要依赖多个微服务提供的数据,为了避免串行请求导致的耗时过长,我们一般会并行的请求多个微服务,这个时候其中的某个服务请求异常的话我们可能需要做一些特殊的处理,比如提供一些降级的数据等。还有我们的页面展示的数据往往都是面向业务功能的,而不是单单某一个微服务的数据,这时候我们往往需要组装多个微服务的数据来满足需求,如果我们每个微服务都直接对外提供HTTP接口的话,那么这些复杂的数据组装和异常处理等工作只能由客户端来完成。众所周知客户端是不宜做复杂的业务逻辑的,客户端的重点应该更多是做交互体验上的优化,我们的整体架构需要做到前轻后重,即客户端逻辑尽量少而把比较重的业务处理逻辑下沉到服务端,而服务端又根据业务职能拆分成了不同的微服务,这些微服务只关注单一的业务,那么这些面向业务场景的复杂逻辑的处理应该放到哪里呢?我们的解决方案就是加一层,即BFF层,通过BFF对外提供HTTP接口,客户端只与BFF进行交互。

BFF层的引入解决了我们上面遇到的问题,但增加一层就会增加架构的复杂度,所以如果你的服务是一个单体应用的话,那么BFF是不必要的,引入它不会增加任何价值。对于我们这个项目来说,我们的应用程序依赖于微服务,同时我们需要面向业务功能提供HTTP接口和要保证接口的高可用,所以BFF对于我们这个项目来说是一个合适的选择。

我们可以提供多个BFF吗?答案是当然可以。BFF的目的是为客户端提供一个集中的接口,例如移动端页面和浏览器页面的数据协议不同,这种情况下为了更好的表示数据,可以使用两个BFF,同时只供一个BFF如果该BFF异常就会导致所有的业务受影响,提供多个BFF也可以提高服务的可用性,降低业务异常的影响面。多个BFF架构图如下:

8eccd2b16d9afefc384d83e87222dde8.png 我们的这个项目为了简化只会采用一个BFF服务。

工程结构

我们采用集中管理的方式,把所有的服务放到一个大仓库中,仓库的目录结构如下:

6773d6f580480954375cd89f4763602e.png lebron为工程名,lebron下面有apps和pkg两个目录,其中apps存放的是我们所有的微服务,比如order为订单相关的微服务,pkg目录为所有服务共同依赖的包的存放路径,比如所有的服务都需要依赖鉴权就可以放到pkg目录下。

  • app - BFF服务
  • cart - 购物车服务
  • order - 订单服务
  • pay - 支付服务
  • product - 商品服务
  • recommend - 推荐服务
  • reply - 评论服务
  • user - 账号服务

在每个服务目录下我们又会分为多个服务,主要会有如下几类服务:

  • api - 对外的BFF服务,接受来自客户端的请求,暴露HTTP接口
  • rpc - 对内的微服务,仅接受来自内部其他微服务或者BFF的请求,暴露gRPC接口
  • rmq - 负责进行流式任务处理,上游一般依赖消息队列,比如kafka等
  • admin - 也是对内的服务,区别于rpc,更多的是面向运营侧的且数据权限较高,通过隔离可带来更好的代码级别的安全,直接提供HTTP接口

apps目录下每个服务的结构如下:

大多服务都会拆分成rpc、rmq和admin来满足对内提供rpc接口和运营数据的需求,同时通过rmq来处理流式任务。比较特殊的是app下只有api服务,因为app是BFF所有只有api服务,后面可能会增加rmq服务,比如来流式处理用户每天首次登陆加经验之类的逻辑,我们后面可以随时扩展,暂时先只提供api服务。recommend只有rpc服务,因为推荐服务需要依赖AI团队或者大数据团队提供的数据,我们只需要请求对应的数据接口和做一些满足业务的处理即可,所以这里recommend只有rpc服务。

代码初始化

整个工程的结构已经定义清楚了,下面我们做服务代码的初始化

我们使用goctl来进行项目的初始化,比如我们先初始化order,先进入order目录下:

$ cd lebron/apps/order

执行如下命令即可初始化order rpc代码

$ goctl rpc new rpc

生成的代码结构如下:

执行如下命令即可初始化order admin代码,注意order admin为api服务,直接对前端提供HTTP接口

$ goctl api new admin

生成的代码结构如下:

生成的服务代码我们可以直接运行,默认侦听在8888端口

$ go run admin.go
Starting server at 0.0.0.0:8888...

对于rmq服务我们会使用go-zero提供的 kq 功能,这里先初始化main.go

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

pkg下目前不需要初始化,当我们需要提供业务通用功能的时候我们再进行添加。

结束语

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

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

接着我们定义了我们这个工程的目录结构,主要分为api、rpc、rmq和admin等服务,不同服务的职责不同,api对外提供HTTP接口,rpc对内提供RPC接口,rmq做流式数据的处理,admin面向运营后台提供HTTP接口。

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

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

每周一、周四更新

代码仓库:https://github.com/zhoushuguang/lebron

参考

https://microservices.io/index.html

https://blog.bitsrc.io/bff-pattern-backend-for-frontend-an-introduction-e4fa965128bf

项目地址

https://github.com/zeromicro/go-zero

相关文章
|
1月前
|
JavaScript Java Go
探索Go语言在微服务架构中的优势
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出。本文将深入探讨Go语言在构建微服务时的性能优势,包括其在内存管理、网络编程、并发模型以及工具链支持方面的特点。通过对比其他流行语言,我们将揭示Go语言如何成为微服务架构中的一股清流。
129 53
|
3月前
|
Go API Docker
热门go与微服务15
热门go与微服务15
36 2
|
3月前
|
Shell Go API
Go语言grequests库并发请求的实战案例
Go语言grequests库并发请求的实战案例
|
5天前
|
存储 监控 供应链
微服务拆分的 “坑”:实战复盘与避坑指南
本文回顾了从2~3人初创团队到百人技术团队的成长历程,重点讨论了从传统JSP到前后端分离+SpringCloud微服务架构的演变。通过实际案例,总结了微服务拆分过程中常见的两个问题:服务拆分边界不清晰和拆分粒度过细,并提出了优化方案,将11个微服务优化为6个,提高了系统的可维护性和扩展性。
22 0
|
1月前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
1月前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
1月前
|
运维 NoSQL Java
后端架构演进:微服务架构的优缺点与实战案例分析
【10月更文挑战第28天】本文探讨了微服务架构与单体架构的优缺点,并通过实战案例分析了微服务架构在实际应用中的表现。微服务架构具有高内聚、低耦合、独立部署等优势,但也面临分布式系统的复杂性和较高的运维成本。通过某电商平台的实际案例,展示了微服务架构在提升系统性能和团队协作效率方面的显著效果,同时也指出了其带来的挑战。
85 4
|
2月前
|
Cloud Native Go API
Go语言在微服务架构中的创新应用与实践
本文深入探讨了Go语言在构建高效、可扩展的微服务架构中的应用。Go语言以其轻量级协程(goroutine)和强大的并发处理能力,成为微服务开发的首选语言之一。通过实际案例分析,本文展示了如何利用Go语言的特性优化微服务的设计与实现,提高系统的响应速度和稳定性。文章还讨论了Go语言在微服务生态中的角色,以及面临的挑战和未来发展趋势。
|
2月前
|
运维 Go 开发者
Go语言在微服务架构中的应用与优势
本文深入探讨了Go语言在构建微服务架构中的独特优势和实际应用。通过分析Go语言的核心特性,如简洁的语法、高效的并发处理能力以及强大的标准库支持,我们揭示了为何Go成为开发高性能微服务的首选语言。文章还详细介绍了Go语言在微服务架构中的几个关键应用场景,包括服务间通信、容器化部署和自动化运维等,旨在为读者提供实用的技术指导和启发。
|
2月前
|
负载均衡 Go API
探索Go语言在微服务架构中的应用与优势
在这篇技术性文章中,我们将深入探讨Go语言(又称为Golang)在构建微服务架构时的独特优势。文章将通过对比分析Go语言与其他主流编程语言,展示Go在并发处理、性能优化、以及开发效率上的优势。同时,我们将通过一个实际的微服务案例,详细说明如何利用Go语言构建高效、可扩展的微服务系统。