项目开发 - 整体开发流程

来自程序员鱼皮的开发流程经验分享。

概述

整体开发流程如图:

项目流程

1. 如何做好项目负责人

立项

主观思考并确认你想做的项目:

  1. 为什么想做? 巩固所学知识,学习微服务的思想
  2. 这个项目能解决什么问题?有什么实际意义? 微服务的知识点比较多和广,光看学习视频,无法很好地沉淀。 同时,可以帮助同样有学习微服务的同学,一起巩固所学知识
  3. 这个项目的核心亮点在哪里? 知识沉淀
  4. 项目取名(中英文) mirco_service

调研

客观分析并确认你想做的项目的意义:

  1. 市场上有没有类似的项目?你的项目和它们比有哪些异同(优缺点)? JAVA在github上有很多微服务项目,都是各有侧重点。 本项目,可以提供裁剪化部署的方式,例如,没有学过Redis,可以采用本地的Map来缓存等
  2. 问一问其他朋友,同学的想法

需求分析

  1. 项目要有哪些功能?

    • 服务网关
    • 注册中心
    • 消息队列
    • 负载均衡
    • 分布式存储
    • 分布式搜索 .....
  2. 给功能划分优先级(P0 - P4),区分哪些功能是必须要做的?哪些功能是可有可无、或者不急着做的?

    1. P0 核心,不做的话网站不能上线
    2. P1 最好有
    3. P2 可以有
    4. P3 可有可无,有更好
  3. 简单评估每个功能是否可以实现?要花多久实现?

组队

建议团队人数最多为 3-5

组队之后,队长需要带领团队内部同学确认:

  1. 沟通协作方式(交流群、腾讯会议)
  2. 团队文档沉淀方式(语雀知识库)
  3. 确认代码协作方式(星球 GitLab 或 GitHub 私仓)
  4. 确认分工和对接方式(比如前后端用接口文档对接,记录到文档中)
  5. 建设知识库,并给成员开设对应的权限

要求

  1. 人人都想抱大腿(不要养成习惯),要先保证自己有一个基础的技术,找能力和技术匹配的
  2. 加入团队:描述自己的优势、能给别人带来什么
  3. 招人要求:
    1. 你要知道自己缺什么?大家互补
    2. 要控制人数
    3. 要清晰地列举自己的需求

2. 如何做好架构师

技术选型

如何做好技术选型?

人:你的团队会什么?大家熟悉什么?有没有大佬能 cover 这个技术?

不要用冷门的技术,尽量用热门的。

需求:

  1. 项目的量级?(比如百万并发,消息队列、分库分表;如果是小项目,尽量简单)
  2. 项目的功能?(比如检索:可以用 ES)
  • 大的前端项目我个人建议用 React(也要看你自己的熟悉程度)
  • 小的工具列项目我会用 Vue 多一点
  • 考虑做的项目的样式和哪个组件库最搭,根据组件库去倒推框架

