龙空技术网

100W请求秒杀架构体系-静态资源处理

JAVA小学生 485

前言:

今天我们对“nginx正则表达式转义符”大概比较关怀,看官们都需要学习一些“nginx正则表达式转义符”的相关资讯。那么小编也在网摘上网罗了一些关于“nginx正则表达式转义符””的相关文章,希望朋友们能喜欢,你们一起来学习一下吧!

目标1:秒杀设计-业务设计、架构设计、表设计

目标2:工程讲解

目标3:商品详情页开发

目标4:数据同步Canal学习

目标5:分布式任务调度elastic-job学习

目标6:静态页动态更新

1 秒杀设计

业务流程

电商项目中,秒杀属于技术挑战最大的业务。后台可以发布秒杀商品后或者将现有商品列入秒杀商品,热点分析系统会对商品进行分析,对热点商品做特殊处理。商城会员可以在秒杀活动开始的时间内进行抢购,抢购后可以在线进行支付,支付完成的订单由平台工作人员发货,超时未支付订单会自动取消。

当前秒杀系统中一共涉及到管理员后台、搜索系统、秒杀系统、抢单流程系统、热点数据发现系统,如下图:

秒杀架构

B2B2C商城秒杀商品数据一般都是非常庞大,流量特别高,尤其是双十一等节日,所以设计秒杀系统,既要考虑系统抗压能力,也要考虑系统数据存储和处理能力。秒杀系统虽然流量特别高,但往往高流量抢购的商品为数不多,因此我们系统还需要对抢购热门的商品进行有效识别

商品详情页的内容除了数量变更频率较高,其他数据基本很少发生变更,像这类变更频率低的数据,我们可以考虑采用模板静态化技术处理。

秒杀系统需要考虑抗压能力,编程语言的选择也有不少讲究。项目发布如果采用Tomcat,单台Tomcat抗压能力能调整到大约1000左右,占用资源较大。Nginx抗压能力轻飘的就能到5万,并且Nginx占用资源极小,运行稳定。如果单纯采用Java研发秒杀系统,用Tomcat发布项目,在抗压能力上显然有些不足,如果采用Lua脚本开发量大的功能,采用Nginx+Lua处理用户的请求,那么并发处理能力将大大提升。

下面是当前秒杀系统的架构图:

数据库设计

数据库名字: seckill_goods

秒杀订单数据库

秒杀订单表: tb_order

管理员数据库

管理员表: tb_admin

用户数据库

用户表: tb_user

项目介绍

技术栈介绍

商品详情页

分析

秒杀活动中,热卖商品的详情页访问频率非常高,详情页的数据加载,我们可以采用直接从数据库查询加载,但这种方式会给数据库带来极大的压力,甚至崩溃,这种方式我们并不推荐。

商品详情页主要有商品介绍、商品标题、商品图片、商品价格、商品数量等,大部分数据几乎不变,可能只有数量会变,因此我们可以考虑把商品详情页做成静态页,每次访问只需要加载库存数量,这样就可以大大降低数据库的压力。

我们这里将采用freemarker来实现商品详情页的静态化,关于freemarker的语法我们就不在这里讲解了,大家可以自行去网上查阅相关API。并发处理能力

1、降低了数据库查询频率

2、使用Nginx实现详情页访问效率远高于Tomcat

Canal增量数据同步利器

canal主要用途是基于 MySQL 数据库增量日志解析,并能提供增量数据订阅和消费,应用场景十分丰富。

github地址:

版本下载地址:

文档地址:

Canal应用场景

1.电商场景下商品、用户实时更新同步到至Elasticsearch、solr等搜索引擎;

2.价格、库存发生变更实时同步到redis;

3.数据库异地备份、数据同步;

4.代替使用轮询数据库方式来监控数据库变更,有效改善轮询耗费数据库资源。

MySQL主从复制原理

