项目开发 - 整体开发流程
来自程序员鱼皮的开发流程经验分享。
概述
整体开发流程如图:
1. 如何做好项目负责人
立项
主观思考并确认你想做的项目:
- 为什么想做? 巩固所学知识,学习微服务的思想
- 这个项目能解决什么问题?有什么实际意义? 微服务的知识点比较多和广,光看学习视频,无法很好地沉淀。 同时,可以帮助同样有学习微服务的同学,一起巩固所学知识
- 这个项目的核心亮点在哪里? 知识沉淀
- 项目取名(中英文) mirco_service
调研
客观分析并确认你想做的项目的意义:
- 市场上有没有类似的项目?你的项目和它们比有哪些异同(优缺点)? JAVA在github上有很多微服务项目,都是各有侧重点。 本项目,可以提供裁剪化部署的方式,例如,没有学过Redis,可以采用本地的Map来缓存等
- 问一问其他朋友,同学的想法
需求分析
项目要有哪些功能?
- 服务网关
- 注册中心
- 消息队列
- 负载均衡
- 分布式存储
- 分布式搜索 .....
给功能划分优先级(P0 - P4),区分哪些功能是必须要做的?哪些功能是可有可无、或者不急着做的?
- P0 核心,不做的话网站不能上线
- P1 最好有
- P2 可以有
- P3 可有可无,有更好
简单评估每个功能是否可以实现?要花多久实现?
组队
建议团队人数最多为 3-5
组队之后,队长需要带领团队内部同学确认:
- 沟通协作方式(交流群、腾讯会议)
- 团队文档沉淀方式(语雀知识库)
- 确认代码协作方式(星球 GitLab 或 GitHub 私仓)
- 确认分工和对接方式(比如前后端用接口文档对接,记录到文档中)
- 建设知识库,并给成员开设对应的权限
要求
- 人人都想抱大腿(不要养成习惯),要先保证自己有一个基础的技术,找能力和技术匹配的
- 加入团队:描述自己的优势、能给别人带来什么
- 招人要求:
- 你要知道自己缺什么?大家互补
- 要控制人数
- 要清晰地列举自己的需求
2. 如何做好架构师
技术选型
如何做好技术选型?
选
人:你的团队会什么?大家熟悉什么?有没有大佬能 cover 这个技术?
不要用冷门的技术,尽量用热门的。
需求:
- 项目的量级?(比如百万并发,消息队列、分库分表;如果是小项目,尽量简单)
- 项目的功能?(比如检索:可以用 ES)
- 大的前端项目我个人建议用 React(也要看你自己的熟悉程度)
- 小的工具列项目我会用 Vue 多一点
- 考虑做的项目的样式和哪个组件库最搭,根据组件库去倒推框架
技术选型的渠道
- 网上搜索(掘金、github、百度开发者搜索 https://kaifa.baidu.com/home)
- OpenBase(后端 Spring 基本上都能满足)
- 第三方平台(直播、短信发送、视频点播、存储、OCR、人脸识别等)
数据库选型:
思考量级 思考数据的应用场景(数据的联系)
- MySQL
- MongoDB
- PostgreSQL
- TiDB
- OceanBase
- HBase
- ClickHouse
- Kylin
- Druid
C++全栈知识体系选型:
技术栈
- 开发框架:vue
- 组件库:vuepress
- 主语言:JavaScript
- 环境:腾讯云(nginx 部署)
用
- 看文档确认版本号
- 先跑起来 Demo, demo 跑完,没问题,再确认技术选型。
系统开发
- 前端
- 后端
- 部署上线
工具链
- 开发工具 Idea,VS code
- 测试工具 Postman,swagger
- 上线工具 利用Nginx反向代理
资源准备
- 服务器
- 数据库
- 第三方服务(短信、存储、OCR)
- 开发软件
服务器
- 带宽
- 服务器的内存
- 服务器的 CPU
- 硬盘
带宽计算:
- 打开一次网页传输 1.2 M
- 计算每秒访问的总资源大小(人数 * 单位资源大小)
- 内存:需要自己查看所有进程的内存占用
- CPU:需要自己查看所有进程的资源占用
精打细算,先从最小的设备搞起。
系统设计
只用语言描述,不写代码
- 功能模块图(思维导图)
- 技术架构图
- 库表设计
- 每个功能的实现逻辑
功能模块图
从整体到局部
先划分子系统
库表设计
- 划分哪些库(每个项目 1 个库)
- 划分哪些表(正常情况下每个大的功能一个表)
- 每个表有哪些字段?
- 表之间的关联关系(通过字段约定式关联)
id, create_time, update_time, delete(软删除)
开发规范
没有绝对的好坏、也没有绝对的一致,保证团队内部统一即可
编码规范
人为约定:比如 https://blog.csdn.net/weixin_43932564/article/details/108995713、阿里巴巴 Java 规约、前端规范:https://wenku.baidu.com/view/dd64bd8fd2f34693daef5ef7ba0d4a7302766cfe.html (opens new window) 等等
工具:
- 后端:alibaba java coding guide、sonarlint、checkstyle(https://blog.csdn.net/liuwei0376/article/details/123180920)
- 前端:eslint(校验 js、ts 等文件的语法) + prettier(美化、格式化代码) + stylelint(检查校验 css 代码)
提交规范
- 统一的提交记录,比如关联需求文档
- 忽略某些文件的提交,保护隐私(可以使用 .gitignore)
3. 做好开发第一步
前后端协作
接口文档
- 全员参加需求评审,都知道要做什么事情。
- 前端和后端分别考虑怎么实现这个需求?前端要找后端要接口;后端提供给前端哪些接口?
- 前后端对齐(确认了字段信息、接口信息)
- 并行:前端用 mock 或假数据;后端自己开发
如何做好开发第一步 (如果是个人开发,建议先后端)
后端
- 创建数据表
- 使用MyBatis X插件生成代码
- 检查并复制生成的代码到实际项目目录中
- 创建 Controller,生成增删改查接口
- 创建一些请求类(比如 XXXAddRequest
- 最好编写单元测试
接口设计规范:
- 自己定义开发规范
- 遵循业内的准备
Restful 接口设计规范:
- 操作、请求类型、接口地址
- 增、POST、/{resource},比如/post
- 删、DELETE,/{resource}/{id},比如 /post/{id}
- 改、PUT、/{resource}/{id},比如/post/{id}
- 查、GET、/{resource}/{id},比如 /post/{id}(OpenAPI)
前端
- 根据后端的接口文档,找到实体(/SwaggerModels/default),编写 model(typescript数据类型定义代码)
- 创建 service(api),调用后端接口的代码,也是对应了后端的增删改查
- 创建页面: 使用procomponents 组件 https://procomponents.ant.design/components/table?current=1&pageSize=5
- 登录页面: 使用procomponents 组件 https://procomponents.ant.design/components/login-form
登录注册功能参考早球的用户中心项目
主要包括以下几部分:
- 基本操作:增、删、改、查(根据 id 查、全量条件查询、分页条件查询)
- 用户登录注册
- 单元测试
4. 如何聪明地写代码
业务功能开发
核心:先做设计,再写代码
- 项目功能具体设计+讲解(以点赞功能为例)
- 从设计到开发一个新的功能
点赞功能
需求分析
- 用户可以对帖子进行点赞/取消点赞
- 用户对单个帖子只能点赞1次
方案设计
为什么要写?
- 便于开发
- 自己总结
- 明确依赖,防止抵赖
- 更好地沉淀、给他人给团队做参考
后端业务流程:
- 输入:接受请求参数,帖子 id(肯定不能传递 userld 和点赞状态,直接从数据库里取)
- 参数校验 a. 业务不相关:请求参数是否为 null、id 不能小于等于0 b. 业务相关的校验:帖子是否存在,帖子的状态要是允许点赞的(比如必须审核通过)
- 权限校验 a. 判断用户是否登录,获取当前登录用户信息(userld)
- 执行操作 a. 判断用户是否已点赞,根据 userld 和 postld 查询 post thumb 表,如果存在,则表示已点赞,否则未点赞 b. 如果已点赞,执行【取消点赞】操作: i. 从post_thumb 表删除数据(userld、postld) ii.post 帖子表的点赞数量-1 c. 如果未点赞,执行【点赞】操作 i.向post_thumb表插入新数据(userld、postld ii.post帖子表的点赞数量+1 d. 使用事务来管理所有的操作
- 返回一个能区分是点赞成功还是取消点赞成功的值
- 通过加锁的方式保证冥等性(需要考虑加锁粒度,例如考虑给方法加锁,还是方法中具体逻辑加锁,例如点赞)
先构思,把业务流程想清楚,具体编码时,再去查某一步骤的具体实现方式
- 安全性(权限、限制频率)
- 幂等性(用户不能重复点赞) , 解决方法加锁:synchornized(String.valueOf(userId).intern()){}
- 性能(比如接口响应时长,可以用Redis)、存储(硬删除)
- 高性能校验原则: 优先校验不需要查数据库、操作第三方资源的
前端:
- 请求后端接口
- 根据后端返回的数据改变图标和帖子点赞数
切换 banner
需求分析
- 管理员可以在管理后台切换首页的 banner 图
- 切换方式: a. 本地上传文件 b. 直接复制一个图片的地址 c. 在线裁切
详细:
- 本地上传文件 a. 保存文件(本地服务器)或者第三方存储 b. 文件清理 c. 开发文件上传组件、动态查看图片效果等 d. 不存在防盗链
- 直接复制一个图片的地址 a. 不用自己存图片 b. 前端提供地址输入框 c. 存在防盗链
不同视角
- 产品经理:关注怎么用方便?
- 程序员:能不能实现?怎么实现? —— 没有最好的实现,只有最合适的
系统设计
图片的地址如何存储?
- 存在配置中心(nacos、apollo、spring cloud config)
- 存到数据库表里
- 本地文件(内存),容易丢失
库表设计
- id
- params:管理员配置(json 对象字符串,可以存 bannerUrl、logoUrl),利用json对象字符串,保证扩展性
- userId: 谁设置的
- createTime
- updateTime
- isDelete
前后端
前端
- 提供新的管理页面,本质上是一个配置管理。
后端
- 提供接口,仅管理员可以访问,如果没有配置,那就新增;如果有,那就修改
5. 如何优化项目
目的:
- 能学到更多优化项目的思路(打开思路),,之后自己项目的时候可以想到这些
- 让大家写简历的时候多一点亮点
如何优化项目
参考: https://bcdh.yuque.com/books/share/2dd2567c-a826-4d9d-9303-bd288269e874/ndphah
新增功能
- 把现有的功能做的更好(比如增强用户体验)
- 尽量避免无用的功能堆砌(尤其是重复的增删改查)
- 如果处理日常工作中的增删改查,尽量写好代码,用更快地时间完成;剩余的时间用于自我提升
从一些维度/指标进行优化
从下面的优化点来看,思路很重要,不要过分在意实现。
如何自我提升,自己做项目,考虑优化点,然后再去学习相关技术,进行实现
性能优化
前端
- 缓存(浏览器缓存)
- 减少文件的体积(压缩文件qzip、减少代码、减少依赖)
- 按需引入(按需加载)
- 懒加载(节省流量、提升页面加载速度)
- CDN(减少文件的传输时间)
- 传输协议升级 HTTP 1.x => HTTP 2.x
- 代码层面:减少无用的请求、减少无用的状态变更、减少无用的渲染
- 请求合并(受到 http 请求输的限制)
后端
- 缓存(Nginx、Tomcat、Redis 多级缓存)
- 查询合并(查数据库 select id =1、id=2、id=3=> select id in(123)),减少重复操作
- 并发编程 a. 异步:不影响主流程的操作,可以单独开线程处理/消息队列 b. 并发:把一个大的动作分为多个小工作,大家一起干活,干完之后再汇总 c. 池化:线程池(避免重复的线程创建和销毁,复用线程)、连接池(避免重复的链接建立和释放,复用连接)
- 限流
- 降级(有损服务)
- 数据压缩(返回给前端、存储前)
e.g.删除用户发的帖子,里面有很多图片:先删帖子,
- 用户发送州除请求,后端执行州帖子操作(操作成功),再开一个线程惕慢地去删图片
e.q.数据写入 Redis 前,用 JDK 序列化器。(可以改用 kryo 来压缩,或者用 hash 代替 string 存储)
- User {id = 1, name =xxx, age=20)
- id=1,name=xxxage=20
成本优化
- 分析自己用了哪些资源
- 降低 CPU利用(比如,根据实际情况降低定时任务的频率,也不能为了省钱不去做计算 哈哈哈哈)
- 节约内存(Java GC,尽量避免占用内存的大任务持续执行、分批处理-能及时释放就及时释放,尽量用占用空间少的数据结构,Java 可以用 MAT来分析) hashMap 来存用户,string 来存储 json
- 节约磁盘:人工分析删除、定期删除,低频存储、淘汰策略(例如,磁盘利用率达到阈值,去删除最久未被访问的文件),数据压缩
- 减少带宽占用:数据压缩、连接复用、本地查询(缓存)、打包
可用性
- 集群
- 主备
- 自动故障恢复(Redis哨兵) 写代码 写进ICU —— 医生来治一下
- 容灾
可靠性
尽可能地让系统提供可靠的服务,不要出现崩溃中断
方法:集群、主备、异常处理、降级、容灾
稳定性
方法:保证每个服务节点状态正常、性能相当(不要有的机器好有的机器垃圾导致接口时快时慢);合理规划服务调用链路,不能过长;做好技术选型,避免使用不稳定的第三方依赖
核心:保证所有依赖(服务器、接口、数据库等)都要稳定。
怎么排查稳定性:
- 链路追踪
- 打日志
健壮性
异常处理(NPE(NullPointerException),"A".equals(xxx) > xxx.equals("A")、全局异常处理器)
系统复杂度
方法:软件开发原则、设计模式、系统架构设计(如微服务)、开发规范、工作流
可维护性
方法:软件开发原则、设计模式、系统架构设计(如微服务)、开发规范、工作流、抽象复用(组件化模块化)
可扩展性
使整个系统能够轻松应对未来新增的需求及业务增长,不会牵一发而动全身
方法:设计模式、架构设计、集群、分库分表、技术选型
可扩展性例子: * 枚举值,例如:小学,初中,高中,继续可以扩展新的枚举大学,研究生,博士 * 标签名称,例如,类别可以是地点、职业;标签名称是上海、程序员;最终按照标签名称就可以搜索更多条件的内容,而不是仅根据地点或职业分类
开闭原则
可观测性
系统埋点上报、监控告警(prometheus)、ELK日志收集、可视化分析(Grafana)
- 利用定时任务对系统程序里线程池使用的资源情况进行记录日志
可伸缩性
系统根据负载情况动态增加或减少节点,从而能够应对流量高峰、并在空闲时节约成本
方法:K8S+Docker容器、云原生
用户体验
方法:网页性能优化、接口性能优化、懒加载、占位符、骨架屏、设备适配、浏览器兼容性、满意度调研(如 NPS)
安全性
方法:参数校验、常用安全措施(防XSS、CSRF、SQL注入等)、网络防护(反 DDOS)、反爬虫、限流、黑白名单、防火墙等
6. 绽放项目的价值
项目上线
- 准备资源:域名、服务器
- 新的服务器可以装宝塔面板,可以方便地管理服务器、快速上线项目,节省操作时间。
- 区分环境
- baseUrl: isDev ? 'http://localhost:8081:api' : 'http://myprj:8081:api'
- 联调部署
前端
- 打包构建 => 把网页文件放到服务器上 => 用Nginx等web 服务器来提供访问能力
- 如果使用了框架,建议是参考官方文档来学习部署
- 多环境区分(编译/打包阶段):
- 开发环境: 前端请求的是localhost:xxxx 或者说是测试用的接口地址
- 上线: 前端请求的是myprj/api之类的正式地址
后端
- 对于 Java 项目,编译构建 => 把jar 包放到服务器上=>手动执行
- 多环境区分(启动阶段):
- 开发环境: 前端请求的是localhost:xxxx 或者说是测试用的接口地址
- 上线: 前端请求的是myprj/api之类的正式地址
注意跨域问题:前端请求的后端域名最好是一致的
开源
写 README.md 文档
- 证明你的项目是有认真在做,是正经开源而不是个人学习
- 给别人介绍你的项目,吸引别人来关注(star)
- 介绍怎么参与项目,吸引别人来参与
- 便于 自己梳理业务逻辑
- 写简历的时候,可以给面试官看的
写哪些点?如下:
小技巧:
- 参考别人现成的(最好是参考同类项目)
- 多列举一些截图
- 把最想让别人看到的前置
项目介绍
用最简洁清晰的话语描述你的项目。
最好能提供线上可访问的地址或者介绍视频。
- 项目的功能、解决了什么问题、优势?
- 项目背景:为什么想做这个项目?
- 比如现有的产品不能满足诉求(存在痛点)、或者目前没有类似的产品、或者出于其他目的。
- 项目意义:这个项目能解决什么问题?有什么实际意义?
- 比如方便使用者、提升效率等。
- 核心亮点:这个项目的核心亮点在哪里?
使用说明
让用户来实际构建运行项目
技术栈
介绍项目所用到的技术
快速启动
提供启动项目的流程和命令
内容展示
通过图的方式:
- 业务流程
- 架构设计
- 功能模块
代码讲解
- 列举项目目录结构,各个目录的内容介绍
- 写一些项目中的优点、编码中值得注意的小细节等。
- 具体的业务流程
贡献指南
如何让别人跟你一起参与项目?
其他
代码脱敏
不能把一些配置文件上传,例如包含后端数据库密码的xml文件等
开源协议
https://www.runoob.com/w3cnote/open-source-license.html
推广
- 前提:作品用心、质量高、内容过硬
- 友链
- SEO:内容标签要清晰,尽量多出现一些关键
- 利用其他渠道,比如发布视频,在合适的时候给别人推荐项目
- GitHub 开源指南:https://github.phodal.com/#/