解决方案:黑*头条_第1章_项目介绍和工程搭建
优采云 发布时间: 2022-11-23 23:24解决方案:黑*头条_第1章_项目介绍和工程搭建
黑*今日头条_第1章_项目介绍与项目建设
文章目录
学习目标 1. 项目介绍 1.1 项目背景
?随着智能手机的普及,人们越来越习惯于通过手机收看新闻。由于生活节奏的加快,很多人只能利用碎片化的时间来获取信息。因此,移动信息客户端的需求也越来越大。黑马头条项目就是在这样的背景下诞生的。黑马头条项目是采用当下火热的微服务+大数据技术架构实现的。本项目主要专注于获取最新最热的新闻资讯,通过对用户偏好的大数据分析,精准推送咨询新闻
1.2 项目概况
黑马头条项目是在线教育平台业务大数据统计分析系统。碎片化、频繁切换、社会化、个性化是如今人们阅读行为的标签。黑马头条采集
海量信息,通过系统进行统计、分类,分析用户兴趣并推送,满足用户需求。
1.3 项目术语定义 2. 项目要求
功能需求项目模块结构
2.1 APP主要功能概述
2.2 APP用例图(主要功能)
2.3 WEMEDIA功能概述
2.4 WEMEDIA用例图(主要功能)
2.5 ADMIN功能概述
**
**
2.6 ADMIN用例图(主要功能)
2.7 其他要求
2.8 交互要求
3. 项目技术介绍 3.1 技术栈-基础六层技术
基础六层包括前端(Weex、Vue、Echarts、WS)、网关(GateWay)、DevOps(单元测试、代码规范)等重点难点技术
3.2 技术栈-服务四层技术
四层服务包括中间件(Kafka、Mycat)、计算(Spark、Neo4j、Hive)、索引、微服务、大数据存储等重点难点技术
3.1 技术栈-分布
4. 数据库设计 4.1 ER图设计
er图设计划分了9个库,每个库主要解决一个特定的业务。
数据库设计规范详见data文件夹下的《黑马头条-数据库规范设计手册.md》文件。
PowerDesinger工具的使用请参考data文件夹下“powerdesinger的基本使用”文件夹中的文档“powerdesinger的基本使用”。
4.2 分库设计
?黑马头条项目采用的分库分表设计,由于业务比较复杂,后期访问量巨大,为了分担数据库的压力,整个项目使用较多多于一个数据库。其中核心库有5个,每个数据库解决一个业务点,非常贴近实际项目设计。
**
**
4.3 核心数据流程图
黑马项目中的文章采用多库设计的方式,降低高并发下对核心库表的压力。一共设计成三个数据库表:
cl_news和wm_news中的数据在审核通过后会发布到ap_article中。
4.4 冗余设计
?黑马头条的项目都是使用逻辑关联,没有使用主键和外键约束。也方便数据源冗余,尽量少用多表关联查询。冗余是为了提高效率并减少连接。单表查询比关系查询更快。一个经常访问的字段可以冗余存储在两个表中,没有关联。
?如果需要查询订单的用户名去查询一张订单表,则必须加入另一张用户表。如果业务表很大,查询会很慢。这时候,我们就可以使用冗余来解决这个问题。创建新订单时,不仅需要存储用户ID,还需要存储用户名。这样,我们在查询订单表的时候,不需要再加入另外一个用户表,也可以查询到订单的用户名。这样的冗余可以直接提高查询效率,单表速度更快。
4.5 导入数据库
当天的data文件夹下:数据库脚本
5. 后端工程结构
5.1 后端工程说明
后台工程基于Spring-boot 2.1.5.RELEASE版本搭建,项目父工程为heima-leadnews,通过继承集成Spring-boot。
【父项目下有4个公共子项目】:
【多微服务】:
5.2 后端通用项目搭建 5.2.1 开发环境说明
项目依赖环境(需要提前安装):
5.2.2 IDEA开发工具配置
5.2.3 后台初始项目导入
解压当天资料中的heima-leadnews.zip文件,复制到一个没有中文和空格的目录下,用idea打开
6 后端开发-总体描述及开发规范 6.1 后端接口开发规范 6.1.1 开发原则 6.1.2 开发步骤 6.1.2 接口版本规范
随着业务的复杂化,可能会出现同一个界面的多个版本。为了方便后期切换和AB测试,需要定义接口的版本号
6.2.3 接口通用规范 ID混淆 不断增长的请求和响应的ID需要混淆加密
日期数字化
请求和响应的时间字段统一转换为13位的时间戳
字符编码
请求和响应的内容字符集为UTF-8
支持多种格式
响应结果支持JSON和XML,可通过Header Accept设置
网址格式
url全小写,多个单词用下划线分隔
令牌
在请求头中存储当前用户的请求令牌(JWT格式)
吨
当前请求的时间保存在请求头中,用于基本的请求时效性判断
医学博士
当前请求参数的签名验证字符串存放在请求头中(查询字符串经过MD5加密排序)
响应格式
响应格式只接受ResponseResult,代码必须定义在AppHttpCodeEnum
6.2 工具类说明 6.3 接口通用请求和响应
dto(Data Transfer Object):数据传输对象,用于显示层与服务层之间的数据传输对象
6.3.1 通用响应对象:
无分页:mon.dtos.ResponseResult
/**
* 通用的结果返回类
* @param
*/
public class ResponseResult implements Serializable {
private String host;
private Integer code;
private String errorMessage;
private T data;
public ResponseResult() {
this.code = 200;
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.errorMessage = msg;
this.data = data;
}
public ResponseResult(Integer code, String msg) {
this.code = code;
this.errorMessage = msg;
}
public static ResponseResult errorResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.error(code, msg);
}
public static ResponseResult okResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.ok(code, null, msg);
}
public static ResponseResult okResult(Object data) {
ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS,AppHttpCodeEnum.SUCCESS.getErrorMessage());
if(data!=null) {
result.setData(data);
}
return result;
}
public static ResponseResult errorResult(AppHttpCodeEnum enums){
return setAppHttpCodeEnum(enums,enums.getErrorMessage());
}
public static ResponseResult errorResult(AppHttpCodeEnum enums,String errorMessage){
return setAppHttpCodeEnum(enums,errorMessage);
}
public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
return okResult(enums.getCode(),enums.getErrorMessage());
}
private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums,String errorMessage){
return okResult(enums.getCode(),errorMessage);
}
public ResponseResult error(Integer code, String msg) {
this.code = code;
this.errorMessage = msg;
return this;
}
public ResponseResult ok(Integer code, T data) {
this.code = code;
this.data = data;
return this;
}
public ResponseResult ok(Integer code, T data, String msg) {
this.code = code;
this.data = data;
this.errorMessage = msg;
return this;
}
public ResponseResult ok(T data) {
this.data = data;
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getErrorMessage() {
<p>
" />
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
}
</p>
分页一般返回:mon.dtos.PageResponseResult
public class PageResponseResult extends ResponseResult {
private Integer currentPage;
private Integer size;
private Integer total;
public PageResponseResult(Integer currentPage, Integer size, Integer total) {
this.currentPage = currentPage;
this.size = size;
this.total = total;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}
6.3.2 普通请求dtos
mon.dtos.PageRequestDto
<p>@Data
@Slf4j
public class PageRequestDto {
protected Integer size;
protected Integer page;
public void checkParam() {
if (this.page == null || this.page