1. MySQL master 将数据变更写入二进制日志( binary log , 其中记录叫做二进制日志事件 binary log events ,可以通过 show binlog events 进行查看) 2. MySQL slave 将 master 的 binary log events 拷贝到它的中继日志( relay log ) 3. MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

Canal工作原理

1.canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议

2. MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal ) 3.canal 解析 binary log 对象(原始为 byte流)

Canal安装

参考文档:

MySQL Bin-log开启

1)MySQL开启bin-log

a.进入mysql容器

docker exec ‐it ‐u root mysql /bin/bash

cd /etc/mysql/mysql.conf.d

b.开启mysql的binlog

在mysqld.cnf最下面添加如下配置

# 开启 binlog

log‐bin=/var/lib/mysql/mysql‐bin

# 选择 ROW 模式

binlog‐format=ROW

# 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复

server‐id=12345

c.创建账号并授权

授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant:

create user canal@'%' IDENTIFIED by 'canal';

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%';

FLUSH PRIVILEGES;

d.重启mysql

docker restart mysql

开启bin-log后,我们可以用sql语句查看下:

show variables like '%log_bin%'

效果如下:

Canal安装

1)拉取镜像

docker pull canal/canal‐server:v1.1.1

2)安装容器

a.安装canal-server容器

docker run ‐p 11111:11111 ‐‐name canal ‐d docker.io/canal/canal‐server

b.配置canal-server

修改 /home/admin/canal-server/conf/canal.properties ,将它的id属性修改成和mysql数据库中server-id不同的值,如下图:

c.修改 /home/admin/canal-server/conf/example/instance.properties ,配置要监听的数据库服务地址和监听数据变化的数据库以及表,修改如下:

指定监听数据库表的配置如下 canal.instance.filter.regex :

mysql 数据解析关注的表,Perl正则表达式.

多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\)

常见例子:

1. 所有表:.* or .*\\..*

2. canal schema下所有表: canal\\..*

3. canal下的以canal打头的表:canal\\.canal.*

4. canal schema下的一张表:canal.test1

5. 多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)

注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为不解析sql,所以无法准确提取tableName进行过滤)

重启canal

docker restart canal

Canal微服务

我们搭建一个微服务,用于读取canal监听到的变更日志,微服务名字叫 seckill-canal 。该项目我们需要引入canal-spring-boot-autoconfigure 包,并且需要实现 EntryHandler<T> 接口,该接口中有3个方法,分别为insert 、 update 、 delete ,这三个方法用于监听数据增删改变化。

参考地址:

静态页同步

只需要添加Feign包,注入SkuPageFeign,根据增删改不同的需求实现生成静态页或删除静态页。修改SkuHandler

分布式任务调度

分布式任务调度介绍

很多时候,我们需要定时执行一些程序完成一些预定要完成的操作,如果手动处理,一旦任务量过大,就非常麻烦,所以用定时任务去操作是个非常不错的选项。

现在的应用多数是分布式或者微服务,所以我们需要的是分布式任务调度,那么现在分布式任务调度流行的主要有elastic-job、xxl-job、quartz等

elastic-job讲解

官网:

静态任务案例

使用elastic-job很容易,我们接下来学习下elastic-job的使用,这里的案例我们先实现静态任务案例,静态任务案例也就是执行时间事先写好。

实现步骤:

1.引入依赖包

2.配置zookeeper节点以及任务名称命名空间

3.实现自定义任务,需要实现SimpleJob接口

静态页动态更新

索引和静态资源的更新功能已经完成,所有秒杀商品都只是参与一段时间活动,活动时间过了需要将秒杀商品从索引中移除,同时删除静态页。我们需要有这么一个功能,在秒杀商品活动结束的时候,将静态页删除、索引库数据删除。

此时我们可以使用elastic-job定时执行该操作,我们看如下活动表,活动表中有一个活动开始时间和活动结束时间,我们可以在每次增加、修改的时候,动态创建一个定时任务,把活动结束时间作为任务执行时间。

标签: #nginx正则表达式转义符