测试环境搭建流程_前端构建 DevOps 搭建 DevOps 基础平台(中)

前言

搭建基础平台搭建上篇的时候的时候,已经介绍过了项目流程设计、数据库搭建、jwt 登录等模块。

此篇我们介绍分支管理设计及其他的基础模块。

后端模块

  1. DevOps - Gitlab Api使用(已完成,点击跳转)
  2. DevOps - 搭建 DevOps 基础平台(已完成 50%)基础平台搭建上,点击跳转
  3. DevOps - Gitlab CI 流水线构建
  4. DevOps - Jenkins 流水线构建
  5. DevOps - Docker 使用
  6. DevOps - 发布任务流程设计
  7. DevOps - 代码审查卡点
  8. DevOps - Node 服务质量监控

后期可能会根据 DevOps 项目的实际开发进度对上述系列进行调整

Git 分支管理流程

Git Flow 流程

502d64096091d2cde9278e96bc439ff1.png

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

整体的分支管理流程如下图所示

31c70a3b7a3d258b383bd29f1122e159.png

项目自建流程

上述的 Git Flow 流程使用可以规范约束开发质量跟流程,我们稍微修改一下部分流程,融入到项目中进行使用。

5abf6e581780bfdb37dd5edfcfd1c69f.png
699e7f0c58823d99fc780cd064e517e8.png

如图每个工程都共享一个 version 版本号,分支创建分为版本升级、特性更新、修订补丁三种模式,强制项目所有分支创建的命名规则都会升级,不会出现重复跟降级。

83e9cd112f943d276df110ec2a70ac8e.png

上述流程的优点

  1. 工程使用固定的版本锁死,版本对应需求流程,上线质量得到保障
  2. 每个开发分支都只能部署到测试环境,必须合并到合并到对应的版本分支之后才能上生产
  3. 所有合并到 master 或者 relase 分支会被删除,防止一条分支处理过多业务,后期 review、回滚难度提升
  4. realse 版本分支上线之后,生成对应 tag
  5. hotfix 版本可以从对应的 tag 拉出,可以明确的知道 hotfix 具体修复的是哪个版本的问题

上述流程的缺点

  1. 固化版本流程导致创建命名规则固定,且版本号不能升级只能降级
  2. 流程限制,降低开发灵活性

没有完美的解决方法,所有 devops 流程都要结合真实项目需求来设计,上述只是一种解决方案,有更通用的方案设计请加我微信 Cookieboty 探讨

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。具体安装步骤请参考教程,这边展示一下部分业务端的代码。

f017eb76d938a5bcc40615d9158604d1.png

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,后续可以正常请求接口。

尾声

此项目是从零开发,后续此系列博客会根据实际开发进度推出(真 TMD 累),项目完成之后,会开放部分源码供各位同学参考。

如对文章内容有任何疑问、见解可添加微信 Cookieboty 沟通。

另外关注公众号 Cookieboty1024,欢迎加入前端小兵成长营

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是PermGen泄漏?

接下来是对Java应用程序中特定类型的内存问题的实用介绍。 即–我们将分析导致java.lang.OutOfMemoryError:PermGen空间的错误 堆栈跟踪中的症状。 首先,我们将介绍理解该主题所需的核心概念,并说明什么是对象,类,类…

rto净化效率计算公式_全面剖析 石油化工行业RTO蓄热式焚烧炉的优势要素

在我国的国民经济发展中,石油化工产业是重要的能源基础工业,但是废气的治理问题一直困扰着许多企业。直到RTO蓄热式焚烧炉的面世,为石油化工行业的废气治理带来了新希望。如今,有机废气治理工作越来越受到广泛重视,传统…

python作业:高级FTP程序

要求: 用户加密认证允许同时多用户登录每个用户有自己的家目录 ,且只能访问自己的家目录对用户进行磁盘配额,每个用户的可用空间不同允许用户在ftp server上随意切换目录允许用户查看当前目录下文件允许上传和下载文件,保证文件一…

webpack学习笔记 (一)

一、安装nodejs; 点击打开nodejs官方站点; 点击下图框住的按钮,下周nodejs安装包; 安装下载好的安装包。 安装完毕之后,在cmd中输入node -v查看是否已经安装成功 如果有版本号显示,则代表安装成功&#xf…

将涡轮增压器添加到JEE Apps

我扮演的关键角色之一是在本地社区中传播Akka。 作为讨论的一部分,人们通常会想到的问题/疑问是Akka如何针对编写良好的Java / JEE应用程序提供更好的可伸缩性和并发性。 由于底层硬件/ JVM保持不变,因此参与者模型如何比传统的JEE应用程序发挥更多的功…

MapReduce的工作原理

一、MapReduce模型框架 MapReduce是一个用于大规模数据处理的分布式计算模型,最初由Google工程师设计并实现的,Google已经将完整的MapReduce论文公开发布了。其中的定义是,MapReduce是一个编程模型,是一个用于处理和生成大规模数据…

react实现多行文本超出加省略号

