Mysql8.0主从复制搭建,shardingsphere+springboot+mybatis读写分离

本文详细介绍MySQL8.0在Linux环境下的安装配置过程,包括主从复制的设置,以及如何利用ShardingSphere在SpringBoot项目中实现数据库的读写分离。涵盖依赖配置、服务启动、权限分配、日志查询等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、安装mysql8.0

首先需要在192.167.3.171上安装JDK。

下载mysql安装包,https://dev.mysql.com/downloads/,找到以下页面下载。

 

 

下载后放到linux系统中

官网说需要先查看本机是否已安装mysql,删除mysql这里不介绍。

1
yum install libaio  yum install openssl

安装mysql所需的软件包:libaiohe openssl。

1
tar -xvf mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz

解压。

1
mv mysql-8.0.13-linux-glibc2.12-x86_64 /usr/local/mysql

将解压文件移动到local下。

1
2
3
4
5
6
7
8
9
10
11
12
13
groupadd mysql
 
useradd -r -g mysql -s /bin/false mysql
 
cd /usr/local/mysql
 
mkdir mysql-files
 
chown mysql:mysql mysql-files
 
chmod 750 mysql-files
 
bin/mysqld --initialize --user=mysql

初始化数据库,注意此处随机生成的密码,第一次登陆mysql的时候要使用。

1
bin/mysql_ssl_rsa_setup

安装ssl。

1
cp support-files/mysql.server /etc/init.d/mysql.server

将服务文件复制到开机启动目录,实现服务开机自启动。

1
bin/mysqld_safe --user=mysql &

开启服务,&是后台运行的意思,执行命令之后,终端会卡在一个位置,再按一下Enter即可。

如果上面命令报错,什么log,pid文件未找到之类的,就需要执行下面方法。由于mysql服务启动时,会去读取/etc/my.cnf文件中的配置内容,我们打开文件来看,文件内容如下(我已修改):

原来的内容地址就是启动mysql服务时报错的路径,我们可以知道,文件不存在问题导致启动失败。这时,就需要新建文件,并设置文件权限了。我这里修改了红框内的路径,具体命令如下:

1
2
3
4
5
6
7
8
9
10
11
cd /usr/local/mysql/mysql-files
 
mkdir log ;  mkdir pid
 
touch log/mysql.log ; touch pid/mysql.pid
 
cd /usr/local/mysql
 
chown -R mysql:mysql mysql-files
 
chmod -R 750 mysql-files

然后再次执行:

1
bin/mysqld_safe --user=mysql &
1
bin/mysql -uroot -p

登陆mysql,回车后粘贴之前初始密码。

如果登陆时报错,错误如下图,然后,去查看/tmp下面的文件,发现确实没有mysql.sock文件,本地用户登录时使用socket登陆,所以需要这样一个文件,那好,就找一个呗,执行  find / -name mysql.sock,找到在/var/lib/mysql下面有一个文件,然后,我尝试cp到tmp下,发现失败,那行,我ln一个呗,ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock,然后再尝试登陆,有一台机器就可以了,另一台始终不行。那行,我指定行了吧,用以下命令登陆:mysql -uroot -p -S /var/lib/mysql/mysql.sock,试了下可以,那就这样吧!

1
2
3
ALTER USER 'root'@'localhost' IDENTIFIED BY 'ibethfy;
 
flush privileges

执行完成后,我又想使用navicat登陆,那好,试试呗,navicat连接直接报找不到服务,2003 cannot。。。。。,行嘛,排除原因,总结如下:

1、建立供外部连接的mysql用户。

1
2
3
4
5
6
7
mysql -uroot -pibethfy -s /var/lib/mysql/mysql.sock
 
create user 'ibethfy'@'%' identified by 'ibethfy';
 
grant all on *.* to 'ibethfy'@'%';     --注意,mysql8的grant语句和之前版本有差别。
 
flush privileges;

2、防火墙关了,我用的centos。

