章
目
录
在开发微服务系统时,选对技术栈至关重要。这篇文章里,咱们就基于一套热门技术栈,一步步构建一个完整的微服务解决方案。先给大伙介绍下用到的技术:
- 基础环境: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 ,让系统性能更好一点。