网站首页 > 技术文章 正文
前言
介绍过了项目流程设计、数据库搭建、jwt 登录等模块。
此篇我们介绍分支管理设计及其他的基础模块。
后端模块
- DevOps - Gitlab Api使用(已完成,点击跳转)
- DevOps - 搭建 DevOps 基础平台(已完成 50%)基础平台搭建上,点击跳转
- DevOps - Gitlab CI 流水线构建
- DevOps - Jenkins 流水线构建
- DevOps - Docker 使用
- DevOps - 发布任务流程设计
- DevOps - 代码审查卡点
- DevOps - Node 服务质量监控
后期可能会根据 DevOps 项目的实际开发进度对上述系列进行调整
Git 分支管理流程
Git Flow 流程
Production 分支
就是常用的 Master 分支,这个分支包含最近发布到生产环境的代码,最近发布的 Release, 这个分支只能从其他分支合并,不能在这个分支直接修改
Develop 分支
这个分支是的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并于其他分支,比如 Feature 分支
Feature 分支
这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回 Develop 分支,并进入下一个 Release
Release 分支
当需要发布一个新 Release 的时候,基于 Develop 分支创建一个 Release 分支,完成 Release 后,合并到 Master 和 Develop 分支
Hotfix 分支
当在 Production 发现新的 Bu g时候,需要创建一个 Hotfix, 完成 Hotfix 后,合并回 Master 和 Develop 分支,所以 Hotfix 的改动会进入下一个 Release
整体的分支管理流程如下图所示
项目自建流程
上述的 Git Flow 流程使用可以规范约束开发质量跟流程,我们稍微修改一下部分流程,融入到项目中进行使用。
如图每个工程都共享一个 version 版本号,分支创建分为版本升级、特性更新、修订补丁三种模式,强制项目所有分支创建的命名规则都会升级,不会出现重复跟降级。
上述流程的优点:
- 工程使用固定的版本锁死,版本对应需求流程,上线质量得到保障
- 每个开发分支都只能部署到测试环境,必须合并到合并到对应的版本分支之后才能上生产
- 所有合并到 master 或者 relase 分支会被删除,防止一条分支处理过多业务,后期 review、回滚难度提升
- realse 版本分支上线之后,生成对应 tag
- hotfix 版本可以从对应的 tag 拉出,可以明确的知道 hotfix 具体修复的是哪个版本的问题
上述流程的缺点:
- 固化版本流程导致创建命名规则固定,且版本号不能升级只能降级
- 流程限制,降低开发灵活性
没有完美的解决方法,所有 devops 流程都要结合真实项目需求来设计,上述只是一种解决方案
DevOps 开发中篇
添加全局报错回调
没有绝对安全的程序,所有程序在运行中因各种情况会出现 error,全局错误回调是基础模块必要的。
export default class HttpExceptions extends Error { // 继承修改 error 类型
code: number;
msg: string;
httpCode: number;
constructor({ msg = "服务器异常", code = 1, httpCode = 400 }) {
super();
this.msg = msg;
this.code = code;
this.httpCode = httpCode;
}
}
import HttpExceptions from "../exceptions/http_exceptions"; // 全局拦截错误处理
export default () => {
return async function errorHandler(ctx, next) {
try {
await next();
} catch (err) {
// 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
ctx.app.emit("error", err, ctx);
let status = err.status || 500;
let error: any = {};
if (err instanceof HttpExceptions) {
status = err.httpCode;
error.requestUrl = `${ctx.method} : ${ctx.path}`;
error.msg = err.msg;
error.code = err.code;
error.httpCode = err.httpCode;
} else {
// 未知异常,系统异常,线上不显示堆栈信息
// 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
error.code = 500;
error.errsInfo =
status === 500 && ctx.app.config.env === "prod"
? "Internal Server Error"
: err.message;
}
// 从 error 对象上读出各个属性,设置到响应中
ctx.body = error;
if (status === 422) {
ctx.body.detail = err.errors;
}
ctx.status = status;
}
};
};
复制代码
如上,我们拓展默认错误类,添加错误中间件拦截全局异常,如果出现自定义异常抛出的时候,则处理全局异常,否则统一抛出 500 错误,去除敏感信息。
webSocket 使用
为什么要使用 webSocket
项目管理中,会涉及到同一个项目多人协作操作,而 ajax 轮训既消耗性能,实时性也不能完全保证,也会推送大量无效信息。所以项目采用 websocket 来推送多人协作信息以及后期构建流程的状态推送。
egg-socket
框架提供了 egg-socket.io 插件,增加了以下开发规约:
- namespace: 通过配置的方式定义 namespace(命名空间)
- middleware: 对每一次 socket 连接的建立/断开、每一次消息/数据传递进行预处理
- controller: 响应 socket.io 的 event 事件
- router: 统一了 socket.io 的 event 与 框架路由的处理配置方式。
具体的使用方式请参考:egg-socket.io 使用,下面简单说下 ts 的配置
import { Application } from "egg"; // io路由使用方式
import { EggShell } from "egg-shell-decorators";
export default (app: Application) => {
const { router, controller, io } = app;
EggShell(app);
// socket.io
io.of('/').route('server', io.controller.nsp.ping);
};
复制代码
ts 使用中 io.controller.nsp 会报类型未定义,所以需要修改一下 typings/index.d.ts 文件。
import "egg";
declare module "egg" {
interface Application { }
interface CustomController {
nsp: any;
}
interface EggSocketNameSpace {
emit: any
}
}
复制代码
socket.io-client
window.onload = function () {
// init
const socket = io('http://127.0.0.1:7001', {
// 实际使用中可以在这里传递参数
query: {
room: 'nsp',
userId: `client_${Math.random()}`,
},
transports: ['websocket'],
});
socket.on('connect', () => {
const id = socket.id;
log('#connect,', id, socket);
// 监听自身 id 以实现 p2p 通讯
socket.on(id, (msg: any) => {
log('#receive,', msg);
});
});
// 接收在线用户信息
socket.on('online', (msg: any) => {
log('#online,', msg);
});
// 系统事件
socket.on('disconnect', (msg: any) => {
log('#disconnect', msg);
});
socket.on('disconnecting', () => {
log('#disconnecting');
});
socket.on('error', () => {
log('#error');
});
window.socket = socket;
};
复制代码
客服端采用 socket.io-client 去链接 websocket。上述是基础链接部分,具体的实现要根据业务需求开发。
客服端实现
为了保障项目开发速度,客户端选择了 ANT DESIGN PRO。具体安装步骤请参考教程,这边展示一下部分业务端的代码。
JWT 前端使用
/**
* 异常处理程序
*/
const errorHandler = (error: { response: Response }): Response => {
const { response } = error;
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, url } = response;
if (response.status === 401) {
window.location.href = '/user/login';
}
notification.error({
message: `请求错误 ${status}: ${url}`,
description: errorText,
});
} else if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常',
});
}
return response;
};
/**
* 配置request请求时的默认参数
*/
const request = extend({
prefix: '/api',
errorHandler, // 默认错误处理
credentials: 'include', // 默认请求是否带上cookie
headers: {
authorization: localStorage.getItem('authorization'), // 读取本地保存的 authorization token
},
});
export default request;
复制代码
改造 request 模块
import request from '@/utils/request';
export interface LoginParamsType {
username: string;
password: string;
mobile: string;
captcha: string;
}
export async function fakeAccountLogin(params: LoginParamsType) {
return request('/user/getUserToken', {
getResponse: true, // 开启可以拿到返回 header 参数,将对应的 authorization token 存入本地使用
method: 'POST',
data: { params },
});
}
复制代码
如上,拿到 response header 里面的 token,后续可以正常请求接口。
尾声
此项目是从零开发,后续此系列博客会根据实际开发进度推出,项目完成之后,会开放部分源码供各位同学参考。
最后,咱给小编:
1. 点赞+评论
2. 点头像关注,转发给有需要的朋友。
谢谢!!
猜你喜欢
- 2024-12-14 看完让你彻底理解 WebSocket 原理,附完整的实战代码(包含前端和后端)
- 2024-12-14 程序猿何苦为难程序猿:前端与后端不得不说的密码
- 2024-12-14 开发一个小程序需要多长的时间?
- 2024-12-14 前端开发79条知识点汇总
- 2024-12-14 详细解读小程序的构成,看完你就全部懂了
- 2024-12-14 微信小程序前端与后端怎么搭建,教你如何使用小程序模板
- 2024-12-14 bat 脚本简单优雅的启动你的程序
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)