1
2
3
4
5
firewall-cmd --state          -- 查看防火墙状态,发现时running;
 
systemctl stop firewalld.service     -- 关闭防火墙
 
firewall-cmd --state        --  再次查看,发现not running;

然后再用navicat连接,好嘛,又报错,caching-sha2-password,看来一下,应该是mysql的加密策略变了,navicat版本没跟上呗,那行,执行下面命令,然后再连接,没问题了!

1
2
3
4
5
6
7
mysql -uroot -pibethfy -s /var/lib/mysql/mysql.sock
 
alter user 'ibethfy'@'%' identified by 'ibethfy' password expire never;
 
alter user 'ibethfy'@'%' identified with mysql_native_password by 'ibethfy';
 
flush privileges;

ps -ef |grep mysql,可以看到mysql服务有两个,mysqld_safe和mysqld。说明启动成功了。

大家在linux装mysql8.0的时候,如果按照步骤来,还出现问题,就分析一下,主要导致的一些原因就是权限问题和文件问题,依次解决一下再试试。

2、mysql主从安装

分别按以上方发安装两个mysql服务,分别为192.167.3.171(主),192.167.3.172(从)。

配置主服务

my.conf 文件修改。添加log-bin与server-id,具体配置如下:

重启mysql,service restart mysql;如果没有找到服务,直接用ps -ef|grep mysql,找到对应进程,kill -9强行终止后,使用mysqld_safe --user=mysql &  重启。

登陆mysql,赋予外部连接的ibethfy用户权限并刷新。grant replication slave on *.* to 'ibethfy'@'%';         flush privileges;

查看主服务信息,从服务配置时需要用到,show master status;

修改从mysql服务配置

修改my.cnf,vi /etc/my.cnf

配置从服务,先登陆后,执行  CHANGE MASTER TO MASTER_HOST='192.167.3.171', MASTER_USER='ibethfy', MASTER_PASSWORD=ibethfy',MASTER_LOG_FILE='binlog.000010',  MASTER_LOG_POS=1179;

start slave;

show slave status\G;查看从服务状态,如果内容中有Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the –replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it);错误,需要执行下面语句:

show variables like 'server_id';可以看见server_id=1,这里与主服务id相同,则执行,set global server_id=2;与my.cnf内容相同即可。

重新启动start slave;

如果得到以下信息,则提示主从复制配置成功。

现在可以测试了,在主服务建一个database,从服务可以看见,代表配置成功。

3、springboot+mybatis+shardingsphere搭建主从分离

使用idea创建springboot工程

pom.xml依赖jar配置,具体配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SharingJDBCDemo</name>
    <description>Demo project for Spring Boot</description>
 
    <properties>
        <java.version>1.8</java.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mybatis 依赖jar包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--shardingsphere的springboot依赖jar-->
        <dependency>
            <groupId>io.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!--mybatis的自动生成器配置-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.5</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>src/main/resources/generateMybatis.xml
                    </configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>

application.yml配置,具体如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
server:
  port: 8888
spring:
  application:
    name: SharingJdbc
