搭建开发流程需要的系统

本文主要根据自己的工作经历,整理了一些常见内部系统的基本使用和大致实现原理,了解如何搭建一套比较规范的开发流程。

<!--more-->

1. 项目管理

1.1. 安装Redmine

参考

Redmine是一个使用Rails编写的开源项目管理工具,如果公司还没有一个比较规范的项目流程管理,可以尝试使用这个工具。

新建一个docker-compose.yml文件,填写下面配置(来自于上面的参考文章)

version: '3.1'

services:

  redmine:
    image: redmine:latest
    restart: always
    ports:
      - 15643:3000
    environment:
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PASSWORD: pwd_root
    volumes:
      - ./datadir:/usr/src/redmine/files

  db:
    image: mysql:5.7
    restart: always
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --init-connect='SET NAMES utf8mb4;' --innodb-flush-log-at-trx-commit=0
    environment:
      MYSQL_ROOT_PASSWORD: pwd_root
      MYSQL_DATABASE: redmine
    volumes:
      - ./datadir:/var/lib/mysql:rw

上面配置将mysql所有的数据表的字符集改变为 utf-8,避免redmine安装脚本初始化时出现字符问题

然后运行docker-compse up -d即可

1.2. 基本使用

由于配置的端口号映射是15643,所以在启动完成后,可以直接通过http:${ip}:15643在浏览器中访问redmine了,我配置了一个redmine.shymean.com本地域名进行测试

  • 首次登录需要修改密码,默认账号admin,默认密码admin
  • 然后访问/projects/new新建一个项目
  • 选择项目,新建工单

redmine提供了通用的项目管理流程,如果还需要进行定制化开发,可以去github上拉取代码然后修改,常见的定制需求包括

  • 细化工单类型,如Feature工单、Bug工单等
  • 指派工单和工单变更时通知工单关注人,可以通过邮件、消息机器人等
  • 关联工单和git仓库,添加上线配置和脚本,如sql语句、打包环境变量等

下面是我体验过的一种Feature工单开发流程

  • 运营提出需求,标注优先级和上线节点,新建工单指派给对应产品
  • 产品评估需求,完善细节,更新需求文档、prd、原型图等到工单
    • 如果需求比较复杂,一般需要通知开发和测试开会进行评估,确认开发节点、上线时间,
    • 如果无法实现,则重新确认需求,或拒绝并关闭工单
    • 如果可以实现,则确认排期,包括工单组装方、开发节点、测试节点等,进入下一步
  • 需求确定为完毕,工单流转给程序员并进入开发阶段
    • 项目组装方Leader分配给具体开发人员,由负责开发人员确定开发方案并更新工单
    • 如果存在跨部门协作,比如前后端接口依赖,则由工单组装方拆分子工单,指派给具体开发,约定开发方案、联调时间、接口文档等
    • 进入开发流程,切换git分支,在代码合适位置添加对应工单注释,追踪每一次提交对应的需求工单
    • 开发、自测、联调完毕后进入提测阶段,将工单指派给测试,同时将代码部署到测试环境
    • 如果需要,可以在提测前进行code review
  • 测试根据需求文档进行测试,
    • 如果发现bug,则在当前工单下新建bug工单,bug工单指派给对应开发,开发修复并更新测试环境后重新指派给测试进行验证,验证无误后关闭该bug工单
    • 所有需求的测试用例均验证完毕后,测试将工单更新为可上线状态,指派给对应开发或运维进行上线操作
  • 合并代码并部署到线上,工单流转回产品
    • 可以进行灰度发布,只上线部分机器
    • 封板限制,重要活动或节假日上线前需提交申请
  • 产品验证功能并关闭工单

在这个流程中,保证了每一个需求都是有迹可循的,在翻阅代码时可以快速定位对应的工单,方便理清业务逻辑。

