秒杀系统SpringCloud架构选型以及后台代码搭建(一)

简介

“秒杀”,就是在同一个时刻有大量请求争抢购买同一个商品,并完成交易的过程,其间涉及大量的并发读和并发写,并要求高可靠和高性能的系统支持。

也因此,“秒杀”对于程序员来讲也意味着巨大的挑战。

在这里插入图片描述

秒杀的三个可用性

高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。本专栏将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。

一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,我将用一篇文章来专门讲解如何设计秒杀减库存方案。

高可用。 虽然我介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,我们还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。专栏的最后,我将带你思考可以从哪些环节来设计兜底方案。

秒杀系统的关键点

防止超卖

超过了库存还可以卖给用户,这就是“超卖”,也是系统设计需要避免的。为了承受大流量的访问,我们用了水平扩展的服务,但是对于他们消费的资源“库存”来说,却只有一个。

为了提高效率,会将这个库存信息放到缓存中。以流行的 Redis 为例,用它存放库存信息,由多个线程来访问就会出现资源争夺的情况。也就是分布式程序争夺唯一资源,为了解决这个问题我们需要实现分布式锁。

假设这里有多个应用响应用户的订单请求,他们同时会去访问 Redis 中存放的库存信息,每接受用户一次请求,都会从 Redis 的库存中减去 1 个商品库存量。

当任何一个进程访问 Redis 中的库存资源时,其他进程是不能访问的,所以这里需要考虑锁的情况(乐观,悲观)。

接下来将直接用代码的形式实战秒杀接口结构

搭建的服务架构如图
在这里插入图片描述
kill-commons 公共服务组件
kill-eureka 使用eureka作为注册中心
kill-item 商品服务
kill-item 商品服务前置服务(主要用来秒杀时为item商品服务抗住流量压力,进行分流)
kill-order 订单服务
kill-zuul 网关服务

主pom依赖

<?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>

    <groupId>com.kimwu</groupId>
    <artifactId>kimwu_kill_mall</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0</version>
    <modules>
        <module>kimwu_kill_order</module>
        <module>kimwu_kill_eureka</module>
        <module>kimwu_kill_zuul</module>
        <module>kimwu_kill_item</module>
        <module>kimwu_kill_commons</module>
        <module>kimwu_kill_item_pre</module>
    </modules>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>2.2.6.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
        <consul.versin>1.4.5</consul.versin>
        <lombok.version>1.18.12</lombok.version>
        <mybatis.version>3.1.0</mybatis.version>
        <fastjson.version>1.2.47</fastjson.version>
        <commons-lang3.versin>3.4</commons-lang3.versin>
        <apollo.version>1.3.0</apollo.version>
        <easypoi.version>3.0.1</easypoi.version>
        <poi.version>3.15</poi.version>
        <fastdfs.version>1.27</fastdfs.version>
        <valid.version>2.0.1.Final</valid.version>
        <hutool.version>5.6.3</hutool.version>
        <xxljob.version>2.1.2</xxljob.version>
        <redis.version>1.4.3.RELEASE</redis.version>
        <druid.version>1.1.10</druid.version>
        <knife4j.version>1.9.6</knife4j.version>
        <guava.version>25.1-jre</guava.version>
        <elasticsearch.version>6.6.0</elasticsearch.version>
        <springboot.pageHelper.version>1.2.3</springboot.pageHelper.version>
        <springboot.easypoi.version>4.1.2</springboot.easypoi.version>
        <parquet.hadoop.version>1.8.2</parquet.hadoop.version>
        <hadoop.common.version>2.7.3</hadoop.common.version>
        <commons.logging.version>1.1.1</commons.logging.version>
        <commons.configuration.version>1.7</commons.configuration.version>
        <commons.collections.version>3.2.1</commons.collections.version>
        <log4j.version>1.2.14</log4j.version>
        <nacos.version>2.2.1.RELEASE</nacos.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springboot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- springcloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-redis</artifactId>
                <version>${redis.version}</version>
            </dependency>
            <!-- consul -->
            <dependency>
                <groupId>com.ecwid.consul</groupId>
                <artifactId>consul-api</artifactId>
                <version>${consul.versin}</version>
            </dependency>
            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- commons-lang3 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.versin}</version>
            </dependency>
            <!-- apollo -->
            <dependency>
                <groupId>com.ctrip.framework.apollo</groupId>
                <artifactId>apollo-client</artifactId>
                <version>${apollo.version}</version>
            </dependency>
            <!-- easypoi -->
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-base</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-web</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-annotation</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
            <!-- poi -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!-- springboot easypoi-->
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-spring-boot-starter</artifactId>
                <version>${springboot.easypoi.version}</version>
            </dependency>
            <!-- fastdfs -->
            <dependency>
                <groupId>cn.bestwu</groupId>
                <artifactId>fastdfs-client-java</artifactId>
                <version>${fastdfs.version}</version>
            </dependency>
            <!-- valid -->
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>${valid.version}</version>
            </dependency>
            <!-- hutool -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <!-- xxljob -->
            <dependency>
                <groupId>com.xuxueli</groupId>
                <artifactId>xxl-job-core</artifactId>
                <version>${xxljob.version}</version>
            </dependency>
            <!-- druid -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- guava -->
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>
            <!-- es -->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <!--hadoop-->
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-client</artifactId>
                <version>${hadoop.common.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-common</artifactId>
                <version>${hadoop.common.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-hdfs</artifactId>
                <version>${hadoop.common.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>${commons.logging.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons.collections.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-configuration</groupId>
                <artifactId>commons-configuration</artifactId>
                <version>${commons.configuration.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!--nacos-config-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
                <version>${nacos.version}</version>
            </dependency>
            <!--nacos-discovery-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>${nacos.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值