这部分是师哥发的还没有进行项目开发前的项目文档内容。
项目背景依托微信小程序和App 客户端提供线上预定酒店和旅游产品的互联网产品。
• 解决用户痛点1:提高了用户搜索酒店和预定酒店的效率
• 解决用户痛点2:售后功能保障了用户的合法权益
• 解决用户痛点3:基于数据分析提供给用户多需求场景的组合产品
描述本项目期望达成的目标,目标需满足Smart原则:
- 具体的(Specific)
- 可以衡量的(Measurable)
- 可以达到的(Attainable)
- 要与其他目标具有一定的相关性(Relevant)
- 有明确的截止期限(Time-bound)
1.用户在客户端发起请求,进行DNS(Domain Name System域名服务器)解析,其中包括WAF(Web Application Firewall)、CDN(Content Distribution Network内容分发网络)、防火墙。
2.再通过Nginx集群反向代理到Spring5.0之后添加的Webflux网关,通过SpringCloud Gateway进行动态路由指定Predicate(断言)和Filter(过滤器)寻址与Sentinel+Shard进行认证授权和令牌限流,中间还可以整合Redis;
3.另一方面还可以同时与Nacos合作为它提供监控报警和日志,集成服务注册发现功能,Nacos集群在整个架构中都能提供服务注册发现与动态配置和配置管理功能,整合SpringBoot Admin进行服务监控
4.同时Gateway可以通过Ribbon进行负载均衡、Sentinel熔断降级和业务集群建立桥梁,形成联系,先是通过SpringSecurity框架与OAuth2认证中心整合JWT进行公钥私钥的颁发授权与相应验签认证功能。
5.SpringBoot应用在业务集群中通过OpenFeign进行相互调用,中间还整合Redis、Mysql、MQ、ES、OSS、JOB等工具,其中Redis集群可以用来做分布式数据缓存,Mysql主从复制进行数据的持久化,RabbitMQ进行系统解耦削峰填谷异步调用,ES全文搜索引擎整合Kibana、Logstash进行近乎实时搜索、分析和可视化的全文检索,使用阿里云OSS云存储服务进行对象存储、企业数据管理,使用xxl-job进行分布式任务调度。
6.业务集群还与分布式相挂钩,有着分布式主键,分布式锁,分布式事务,其中有两个理论,一个是CAP(分别是Consistency一致性、Availability可用性、Partitiontolerance 分区容错性)理论(这三个要素最多只能同时实现两点,不可能三者兼顾),一个是BASE(Basically Available基本可用、Soft State软状态、Eventual Consistency最终一致性)理论(即使无法做到强一致性,CAP的核心就是强一致性,但应用可以采用适合的方式达到最终一致性)
7.日志收集通过Beats、ELK、和Kafka整和完成,具体过程是这样的:Beats用于日志数据采集使用,Logstash收集日志,发送给Kafka进行解耦、异步处理和流量削峰,然后通过Elasticsearch集群存储日志数据,索引日志数据,再通过Kibana视图形式展现日志信息,更加人性化地在客户端进行检索以及相关操作。
8.以Skywalking为核心的运维监控中心可用提供链路追踪和监控报警机制,与运维报警系统Prometheus结合Grafana最终和Alertmanager通过短信、微信或者邮件的形式给模块负责人发送警告通知。
9.最后Developer将代码文件上传到GitHub上通过docker容器部署,使用K8s AP对资源进行编排,管理应用的全生命周期,同时也提高发布与更新版本的效率,然后通过Jenkins Pipeline进行整个构建、测试、交付等持续集成,运维人员继续对这些进行维护。
这里抄袭:https://blog.csdn.net/qq_57469718/article/details/124533954
这个写项目的时候新增加了一些。
我学习到了什么。
我首先,进行产品的流程梳理,知道了我们要做什么。要展现的效果是什么样子的。
然后参与了架构admin的设计,了解了一个大工程的结构格式和基础的微服务模块样式。
再然后进行了数据库的设计,这里感受到了大家对于一个事情理解的偏差,我的数据库设计和大家差好多。之后就是接口的编写。感受到了那一份严谨吧,毕竟以前都没有接触这方面的内容。要求好多,好麻烦。最后就是编码,写了枚举,知道了ES的简单使用。最为主要的是编写代码的规范。没有想到简单拿到增删改查竟然有那么多需要注意的。一个项目里竟然需要用到那么多东西,像链路追踪,日志,运维什么的,目前算是知道了项目里有这些。再最后学习到的是那种工作意识。这个有点玄了,就是我们开发的流程,应该如何分析,设计,完成一个东西。
这里参考最新的阿里代码设计规范。我但是忘记做笔记了。再抄袭一下吧。
请求方式只用 GET/POST
请求路径按照任务分配表上的写
GET 请求的参数在 Query 里面填写,POST 在 Body 里写。不要混用
不要使用 RESTFul 的路径传参
环境的使用:
不要使用环境变量,目前用不上
只使用一个环境 url 前缀即可(协议+ip+端口)
已有的环境可以直接用,但是不要改,因为这是公用的。如果有需求自己建一个环境即可。
请求参数规范:以下
参数名采用驼峰命名
数据库中存在的字段的参数,命名要保持一致
如果参数中用多个 id 参数,必须区分命名,且要与数据库一致
传参的实例值尽量真实一点
类型要选择正确,类型的选项很多自己看看。
参数描述简练准确
响应数据示例的格式必须的实际的格式
响应数据的类型和描述和请求参数的要求一致
金额数据:后端使用整数存,但是到了前端部分要转化为小数(类型为Number),这点也是师哥提过
原文链接:https://blog.csdn.net/qq_57469718/article/details/124533954
下图就是我们队伍讨论后的数据库部分。
接口部分:
主要负责酒店搜索,获取枚举,后端修改枚举三个接口。
使用工具为APipost.
以获取枚举接口为例:
基本信息:
响应示例:
成功响应示例
{
"code": 200,
"message": "操作成功",
"data": [
{
"id": 1, //一级枚举id
"name": "附近", //一级枚举名称
"parentId": 0,
"children": [
{
"id": 101, //二级枚举id
"name": "行政区", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 102, //二级枚举id
"name": "商圈", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 103, //二级枚举id
"name": "机场/车站", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 104, //二级枚举id
"name": "医院", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 105, //二级枚举id
"name": "地铁站", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 106, //二级枚举id
"name": "大学", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 107, //二级枚举id
"name": "景点", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
},
{
"id": 108, //二级枚举id
"name": "演出场馆", //二级枚举名称
"parentId": 1, //二级枚举父id
"children": null
}
] //二级枚举
}
失败响应示例:
{
"code": 404,
"message": "未找到资源",
"data": []
}
字段描述:
再多人进行项目开发的时候,git使用可能会遇到一点小问题。
那么怎么进行git的使用:
1,服务器项目下载到本地
2,再本地操作分支
检查一下本地是否能获取到新的分支 右键项目 -> Git -> Repository -> Pull
获取到目标分支
切换到目标分支 右键项目 -> Git -> Repository -> Branches
选择目标分支 -> Checkout As
查看当前分支,
已切换成功
ES快速入门:
MySQL与ES同步
ES+7需要注意的地方
文章写的不和我心意。主要的工作都被他人完成了。感觉不知道写什么。连不起来。罢了。
枚举还是真的写了的。这里写下我最终确认的枚举的代码。
数据库表:
@Data
@ApiModel(value = "EnumType", description = "枚举表")
@TableName(value = "enum_type")
public class EnumType implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
private long id;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "父id")
@TableField(value = "parent_id")
private long parentId;
@ApiModelProperty(value = "逻辑删除")
private long deleted;
@ApiModelProperty(value = "创建时间")
@TableField(value = "create_time")
private Date createTime;
@ApiModelProperty(value = "更新时间")
@TableField(value = "update_time")
private Date updateTime;
}
@Service @Slf4j public class EnumServiceImpl extends ServiceImplimplements EnumService { @Autowired EnumService hotaiEnumService; @Override public List search(Long id) { // 加入条件进行枚举查询 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(EnumType::getParentId, id); List enumList = this.list(wrapper); //判断是否为空 if (CollUtil.isEmpty(enumList)) { Asserts.fail("无查询结果"); } return enumList; } }
public interface EnumService extends IService{ List search(Long id); }
@Override public Listsearch(Long id) { // 加入条件进行枚举查询 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(EnumType::getParentId, id); List enumList = this.list(wrapper); //判断是否为空 if (CollUtil.isEmpty(enumList)) { Asserts.fail("无查询结果"); } return enumList; }
@Repository public interface EnumMapper extends BaseMapper{ }