http://www.css88.com/archives/5206 overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; 根据该文章方法,放在react项目中发现并不能实现,仔细观察发现原来react解析出来的css样…

qq群 html,我的群组-普通群组.html

我的群组-普通群组$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resou…

查看PLC IP 端口_西门子828D数控系统X130接口通讯怪异现象(X130手动设置的 IP)...

西门子828D数控系统,调试PLC过程中遇到网络通信怪异问题(不能直连非要加个路由器),笔记本电脑的以太网网络直接连接显示网络电缆被拔出,如下图所示:奇怪,怎么出现这种情况了呢,因为我用这台电脑调试过别的P…

bzoj1263

贪心 n%31 分出一个4&#xff0c;其余用3&#xff0c;n%32&#xff0c;分出一个2&#xff0c;其余用3&#xff0c;然后高精度就行了 #include<bits/stdc.h> using namespace std; const int N 5005; struct BigInt {int len;int a[N];BigInt() { memset(a, 0, sizeof(a)…

c语言volatile_[技术]为什么单片机C语言编程时某一变量有时乱码

最近一个项目里面&#xff0c;在KEIL中用C语言在单片机里面定义了一个状态机全局变量&#xff0c;这个变量随时会改变&#xff0c;用于切换触摸屏的界面&#xff0c;可是程序运行中出现了一个问题&#xff0c;这个状态机号总是出现了被莫名奇妙改变的问题&#xff0c;导致触屏不…

微型计算机2017年9月上,2017年9月计算机一级考试WPS Office冲刺题

2017年9月计算机一级考试WPS Office冲刺题2017年下半年计算机一级考试将在9月份进行&#xff0c;为了方便考生备考计算机一级考试。下面是小编为大家带来的计算机一级考试WPS Office冲刺题&#xff0c;欢迎阅读。冲刺题一&#xff1a;1、PowerPoint 演示文稿和模板的扩展名是【…

11尺寸长宽 iphone_弱电工程LED显示屏尺寸规格及计算方法

前言&#xff1a;led屏幕在生活中&#xff0c;随处可见&#xff0c;显示屏、广播屏等等&#xff0c;但是led尺寸怎么计算的&#xff0c;你知道吗&#xff1f;今天我们一起了解一下led屏幕尺寸的计算方法。正文&#xff1a;一、点间距的计算1、各单元板常见型号及尺寸LED屏普遍是…

marquee标签的使用

<!DOCTYPE html> <html> <head><meta charset"utf-8" /><title>演示marquee</title><style type"text/css">*{padding: 0px;margin: 0px;}marquee{border: 1px solid purple;}img{width: 360px;height: auto;}&…

32位数据源中没有mysql_[SpringBoot实战]快速配置多数据源(整合MyBatis)

前言由于业务需求&#xff0c;需要同时在SpringBoot中配置两套数据源&#xff08;连接两个数据库&#xff09;&#xff0c;要求能做到service层在调用各数据库表的mapper时能够自动切换数据源&#xff0c;也就是mapper自动访问正确的数据库。本文内容&#xff1a;在SpringbootM…

考研计算机冷门学校,考研5个冷门的985院校 别随大流,这些几所也是很不错的...

导语&#xff1a;想必大家考研的目的有很多&#xff0c;最主要的就是想去更好的学校提升自己&#xff0c;大部分会肯定是会更倾向于985这类的院校&#xff0c;每年其实除了那些被“挤破头”的985院校&#xff0c;其实还有不少“低调”的985院校是非常值得报考的&#xff0c;下面…

名为 cursor_jinserted 的游标不存在_质量工程师必须了解的测量常识,你不知道怎么行...

01测量器具的分类测量器具是一种具有固定形态、用以复现或提供一个或多个已知量值的器具。按用途的不同量具可分为以下几类&#xff1a;1. 单值量具只能体现一个单一量值的量具。可用来校对和调整其它测量器具或作为标准量与被测量直接进行比较&#xff0c;如量块、角度量块等。…

bzoj4869

http://www.lydsy.com/JudgeOnline/problem.php?id4869 终于A了。。。参考了下dalao的代码。。。 拓展欧几里得定理&#xff0c;改了几次就不变了&#xff0c;但是用的时候要在快速幂里判是不是要用。 #include<bits/stdc.h> using namespace std; typedef long long ll…

一张图一个表——CSS选择器总结

CSS选择器总结&#xff1a; (这些表是一张图片^_^) 看底部 完整思维导图图片和表格的下载地址&#xff1a;https://download.csdn.net/download/denlnyyr/10597820 &#xff08;我不想选择要积分币下载的&#xff0c;但那里最低必须选择1个积分……&#xff09; 参考文献&…

native层 安卓_安卓逆向——拼xx协议java层分析

制丨阿星整理丨阿星老铁们大家好&#xff0c;今天小编给大家带来很实用的技巧叫拼xx协议java层分析&#xff0c;有啥不足的地方望大家指点指点&#xff01;首先抓包 反编译这个时间段我们方法剖析一下找到onclick 看他的走向找到方法的地方都是在进行写入 所以我们直接分析结果…