mybatis:
  type-aliases-package: com.example.demo.entity
  mapper-locations: classpath:mapper/*.xml
sharding:
  jdbc:
    datasource:
      names: master1,slave1
      master1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.167.3.171:3306/ibethfy?useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true
        username: ibethfy
        password: ibethfy
        maxPoolSize: 20
      slave1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.167.3.172:3306/ibethfy?useSSL=false&useUnicode=true&characterEncoding=utf8&autoReconnect=true
        username: ibethfy
        password: ibethfy
        maxPoolSize: 20
    config:
      masterslave:
        load-balance-algorithm-type: round_robin
        name: db_m1_s1
        master-data-source-name: master1
        slave-data-source-names: slave1
      sharding:
        props:
          sql:
            show: true

mybatis自动生成器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 
<generatorConfiguration>
    <!--配置连接器jar地址-->
    <classPathEntry
            location="C:\Users\c17763\.m2\repository\mysql\mysql-connector-java\8.0.13\mysql-connector-java-8.0.13.jar"/>
    <context id="my" targetRuntime="MyBatis3" defaultModelType="flat">
        <commentGenerator>
            <property name="suppressDate" value="false"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--连接驱动配置-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://192.167.3.171:3306/ibethfy?useUnicode=true" userId="ibethfy"
                        password="ibethfy"/>
        <!--生成的entity实体类路径-->
        <javaModelGenerator targetPackage="com.example.demo.entity"
                            targetProject="E:\test\SharingJDBCDemo\src\main\java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
 
        <!--mapper.xml文件路径-->
        <sqlMapGenerator targetPackage="\resources\mapper"
                         targetProject="E:\test\SharingJDBCDemo\src\main">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
 
        <!--mapper接口类生成的路径-->
        <javaClientGenerator targetPackage="com.example.demo.mapper"
                             targetProject="E:\test\SharingJDBCDemo\src\main\java" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
 
        <!--<table tableName="T_FEE_AGTBILL" domainObjectName="FeeAgentBill"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"/>-->
        <!--需要生成的table,tableName是表名,domainObjectName是生成的实体类名-->
        <table tableName="people" domainObjectName="People"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
 
    </context>
</generatorConfiguration>

项目demo结构图,比较简单,只实现功能

Mysql8.0主ä»å¤å¶æ­å»ºï¼shardingsphere+springboot+mybatis读åå离

自动生成器执行方法,打开maven project,点击运行,具体参考下图

Mysql8.0主ä»å¤å¶æ­å»ºï¼shardingsphere+springboot+mybatis读åå离

SharingJdbcDemoApplication,配置mapper扫描路径,也可直接在mapper类上增加@Mapper.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.demo;
 
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class SharingJdbcDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SharingJdbcDemoApplication.class, args);
    }
 
}

DemoController类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.example.demo;
 
        import com.example.demo.entity.People;
        import com.example.demo.mapper.PeopleMapper;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
 
        import java.util.List;
 
@RestController
public class DemoController {
 
    @Autowired
    PeopleMapper peopleMapper;
 
    @RequestMapping("/{id}")
    public People getPeople(@PathVariable(value = "id") int id)
    {
        return peopleMapper.selectByPrimaryKey(id);
    }
 
    @RequestMapping("/insert/{name}")
    public void insert(@PathVariable(value = "name") String name)
    {
        People p  = new People();
        p.setName(name);
        peopleMapper.insert(p);
    }
}

 

启动工程后,即可测试读写分离。关于如何查看读写分离效果,可以开启mysql的查询日志,开启方法如下

登陆mysql,执行语句查询日志记录开启情况:show variables like "%general%";

+------------------+------------------------------+
| Variable_name    | Value                        |
+------------------+------------------------------+
| general_log      | OFF                          |
| general_log_file | /var/lib/mysql/localhost.log |
+------------------+------------------------------+

set global general_log = "ON";开启日志记录,可以在/var/lib/mysql中查看日志。

测试:访问http://localhost:8888/1,查询数据,在日志中,可以看到,172从服务日志记录查询语句,171没有日志。

测试:访问http://localhost:8888/insert/ibethfy,插入语句,可以看到171主服务有日志,172从服务没有日志。

注意:io.shardingsphere用3.0.0版本即可,3.1.0引入maven会报关联错误。

之前想使用mycat实现读写分离等,结果发现mycat只支持mysql5版本,其余版本未在其支持列表,并且mycat很久没更新啦!我自己试了很久都没搭建好mycat的环境,哎!

好啦,基本的都搞完了,之后实施shardingsphere的分库分表!

<think>嗯,用户想做一个基于Spring Boot和Vue的前后端分离的购物商城系统。首先,我需要确认用户的技术背景。可能他们有一定的开发经验,但可能对前后端分离架构不太熟悉。需要先解释前后端分离的基本概念,然后分步骤讲解。 首先,技术选型方面,后端用Spring Boot是合理的,因为它简化了Spring应用的初始搭建和开发。前端用Vue.js,因为它的轻量化和响应式数据绑定适合单页面应用。数据库方面,MySQL是常用的关系型数据库,适合电商系统的数据管理。可能还需要考虑Redis做缓存,提升性能。权限控制用Spring Security,安全可靠。支付接口的话,支付宝和微信支付是必须的,但集成时需要注意合规性和安全性。 接下来是系统架构设计。前后端分离意味着前端和后端通过API交互,所以需要设计清晰的RESTful接口。可能需要用Swagger来生成API文档,方便前后端协作。模块拆分方面,用户管理、商品管理、订单、购物车、支付、搜索和权限这些模块都是电商系统的核心部分。每个模块需要明确职责,比如用户管理处理注册登录,商品管理处理CRUD等。 数据库设计部分,用户表、商品表、订单表、购物车表、分类表、评价表这些是基础。需要详细说明每个表的字段,比如用户表可能有用户名、密码(加密存储)、手机号等。外键关系要注意,比如订单表需要关联用户和商品。索引的优化也很重要,比如商品名称和分类的索引可以提升搜索速度。 后端开发步骤,先用Spring Initializr创建项目,添加依赖。然后配置数据库连接,比如用MyBatis或者JPA。接着按模块开发,每个Controller处理HTTP请求,Service层处理业务逻辑,Mapper或Repository处理数据访问。需要集成Spring Security实现权限控制,比如用户、商家、管理员的不同角色权限。支付模块需要调用第三方API,这里要处理异步通知和订单状态更新。最后用Swagger生成接口文档,方便测试和前端对接。 前端开发方面,Vue CLI创建项目,选择合适的UI框架如Element UI或Ant Design Vue。路由用Vue Router管理页面跳转,状态管理用Vuex。Axios处理HTTP请求,拦截器可以用来处理token和统一错误提示。页面部分,首页展示商品列表,商品详情页需要轮播图和加入购物车功能。购物车页面要实时更新数量和总价。订单页面需要填写收货信息,支付跳转。用户中心包括个人信息和订单历史。权限控制方面,路由守卫检查用户角色,决定是否允许访问某些页面。 联调测试阶段,需要确保前后端接口正常通信。Postman测试后端接口,Vue前端调用并处理响应。跨域问题可能通过Nginx反向代理或后端CORS配置解决。性能优化方面,后端用Redis缓存热点数据,前端用懒加载和CDN加速资源。压力测试工具如JMeter可以模拟高并发场景。 部署上线的话,后端打包成JAR用Java命令运行,或者用Docker容器化。前端build后部署到Nginx或OSS。数据库用主从复制提高可用性,Redis集群处理缓存。监控方面,Prometheus和Grafana监控系统状态,日志用ELK收集分析。 可能遇到的难点包括支付模块的异步通知处理,需要确保订单状态正确更新。权限管理的细粒度控制,比如不同角色的访问权限。高并发下的库存扣减,可能需要用Redis分布式锁或消息队列来避免超卖。还有安全性问题,比如XSS和SQL注入,后端需要做好输入校验和过滤,前端也要防止XSS攻击。 总结来说,整个项目需要分模块逐步开发,前后端协同工作,注意接口设计和安全性,同时考虑性能和用户体验。用户可能需要更多的细节或具体某个模块的实现,比如如何集成支付,或者权限控制的具体代码示例。需要保持回答结构清晰,逐步引导用户理解整个开发流程。</think>好的,我将从技术选型、系统架构、核心模块和实现步骤四个方面,分步骤为您解析如何搭建基于SpringBoot+Vue的购物商城系统。 ### 一、技术选型 ``` 后端技术栈: - 核心框架:Spring Boot 2.7.x - 安全框架:Spring Security + JWT - 持久层:MyBatis-Plus - 数据库:MySQL 8.0 + Redis - 接口文档:Swagger3 - 支付接口:支付宝沙箱 + 微信支付SDK 前端技术栈: - 核心框架:Vue3 + TypeScript - UI框架:Element Plus - 状态管理:Pinia - 路由管理:Vue Router - HTTP库:Axios - 构建工具:Vite ``` ### 二、系统架构设计 $$ \begin{array}{ccc} \text{客户端} & \leftrightarrow & \text{Nginx} \\ & & \downarrow \\ \text{Vue前端} & \xrightarrow[RESTful API]{HTTP/HTTPS} & \text{SpringBoot后端} \\ & & \downarrow \\ \text{浏览器} & & \text{MySQL/Redis} \\ \end{array} $$ ### 三、核心模块设计 1. **用户模块** - 手机号/邮箱注册 - JWT令牌登录 - 第三方登录(微信/QQ) - 权限控制(RBAC模型) 2. **商品模块** - 商品分类管理 - 商品搜索(ElasticSearch集成) - 商品详情展示 - 商品评价系统 3. **订单模块** - 购物车设计(Redis实现) - 订单状态机设计 - 分布式事务处理(Seata) - 支付回调处理 4. **后台管理** - 数据统计看板 - 商品上下架管理 - 订单审核/发货 - 用户权限管理 ### 四、数据库关键表设计示例 ```sql -- 用户表 CREATE TABLE `user` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) UNIQUE, `password` VARCHAR(100), -- BCrypt加密存储 `mobile` VARCHAR(20), `email` VARCHAR(50), `status` TINYINT DEFAULT 1 ); -- 商品表 CREATE TABLE `product` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(100), `price` DECIMAL(10,2), `stock` INT, `category_id` BIGINT, `detail` TEXT ); -- 订单表 CREATE TABLE `order` ( `id` VARCHAR(32) PRIMARY KEY, -- 雪花算法生成 `user_id` BIGINT, `total_amount` DECIMAL(10,2), `status` TINYINT, -- 0-未支付 1-已支付 2-已发货 etc. `payment_time` DATETIME ); ``` ### 五、后端核心代码示例 ```java // 订单服务接口 public interface OrderService { String createOrder(CartDTO cartDTO); // 创建订单 void paySuccess(String orderNo); // 支付成功回调 } // JWT认证过滤器 public class JwtFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 验证Token逻辑... } } ``` ### 六、前端关键实现 1. **路由守卫实现** ```javascript router.beforeEach((to, from, next) => { const hasToken = localStorage.getItem('token'); if (to.meta.requiresAuth && !hasToken) { next('/login'); } else { next(); } }); ``` 2. **商品搜索组件** ```vue <template> <el-autocomplete v-model="keyword" :fetch-suggestions="querySearch" @select="handleSelect" /> </template> <script setup> const searchProducts = async (query) => { const res = await axios.get('/api/products/search', { params: { q: query } }); return res.data; }; </script> ``` ### 七、部署方案 1. **后端部署** - 使用Docker构建镜像 - Kubernetes集群部署 - 配置Nginx负载均衡 2. **前端部署** ```bash npm run build # 生成dist目录部署到Nginx location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } ``` ### 八、性能优化建议 $$ \begin{aligned} &\text{前端优化:} \\ &\quad\bullet\ \text{路由懒加载} \\ &\quad\bullet\ \text{CDN静态资源加速} \\ &\text{后端优化:} \\ &\quad\bullet\ \text{Redis缓存热点数据} \\ &\quad\bullet\ \text{数据库读写分离} \\ &\quad\bullet\ \text{消息队列削峰填谷} \end{aligned} $$ ### 九、常见问题解决方案 1. **跨域问题** ```java @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .maxAge(3600); } } ``` 2. **重复提交问题** - 前端:按钮防抖(300ms) - 后端:Redis分布式锁(Redisson实现) 如果需要某个模块的详细实现方案(如秒杀系统设计、支付对接细节等),可以提出具体问题,我将提供针对性解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值