(经历过工单排到下下周的时刻,也体验过一个月没有工单的时刻...回头来看,这种项目管理比目前使用的TAPD要好很多~当然也有可能是使用TAPD姿势不太对的缘故

2. 代码托管

一般稍微有点规模的公司都会搭建自己的代码库,作为互联网公司的重要资产,下面介绍搭建私有gitlab仓库

2.1. 安装gitlab

参考

编写docker-comopse.yml

# 大概有1个多G,记得先配置先docker镜像仓库
version: '3.7'
services:
    gitlab:
      image: 'gitlab/gitlab-ce'
      restart: unless-stopped
      environment:
        TZ: 'Asia/Shanghai'
        GITLAB_OMNIBUS_CONFIG: |
          gitlab_rails['time_zone'] = 'Asia/Shanghai'
      ports:
        - '16985:80'
      volumes:
        - ./config:/etc/gitlab
        - ./data:/var/opt/gitlab
        - ./logs:/var/log/gitlab

然后运行docker-compse up -d

第一次启动大概需要花一点时间,可以使用docker ps查看启动状态,当容器STATUS变成health的时候就可以了。

2.2. 使用

容器运行成功后,打开浏览器访问http:${ip}:16985就可以看见登录界面

  • 首次登录需要设置root账号的密码
  • 设置完成后,就可以使用root账号和刚才设置的密码进行登录了

可以通过修改host文件和nginx代理配置一个本地域名gitlab.shymean.com,然后初始化一个仓库test,最后提交代码测试一下

mkdir test && cd test
git init
echo "hello gitlab" > readme.md
git add .
git commit -m "init"
# 新建一个远程仓库root/test.git,然后关联本地仓库
git remote add origin http://gitlab.shymean.com/root/test.git

# 推送本地仓库
git push
# 如果没有配置ssh,直接填账号密码登录提交代码

Nice大功告成。我们可以把自己项目的star改成1000关于表结构详情可以查看gitlabhq-schema,发现不会操作gitlab-rails,挖个坑后面再折腾一下

3. 开发

下面整理了一些在开发中可能会接触到的系统。

3.1. mock服务器

在前后端分离的项目中,mock数据是一种提高生产力的重要方式。

不吹不黑,之前写的mock-server这个小工具确实挺好用的,原本只是为了开发小程序的时候实现本地mock数据,后来就变成了一个可以根据mock模板快速搭建mock数据服务器

# 全局安装
npm i @shymean/mock-server -g

# 创建mock模板文件,编写mock接口
touch _mock.js
# 启动服务器
mock -f ./mock.js -p 9999

模板文件除了启动mock数据服务器之外,也可以很清晰地描述接口定义,不失为一种编写文档的方案。

3.2. 日志服务系统

负载均衡会将请求分发到各台业务机器上,如果在代码中使用的是文件日志,那么在查询日志时就会变得十分麻烦

  • 首先需要追踪请求由哪台机器处理
  • 然后去对应机器查看对应文件日志

然而往往第一步就卡住了~所以对于大型的分布式系统项目,往往需要一个集中的日志系统来收集、存储和查询各个业务的日志记录,方便定位和排查问题。

在业务代码中可以使用诸如log4js等库来记录日志,然后将日志信息保存起来,至于如何保存这里有两种思路

  • 直接保存到数据库中,优点是可以统一存储日志信息,但是日志记录比较频繁时会增加很多插入操作,影响服务器性能
  • 保存到本地文件中,然后通过独立的定时任务将各台机器上的日志文件同步到数据库中

日志文件统一保存起来之后,就可以统一查询日志信息了。为了加快检索效率,一般还需要为每个应用分发独立的key,方便快速定义该应用的日志信息。

3.3. 监控系统

在某些业务场景下,性能监控是很有必要的,日志系统主要用来查询业务代码中的日志,而监控系统主要用来监控网络请求数量、服务器性能和报错等信息。

之前在业务中使用过tingyun的应用监控服务,感觉还是挺方便的

听云可以实现您的应用性能全方位可视化,从PC端、浏览器端、移动客户端到服务端,帮您监控定位崩溃、卡顿、交互过慢、第三方API调用失败、数据库性能下降、CDN质量差等多维复杂的性能问题

在业务代码中,安装对应语言或框架的tingyun探针,初始化一下配置就可以了。

我理解的大致实现思路是实现请求拦截器,在请求前后都记录一下,这样就可以精确到每一个URL的请求,最后汇总到可视化面板查询数据,参考

4. 提测环境

目前使用过两种类型的测试环境

一种是使用独立的域名进行访问的测试环境,比如正式环境http://app.shymean.com,测试环境对应app-test.shymean.com,这种方案的优点在于:

  • 实现简单,部署方便,可以同时访问测试环境和正式环境

但是缺点也很明显

  • 后台接口也有对应的测试域名,需要通过环境变量控制请求的baseURL,对代码有侵入性
  • 请求域名不同,导致无法完全还原用户使用场景,比如在与外部服务如微信公众号授权跳转等地方需要额外配置很多东西
  • 只能通过测试域名访问单个测试环境,无法同时部署多套测试环境,在项目规模较大的时候影响测试效率

针对上面第三条缺点,可以通过将测试环境部署在不同的机器上,然后通过修改host,访问对应ip的测试环境。既然都改host了,何不让测试环境和正式环境的域名保持一致呢?

基于这个想法,可以实现第二种与正式环境域名相同的测试环境。其大致实现思路是

  • 测试服务器上通过Docker部署项目服务
  • 在构建测试环境时,在对应的容器中拉去测试代码分支并运行容器,同时将容器内部的端口号映射到测试服务器的某个随机端口号上面
  • 更新测试服务器上的nginx配置,将该服务host对应的请求代理到该端口号,这样当访问这台测试服务器的时候,可以将请求转发到容器中
  • 将本地服务的host修改为测试服务器的ip,由于业务涉及域名可能比较多,可以在部署测试环境后自动输出相关host配置
  • 如果需要切换为其他测试环境,就将host修改为对应测试服务器的ip即可
  • 单台测试服务器只能部署单个测试环境,这个就有点奢侈了;貌似可以通过虚拟ip等技术实现单台服务器实现绑定多个ip,这个暂时没有深入研究~

发现目前社区貌似并没有类似的集成测试环境,最近有时间打算折腾一下,由于我的docker水平还停留在基础使用阶段,需要花点时间学习一下。参考

待我学成之日回来补充这个章节~哈哈

5. Walle项目部署

将代码部署到生产机器上还是比较简单的,大体流程是

  • 提交部署任务,合并代码到master
  • 在服务器上拉取master代码,执行build任务
  • 某些时候还需要重启服务等

除了最基本的合并代码打包之外,项目部署一般的需求包括

  • 自定义部署脚本
  • 灰度发布
  • 部署任务回滚
  • 热更新,部署时不影响正在使用的线上用户
    • 可以从技术层面实现
    • 使用负载均衡,将流量从正在部署的机器断开,然后依次部署机器,在短时间内可能导致某些机器的流量较大

一般来说部署系统还会接入上线工单申请、封板等逻辑,开源的部署系统比如Walle是一个不错的选择,

参考:使用docker安装Walle

目前还有一个比较流行的概念:持续集成,为了提高软件开发效率,往往希望测试和构建部署自动化,常用的工具有比如travis CI,其大致原理是使用github、gitlab等提供的web hooks推送提交消息,然后触发任务执行对应的构建脚本。

6. 内部账号权限

前面主要整理了一些常见的内部系统

  • 使用redmine管理项目流程
  • 使用gitlab托管项目代码
  • 在开发阶段使用mock数据服务器、日志系统和监控系统等
  • 两种不同访问方式的测试环境,以及如何构建了一个基本的提测系统
  • 使用Walle将代码部署到master上面

从业务上来看,每个系统实际上是比较独立的;但实际上存在很多需要互相协作的地方

  • 项目管理、日志系统、监控系统等基本上所有系统都需要进行账号权限分组
  • 提测系统和发布部署系统需要gitlab权限拉取代码

实现单个业务的账号管理系统并不困难,但是在多个不同的系统之间实现统一的权限校验就需要好好思考一下了。

多个系统之间的通用权限认证,可以自己实现一套用户权限管理体系,然后各个系统各自接入这一套用户权限管理体系;也可以直接使用LDAP这种使用比较广泛的认证协议

LDAP是开放的Internet标准,支持跨平台的Internet协议,在业界中得到广泛认可的,并且市场上或者开源社区上的大多产品都加入了对LDAP的支持,因此对于这类系统,不需单独定制,只需要通过LDAP做简单的配置就可以与服务器做认证交互。“简单粗暴”,可以大大降低重复开发和对接的成本。

参考

此外还有一些更严格的内部系统安全策略,比如在非内网网络环境下访问服务时需要连接VPN或跳板机等措施。

7. 小结

可见要搭建一套比较规范的开发体系,其工作量还是比较大的。回想到刚开始转行从外包开始,经历了

  • 刀耕火种阶段,直接在ftp服务器上改源码
  • github加密仓库托管代码,通过bash脚本推送文件改动到服务器
  • gitlab私有仓库、提测环境、发布系统等各种比较规范的开发流程

所以这篇文章可以算作是对过往开发流程的一个小结吧~接下来就是去试试实现一个完整的提测平台啦

一些提高代码健壮性的方法使用Electron实现一个iPic