当前位置: 首页 > article >正文

【商城实战(39)】Spring Boot 携手微服务,商城架构焕新篇

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从 0 到 1 的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战之旅。

目录

  • 一、微服务架构探秘
  • 二、Spring Cloud Alibaba 搭建微服务架构
    • 2.1 环境准备
    • 2.2 Nacos 实现服务注册与发现
    • 2.3 示例演示
  • 三、配置 Spring Cloud Gateway
    • 3.1 Gateway 基础配置
    • 3.2 服务路由
    • 3.3 鉴权功能实现
  • 四、总结与展望


一、微服务架构探秘

在当今的软件开发领域,微服务架构无疑是一颗耀眼的明星。简单来说,微服务架构是一种将大型应用程序拆分成多个小型、独立服务的架构风格,每个服务都围绕着特定的业务能力构建,并且能够独立地进行开发、部署和扩展。

与传统的单体架构相比,微服务架构有着诸多显著优势。在单体架构中,所有的功能模块都被打包在一个应用程序中,就像一个庞大而复杂的 “巨石”,牵一发而动全身。随着业务的不断发展和功能的日益增多,单体应用的代码库会变得越来越庞大,难以维护和扩展,开发效率也会大幅降低。而微服务架构则像是将这块 “巨石” 拆解成了许多小巧灵活的 “积木”,每个 “积木” 都能独立运作,各个服务之间通过轻量级的通信机制(如 HTTP/RESTful API )进行交互,大大降低了系统的耦合度。

这种架构风格为开发团队带来了更高的敏捷性,不同的服务可以由不同的团队并行开发,每个团队专注于自己负责的业务领域,开发和迭代速度更快。当某个服务需要进行升级或修改时,不会影响到其他服务的正常运行,从而实现了局部修改容易部署。同时,微服务架构还具有强大的可扩展性,企业可以根据业务需求的变化,灵活地对单个服务进行扩展或缩减,避免了资源的浪费。

对于商城项目而言,以下这些业务模块非常适合微服务化:

  • 商品管理模块:商品管理涉及到商品的添加、编辑、删除、查询等操作,业务逻辑相对独立。将其微服务化后,可以方便地对商品服务进行优化和扩展,比如在促销活动期间,可以单独对商品查询服务进行扩容,以应对大量的商品浏览请求。
  • 订单处理模块:订单处理包括订单的创建、支付、状态更新等功能,是商城业务的核心流程之一。通过将订单处理模块微服务化,可以更好地实现订单服务的高可用性和高性能,并且方便与其他服务(如支付服务、库存服务)进行解耦和协作。
  • 用户服务模块:用户服务主要负责用户的注册、登录、信息管理等功能。将用户服务独立成一个微服务,能够更好地保护用户数据的安全性和隐私性,同时也便于对用户服务进行个性化的定制和扩展。

二、Spring Cloud Alibaba 搭建微服务架构

2.1 环境准备

工欲善其事,必先利其器。在使用 Spring Cloud Alibaba 搭建微服务架构之前,我们需要做好一系列的环境准备工作 。首先,确保你的开发环境中已经安装了 Java 开发工具包(JDK),并且版本不低于 1.8,因为 Spring Cloud Alibaba 在功能实现和性能优化上充分利用了 Java 8 的新特性 。可以通过在命令行中输入java -version来检查 JDK 的安装情况和版本信息。

接下来是构建工具 Maven 的配置,Maven 是一个项目管理和构建工具,它能够帮助我们方便地管理项目的依赖关系和构建过程 。从 Maven 官方网站下载并安装最新版本的 Maven,然后在系统环境变量中配置MAVEN_HOME,并将%MAVEN_HOME%\bin添加到PATH变量中 。完成配置后,在命令行中输入mvn -version验证 Maven 是否安装成功。

为了在项目中使用 Spring Cloud Alibaba,我们需要在项目的pom.xml文件中引入相关的依赖。在标签内添加 Spring Cloud Alibaba 的依赖管理:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.8.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这样,我们就可以在标签中引入具体的 Spring Cloud Alibaba 组件依赖了,例如 Nacos 服务注册与发现组件:

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

上述依赖引入后,Maven 会自动下载所需的库文件及其依赖项,为我们后续的开发工作奠定基础。

2.2 Nacos 实现服务注册与发现

Nacos 是 Spring Cloud Alibaba 生态系统中非常重要的一个组件,它提供了服务注册、发现和配置管理等功能 。首先,我们需要下载 Nacos 服务器的安装包,可以从 Nacos 的官方 GitHub 仓库中获取最新版本的安装包 。下载完成后,解压安装包到指定目录。

如果是在 Windows 系统上,进入解压后的bin目录,在命令行中执行startup.cmd -m standalone命令来启动 Nacos 服务器 。这里的standalone表示以单机模式启动,适用于开发和测试环境 。启动成功后,在浏览器中访问http://localhost:8848/nacos,可以看到 Nacos 的管理界面,默认的用户名和密码都是nacos。

在商城项目中,我们以商品服务和订单服务为例,配置 Nacos 实现服务注册与发现 。假设商品服务模块的pom.xml文件中已经引入了 Nacos 依赖,在src/main/resources目录下的application.yml文件中添加如下配置:

server:
  port: 8081
spring:
  application:
    name: product-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

上述配置中,server.port指定了商品服务的端口号为 8081,spring.application.name指定了服务名称为product-service,spring.cloud.nacos.discovery.server-addr指定了 Nacos 服务器的地址。

同样,在订单服务模块的application.yml文件中进行类似的配置,只不过服务名称和端口号需要根据实际情况进行调整:

server:
  port: 8082
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

在商品服务和订单服务的启动类上,添加@EnableDiscoveryClient注解,开启服务注册与发现功能 。例如,商品服务的启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ProductServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServiceApplication.class, args);
    }
}

订单服务的启动类也进行同样的配置 。这样,当商品服务和订单服务启动后,它们会自动将自己注册到 Nacos 服务器上。

2.3 示例演示

当商品服务和订单服务都成功注册到 Nacos 服务器后,我们可以通过 Nacos 的管理界面查看已注册的服务列表 。在浏览器中访问http://localhost:8848/nacos,登录后点击左侧菜单的 “服务管理” -> “服务列表”,可以看到product-service和order-service都在列表中,并且显示了服务的健康状态、实例数量等信息。

在实际的业务场景中,订单服务可能需要调用商品服务来获取商品的详细信息 。在订单服务中,我们可以使用RestTemplate并结合负载均衡器来实现对商品服务的调用 。首先,在订单服务的配置类中创建一个RestTemplate的 Bean,并添加@LoadBalanced注解开启负载均衡功能:

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

然后,在订单服务的业务代码中,通过RestTemplate调用商品服务的接口 。例如,订单服务中有一个方法用于获取商品信息:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/order/{productId}")
    public String getProductInfo(@PathVariable String productId) {
        String url = "http://product-service/product/" + productId;
        return restTemplate.getForObject(url, String.class);
    }
}

在上述代码中,http://product-service/product/{productId}中的product-service是商品服务在 Nacos 中注册的服务名称,RestTemplate会通过 Nacos 获取到商品服务的实际地址,并进行调用 。这样,就实现了订单服务对商品服务的调用,充分体现了 Nacos 服务注册与发现的功能和优势。

三、配置 Spring Cloud Gateway

3.1 Gateway 基础配置

Spring Cloud Gateway 作为 Spring Cloud 生态中的网关组件,为微服务架构提供了强大的路由和过滤功能 。在商城项目中,配置 Spring Cloud Gateway 是实现服务网关的关键步骤 。首先,在项目的pom.xml文件中引入 Spring Cloud Gateway 的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

