高并发架构实战(一) 电商系统设计

电商平台微服务架构设计

按照孢子框架要义对电商平台进行微服务架构设计。假设我们设计的目标是简易版淘宝。

1. 需求分析

由于主要是学习技术,所以没对业务规划得过于详细和全面。大的功能分为三个,用户、商品、订单。主要需求如下:

分类 功能 质量
前端首页 注册 及时响应、安全性
  商品展示 及时响应、搜索引擎优化
  商品搜索 及时响应、搜索引擎优化
  秒杀购买商品 及时响应、安全性、可靠性
用户中心 我的订单 及时响应、安全性

2. 系统分析

要将需求进行系统分析,还需要有企业的运营目标做支持。假设我们运营目标是:

  • 用户量:3000万
  • 网站日访问量:3000万PV
  • 商品购买并发:1000 QPS
    我们按照上面的需求进行系统分析,首先按大的职责将职责相同的划分为一个服务。并且有了上面这个运营目标,所有功能需求都需要增加一项“质量”特性,那就是“高并发”,高并发会影响到所有设计。安全性和可靠性也会直接影响功能的技术实现,但并没有并发性影响性大。深入分析职责后把每一种功能的实现关键技术列出,如下:
分类 需求 实现子系统及服务 实现技术(软硬件结合)
前端首页 商品展示、商品搜索 商品系统 集群部署、高速缓存、分布式缓存、搜索引擎技术、静态化
  秒杀购买商品 订单系统 集群部署、消息队列、实时计算
用户中心 我的订单 订单系统 集群部署

如上所述,要支持运营目标的电商平台,可以分为大小几个服务和子系统。系统划分的依据一方面是职责,一方面跟实现技术有关,同一职责下实现技术不同会被划分为两个服务,比如购买商品和商品展示原本属于同一个大的领域,但其因为实现技术和质量要求不同需要划分为两个模块。这是因为微服务和传统SOA最大的区别就是技术实现的个性化,只有个性化才能做好做专,并节省成本。用户购买产品产生订单相关数据,订单数据关系到商品和用户两方面,如果是超高并发的系统,用户购买行为需要单独的服务。

3. 逻辑架构

逻辑视图采用以下方法建立。

按照职责、通用性、技能及工作量综合考虑和计量,平台逻辑架构设计如下图:

用户通过终端层发起请求,请求经由网关层nginx,路由到业务层,业务层通过业务逻辑判断,再访问数据访问层,数据访问层再通过数据库层获取到想要的内容。

  • 使用kafka,可优化下单性能,可以处理秒抢,或者异步处理一些事情,如送下单后优惠券。
  • 使用Elasticsearch,可优化商品查询,商品一般数据量比较大,用户经常模糊查询,近义词要能查出来,且要求及时响应,Elasticsearch正好能解决这种难题,所以非它莫属啦!
  • 使用mongoDB,可优化订单列表。后台订单经常按照时间查询订单列表。
  • 使用redis,可优化库存管理,以免在秒抢时,出现多用户同时抢到同一商品的情况。

4. 开发架构

系统所需的工程:

~/workspace/gitee/high-concurrency on master ⌚ 9:54:01
$ tree -I target
.
├── common            //公共模块 [cn.lilyssh.common]
├── config-server     //分布式配置中心服务 [cn.lilyssh.config]
├── goods             //商品服务
│   ├── goods-api         //实体类和接口定义层 [cn.lilyssh.goods.api]
│   ├── goods-consumer    //接口访问层 [cn.lilyssh.goods.consumer]
│   └── goods-provider    //数据访问层 [cn.lilyssh.goods.provider]
├── order             //订单服务
│   ├── order-api         //实体类和接口定义层 [cn.lilyssh.order.api]
│   ├── order-consumer    //接口访问层 [cn.lilyssh.order.consumer]
│   └── order-provider    //数据访问层 [cn.lilyssh.order.provider]
└── user              //用户服务
    ├── user-api          //实体类和接口定义层 [cn.lilyssh.user.api]
    ├── user-consumer     //接口访问层 [cn.lilyssh.user.consumer]
    └── user-provider     //数据访问层 [cn.lilyssh.user.provider]

开发环境:

编码 工具 版本控制 JDK 开发环境
UTF-8 IDEA Git JDK1.8 Maven 3

开发技术选型:

分类 实现 分类 实现
MVC框架: Spring Boot 2.0.4 Rest接口实现: Spring MVC Rest
持久层: mybatisplus-spring-boot 1.0.5 数据库连接池: druid 1.1.10
分库分表: mycat 数据库: MySql 5.6
缓存框架: Redis、mongoDB 搜索引擎: Elasticsearch
网关: Nginx、Kong(纯属学习使用) API 开发: swagger
RPC框架: dubbo-spring-boot 2.0.0 注册中心: zookeeper
日志管理: SLF4J 消息队列: Kafka
分布式配置中心: spring cloud config 部署: Jenkins

1).微服务的架构

每个微服务的架构基本上是一致的。拿order来说,分为 order-api、order-consumer、order-provider。

