这个测试是因为以后工作可能没有前端页面给我们看,
亦或是前端还没有我们的进度快,在前后端分离开发的时候,所以要基于这个发起各种请求
测试的是频道列表展示,我知道是需要先登录获取token值,把token放到请求头里在操作的
具体细节有些迷惑...截图说明,明早问老师.
比如这个吊东西是干啥的,一直弹弹弹,这个是一个什么冲突,当时老师说的,
我的阿里密钥那个东东
Set Background Image
87u3j90m0Z8H5ZKVk4MKJv
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXD59sQb-1632813957818)(images\image-20210927133628240.png)]
//TODO:这里照猫画虎是测试出来了,不理解这个wemedia是哪里来的,是看网关还是看controller哪里有写?
走本机的6002就是自媒体的网关端口,后面是请求路径,
这个是和杨纪聪说的是一样,就是网关里面的路由Path后面的路径,下面的1就是删除掉端口后的一个名称,
以接下来的路径去访问
再下面是页数,每页条数,channeId这个是自媒体用户在数据库的ID???
//TODO:这个没有显示出来的确是因为的代码没有写完就提前引入了依赖,引了依赖但是没有写配置所以渣找不到
/**
* 状态
0 暂时不可用
1 永久不可用
9 正常可用
*/
status状态为9
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZyPc0MS-1632813957820)(images\image-20210927133951345.png)]
Content-Type(内容类型) application/json(json类型,key:value格式)
引入依赖
功能:文档说明 和 在线调试
<!--添加knife4j文档依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
常用注解:将默认的英文解释改为自定义的中文
@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiModelProperty:用对象接收参数时,描述对象的一个字段
//TODO:方便帮我们调试问题
1.重要的方法入参的部分打印日志,好知道方法被调用了,和调用的参数是什么
2.一些重要的流程完事以后要打印日志,比如敏感词调用完了,打印日志
3.在你的方法出错的位置打印error日志
现在可以在控制台上看到异常信息(开发环境时候),
项目到生产环境的时候就看不到了,只能通过自己的日志找,
当初写的越详细,后期有问题越好找
1.换一下app的前端代码,他改过了
2.导入依赖都是一个:cnpm install 启动命令:npm run serve
3.搭建网关,改配置路径login_auth初识化白名单里
4.在保存文章的时候生成静态页面,思路就是这一句话
5.(模板引擎)freemarker面试的时候不用提起,就说放在OSS里面就行,但是阿里那个需要有一个自己的域名
我们现在没有,用这个开源的前端框架技术代替,等到了公司就有了
6.循环遍历,判断,取值表达式,记得前后有#号list if ${变量.属性}
空值判断,集合存在不存在,用两个问号??,----有点像我们平时聊天??
那项目是一个资讯类的项目,有点类似于今日头条,细节没有今日的那么全,大体上的功能是都很像,是一个面向toc用户的APP,分为三个端开发的,app端就是大体用户,平时等电梯坐地铁的时候用它来刷刷新闻,看看段子,自媒体端就像是B站里的up主,可以通过实名认证来当,通过后就可以发一些自己的东西来吸引粉丝,内容我们后台也是有自动审核的,过不了审的肯定是不行的,自动审核不确定的就交给运营端的后台管理员人工审,这个尺度就看他们的怎么把握了,第三个端就是这个运营管理端,给他们平时维护后台的数据和升级app用的
整体架构用的是分布式架构,前端的数据都要过网关,过网关后微服务与微服务之间的内部调用就是通过feign来发起远程调用,feign是StringCloud引入的,在集成Ribbon负载均衡策略,就能让客户端实现负载均衡调用了么,
(tob是面向企业)
分为三个端:
app端:用户可以下载app,阅读最新,最热点的新闻,资讯
运营管理: 给管理员 管理后台数据
自媒体管理: 普通用户可以通过实名认证来成为自媒体人 发表文章
我主要是负责自媒体端的用户登录模块,实名认证模块,和文章自动审核这里
然后再把这三个模块展开聊聊
用户登录模块:
技术:
实名认证模块:
技术:
文章自动审核模块:
技术:
基于需求/原型 定义 接口文档
接口文档: 1. 接口描述 2. 接口路径 3. 接口的请求方式 4. 接口请求参数 5. 接口的响应内容
前端 和 后端 并行开发
后端实现web接口: controller service mapper三层
自测: 单元测试 接口测试 postman knife4j
前端和后端进行联调
前端会将请求路径改为后台网关 进行测试
出现问题: 谁的问题谁去改
mysql 6个数据库 70张表
PowerDesginer 进行数据库建模 基于模型反向生成sql语句
按照需求 或 原型
//TODO:这个不懂
父工程 定义依赖版本 继承springboot
basic: 存储starter起步依赖 通用的配置
common: 常量
model: 实体类 DTO (请求参数对象 service) VO (响应页面的视图对象) POJO (和数据库表对应的实体类)
gateways: 网关聚合工程 (3个网关)
services: 微服务聚合工程
utils: 工具类工程
test: demo
swagger: 生成接口的框架
使用步骤: 引入对应依赖
准备配置类: 定义要扫描的包 识别所有的mvc的注解
添加注解: @Api 类 @ApiOperation 方法 @ApiModelProperty 属性
项目路径/swagger-ui.html
knife4j: swagger增强, 全局参数的设置 离线接口文档的下载
项目启动 ==> @SpringBootApplication ==> @EnableAutoCongifuration ==> @Import(importSelector) 导入配置 ==>
导入选择器会去 所有依赖中==> META-INF文件下的spring.factories 找 key为enableAutoConfiguration所有配置找到这些候选配置
候选者配置过滤
1. 去重复的配置
2. 去除排除的配置
3. 按照条件注解进行过滤
剩下的配置 就是要加载的配置
定义配置类
定义META-INF/spring.factories key=配置类的路径
采用统一异常的方式处理:
主要: @ContorllerAdvice (controller增强) @ExceptionHandler (异常处理器)
创建一个异常统一处理类: 类上添加 @RestControllerAdvice
不可预知异常方法 @ExceptionHandler(Exception.class)
统一的错误响应结果
自定义异常方法 @ExceptionHandler(CustomException.class)
按照自定义的状态码和消息进行响应
@PathVariables 接收路径参数
@RequestBody 接收请求体中的json对象
@RequestParam 接收key = value参数
@Autowired 和 @Resource 区别:
Spring JDK
类型 bean名称 如果没有找到对应的bean会按照类型注入
@Qualifier(value = "beanName")
@Primary
Spring Cloud alibaba nacos : 1.3.2
nacos :
注册中心
服务的注册
服务的发现
服务的状态监控
配置中心
统一管理配置
共享配置的复用
namespace命名空间
Spring Cloud Gateway
路由: (1.id唯一标识 2.uri要路由到的地址 3.断言是否满足此路由 4.过滤器 )
hystrix: 降级
限流: 利用令牌桶算法,防止高并发对微服务带来压力
统一认证:
nodejs npm
# 安装依赖
npm install
# 运行
npm run dev
前端:
F12
network : 路径 请求方式 请求参数 响应结果
后台:
debug : 入参对不对
log日志: 生产环境
可逆算法加密:
* 对称加密
文件加密和解密使用相同的密钥.
安全性较低.
* 非对称加密
分为公钥和私钥.
公钥加密的数据只能用私钥解密,反之私钥加密的技术只能用公钥解密.
安全性较好.
不可逆加密算法
* 一旦加密就不能反向解密,常用于登录密码的加密
常见有MD5,SHA,HMAC
* 服务端有状态
用户登录后,在服务器端保存用户的登录信息.
可以使用session域对象,或redis存储数据.
高并发访问,服务器要存储大量数据,压力大.
涉及微服务跨域共享,使用较繁琐
* 服务端无状态
服务器不保存用户的登录信息.
在用户登录,服务器颁发一个令牌给浏览器,浏览器保存到本地,每次发送请求时携带token,服务端只需验证token即可得知用户登录状态.
//TODO:基于无状态请求流行起来的一种登录认证技术.
○ JSON Web Token(JWT)是一种通信双方传输token的协议,简洁安全.
* jwt令牌有三部分组成.
* Header
头部包含令牌的类型及使用的加密算法.
* Payload
负载保护服务器保存的数据,格式为JSON对象.
* Signature
签名,将前两部分编码后用.拼接,再使用header声明的算法进行加密.
可以防止令牌信息被篡改.
答案就在上面,
Signature(签名)
它由两部分组成 :
第一部分: 首先将header和Payload进行base64url编码处理得到的信息后加上 (.)
第二部分: 将jwt整体使用header中定义的加密方式,进行加密,得到的内容和上面拼接
//TODO: 该接口是管理人员登录到后台管理页面后,对app端用户发起的实名认证请求进行审核.
● user-service微服务接口
○ app端用户实名认证审核
1. 使用mybatis-plus技术,查询ap_user数据库中的实名认证信息,并分页显示在网页.
2. 管理人员对认证请求选择通过或驳回.
* 实名认证通过
.修改数据库中该条信息相关的status状态信息
.检查wemedia数据库,是否存在该用户的关联账号,若不存在,则创建.
.检查article数据库,是否存在关联的作者账号,若不存在,则创建.
.调用wemedia和article微服务的接口,都使用feign技术进行远程调用.
.以上流程任意位置出错,都将进行事务回滚.(开启seata全局事务)
.若全部成功则返回认证通过.
* 实名认证驳回
.修改该条认证数据的status为驳回.
.返回认证驳回成功.
○ 通过全局过滤器实现jwt校验
1. 编写自定义类,实现GolbalFilter接口.
* 添加@Component注解,自动装配
* Order(1) 括号内数字越小,加载优先级就越高
2. 重写filter方法.
* 添加白名单,将如 登录,文档接口等访请求路径,不经检查直接放行.
* 对于需要过滤的路径请求,尝试从请求头中获取TOKEN信息
- 若不存在,终止请求,并提示用户登录
- 若存在token,校验token中的信息是否被篡改,是否有效,若都通过则取出令牌中,登录 用户的id信息,放入请求头中并放行,实现跨微服务共享. ..mutate()方法
分布式事务,指的是在分布式的架构中,一个业务操作可能需要多个服务,多个数据库共同完成,传统的数据库事务只能保证当前服务的事务,无法保证分布式事务的一致性
常见解决方案:
基于XA的二阶段提交 : 强一致性,性能差
基于TCC : 补偿性, 性能好,不依赖数据库, 但是每个事务环节都要提供3个方 try confirm cancel 代码改造量大
基于MQ+本地消息表 : 利用可靠性消息,将一个大分布式事务,拆成若干小的环节,通过消息队列达到最终一致性 异步 性能快 ,代码实现复杂,一致性比较弱
在分布式中,一个付款微服务调用另一个收款微服务,前面一个成功了.,前面微服务关联的数据库会改变,因为事务已经提交,在调用后一个微服务的时候,后一个微服务失败了,只会回滚当前的微服务,前面一个提交了的不会回滚,可以拿收付款来说
C: 一致性
A: 高可用性
P: 分区容错性
CAP定理指的在分布式的架构中,要想完成实现上面3种指标是不可能的,
P是必须要满足的,所以要在A和C之前进行选择
CP 强调一致性
AP 强调高可用性
基本可用:
主体的服务可用,特殊期间可以采用降级,为了保护主体服务的稳定.或者是时间上的一些损失,本来是0.5秒能搜索的,实际1秒对于大部分用户来说还是可以接受的
软状态:
允许数据出现中间状,短时间内不一致,也不会影响系统的整体可用.
最终一致:
并发没有那么高的时候,客户端最终访问的数据都是最新的值,使其达到最终一致
概念:
是CAP中的一致性和可用性权衡的结果,根据大型互联网分布式实践的总结,核心思想,无法做到强一致性,但是每个应用都可以根据自身业务的特点,采用适当的方式来达到最终一致性
XA模式:
分两阶段提交,实现强一致,性能很差,因为要第一阶段需要锁定数据库资源,等第二段结束才能释放
TCC(try--confirm--cancel)模式:
不依赖数据库,依赖补偿操作,一阶段完成直接提交事务,释放数据库资源,性能好,无需快照,无需全局锁,
缺点有代码入侵,事务是最终一致的.需要考虑Confirm和Cancel的失败,做好幂等处理
基于MQ+本地消息表
AT模式:seata的默认模式(分布式解决方案)
阶段一RM的工作:
- 注册分支事务
- 记录undo-log(数据快照)
- 执行业务sql并提交
- 报告事务状态
阶段二提交时RM的工作:
- 删除undo-log即可
阶段二回滚时RM的工作:
- 根据undo-log恢复数据到更新前
解决了分布式存储的问题, 我们将项目中所有的素材信息存储到了OSS
项目中具体使用:
阿里云官网 开通OSS对象存储服务
根据网关下载对应SDK
申请对应的访问key 和 密钥
根据SDK所提供的demo , 封装成一个starter依赖 (FileStorageService OSS实现类)
在项目中直接引入starter依赖即可
前端点击上传素材,传入素材图片
后台@PostMapping 使用 MultipartFile 参数接收
判断后缀格式 文件信息是否正确
生成新文件名称(UUID) + 后缀(substring(原文件名称))
@Autowired 注入 FileStorageService , 调用上传文件方法
创建素材实例 ==> 将文件路径存入到素材实例信息中
保存素材
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sTDJSUWf-1632813957821)(images\image-20210925190756132.png)]
filter ==> header userId ==> Threadlocal
service ==> ThreadLocal.get();
无状态的登录方式,那我们去哪里获取用户呢
不是session存了,是由每一个线程的本地变量带过来的,用户信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SASCfS76-1632813957823)(images\image-20210925191134482.png)]
1.过滤器是javaweb的标准,和框架没有关系,只要你用javaweb这个项目,就能用过滤器
2.拦截器interceptor是需要框架去实现的,它有前置处理和后置处置,比如SpringMVC的拦截器,可以拦截到网关发过来的参数中的token
3.既有过滤器又有拦截器先走,过滤器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S74pCStm-1632813957824)(images/image-20210928152155276.png)]
涉及模块: 实名认证 user服务 (ap_user_realname) article服务(ap_author) wemedia服务(wm_user)
解决方案: seata
alibaba的开源 分布式事务一站解决方案 , 支持的事务模式: AT模式、TCC模式 XA模式 、SAGA模式
我们使用的是AT模式 Atomic Transactional 原子事务
优点: java项目 JDBC
可实现原子性事务,要么全部成功 要么全部失败
性能要比XA非常高
对代码的侵入性非常低
使用方式:
1. 先部署 Seata Server服务端,服务支持高可用集群, 事务相关数据 存放在数据库中 (全局事务表、分支事务表、全局锁表)
2. 微服务整合seata . 抽取了一个通用配置 (数据源代理, 配置服务端的连接地址)
3. 每个涉及分布式事务的数据库,都要创建一张undo_log日志表
4. 在发起分布式事务的方法中 加上@GlobalTransactional注解 代码开启了全局事务
AT模式采用二阶段提交:
@GlobalTransactional 给方法开启全局事务,实现AOP方法的增强, 会调用服务端创建一条 全局事务数
第一阶段: 执行每个分支事务
当我们的业务sql被执行前,会先注册一个分支事务, 将我们的业务sql + 业务sql对应生成回滚信息 在一个本地事务中执行,回滚信息会存放在undo_log表中
第二阶段:
情况1: 一阶段全部成功
根据全局事务ID 及 分支事务ID 异步的删除所有相关的回滚日志undo_log日志
情况2: 一阶段失败
根据全局事务ID 及 分支事务ID,查询对应的回滚日志,根据回滚日志的内容生成反向的sql 进行数据的回滚
1. 执行sql时,seata会解析sql语句 seata会查询你修改前的数据 存储为==> before image 前置镜像
执行业务sql
执行sql后,seata会查询你修改完毕后的数据 存储为==>after image 后置镜像
2. 需要回滚时,查询到对应的回滚日志, 先根据后置镜像 进行数据的校验 如果当前数据库数据和后置镜像不一致,说明数据被seata以外的操作修改了,那么回滚将失败,seata会不断重试回滚
如果当前数据库数据和后置镜像一致, 会根据前置镜像的数据内容,生成一条反向的sql语句 , 进行数据回滚
优点: java项目 JDBC
可实现原子性事务,要么全部成功 要么全部失败
性能要比XA非常高
对代码的侵入性非常低
缺点: 脏读 如果想避免 select for update , 开启全局锁 性能下降
如果数据被seata以外操作修改,回滚有可能失败
性能相对xa和高,但要其它的 mq方案 tcc方案
创建stream流对象
集合.stream() Arrays.stream(数组) Stream.of(1,2,3,4,5)
定义多个中间操作
filter 过滤
map 映射
distinct 去重 重写 hashcode equals
limit 截取
skip 跳过
sorted 排序
定义终止操作
foreach 遍历流数据
collect 收集 (toList 集合 toMap toJoinning() 拼接字符串 groupingBy 数据分组)
stream流操作 会不会对原有数据集做改变 不会
流是延时处理
涉及表: wm_news 文章表 wm_material 素材 wm_news_material 文章和素材的关联表
业务流程:
自媒体人,可以在自媒体端发表文章, 点击发表文章页面 填写文章基本内容
(title images content type publishTime)
已json形式传入后台,后台服务封装dto接收参数
1. 解析校验参数 封装成wm_news对象
2. 保存或修改wmnews对象
如果有id 修改
修改前删除文章和素材的关联关系
如果没有id 直接保存
3. 保存 内容图片 和 封面图片 与素材的关联关系
3.1 先根据文章内容抽取所有相关的素材url路径
content = "[{},{type:image,value:url路径}]";
3.2 保存内容和素材的关联关系
3.3 保存封面和素材的关联关系
当type=-1 代表要自动生成封面
根据内容图片集合生成封面
> 2 多图
> 0 <=2 单图
没有 无图
4. 保存关联关系
4.1 先根据url路径集合 查询出对应所有素材
4.2 将素材集合转为 map key: url value: id
4.3 得到所有的素材id
4.4 调用mapper方法保存关联关系
insert into
由自媒体端发表文章,把携带newsID的消息提交到RabbitMQ消息队列,再由自动审核方法去消费队列中的消息
1.先要检查状态是否是1就是待审核,有可能别人已经审核过了
2.在通过DFA算法检查敏感词,这里面我们可以自定义一些敏感词
3.之后交由阿里云检测图片和文本信息,是否合规
3.1审核判定失败,直接改变消息状态为2,不通过
3.2审核判定通过,直接改变消息状态为8,通过
3.3审核判定不确定,直接改变消息状态为3,不确定,交给人工管理员判定是否可以发表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xjpiPrUR-1632813957825)(images\image-20210925202243713.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-45WwM2Jh-1632813957826)(images\image-20210925201424791.png)]
管理员通过运营管理前端登录后台
后端要实现查询wm_news列表,和它其中的每一个字段
人工点击通过改变文章状态为4,通过
人工点击驳回改变文章状态为2,失败,这不得给一个失败的理由???注意尺度问题
收费的
给我们提供了针对,音频,图片等等各种的检测
PASS(通过)
REVIEW(不确定,复核)
BLOCK(审核失败,阻止)
确定有穷自动机(一种数据结构)
要用这个算法,要先把数据封装成map嵌套map的模型,具体嵌套多少层,就看敏感词有多长
要先把我们想要禁用的敏感词封装成大Map集合,每一个敏感词的字都对应其中的一个map
敏感词的第一个字,对应的就是key,敏感词的字位置一样,只会有一个key
会有一个isEnd字段,为零就不是敏感词的结尾,后面还有字需要判断
为1的时候代表结束词,后面就没有文字了
遍历哈希速度很快,效率高,getkey
MQ消息队列
应用场景,在我们的头条项目中,发布文章去调用审核文章的时候可以用到,可以解耦合,因为这个两个不同的业务
实现异步调用,分时处理,效率更高
发消息的高级通信协议
生产者(producer) 消费者(consumer) 交换机(Exchange) 消息队列(queue) route key(这里是绑定)
生产者:发送消息,发到交换机
消费者:消费,监听指定队列中的消息,能者多劳,可以有多个
交换机:会把消息路由到指定的队列中,具体怎么路由看交换机的类型
消息队列:用于存放消息,有上限.
一共有五种
1.简单的工作模式:
交换机可以写成"",就是默认的交换机.只要写一个路由参数的名称,即可找指定队列.
2.工作队列模式:
和第一个一样,也用默认交换机,
区别是可以有多个消费者,哪个来消费默认采用轮询规则,也可以能者多劳.
3.路由模式: direct(直接的)
用的是直连交换机,这个交换机要和队列提前绑定,靠这个绑定关系来路由消息
发消息前要声明用这个直连交换机,和路由名称,带上消息内容就可以发到指定的队列(可多个),
4.发布订阅模式: fanout(扇出,分列,这里是广播的意思)
一对多发消息的模式,不用指定绑定关系,指定fanout交换机即可,由它广播到所有订阅它的队列,
每个订阅的消费者都可以收到消息
5.主题模式(通配符模式): topic(主题)
指定主题交换机topic,
route_key支持通配符的写法
#号可以匹配任意个单词,*号只匹配1个单词
简单工作模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jmXMKOUa-1632813957827)(images\image-20210925221937208.png)]
工作队列模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6AVI19b6-1632813957828)(images\image-20210925222105371.png)]
路由模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CqXJlQ6Z-1632813957829)(images\image-20210925222116456.png)]
发布订阅模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfuMED0W-1632813957829)(images\image-20210925222125938.png)]
主题模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvZ67UNY-1632813957830)(images\image-20210925222138322.png)]
可以通过搭建集群来实现,运维去搭建
镜像集群模式
虎哥装过的B:
RabbitMQ消息丢失可能发生在多种场景下
1.生产者发送到MQ的时候可能丢失
2.MQ存放的时候可能会把消息弄丢
3.投递给消费者,消费者可能把消息弄丢
发送确认机制(对于生产者)
用一个回调方法,消息正确发送到交换机了,
MQ服务端会告诉生产者一声ture,发送到交换机了
交换机不存在,返回false,发送失败
这部分先不用记
publisher-confirm,发送者确认:
消息成功投递到交换机,返回ack
消息未投递到交换机,返回nack
pubisher-return,发送者回执
消息投递到交换机,但是没有路由到队列,返回ACK,及路由失败原因
消息成功发送到exchange,但是没有路由到queue,调用ReturnCallback
消息返还机制(对于生产者)
虽然发送到交换机了,但是没有一个正确的路由,也会丢失
比如路由是XX,队列没有XX,匹配不上
就是没有正确队列能够接收,有了这个机制,会把消息返还给生产者,
生产者得到这个消息,可以选择重发,也可以报一个错误日志通知管理员
通过这两个机制,确保消息到达MQ
持久化机制(对于MQ的服务端)
MQ的服务端有一个持久化的机制
可以把交换机,MQ消息队列,消息都做持久化,
把存在内存的消息,存到磁盘,确保意外宕机或MQ挂了,重启服务消息还能同步回来
消息确认机制(对于消费者)
开启消费者确认机制为auto,由spring确认消息处理成功后完成ack
消费成功要告诉MQ服务端一声
自动确认:这个不行,接到消息,自动确认,这个时候MQ会删除掉消息,下面的代码也有可能报异常.
手动确认:写代码调用API,告诉服务端,消息被消费掉,写在最后一步.
消息重试机制(对于消费者)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qhRxu8IS-1632813957831)(images\image-20210925234952011.png)]
失败处理策略 retry(重试)
Spring整合RabbitMQ的时候
用AOP提供 消息自动补偿(自动重试)
先记这个
3
项目里他说是用业务处理的
(1)、可在内存中维护一个set,只要从消息队列里面获取到一个消息,先查询这个消息在不在set里面,如果在表示已消费过,直接丢弃;如果不在,则在消费后将其加入set当中。
(2)、如何要写数据库,可以拿唯一键先去数据库查询一下,如果不存在在写,如果存在直接更新或者丢弃消息。
(3)、如果是写redis那没有问题,每次都是set,天然的幂等性。
(4)、让生产者发送消息时,每条消息加一个全局的唯一id,然后消费时,将该id保存到redis里面。消费时先去redis里面查一下有么有,没有再消费。
(5)、数据库操作可以设置唯一键,防止重复数据的插入,这样插入只会报错而不会插入重复数据。
这个要回答
老师那个临时加代码,原来积压消息有可能是消费者出异常了造成的.
用一个临时的交换机和抽调来的一些消费者来处理掉那些积压的消息.
在撤出,恢复一下原来的状态.
你们公司有那么多消息么,别管有没有,你得回答的上来 Lazy(懒惰)
1.加钱,多加几个消费者,这个显然不行,不能为公司省钱的程序猿
2.在消费者内开启线程池,加快消费处理速度,(但是如果是高频消息,会增加CPU消耗,低频的,1秒一次的还可以)
3.扩大队列容积,提高堆积上限(惰性队列,从RabbitMQ的3.6.0版本开始,增加Lazy Queues概念)
可以利用惰性队列特征如下:
1.接收到消息后直接存入磁盘而不是内存中(磁盘便宜啊,嫌弃读写性能慢就用固态磁盘)
(这里会牺牲一个实时性,因为有一个IO的过程,但是也就几毫秒,对比好处可以忽略)
2.消费者要消费消息时才会从磁盘中读取并加载到内存
3.支持数百万的消息存储
MQ默认是把消息存内存,比如32G,分配MQ20G,每个队列也都有自己的内存大小,RabbitMQ会给内存设置一个预警线,
当队列里的内存超过了这个线40%左右,RabbitMQ会认为内存不足,尝试清理内存,这段时间,整个MQ是阻塞的状态,
在来发消息MQ也不收了,清理内存的原理也是把多余的数据转移到磁盘(叫扇出)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NprM4fQj-1632813957831)(images\image-20210926004420757.png)]
雪花算法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QW0cKCGW-1632813957832)(images\image-20210926155035106.png)]
线程池族谱
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z7AdpE5h-1632813957833)(images\image-20210926155129249.png)]
创建线程池的参数
//核心线程数量
//最大线程数量
//保持存活时间
//时间单位(指存活时间)
//阻塞队列 任务队列
//拒绝策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n4kKPuu1-1632813957834)(images\image-20210926155344840.png)]
线程池执行任务过程图
azy(懒惰)
1.加钱,多加几个消费者,这个显然不行,不能为公司省钱的程序猿
2.在消费者内开启线程池,加快消费处理速度,(但是如果是高频消息,会增加CPU消耗,低频的,1秒一次的还可以)
3.扩大队列容积,提高堆积上限(惰性队列,从RabbitMQ的3.6.0版本开始,增加Lazy Queues概念)
可以利用惰性队列特征如下:
1.接收到消息后直接存入磁盘而不是内存中(磁盘便宜啊,嫌弃读写性能慢就用固态磁盘)
(这里会牺牲一个实时性,因为有一个IO的过程,但是也就几毫秒,对比好处可以忽略)
2.消费者要消费消息时才会从磁盘中读取并加载到内存
3.支持数百万的消息存储
MQ默认是把消息存内存,比如32G,分配MQ20G,每个队列也都有自己的内存大小,RabbitMQ会给内存设置一个预警线,
当队列里的内存超过了这个线40%左右,RabbitMQ会认为内存不足,尝试清理内存,这段时间,整个MQ是阻塞的状态,
在来发消息MQ也不收了,清理内存的原理也是把多余的数据转移到磁盘(叫扇出)
[外链图片转存中...(img-NprM4fQj-1632813957831)]
# day06-文章定时发布
**雪花算法**
[外链图片转存中...(img-QW0cKCGW-1632813957832)]
##### 1.文章定时发布流程
##### 2.RabbitMQ实现延时队列方案
##### 3.项目中RabbitMQ的使用场景说明
##### 4.自媒体文章上下架功能
# 线程池复习
##### 线程池介绍
**线程池族谱**
[外链图片转存中...(img-Z7AdpE5h-1632813957833)]
**创建线程池的参数**
//核心线程数量
//最大线程数量
//保持存活时间
//时间单位(指存活时间)
//阻塞队列 任务队列
//拒绝策略
[外链图片转存中...(img-n4kKPuu1-1632813957834)]
**线程池执行任务过程图**
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9SdyKpE-1632813957834)(images\image-20210926155658558.png)]