如何基于Spring Boot 3搭建微服务系统

后端 潘老师 1个月前 (03-23) 50 ℃ (0) 扫码查看

在开发微服务系统时,选对技术栈至关重要。这篇文章里,咱们就基于一套热门技术栈,一步步构建一个完整的微服务解决方案。先给大伙介绍下用到的技术:

  • 基础环境:JDK 21搭配Maven 3.9+,这俩就像是微服务系统的地基,稳定又可靠。
  • 核心框架:Spring Boot 3.1.5,它能帮咱快速搭建和开发应用,效率杠杠的。
  • 服务治理:Dubbo 3.2.7和Nacos 2.2.3强强联合,Dubbo负责服务间的调用和管理,Nacos则提供服务注册、配置管理等功能。
  • 数据存储:MySQL 8.0存储数据,MyBatis-Plus 3.5.5做数据持久化,操作数据库超方便。
  • 消息队列:RocketMQ 5.1.3,处理异步消息、削峰填谷都靠它。
  • 缓存系统:Redis 7.0.12,把常用数据放里面,读写速度快到飞起。
  • 容器化部署:Docker 24.0+,用来打包和部署服务,部署效率大幅提升。

一、搭建项目结构

1. Maven父工程配置

Maven父工程就像是项目的“大管家”,管理着各个模块。下面是它的配置代码:

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>cloud-platform</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <modules>
        <module>api</module>
        <module>provider</module>
        <module>consumer</module>
    </modules>

    <properties>
        <java.version>21</java.version>
        <spring-boot.version>3.1.5</spring-boot.version>
        <dubbo.version>3.2.7</dubbo.version>
        <nacos.version>2022.0.0.0</nacos.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

这里指定了项目的基本信息,像组织ID、项目ID、版本号啥的,还管理着各个模块和依赖的版本。

2. API模块(接口定义)

API模块主要用来定义接口,让不同模块之间能按照统一的规范进行交互。比如下面这两个类:

// UserService.java
public interface UserService {
    UserDTO getUserById(Long id);
}

// UserDTO.java
@Data
public class UserDTO implements Serializable {
    private Long id;
    private String username;
    private String email;
}

UserService接口定义了根据用户ID获取用户信息的方法,UserDTO类则用来传输用户数据。

3. Provider模块配置

Provider模块是服务的提供者,它的配置主要是引入一些依赖:

<!-- provider/pom.xml -->
<dependencies>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.5</version>
    </dependency>
</dependencies>

这些依赖分别用于Dubbo服务开发、Nacos客户端连接和MyBatis-Plus数据持久化。

4. 核心配置示例

核心配置文件application.yml里,配置了Dubbo、Spring的数据源、Redis等关键信息:

# application.yml
dubbo:
  application:
    name: user-service-provider
  protocol:
    name: dubbo
    port: 20880
  registry:
    address: nacos://nacos-server:8848
  config-center:
    address: nacos://nacos-server:8848

spring:
  datasource:
    url: jdbc:mysql://mysql-server:3306/cloud_db?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  data:
    redis:
      host: redis-server
      port: 6379

Dubbo相关配置指定了服务名、协议、端口、注册中心地址等;Spring的数据源配置了数据库连接信息;Redis配置了主机和端口。

二、服务实现示例

1. MyBatis-Plus数据访问层

MyBatis-Plus简化了数据库操作,下面是数据访问层的代码:

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> 
    implements UserService {
    
    @DubboService
    @Override
    public UserDTO getUserById(Long id) {
        User user = getById(id);
        return convertToDTO(user);
    }
}

UserMapper继承了BaseMapper,就有了基本的数据库操作方法。UserServiceImpl实现了UserService接口,用@DubboService注解暴露服务,从数据库获取用户信息并转换为UserDTO返回。

2. RocketMQ消息处理

RocketMQ用于处理异步消息,下面是消息监听器的代码:

@Component
@RocketMQMessageListener(
    topic = "ORDER_TOPIC",
    consumerGroup = "order-consumer-group"
)
public class OrderMessageListener implements RocketMQListener<OrderMessage> {
    @Override
    public void onMessage(OrderMessage message) {
        // 处理订单消息
    }
}

这个监听器监听ORDER_TOPIC主题的消息,属于order-consumer-group消费者组,接收到消息后在onMessage方法里处理。

三、容器化部署方案

1. Dockerfile示例

Dockerfile用于构建Docker镜像,以Provider模块为例:

# Provider Dockerfile
FROM openjdk:21-jdk
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

这段代码基于openjdk:21-jdk镜像,把打包好的JAR文件复制到容器里,设置容器启动时执行的命令。

2. docker-compose.yml编排

docker-compose.yml用来编排多个容器,让它们能协同工作:

version: '3.8'

services:
  nacos-server:
    image: nacos/nacos-server:v2.2.3
    environment:
      - MODE=standalone
    ports:
      - "8848:8848"
  
  mysql-server:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: cloud_db
    volumes:
      - mysql_data:/var/lib/mysql

  redis-server:
    image: redis:7.0.12-alpine
    ports:
      - "6379:6379"

  rocketmq:
    image: apache/rocketmq:5.1.3
    ports:
      - "9876:9876"
      - "10909:10909"
      - "10911:10911"

  user-service:
    build: ./provider
    depends_on:
      - nacos-server
      - mysql-server
    environment:
      - SPRING_PROFILES_ACTIVE=prod

volumes:
  mysql_data:

这里定义了Nacos、MySQL、Redis、RocketMQ和user-service等服务的镜像、环境变量、端口映射等信息。

四、系统构建与运行

1. 编译项目

用Maven编译项目,跳过测试:

mvn clean package -DskipTests

这条命令会清理之前的编译结果,重新打包项目。

2. 构建Docker镜像

docker-compose构建镜像:

docker-compose build

它会根据docker-compose.yml和各个服务的Dockerfile构建镜像。

3. 启动所有服务

启动容器:

docker-compose up -d

-d参数表示在后台运行容器,这样就启动了整个微服务系统。

五、关键技术点解析

1. 服务发现机制

Dubbo 3搭配Nacos 2作为注册中心,采用应用级服务发现模型。服务提供者启动时,会自动把元数据信息注册到Nacos上。消费者通过订阅机制,能动态获取服务列表,找到对应的服务提供者进行调用。

2. 数据一致性保障

  • RocketMQ事务消息:它能保证分布式事务最终一致性。比如在电商下单场景,下单和扣库存这两个操作可以通过RocketMQ事务消息保证要么都成功,要么都失败。
  • Redis分布式锁:控制并发操作。像在秒杀活动中,为了防止超卖,就可以用Redis分布式锁。下面是示例代码:
public void deductStock(Long productId) {
    String lockKey = "product_lock:" + productId;
    Boolean success = redisTemplate.opsForValue()
        .setIfAbsent(lockKey, "locked", 30, TimeUnit.SECONDS);
    if (Boolean.TRUE.equals(success)) {
        try {
            // 执行库存扣减
        } finally {
            redisTemplate.delete(lockKey);
        }
    }
}

这段代码尝试获取锁,如果获取成功就执行库存扣减操作,最后释放锁。

3. 性能优化策略

  • MyBatis-Plus二级缓存整合Redis:把常用的数据缓存到Redis里,下次查询时直接从Redis取,减少数据库压力。
  • Dubbo服务调用使用Triple协议(HTTP/3):相比传统协议,Triple协议性能更好,能提高服务调用的效率。
  • RocketMQ消息批量发送与消费:批量处理消息,减少网络开销,提高消息处理速度。

六、常见问题排查

1. Nacos连接失败

  • 检查端口:看看8848端口有没有开放,要是被占用了,Nacos就启动不了。
  • 查看日志:确认Nacos容器日志里有没有报错信息,根据报错提示解决问题。
  • 检查网络策略:检查网络策略,确保容器之间能正常通信。

2. Dubbo服务未注册

  • 检查注解:看看@DubboService注解有没有正确使用,别漏了或者写错了。
  • 确认配置地址:检查Nacos配置地址格式是不是nacos://host:port,格式不对会导致注册失败。
  • 查看启动日志:查看Dubbo启动日志里的注册信息,看看有没有成功注册的记录。

3. Redis连接超时

  • 检查密码配置:检查Redis密码配置对不对,密码错了肯定连不上。
  • 确认防火墙设置:看看防火墙有没有阻止连接,把相关端口开放。
  • 测试连接:用redis-cli测试连接,确认Redis服务正常。

这套微服务架构方案整合了主流技术组件,高可用又易扩展。不过在实际生产部署时,还得根据业务需求调整配置,像Nacos集群部署、RocketMQ多副本配置、Redis哨兵模式或集群方案、MySQL主从复制架构,容器编排也可以用Kubernetes替代Docker Compose ,让系统性能更好一点。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/16161.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】