目录
项目时间
3.20:熟悉产品产品流程管理
3.25:环境搭建、项目熟悉(阿里规范手册)
4.2:基础服务、功能分配
4.13:第一阶段需求开发、第一阶段技术需求
4.22:第二阶段需求开发、第二阶段技术需求
4.26:代码review、代码优化
4.30:技术博客、项目整体验收
5.5:项目结束总结
项目背景
依托微信小程序和App 客户端提供线上预定酒店和旅游产品的互联网产品。
- 解决用户痛点1:提高了用户搜索酒店和预定酒店的效率
- 解决用户痛点2:售后功能保障了用户的合法权益
- 解决用户痛点3:基于数据分析提供给用户多需求场景的组合产品
软件的开发流程图
项目的架构图
具体的流程大概可以跟以下
- 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进行整个构建、测试、交付等持续集成,运维人员继续对这些进行维护。
具体的项目的工程结构
项目代码的逻辑取名结构
具体项目时间线
熟悉产品,产品流程梳理
依托同程旅行小程序,熟悉酒店列表的展示,酒店的搜索等功能流程的实现。
数据库设计
阅读最新版阿里开发手册,分析字段的可读性和合理性,由于做的是有关于酒店房型的列表
下面附图是有关房型模块与用户模块的综合数据库。
使用的工具是CHINER元数建模,有兴趣的同学可以使用,相对来说上手简单,规定字段的默认值和默认类别都可以较方便快捷的实现。
上述的数据表也是经过多次改良优化得出的版本。
接口设计
接口设计的实现借助了工具APIPOST,对中国人的习惯确实更加友好。具体的api设计文档的链接如下:hotel-room整合 (apipost.cn)https://console-docs.apipost.cn/preview/7b11975dce8c4803/b68d9bee740a8a17?target_id=dfb5ef62-e5e8-4fe8-a428-b9b95adb5af2#2946b60a-3f17-40f6-b215-7cbd73d945ac
简单的附几张图
在设计API接口时的一部分注意事项
1.请求的方式一般使用GET/POST
2.请求路径接口文档为准,与代码对应controller层一致
3.GET 请求的参数在 Query 里面填写,POST 在 Body 里写。不要混用
4.不要使用 RESTFul 的路径传参
5.参数名采用驼峰命名
6.数据库中存在的字段的参数,命名要保持一致,参数描述简单
7.如果参数中用多个 id 参数,必须区分命名,且要与数据库一致
8.响应数据示例的格式必须依据实际的格式
9.响应数据的类型和描述和请求参数的要求一致
总体的开发需求
由于第一阶段与第二阶段的代码实现主要区别是代码的优化,在基于mybatisplus开发上,更多的利用了本身分装的方法,使代码更加简洁。基础的房间号的增删改查就不再赘述。
需要注意的是:
全文不要写两表或多表联查,尽量单独的用独立的service封装,联查时调用多个service即可,然后用java的流来拼起来,因为
- 单表走索引好保证,很难保证联合查询走索引,所以不见得联查会有多快
- 系统拆分的话联合索引很难判断
2.返回值使用 CommomResult 分页 CommomResult<CommonPage>, 返回码 使用 resultCode
3.配置 redisTemlate 解决 redis 乱码问题
4.log、mpaop 切面 :log 包提供 各个 controller 的切面处理,主要是记录请求信息。mpaop 提供 在portal 和 admin添加切入点,主要记录一些集合使用的时候出现异常的记录
5.调用Asserts.fail 会抛出 ApiException异常,被 GlobalExceptionHandler 全局异常处理器(处理GlobalExceptionHandler 里面对应的异常),@NotNull 注解也会抛出异常被 ControllerAdvice 捕获
6.redisServiceImpl 对 redisTemlate 的方法进一步封装。提供redis 的各项基本操作。
7.service 里面调用方法要加 this 来调用,直接继承IService。
8.DAO,VO注意大写
额外还添加了有关用户签到的接口实现,在签到接口的实现,选择采用redis的方式,可以使用Redis中的Bitmaps这一个数据集合。
需要注意的是:
- Bitmaps并不是实际的数据类型,而是定义在String类型上的一个面向字节操作的集合。因为字符串是二进制安全的块,他们的最大长度是512M,最适合设置成2^32个不同字节。
- Bitmaps的位操作分为两类:
- 固定时间的单个位操作,比如把String的某个位设置为0或者1,或者获取某个位上的值
- 对于一组位的操作,对给定的bit范围内,统计设定值为1的数目(比如人口统计)
- Bitmaps最大的优势就是在存储数据时可以极大的节省空间,比如在一个项目中采用自增长的id来标识用户,就可以仅用512M的内存来记录40亿用户的信息(比如用户是否希望收到新的通知,用1和0标识)
简单来说bitmaps就是一个长度可变的bit数组。每个位只能存储0或1。就可以通过bitmaps的数据表示用户是否登录。索引的列就可以采用userId即可。
总结
这一个多月的开发时光过得蛮快,其实总体的开发周期并不长,但好在经历了一整个开发的流程,慢慢了解软件开发的全过程,从需求设计,数据库设计,接口设计、熟悉版本控制工具的使用,说到这,对于git的使用也更加的得心应手,代码编写阶段与代码review,期间的很多次小组会议,共同学习阿里开发规约等团队协作。对未来的工作也有了相对更为全面深刻的认知。
期间也遇到不少的问题:
- git的使用,之前没有怎么参与过大型项目的开发,git的使用频率也不是很经常,从自己的团队分支pull到整体的开发分支,也遇到过不少的代码冲突,代码的提交与更新都有更深的认识。
- 在做需求分析的时候,使用的是ProgressOn这种在线画图工具来梳理酒店项目的具体流程。对项目中的模块就行拆分,比如用户中心,商家中心,酒店中心,后台管理员中心。涉及到es的搜索筛选,redis的应用等等,学习过程中最重要的是学习到整体的逻辑思维顺序。
- 数据库设计的过程中,对不少字段都进行了修改,字段是否重复,是否符合阿里的规范,都是需要考虑的范畴,还有字段的冗余,设计中间表,创建合适的索引等等,在数据库设计的过程中,也温习了相关数据库的知识,用索引就要关注索引失效的情况,比如使用了select * 、索引列上有计算、用了函数、不满足最左匹配、like左边包含%、使用OR关键字、NOT IN和NOT EXISTS等
- 接口设计那块,用的是apipost,相对于之前使用的postman来讲,中文界面对我这种初学者会更加的友好,前后端的交互也能简单直接的表现出来,当路径的功能名过长时,中间采用“-”连接而非下划线。
- 具体的代码设计,由于使用的时mp,对于代码的整体整洁性的要求,我摒弃了之前相对冗余的写法,去学习了lambda的各种用法,学会了一些基础用法时发现确实简洁了不少,也没有损失很多的可读性。学会了一些条件构造器的使用,这些就要求了我对SQL语句的熟悉,使用stream流将实体类数据赋值,比如在传输中用的DTO赋值,就会经常用到Stream流。
- 微服务和中间件的使用还是相对欠缺,由于负责的接口并没有直接的对接使用MQ,ES,后期也是详细看了别的模块同学使用的方式,也学会了一些,在实际应用中有了一点的头绪。
下面附一张我在学习mysql的知识点图
最后希望自己能够继续奋发向上,保持初心吧。