技术选型的渠道

  1. 网上搜索(掘金、github、百度开发者搜索 https://kaifa.baidu.com/home)
  2. OpenBase(后端 Spring 基本上都能满足)
  3. 第三方平台(直播、短信发送、视频点播、存储、OCR、人脸识别等)

数据库选型:

思考量级 思考数据的应用场景(数据的联系)

  1. MySQL
  2. MongoDB
  3. PostgreSQL
  4. TiDB
  5. OceanBase
  6. HBase
  7. ClickHouse
  8. Kylin
  9. Druid

C++全栈知识体系选型:

技术栈

  • 开发框架:vue
  • 组件库:vuepress
  • 主语言:JavaScript
  • 环境:腾讯云(nginx 部署)

  1. 看文档确认版本号
  2. 先跑起来 Demo, demo 跑完,没问题,再确认技术选型。

系统开发

  • 前端
  • 后端
  • 部署上线

工具链

  • 开发工具 Idea,VS code
  • 测试工具 Postman,swagger
  • 上线工具 利用Nginx反向代理

资源准备

  1. 服务器
  2. 数据库
  3. 第三方服务(短信、存储、OCR)
  4. 开发软件

服务器

  1. 带宽
  2. 服务器的内存
  3. 服务器的 CPU
  4. 硬盘

带宽计算:

  • 打开一次网页传输 1.2 M
  • 计算每秒访问的总资源大小(人数 * 单位资源大小)
  • 内存:需要自己查看所有进程的内存占用
  • CPU:需要自己查看所有进程的资源占用

精打细算,先从最小的设备搞起。

系统设计

只用语言描述,不写代码

  • 功能模块图(思维导图)
  • 技术架构图
  • 库表设计
  • 每个功能的实现逻辑

功能模块图

从整体到局部

先划分子系统

库表设计

  1. 划分哪些库(每个项目 1 个库)
  2. 划分哪些表(正常情况下每个大的功能一个表)
  3. 每个表有哪些字段?
  4. 表之间的关联关系(通过字段约定式关联)

id, create_time, update_time, delete(软删除)

开发规范

没有绝对的好坏、也没有绝对的一致,保证团队内部统一即可

编码规范

  1. 人为约定:比如 https://blog.csdn.net/weixin_43932564/article/details/108995713、阿里巴巴 Java 规约、前端规范:https://wenku.baidu.com/view/dd64bd8fd2f34693daef5ef7ba0d4a7302766cfe.html (opens new window) 等等

  2. 工具:

    • 后端:alibaba java coding guide、sonarlint、checkstyle(https://blog.csdn.net/liuwei0376/article/details/123180920)
    • 前端:eslint(校验 js、ts 等文件的语法) + prettier(美化、格式化代码) + stylelint(检查校验 css 代码)

提交规范

  1. 统一的提交记录,比如关联需求文档
  2. 忽略某些文件的提交,保护隐私(可以使用 .gitignore)

3. 做好开发第一步

前后端协作

接口文档

  1. 全员参加需求评审,都知道要做什么事情。
  2. 前端和后端分别考虑怎么实现这个需求?前端要找后端要接口;后端提供给前端哪些接口?
  3. 前后端对齐(确认了字段信息、接口信息)
  4. 并行:前端用 mock 或假数据;后端自己开发

如何做好开发第一步 (如果是个人开发,建议先后端)

后端

  1. 创建数据表
  2. 使用MyBatis X插件生成代码
  3. 检查并复制生成的代码到实际项目目录中
  4. 创建 Controller,生成增删改查接口
  5. 创建一些请求类(比如 XXXAddRequest
  6. 最好编写单元测试

接口设计规范:

  1. 自己定义开发规范
  2. 遵循业内的准备

Restful 接口设计规范:

  • 操作、请求类型、接口地址
  • 增、POST、/{resource},比如/post
  • 删、DELETE,/{resource}/{id},比如 /post/{id}
  • 改、PUT、/{resource}/{id},比如/post/{id}
  • 查、GET、/{resource}/{id},比如 /post/{id}(OpenAPI)

前端

  1. 根据后端的接口文档,找到实体(/SwaggerModels/default),编写 model(typescript数据类型定义代码)
  2. 创建 service(api),调用后端接口的代码,也是对应了后端的增删改查
  3. 创建页面: 使用procomponents 组件 https://procomponents.ant.design/components/table?current=1&pageSize=5
  4. 登录页面: 使用procomponents 组件 https://procomponents.ant.design/components/login-form

登录注册功能参考早球的用户中心项目

主要包括以下几部分:

  1. 基本操作:增、删、改、查(根据 id 查、全量条件查询、分页条件查询)
  2. 用户登录注册
  3. 单元测试

4. 如何聪明地写代码

业务功能开发

核心:先做设计,再写代码

  1. 项目功能具体设计+讲解(以点赞功能为例)
  2. 从设计到开发一个新的功能

点赞功能

需求分析

  1. 用户可以对帖子进行点赞/取消点赞
  2. 用户对单个帖子只能点赞1次

方案设计

为什么要写?

  1. 便于开发
  2. 自己总结
  3. 明确依赖,防止抵赖
  4. 更好地沉淀、给他人给团队做参考

后端业务流程:

  1. 输入:接受请求参数,帖子 id(肯定不能传递 userld 和点赞状态,直接从数据库里取)
  2. 参数校验 a. 业务不相关:请求参数是否为 null、id 不能小于等于0 b. 业务相关的校验:帖子是否存在,帖子的状态要是允许点赞的(比如必须审核通过)
  3. 权限校验 a. 判断用户是否登录,获取当前登录用户信息(userld)
  4. 执行操作 a. 判断用户是否已点赞,根据 userld 和 postld 查询 post thumb 表,如果存在,则表示已点赞,否则未点赞 b. 如果已点赞,执行【取消点赞】操作: i. 从post_thumb 表删除数据(userld、postld) ii.post 帖子表的点赞数量-1 c. 如果未点赞,执行【点赞】操作 i.向post_thumb表插入新数据(userld、postld ii.post帖子表的点赞数量+1 d. 使用事务来管理所有的操作
  5. 返回一个能区分是点赞成功还是取消点赞成功的值
  6. 通过加锁的方式保证冥等性(需要考虑加锁粒度,例如考虑给方法加锁,还是方法中具体逻辑加锁,例如点赞)

先构思,把业务流程想清楚,具体编码时,再去查某一步骤的具体实现方式

  • 安全性(权限、限制频率)
  • 幂等性(用户不能重复点赞) , 解决方法加锁:synchornized(String.valueOf(userId).intern()){}
  • 性能(比如接口响应时长,可以用Redis)、存储(硬删除)
    • 高性能校验原则: 优先校验不需要查数据库、操作第三方资源的

前端:

  1. 请求后端接口
  2. 根据后端返回的数据改变图标和帖子点赞数

切换 banner

需求分析

  1. 管理员可以在管理后台切换首页的 banner 图
  2. 切换方式: a. 本地上传文件 b. 直接复制一个图片的地址 c. 在线裁切

详细:

  1. 本地上传文件 a. 保存文件(本地服务器)或者第三方存储 b. 文件清理 c. 开发文件上传组件、动态查看图片效果等 d. 不存在防盗链
  2. 直接复制一个图片的地址 a. 不用自己存图片 b. 前端提供地址输入框 c. 存在防盗链

不同视角

  • 产品经理:关注怎么用方便?
  • 程序员:能不能实现?怎么实现? —— 没有最好的实现,只有最合适的

系统设计

图片的地址如何存储?

  1. 存在配置中心(nacos、apollo、spring cloud config)
  2. 存到数据库表里
  3. 本地文件(内存),容易丢失

库表设计

  • id
  • params:管理员配置(json 对象字符串,可以存 bannerUrl、logoUrl),利用json对象字符串,保证扩展性
  • userId: 谁设置的
  • createTime
  • updateTime
  • isDelete

前后端

前端

  • 提供新的管理页面,本质上是一个配置管理。

后端

  • 提供接口,仅管理员可以访问,如果没有配置,那就新增;如果有,那就修改

5. 如何优化项目

目的:

  1. 能学到更多优化项目的思路(打开思路),,之后自己项目的时候可以想到这些
  2. 让大家写简历的时候多一点亮点

如何优化项目

参考: https://bcdh.yuque.com/books/share/2dd2567c-a826-4d9d-9303-bd288269e874/ndphah

新增功能

  1. 把现有的功能做的更好(比如增强用户体验)
  2. 尽量避免无用的功能堆砌(尤其是重复的增删改查)
    • 如果处理日常工作中的增删改查,尽量写好代码,用更快地时间完成;剩余的时间用于自我提升

从一些维度/指标进行优化

从下面的优化点来看,思路很重要,不要过分在意实现

如何自我提升,自己做项目,考虑优化点,然后再去学习相关技术,进行实现

性能优化

前端

  1. 缓存(浏览器缓存)
  2. 减少文件的体积(压缩文件qzip、减少代码、减少依赖)
  3. 按需引入(按需加载)
  4. 懒加载(节省流量、提升页面加载速度)
  5. CDN(减少文件的传输时间)
  6. 传输协议升级 HTTP 1.x => HTTP 2.x
  7. 代码层面:减少无用的请求、减少无用的状态变更、减少无用的渲染
  8. 请求合并(受到 http 请求输的限制)

后端

  1. 缓存(Nginx、Tomcat、Redis 多级缓存)
  2. 查询合并(查数据库 select id =1、id=2、id=3=> select id in(123)),减少重复操作
  3. 并发编程 a. 异步:不影响主流程的操作,可以单独开线程处理/消息队列 b. 并发:把一个大的动作分为多个小工作,大家一起干活,干完之后再汇总 c. 池化:线程池(避免重复的线程创建和销毁,复用线程)、连接池(避免重复的链接建立和释放,复用连接)
  4. 限流
  5. 降级(有损服务)
  6. 数据压缩(返回给前端、存储前)
  • e.g.删除用户发的帖子,里面有很多图片:先删帖子,

    • 用户发送州除请求,后端执行州帖子操作(操作成功),再开一个线程惕慢地去删图片
  • e.q.数据写入 Redis 前,用 JDK 序列化器。(可以改用 kryo 来压缩,或者用 hash 代替 string 存储)

    • User {id = 1, name =xxx, age=20)
    • id=1,name=xxxage=20

成本优化

  1. 分析自己用了哪些资源
  2. 降低 CPU利用(比如,根据实际情况降低定时任务的频率,也不能为了省钱不去做计算 哈哈哈哈)
  3. 节约内存(Java GC,尽量避免占用内存的大任务持续执行、分批处理-能及时释放就及时释放,尽量用占用空间少的数据结构,Java 可以用 MAT来分析) hashMap 来存用户,string 来存储 json
  4. 节约磁盘:人工分析删除、定期删除,低频存储、淘汰策略(例如,磁盘利用率达到阈值,去删除最久未被访问的文件),数据压缩
  5. 减少带宽占用:数据压缩、连接复用、本地查询(缓存)、打包

可用性

  1. 集群
  2. 主备
  3. 自动故障恢复(Redis哨兵) 写代码 写进ICU —— 医生来治一下
  4. 容灾

可靠性

尽可能地让系统提供可靠的服务,不要出现崩溃中断

方法:集群、主备、异常处理、降级、容灾

稳定性

方法:保证每个服务节点状态正常、性能相当(不要有的机器好有的机器垃圾导致接口时快时慢);合理规划服务调用链路,不能过长;做好技术选型,避免使用不稳定的第三方依赖

核心:保证所有依赖(服务器、接口、数据库等)都要稳定。

怎么排查稳定性:

  1. 链路追踪
  2. 打日志

健壮性

异常处理(NPE(NullPointerException),"A".equals(xxx) > xxx.equals("A")、全局异常处理器)

系统复杂度

方法:软件开发原则、设计模式、系统架构设计(如微服务)、开发规范、工作流

可维护性

方法:软件开发原则、设计模式、系统架构设计(如微服务)、开发规范、工作流、抽象复用(组件化模块化)

可扩展性

使整个系统能够轻松应对未来新增的需求及业务增长,不会牵一发而动全身

方法:设计模式、架构设计、集群、分库分表、技术选型

可扩展性例子: * 枚举值,例如:小学,初中,高中,继续可以扩展新的枚举大学,研究生,博士 * 标签名称,例如,类别可以是地点、职业;标签名称是上海、程序员;最终按照标签名称就可以搜索更多条件的内容,而不是仅根据地点或职业分类

开闭原则

可观测性

系统埋点上报、监控告警(prometheus)、ELK日志收集、可视化分析(Grafana)

  • 利用定时任务对系统程序里线程池使用的资源情况进行记录日志

可伸缩性

系统根据负载情况动态增加或减少节点,从而能够应对流量高峰、并在空闲时节约成本

方法:K8S+Docker容器、云原生

用户体验

方法:网页性能优化、接口性能优化、懒加载、占位符、骨架屏、设备适配、浏览器兼容性、满意度调研(如 NPS)

安全性

方法:参数校验、常用安全措施(防XSS、CSRF、SQL注入等)、网络防护(反 DDOS)、反爬虫、限流、黑白名单、防火墙等

6. 绽放项目的价值

项目上线

  1. 准备资源:域名、服务器
    • 新的服务器可以装宝塔面板,可以方便地管理服务器、快速上线项目,节省操作时间。
  2. 区分环境
    • baseUrl: isDev ? 'http://localhost:8081:api' : 'http://myprj:8081:api'
  3. 联调部署

前端

  • 打包构建 => 把网页文件放到服务器上 => 用Nginx等web 服务器来提供访问能力
  • 如果使用了框架,建议是参考官方文档来学习部署
  • 多环境区分(编译/打包阶段):
    • 开发环境: 前端请求的是localhost:xxxx 或者说是测试用的接口地址
    • 上线: 前端请求的是myprj/api之类的正式地址

后端

  • 对于 Java 项目,编译构建 => 把jar 包放到服务器上=>手动执行
  • 多环境区分(启动阶段):
    • 开发环境: 前端请求的是localhost:xxxx 或者说是测试用的接口地址
    • 上线: 前端请求的是myprj/api之类的正式地址

注意跨域问题:前端请求的后端域名最好是一致的

开源

写 README.md 文档

  1. 证明你的项目是有认真在做,是正经开源而不是个人学习
  2. 给别人介绍你的项目,吸引别人来关注(star)
  3. 介绍怎么参与项目,吸引别人来参与
  4. 便于 自己梳理业务逻辑
  5. 写简历的时候,可以给面试官看的

写哪些点?如下:

小技巧:

  1. 参考别人现成的(最好是参考同类项目)
  2. 多列举一些截图
  3. 把最想让别人看到的前置

项目介绍

用最简洁清晰的话语描述你的项目。

最好能提供线上可访问的地址或者介绍视频。

  • 项目的功能、解决了什么问题、优势?
  • 项目背景:为什么想做这个项目?
    • 比如现有的产品不能满足诉求(存在痛点)、或者目前没有类似的产品、或者出于其他目的。
  • 项目意义:这个项目能解决什么问题?有什么实际意义?
    • 比如方便使用者、提升效率等。
  • 核心亮点:这个项目的核心亮点在哪里?

使用说明

让用户来实际构建运行项目

技术栈

介绍项目所用到的技术

快速启动

提供启动项目的流程和命令

内容展示

通过图的方式:

  • 业务流程
  • 架构设计
  • 功能模块

代码讲解

  • 列举项目目录结构,各个目录的内容介绍
  • 写一些项目中的优点、编码中值得注意的小细节等。
  • 具体的业务流程

贡献指南

如何让别人跟你一起参与项目?

其他

代码脱敏

不能把一些配置文件上传,例如包含后端数据库密码的xml文件等

开源协议

https://www.runoob.com/w3cnote/open-source-license.html

推广

  • 前提:作品用心、质量高、内容过硬
  • 友链
  • SEO:内容标签要清晰,尽量多出现一些关键
  • 利用其他渠道,比如发布视频,在合适的时候给别人推荐项目
  • GitHub 开源指南:https://github.phodal.com/#/