Java后端开发规范
Git分支管理规范
1. 分支说明及操作
-
master 分支
- 主分支,永远处于稳定状态,对应当前线上版本
- 以 tag 标记一个版本,因此在 master 分支上看到的每一个 tag 都应该对应一个线上版本
- 不允许在该分支直接提交代码
-
develop 分支
- 开发分支,包含了项目最新的功能和代码,所有开发都依赖 develop 分支进行
- 小的改动可以直接在 develop 分支进行,改动较多时切出新的 feature 分支进行
注: 更好的做法是 develop 分支作为开发的主分支,也不允许直接提交代码。小改动也应该以 feature 分支提 merge request 合并,目的是保证每个改动都经过了强制代码 review,降低代码风险。
-
feature 分支
- 功能分支,开发新功能的分支
- 开发新的功能或者改动较大的调整,从 develop 分支切换出 feature 分支,分支名称为
feature/xxx
- 开发完成后合并回 develop 分支并且删除该 feature/xxx 分支
-
release 分支
- 发布分支,新功能合并到 develop 分支,准备发布新版本时使用的分支
- 当 develop 分支完成功能合并和部分 bug fix,准备发布新版本时,切出一个 release 分支,来做发布前的准备,分支名约定为
release/xxx
- 发布之前发现的 bug 就直接在这个分支上修复,确定准备发版本就合并到 master 分支,完成发布,同时合并到 develop 分支
-
hotfix 分支
- 紧急修复线上 bug 分支
- 当线上版本出现 bug 时,从 master 分支切出一个
hotfix/xxx
分支,完成 bug 修复,然后将hotfix/xxx
合并到 master 和 develop 分支(如果此时存在 release 分支,则应该合并到 release 分支),合并完成后删除该hotfix/xxx
分支
以上就是在项目中应该出现的分支以及每个分支功能的说明。
其中稳定长期存在的分支只有 master 和 develop 分支,别的分支在完成对应的使命之后都会合并到这两个分支然后被删除。简单总结如下:
- master 分支: 线上稳定版本分支, 该分支代码与线上代码是完全一致的。
- develop 分支: 开发分支,衍生出 feature 分支和 release 分支
- release 分支: 发布分支,准备待发布版本的分支,存在多个,版本发布之后删除。该分支从 develop 分支创建,创建之后由测试人员发布到测试环境进行测试。
- feature 分支: 功能分支,完成特定功能开发的分支,存在多个,功能合并之后删除
- hotfix 分支: 紧急热修复分支,存在多个,紧急版本发布之后删除
2. 提交信息规范
提交信息规范部分参考 Angular.js commit messgae。
git commit 格式 如下:
1 | <type>(<scope>): <subject> |
各个部分的说明如下:
-
type 类型,提交的类别
- feat: 新功能
- fix: 修复 bug
- docs: 文档变动
- style: 格式调整,对代码实际运行没有改动,例如添加空行、格式化等
- refactor: bug 修复和添加新功能之外的代码改动
- perf: 提升性能的改动
- test: 添加或修正测试代码
- chore: 构建过程或辅助工具和库(如文档生成)的更改
-
scope 修改范围
主要是这次修改涉及到的部分,简单概括,例如 login、train-order
-
subject 修改的描述
具体的修改描述信息
-
范例
1
2
3feat(detail): 详情页修改样式
fix(login): 登录页面错误处理
test(list): 列表页添加测试代码
补充规范
服务命名规范
采用英文小写方式
命名结构: 项目名-微服务名-服务类型(如pay-bill-web)
- 项目名: 立项的项目, 如crm、call等
- 微服务名: 表示微服务的核心业务或功能
- 服务类型说明:
- Dubbo: service
- SpringBoot: web
包名命名规范
命名 | 备注 |
---|---|
cn.idea360 | 总体要求 |
cn.idea360.xxx.controller | controller的package |
cn.idea360.xxx.service | service的package |
cn.idea360.xxx.service.impl | service接口实现的package |
cn.idea360.xxx.dao | dao的package |
cn.idea360.xxx.dao.impl | dao接口实现类的package |
cn.idea360.xxx.entity | 表实体的package |
cn.idea360.xxx.vo | api层实体的package |
cn.idea360.xxx.dto | 数据交换的package |
cn.idea360.xxx.common | utils、config等package |
cn.idea360.xxx.api | dubbo接口定义package |
cn.idea360.xxx.provider | dubbo服务提供package |
方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格, 必须遵从驼峰形式
Redis Key名设计规范
redis-key基于以下几个角度进行设计
- 可读性和可管理性(以业务名为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id)
- 简洁性(保证语义的前提下,控制key的长度, 如cid用c, uid用u代替)
- 现在公司是saas业务, 和用户相关的数据最好包含cid和uid, 如不相关可不写
- 需要对key设置合理过期时间
- 命名必须全部小写字母、数字、英文点号(.)和英文半角冒号(:)组成,必须以英文字母开头
key完整示例:
应用名.服务名:c:{cid}:u:{uid}:{xxx}
应用名和服务名需要统一约定字母缩写
1 | # 说明: |
日志使用规范
日志优先参考阿里巴巴日志规约
什么时候使用日志
-
系统初始化:系统或者服务的启动参数。核心模块或者组件初始化过程中往往依赖一些关键配置,根据参数不同会提供不一样的服务。务必在这里记录 INFO 日志,打印出参数以及启动完成态服务表述。
-
编程语言提示异常:如今各类主流的编程语言都包括异常机制,业务相关的流行框架有完整的异常模块。这类捕获的异常是系统告知开发人员需要加以关注的,是质量非常高的报错。应当适当记录日志,根据实际结合业务的情况使用 WARN 或者 ERROR 级别。
-
业务流程预期不符:除开平台以及编程语言异常之外,项目代码中结果与期望不符时也是日志场景之一,简单来说所有流程分支都可以加入考虑。取决于开发人员判断能否容忍情形发生。常见的合适场景包括外部参数不正确,数据处理问题导致返回码不在合理范围内等等。
-
系统核心角色,组件关键动作:系统中核心角色触发的业务动作是需要多加关注的,是衡量系统正常运行的重要指标,建议记录 INFO 级别日志,比如电商系统用户从登录到下单的整个流程;微服务各服务节点交互;核心数据表增删改;核心组件运行等等,如果日志频度高或者打印量特别大,可以提炼关键点 INFO 记录,其余酌情考虑 DEBUG 级别。
-
第三方服务远程调用:微服务架构体系中有一个重要的点就是第三方永远不可信,对于第三方服务远程调用建议打印请求和响应的参数,方便在和各个终端定位问题,不会因为第三方服务日志的缺失变得手足无措。
日志规约补充
- 生产环境的服务需要集成ELK。kafka-topic必须以log-xxx命名, xxx为服务名
- 日志文件目录:/jesong/logs/xxx, xxx为项目名
- 日志文件命名:xxx.level.date.0.log, 其中xxx为项目名, level为日志等级, date为日志日期, 0为日志分割编号
- 日志需要做循环滚动删除配置
- 日志打印必须包含上下文
- 不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志
异常处理规范
- 运行时异常需继承自统一异常
EasyliaoException
, 异常通过全局异常统一返回
1 | <dependency> |
- 异常的捕获用于容错处理。绝大部分场景,不允许捕获异常,不要乱加空判断。只有明显不需要关心的异常,如关闭资源的时候的io异常,可以捕获然后什么都不干,其他时候, 不允许捕获异常, 都抛出去到controller处理。空判断大部分时候不需要,你如果写了空判断,你就必须测试为空和不为空二种场景, 要么就不要写空判断。
强调, 有些空判断是要的,如:参数是用户输入的情况下。
事务使用规范
- 不得使用事务超时时间
- 只读接口不允许使用事务
- 严禁在事务中访问第三方/严禁在事务中使用分布式锁。因为只要进入了Transactional,哪怕没有任何SQL语句,都会占用数据库连接。所以,一旦在事务中访问第三方,第三方的故障可能会导致我方的数据库连接被大量占用。会产生灾难性的结果
- 事务粒度最小化
注释
类注释
类注释必须包含作者+日期+功能描述, 如
1 | /** |
方法注释
方法注释中必须包含功能描述+入参说明+返回说明, 如
1 | /** |
对于多人修改同一方法, 注释中应该标明修改人, 修改日期, 修改说明
1 | /** |
SQL规范
1.使用InnoDB存储引擎
2. 字符集编码utf8mb4, 排序规则 默认采用不区分大小写的utf8mb4_general_ci, 表及字段必须添加COMMENT描述
3. 把字段定义为NOT NULL并且提供默认值
1 | a. null的列使索引/索引统计/值比较都更加复杂,对MySQL来说更难优化。 |
4. 禁止使用小数存储金额等数据, 避免精度丢失
5. 数据量大的表必须建立索引
6. 禁止在更新十分频繁、区分度不高的属性上建立索引
1 | a. 更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能 |
7. 建立组合索引, 把区分度高的字段放在前面
8. 禁止在WHERE条件的属性上使用函数或者表达式