引入依赖后,在src/main/resources目录下的application.yml文件中进行基础配置 。配置一个简单的路由规则,将所有以/product/开头的请求转发到商品服务:

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
        - id: product-service-route
          uri: lb://product-service
          predicates:
            - Path=/product/**

上述配置中,server.port指定了网关服务的端口号为 8080。spring.cloud.gateway.routes配置了路由规则,id为路由的唯一标识,这里设置为product-service-route;uri指定了目标服务的地址,lb://product-service表示通过负载均衡器访问名为product-service的微服务;predicates中的Path=/product/**是一个断言,它表示当请求路径以/product/开头时,该路由规则生效。

3.2 服务路由

在商城项目中,通常会有多个微服务,如商品服务、订单服务、用户服务等 。我们需要为不同的微服务配置相应的路由规则,实现请求的准确转发 。除了前面配置的商品服务路由,再配置订单服务的路由规则 。在application.yml文件中添加如下配置:

spring:
  cloud:
    gateway:
      routes:
        - id: product-service-route
          uri: lb://product-service
          predicates:
            - Path=/product/**
        - id: order-service-route
          uri: lb://order-service
          predicates:
            - Path=/order/**

这样,当客户端发送请求到/product/开头的路径时,请求会被转发到商品服务;当请求路径以/order/开头时,请求会被转发到订单服务。

Spring Cloud Gateway 还支持通过多种断言来灵活配置路由规则 。比如,可以通过Query断言根据请求参数来匹配路由 。假设我们希望只有当请求中包含token参数时,才将请求转发到用户服务,可以这样配置:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Query=token

此外,还可以使用Header断言根据请求头信息来匹配路由,使用Method断言根据请求方法(如 GET、POST 等)来匹配路由,通过组合这些断言,可以满足各种复杂的路由需求。

3.3 鉴权功能实现

在商城系统中,安全是至关重要的,鉴权功能用于验证用户的身份和权限,确保只有合法的用户才能访问受保护的资源 。借助 JWT(JSON Web Token)技术,我们可以在 Spring Cloud Gateway 中实现高效的请求鉴权。

首先,在网关服务的pom.xml文件中引入 JWT 相关的依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

引入依赖后,创建一个 JWT 工具类,用于生成和验证 JWT 令牌 。以下是一个简单的 JWT 工具类示例:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "your-secret-key";
    private static final long EXPIRATION_TIME = 10 * 60 * 1000; // 10分钟

    // 生成JWT令牌
    public static String generateToken(String username) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + EXPIRATION_TIME);

        return Jwts.builder()
               .setSubject(username)
               .setIssuedAt(now)
               .setExpiration(expiration)
               .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
               .compact();
    }

    // 验证JWT令牌
    public static boolean validateToken(String token) {
        try {
            Claims claims = Jwts.parserBuilder()
                   .setSigningKey(SECRET_KEY)
                   .build()
                   .parseClaimsJws(token)
                   .getBody();

            Date expiration = claims.getExpiration();
            return!expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

    // 获取JWT令牌中的用户名
    public static String getUsernameFromToken(String token) {
        Claims claims = Jwts.parserBuilder()
               .setSigningKey(SECRET_KEY)
               .build()
               .parseClaimsJws(token)
               .getBody();

        return claims.getSubject();
    }
}

在上述代码中,generateToken方法用于生成 JWT 令牌,它包含了用户名、签发时间和过期时间等信息,并使用指定的密钥进行签名 。validateToken方法用于验证 JWT 令牌的有效性,检查令牌是否过期。getUsernameFromToken方法用于从 JWT 令牌中提取用户名。

接下来,在 Spring Cloud Gateway 中创建一个过滤器,用于对请求进行鉴权。创建一个实现GlobalFilter接口的过滤器类,例如JwtAuthenticationFilter:

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class JwtAuthenticationFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String token = request.getHeaders().getFirst("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (JwtUtil.validateToken(token)) {
                return chain.filter(exchange);
            }
        }

        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -100;
    }
}

在JwtAuthenticationFilter过滤器中,首先从请求头中获取Authorization字段,提取其中的 JWT 令牌 。然后调用JwtUtil.validateToken方法验证令牌的有效性 。如果令牌有效,则放行请求,继续执行后续的过滤器和路由;如果令牌无效或不存在,则返回HttpStatus.UNAUTHORIZED状态码,表示未授权访问。

通过上述配置和实现,我们在 Spring Cloud Gateway 中成功实现了基于 JWT 的请求鉴权功能,有效地保护了商城系统的安全。

四、总结与展望

通过将 Spring Boot 与微服务架构应用于商城项目,我们成功地实现了系统的高效开发、灵活部署和可靠运行 。微服务架构的引入,使得商城项目的各个业务模块能够独立开发、部署和扩展,大大提高了开发团队的协作效率和系统的可维护性 。借助 Spring Cloud Alibaba 提供的一系列组件,如 Nacos 实现服务注册与发现,Spring Cloud Gateway 实现服务网关功能,我们构建了一个稳定且功能强大的微服务架构体系。

展望未来,随着业务的不断发展和用户需求的日益多样化,商城系统在性能优化、安全加固、多端适配等方面仍有许多工作需要进一步深入开展 。在性能优化方面,我们可以引入更多的缓存技术,如 Redis Cluster 来提高数据的读取速度,减少数据库的压力;同时,利用分布式事务解决方案,如 Seata,确保在分布式环境下的数据一致性和业务的完整性。

安全方面,除了现有的 JWT 鉴权机制,还可以进一步加强数据加密、身份验证等安全措施,防范各类网络攻击和数据泄露风险 。随着移动互联网的普及,多端适配也将成为商城系统发展的重要方向,我们需要不断优化系统在不同终端(如 PC、手机、平板)上的用户体验,确保用户在任何设备上都能享受到流畅的购物服务。

在未来的开发中,我们还可以积极探索新技术的应用,如人工智能技术在商品推荐、智能客服等方面的应用,区块链技术在商品溯源、交易安全等方面的应用,为商城系统注入新的活力,提升商城的核心竞争力 。通过持续不断地优化和创新,我们相信基于 Spring Boot 与微服务架构的商城系统将能够更好地满足市场需求,为用户提供更加优质、便捷的电子商务服务。


http://www.kler.cn/a/590243.html

相关文章:

  • linux 信号量概念
  • 电机控制常见面试问题(十三)
  • 深度学习-简介
  • Spring Boot 集成高德地图电子围栏
  • DBA(数据库管理员)常用的 Linux 命令
  • 【开源免费】基于SpringBoot+Vue.JS电商应用系统(JAVA毕业设计)
  • HTML 基础夯实:标签、属性与基本结构的学习进度(一)
  • FPV无人机战术演练仿真系统技术详解
  • 网络世界探索之旅:初始网络
  • KUKA机器人编程之signal的应用(包括创建组输入和组输出)
  • Day09 -实例:拿到加密密文进行解密
  • Tomcat新手登峰指南:从零到部署的原子化实践
  • repo init 错误 Permission denied (publickey)
  • 机器学习扫盲系列(2)- 深入浅出“反向传播”-1
  • 3.17学习总结 java数组
  • 18.使用读写包操作Excel文件:xlrd、xlwt 和 xlutils 包
  • 浅谈AI落地之-关于数据增广的思考
  • Tomcat线程池详解,为什么SpringBoot最大支持200并发?
  • 从零搭建微服务项目Pro(第6-1章——Spring Security+JWT实现用户鉴权访问与token刷新)
  • 【前端】入门基础(一)html标签