Day01-环境搭建
项目概述
课程大纲
业务说明
技术栈
Spring-Cloud-Gateway : 微服务之前架设的网关服务,实现服务注册中的API请求路由,以及控制流速控制和熔断处理都是常用的架构手段,而这些功能Gateway天然支持
运用Spring Boot快速开发框架,构建项目工程;并结合Spring Cloud全家桶技术,实现后端个人中心、自媒体、管理中心等微服务。
运用Spring Cloud Alibaba Nacos作为项目中的注册中心和配置中心
运用mybatis-plus作为持久层提升开发效率
运用Kafka完成内部系统消息通知;与客户端系统消息通知;以及实时数据计算
运用Redis缓存技术,实现热数据的计算,提升系统性能指标
使用Mysql存储用户数据,以保证上层数据查询的高性能
使用Mongo存储用户热数据,以保证用户热数据高扩展和高性能指标
使用FastDFS作为静态资源存储器,在其上实现热静态资源缓存、淘汰等功能
运用Hbase技术,存储系统中的冷数据,保证系统数据的可靠性
运用ES搜索技术,对冷数据、文章数据建立索引,以保证冷数据、文章查询性能
运用AI技术,来完成系统自动化功能,以提升效率及节省成本。比如实名认证自动化
PMD&P3C : 静态代码扫描工具,在项目中扫描项目代码,检查异常点、优化点、代码规范等,为开发团队提供规范统一,提升项目代码质量
虚拟机环境搭建
用户名:root
密码:itcast
静态ip地址:192.168.200.130
mysql查看端口
netstat -aon|findstr "3306"
工程主体结构
登录->使用盐来配合验证
redis会报错先注释掉
接口工具
postman、swagger、knife4j
我用的是Apifox
swagger常用注解:
@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数的描述信息
@ApiModelProperty:用对象接收参数时,描述对象的一个字段
ApUserLoginController
@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录", tags = "ap_user", description = "app端用户登录API")
public class ApUserLoginController {
@Autowired
private ApUserService apUserService;
@PostMapping("/login_auth")
@ApiOperation("用户登录")
public ResponseResult login(@RequestBody LoginDto dto){
return apUserService.login(dto);
}
}
LoginDto
@Data
public class LoginDto {
/**
* 手机号
*/
@ApiModelProperty(value="手机号",required = true)
private String phone;
/**
* 密码
*/
@ApiModelProperty(value="密码",required = true)
private String password;
}
网关
思路分析:
用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录
用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户
用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN
网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误
前端集成
作用:
通过nginx的反向代理功能访问后台的网关资源
通过nginx的静态服务器功能访问前端静态页面
Day02-文章查看
文章列表加载
三张表
app端文章列表
表的拆分-垂直拆分
垂直拆分:将一个表的字段分散到多个表中,每个表存储其中一部分字段。
优势:
- 减少IO争抢,减少锁表的几率:查看文章概述与文章详情互不影响。
- 充分发挥高频数据的操作效率:对文章概述数据操作的高效率不会被操作文章详情数据的低效率所拖累。
拆分规则:
- 把不常用的字段单独放在一张表。
- 把text,blob等大字段拆分出来单独放在一张表。
- 经常组合查询的字段单独放在一张表中。
会遇到什么类路径找不到的 把target文件夹全部删掉,再次运行
freemarker
FreeMarker 是一款 模板引擎
基础语法
1.注释<#-- -->
2.插值${..}
3.FTL指令<# >FTL指令</#>
4.文本信息<#--freemarker中的普通文本-->
集合指令
<#list stus as stu>
<tr>
<td>${stu_index+1}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<td>${stu.money}</td>
</tr>
</#list>
if指令
<#if ></if>
运算符
<b>算数运算符</b>
<br/><br/>
100+5 运算: ${100 + 5 }<br/>
100 - 5 * 5运算:${100 - 5 * 5}<br/>
5 / 2运算:${5 / 2}<br/>
12 % 10运算:${12 % 10}<br/>
<hr>
比较运算符
=
或者==
:判断两个值是否相等.!=
:判断两个值是否不等.>
或者gt
:判断左边值是否大于右边值>=
或者gte
:判断左边值是否大于等于右边值<
或者lt
:判断左边值是否小于右边值<=
或者lte
:判断左边值是否小于等于右边值
空值处理
1、判断某变量是否存在使用 “??”
2、缺失变量默认值使用 “!”
内建函数
语法:变量+?+函数名称
具体参考MD文档
对象存储服务MinIO
MinIO简介
对象存储的方式对比
存储方式 | 优点 | 缺点 |
---|---|---|
服务器磁盘 | 开发便捷,成本低 | 扩展困难 |
分布式文件系统(MinIO) | 容易实现扩容 | 复杂度高 |
第三方存储 | 开发简单,功能强大,免维护 | 收费 |
文章详情
closing inbound before receiving peer‘s close_notify的解决办法-CSDN博客
MP查询
Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone())
//1.获取文章内容
apArticleContentMapper.selectOne(Wrappers<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, 1302862387124125698L));
Wrapper<WmMaterial> queryWrapper = lambdaQuery()
.eq(WmMaterial::getUserId, WmThreadLocalUtil.getUser().getId())
.eq(WmMaterial::getIsCollection, dto.getIsCollection())
.orderByDesc(WmMaterial::getCreatedTime);
Day03-文章发布
前后台搭建
note
素材上传
实现的思路
步骤:
- 前端发送上传图片请求
- 网关进行token解析后,把解析后的用户信息存储到header中
- 自媒体微服务使用拦截器获取到header中的的用户信息,并放入到threadlocal中
- 把图片上传到minIO中,获取到图片请求的路径
- 把用户id和图片上的路径保存到素材表中
报错了:centos7进入了紧急模式 可能是没挂起虚拟机就关机导致出错
解决方法:重装了虚拟机 修改账号密码
素材列表查询
空指针移异常:当你尝试对一个null
值执行操作时,就会抛出空指针异常。
先手动在数据库把图片改为已收藏
查询所有频道
查询自媒体文章
文章发布
用到的表
实现思路分析
1.前端提交发布或保存为草稿
2.后台判断请求中是否包含了文章id
3.如果不包含id,则为新增
3.1 执行新增文章的操作
3.2 关联文章内容图片与素材的关系
3.3 关联文章封面图片与素材的关系
4.如果包含了id,则为修改请求
4.1 删除该文章与素材的所有关系
4.2 执行修改操作
4.3 关联文章内容图片与素材的关系
4.4 关联文章封面图片与素材的关系
实现效果
Day04- 文章审核
文章自动审核流程
1 自媒体端发布文章后,开始审核文章
2 审核的主要是审核文章的内容(文本内容和图片)
3 借助第三方提供的接口审核文本
4 借助第三方提供的接口审核图片,由于图片存储到minIO中,需要先下载才能审核
5 如果审核失败,则需要修改自媒体文章的状态,status:2 审核失败 status:3 转到人工审核
6 如果审核成功,则需要在文章微服务中创建app端需要的文章
内容安全第三方接口
文本内容审核接口
图片内容审核接口
app端文章保存接口
涉及到的三张表
分布式ID的作用:当ID很多的时候分表之后,对ID进行管理,让它不重复
分布式ID的解决方案:
1.数据库的主键自增
2.redis的incr方法
3.UUID
4.snowflake雪花算法
5.开源的框架(百度、美团、滴滴)
本项目采用的是雪花算法
mybatis-plus已经集成了雪花算法
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
文章保存思路分析
在文章审核成功以后需要在app的article库中新增文章数据
1.保存文章信息 ap_article
2.保存文章配置信息 ap_article_config
3.保存文章内容 ap_article_content
自媒体文章自动审核功能
测试的时候自媒体服务要调用文章服务,文章服务要先启动起来
步骤:
1.查询自媒体文章
2.审核文本内容(阿里云)
3.审核图片内容(阿里云)
4.审核成功
feign远程接口调用方式:
1.注入依赖
2.启动类上扫描包
服务降级处理
作用:即使远程调用失败了,微服务也不会阻塞
步骤:
1.编写降级逻辑
2.远程接口中指向降级代码
@FeignClient(value = "leadnews-article",fallback = IArticleClientFallback.class)
public interface IArticleClient {
@PostMapping("/api/v1/article/save")
public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}
3. 客户段开启降级(nacos中配置)
feign:
# 开启feign对hystrix熔断降级的支持
hystrix:
enabled: true
# 修改调用超时时间
client:
config:
default:
connectTimeout: 2000
readTimeout: 2000
发布文章提交审核集成
同步:实时处理
异步:分时处理
文章审核功能测试
发布一篇正常的文章
article数据库正常保存
自管理敏感词
文章审核过滤一些阿里云过滤不了的敏感词
技术选型
方案 | 说明 |
---|---|
数据库模糊查询 | 效率太低 |
String.indexOf("")查找 | 数据库量大的话也是比较慢 |
全文检索 | 分词再匹配 |
DFA算法 | 确定有穷自动机(一种数据结构) |
图片识别敏感词
需求:识别图片中的文字,过滤掉敏感词
技术选型
方案 | 说明 |
---|---|
百度OCR | 收费 |
Tesseract-OCR | Google维护的开源OCR引擎,支持Java,Python等语言调用 |
Tess4J | 封装了Tesseract-OCR ,支持Java调用 |
步骤
1.导入pom
2.在配置文件中添加属性
3.在实现类中实现代码
tess4jClient.doOCR(imageFile)
静态文件生成
思路分析
复制链接到网页效果图:
作业:
集成Seata
是一个统一的事务协调者
步骤:
1.现在虚拟机上用docker部署seata
2.在对应的微服务中引入seata依赖和nacos依赖(要把seata配置到nacos)
3.在对应的服务中导入seata数据库表方便记录中间数据undo_log
seata最重要的两种模式XA和AT:
day05-服务保护和分布式事务 - 飞书云文档 (feishu.cn)
延迟任务:下一小节会实现