入门微服务架构设计:由下单场景实现服务注册、发现以及调用
本文旨在介绍如何使用 Java 和 Spring Boot 框架设计一个微服务架构,实现服务的注册、发现和调用,并通过Spring Cloud (Alibaba)进行服务治理
我们将通过老生常谈的下单业务场景示例,详细阐述微服务架构的设计思路和技术实现过程
通过本文可以了解微服务架构解决单体架构痛点带来的优势,以及其存在的劣势与常用解决方案
背景
传统的单体架构虽然在早期能够满足大部分业务需求,但随着系统业务需求的变更、日益增长的用户量,其局限性逐渐显现
单体架构将所有功能模块集成在一个单一的应用程序中,这导致代码臃肿、部署周期长、可维护性差以及难以扩展等问题
特别是数据量、并发逐步提升的挑战时,单体架构的瓶颈愈发明显,为了解决单体架构带来的种种问题,微服务架构应运而生
微服务架构将大型应用拆分为一组小型、独立的服务,每个服务都围绕着特定的业务功能进行构建,并且可以独立地部署、扩展和维护,能够有效解决单体架构的难点与痛点,但同时也带来以下的问题:
- 这么多服务的配置能不能集中起来进行配置,分别维护?(配置中心:集中化管理、环境隔离、动态更新)
- 这么多服务如何让它们彼此能够发现?(注册中心:负责服务注册与发现,心跳监听服务的状态)
- 服务要进行网络通信调用其他服务,多节点的情况下又如何负载?(远程调用+负载均衡:使用自定义协议或HTTP协议网络通信调用服务;服务中多节点的情况下,将请求平衡分发到不同节点)
- 服务调用链路太长,某个服务故障超时会导致整个链路阻塞从而影响其他服务,该如何解决?(熔断:故障服务节点立马进行响应,避免影响其他服务节点)
- 这么多服务如何进行管理?(网关:鉴权、过滤、限流、负载、熔断降级…)
- 数据一致性问题…
技术选型
虽然微服务架构下存在许多问题,但是Spring Cloud(Alibaba)框架通过一系列的组件来解决这些问题
本篇文章主要采用以下组件来实现服务的注册、发现以及调用:
Nacos 服务的注册中心与配置中心
OpenFeign 服务间的远程调用(HTTP),并使用Ribbon进行负载均衡
Gateway 网关作为请求入口,统一鉴权、负载、限流
Sentinel 流控、Seata 分布式事务等其他组件后续在本专栏再进行说明
在下单的业务场景中,通常包含用户、商品、订单、库存、支付、通知等服务
为了简化服务调用的流程,只演示其中的订单、库存服务,下单业务流程简化为:更新订单状态并扣减库存
整体架构图如下所示:
目前,我们只需重点关注中间的微服务,网关,注册/配置中心
搭建项目
设计完架构后,我们需要使用Spring Boot、Spring Cloud框架搭建环境
项目整体目录结构如下:
Cloud
├─cloud-api #存储远程调用的API接口
├─cloud-gateway #网关
├─cloud-order #订单服务
└─cloud-stock #库存服务
父工程
我们使用Maven搭建父子工程项目,其中父工程负责依赖版本的管理pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.caicaijava</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Cloud</name>
<description>Cloud Parent</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.7.6</spring-boot.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
<log4j.version>1.2.17</log4j.version>
<spring-cloud-bootstrap>3.0.3</spring-cloud-bootstrap>
<logback-core>1.2.3</logback-core>
</properties>
<packaging>pom</packaging>
<modules>
<module>cloud-gateway</module>
<module>cloud-order</module>
<module>cloud-stock</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version