目录
1. 什么是主从服务器
1.1 基本概念
主从服务器是一种分布式系统架构模式,包含以下角色:
- 主服务器(Master Server):负责处理写操作、协调工作、决策制定
- 从服务器(Slave Server):负责处理读操作、执行主服务器分配的任务
1.2 工作原理
┌─────────────┐ 同步数据/指令 ┌─────────────┐
│ 主服务器 │ ────────────────→ │ 从服务器1 │
│ (Master) │ │ (Slave1) │
└─────────────┘ └─────────────┘
│ │
│ ┌─────────────┐ │
└────────→│ 从服务器2 │←────────┘
│ (Slave2) │
└─────────────┘
1.3 特点说明
- 高可用性:从服务器可以在主服务器故障时接管
- 负载分担:多个服务器分担处理请求
- 水平扩展:可以根据需要增加从服务器
- 数据一致性:主服务器负责维护数据的一致性
2. 主从服务器与主从数据库的区别
2.1 主要区别对比
特性 | 主从服务器 | 主从数据库 |
---|---|---|
作用层面 | 应用服务层 | 数据存储层 |
主要功能 | 处理业务逻辑、API请求 | 存储和查询数据 |
同步内容 | 应用状态、配置信息 | 数据库记录 |
故障转移 | 服务实例切换 | 数据库实例切换 |
扩展方式 | 增加服务器实例 | 增加数据库实例 |
2.2 架构位置
[客户端]
↓
[负载均衡器]
↓
[主从服务器集群] ← 我们要讲解的部分
↓
[主从数据库集群]
↓
[存储系统]
3. 主从服务器的应用场景
3.1 微服务架构
在微服务中,每个服务都可以部署主从架构:
// 用户服务的主从部署
user-service-master: 192.168.1.10:8081
user-service-slave1: 192.168.1.11:8081
user-service-slave2: 192.168.1.12:8081
3.2 API网关
// API网关的主从配置
gateway-master: 处理所有写操作和路由决策
gateway-slave: 处理读操作和请求转发
3.3 缓存服务
// Redis缓存服务的主从应用层
cache-service-master: 负责缓存更新策略
cache-service-slave: 负责缓存查询
4. 主从服务器架构设计
4.1 基础架构图
[负载均衡器]
│
┌──────────┼──────────┐
│ │ │
┌─────────▼─┐ ┌─────▼─┐ ┌─────▼─┐
│ Master │ │Slave1 │ │Slave2 │
│ Server │ │Server │ │Server │
└─────────┬─┘ └───────┘ └───────┘
│
┌─────────▼─────────┐
│ 配置中心/注册中心 │
│ (Nacos/Consul) │
└───────────────────┘
4.2 组件说明
- 注册中心:服务发现和健康检查
- 配置中心:统一配置管理
- 负载均衡器:请求分发
- 监控系统:性能监控和告警
5. Spring Boot实现主从服务器
5.1 项目结构
master-slave-demo/
├── master-server/ # 主服务器
│ ├── src/main/java/
│ ├── src/main/resources/
│ └── pom.xml
├── slave-server/ # 从服务器
│ ├── src/main/java/
│ ├── src/main/resources/
│ └── pom.xml
└── common/ # 公共模块
├── src/main/java/
└── pom.xml
5.2 核心依赖配置
5.2.1 父级pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>master-slave-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<modules>
<module>common</module>
<module>master-server</module>
<module>slave-server</module>
</modules>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.1.0</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
5.3 公共模块实现
5.3.1 服务器角色枚举
package com.example.common.enums;
public enum ServerRole {
MASTER("master", "主服务器"),
SLAVE("slave", "从服务器");
private final String code;
private final String description;
ServerRole(String code, String description) {
this.code = code;
this.description = description;
}
// getter方法
public String getCode() { return code; }
public String getDescription() { return description; }
}
5.3.2 服务器状态管理
package com.example.common.model;
import com.example.common.enums.ServerRole;
import org.springframework.stereotype.Component;
@Component
public class ServerContext {
private ServerRole role;
private String serverId;
private boolean active = true;
private long startTime;
public ServerContext() {
this.startTime = System.currentTimeMillis();
this.serverId = generateServerId();
}
private String generateServerId() {
return System.getProperty("server.role", "unknown") +
"-" + System.currentTimeMillis();
}
// getter和setter方法
public ServerRole getRole() { return role; }
public void setRole(ServerRole role) { this.role = role; }
public String getServerId() { return serverId; }
public void setServerId(String serverId) { this.serverId = serverId; }
public boolean isActive() { return active; }
public void setActive(boolean active) { this.active = active; }
public long getStartTime() { return startTime; }
public boolean isMaster() {
return ServerRole.MASTER.equals(role);
}
public boolean isSlave() {
return ServerRole.SLAVE.equals(role);
}
}
5.3.3 数据同步接口
package com.example.common.service;
public interface DataSyncService {
/**
* 同步数据到从服务器
*/
void syncToSlaves(String data);
/**
* 从主服务器接收数据
*/
void receiveFromMaster(String data);
/**
* 检查同步状态
*/
boolean isSyncComplete();
}
5.4 主服务器实现
5.4.1 主服务器启动类
package com.example.master;
import com.example.common.enums.ServerRole;
import com.example.common.model.ServerContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication(scanBasePackages = "com.example")
@EnableDiscoveryClient
public class MasterServerApplication implements CommandLineRunner {
@Autowired
private ServerContext serverContext;
public static void main(String[] args) {
System.setProperty("server.role", "master");
SpringApplication.run(MasterServerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
serverContext.setRole(ServerRole.MASTER);
System.out.println("主服务器启动完成,角色:" + serverContext.getRole().getDescription());
}
}
5.4.2 主服务器配置
# master-server/src/main/resources/application.yml
server:
port: 8081
spring:
application:
nam