~/workspace/gitee/high-concurrency/order on master ⌚ 11:18:53
$ tree -I target
.
├── order-api
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── cn.lilyssh.order.api
│                   ├── model
│                   │   ├── request
│                   │   │   ├── OrderInsertReq.java
│                   │   │   └── OrderQueryReq.java
│                   │   └── response
│                   │       └── OrderQueryResp.java
│                   └── service
│                       └── OrderServiceApi.java
├── order-consumer
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── cn
│           │       └── lilyssh
│           │           └── order
│           │               └── consumer
│           │                   ├── OrderConsumerApplication.java
│           │                   ├── controller
│           │                   │   └── OrderController.java
│           │                   └── service
│           │                       └── OrderService.java
│           └── resources
│               ├── application.yml
│               └── bootstrap.yml
├── order-provider
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── cn
│           │       └── lilyssh
│           │           └── order
│           │               └── provider
│           │                   ├── OrderProviderApplication.java
│           │                   ├── dao
│           │                   │   ├── entity
│           │                   │   │   └── OrderEntity.java
│           │                   │   ├── mapper
│           │                   │   │   └── OrderMapper.java
│           │                   │   └── repository
│           │                   │       └── OrderRepository.java
│           │                   └── service
│           │                       └── OrderService.java
│           └── resources
│               ├── application.yml
│               └── bootstrap.yml
└── pom.xml
  • api项目 提供 前端与consumer层 以及 consumer层与provider层 进行数据传递的实体类和接口xxServiceApi,实体类分为请求类和响应类,这两个包中又根据不同的业务需求分为不同的实体类。实体和接口访问层虽然属于“层”,但它们并不单独发布,而是使用Jar包类库的方式提供给其它服务调用,是逻辑上的层。其他任意项目可dependency此api模块,并调用此api模块提供的接口。
  • consumer 项目中包含controller层和service层,controller给前端提供rest接口,它调用service的方法,service中写业务逻辑,且调用api模块的接口ServiceApi。
  • provider 项目的主要任务是为api项目的接口xxServiceApi提供实现,即xxService,进行数据访问,分为entity,mapper,repository,entity中存放与数据库表字段一一映射的实体类,用于与数据库进行数据传递的交互。mapper由于继承了mybatisplus的BaseMapper,所以本身提供了增删改查等基本方法,如需自定义方法,可自行添加。repository可对业务逻辑进行进一步的拆解。
  • 配置文件application.yml中存放与其他项目不可公用的配置,如端口,其他公用的配置放在分布式配置中心,bootstrap.yml文件中设置分布式配置中心服务地址,和需要下载的配置文件。由于consumer和provider中都用到了配置文件,所以把这点拿出来单独说。

2).分布式配置中心

我们来看一下配置服务config-server项目的目录结构:

~/workspace/gitee/high-concurrency/config-server on master ⌚ 16:10:35
$ tree -I target
├── pom.xml
└── src
    └── main
        ├── java
        │   └── cn
        │       └── lilyssh
        │           └── config
        │               └── ConfigApplication.java
        └── resources
            └── application.yml

application.yml中用来设置配置仓库地址。

扫描二维码关注公众号,回复: 3757534 查看本文章

3).公用的项目

即common项目的目录结构。common项目主要是放一些工具类、异常的统一捕获处理,还有consumer对前端返回结果的统一封装。

~/workspace/gitee/high-concurrency/common on master ⌚ 16:20:17
$ tree -I target
.
├── pom.xml
└── src
    └── main
        ├── java
        │   └── cn
        │       └── lilyssh
        │           └── common
        │               ├── date
        │               │   └──DateUtil.java
        │               ├── exception
        │               │   └── ExceptionAdviceHandler.java
        │               ├── result
        │               │   ├── Result.java
        │               │   ├── ReturnCode.java
        │               │   └── ReturnCodeInterFace.java
        │               └── validate
        │                   └── ValidateGroup.java
        └── resources
            └── META-INF
                └── spring.factories

5. 表结构

用户表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `uuid` varchar(45) DEFAULT NULL,
  `user_name` varchar(20) DEFAULT NULL,
  `password` varchar(45) DEFAULT NULL,
  `real_name` varchar(20) DEFAULT NULL,
  `sex` bit(1) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `phone` int(11) DEFAULT NULL,
  `email` varchar(45) DEFAULT NULL,
  `status` tinyint(1) DEFAULT NULL,
  `last_login_ip` varchar(45) DEFAULT NULL,
  `last_login_time` datetime DEFAULT NULL,
  `id_type` int(11) DEFAULT NULL,
  `id_number` varchar(45) DEFAULT NULL,
  `address` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

订单表:

CREATE TABLE `order` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  `user_uuid` varchar(45) DEFAULT NULL,
  `goods_id` int(11) DEFAULT NULL COMMENT '商品ID',
  `payment` decimal(14,2) DEFAULT NULL COMMENT '实付金额',
  `pay_type` tinyint(1) DEFAULT NULL COMMENT '支付类型:1 在线支付 2 货到付款',
  `post_fee` decimal(6,2) DEFAULT NULL,
  `status` tinyint(2) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `pay_time` datetime DEFAULT NULL,
  `cosign_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
  `shipping_name` varchar(20) DEFAULT NULL COMMENT '物流名称',
  `shipping_code` varchar(45) DEFAULT NULL COMMENT '物流单号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

商品表:

CREATE TABLE `goods` (
  `id` mediumint(8)  NOT NULL AUTO_INCREMENT,
  `goods_name` varchar(45) NOT NULL COMMENT '商品名称',
  `stock` int(11) NOT NULL,
  `logo` varchar(150) NOT NULL DEFAULT '' COMMENT '商品logo',
  `sm_logo` varchar(150) NOT NULL DEFAULT '' COMMENT '商品缩略图logo',
  `price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品价格',
  `goods_desc` longtext COMMENT '商品描述',
  `is_on_sale` tinyint(3)  NOT NULL DEFAULT '1' COMMENT '是否上架:1:上架,0:下架',
  `is_delete` tinyint(3)  NOT NULL DEFAULT '0' COMMENT '是否已经删除,1:已经删除 0:未删除',
  `create_time` int(10)  NOT NULL COMMENT '添加时间',
  `update_time` int(10)  NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

猜你喜欢

转载自blog.csdn.net/lilyssh/article/details/82753318
今日推荐