一、软件开发生命周期
软件开发生命周期又叫做SDLC(Software Development Life Cycle),它是集合了计划、开发、测试 和部署过程的集合 。
- 需求分析:根据项目需求,团队执行一个可行性计划的分析。项目需求可能是公司内部或者客户提出的。这阶段主要是对信息的收集,也有可能是对现有项目的改善和重新做一个新的项目。还要分析项目的预算多长,可以从哪方面受益及布局,这也是项目创建的目标。
- 设计:系统架构和满意状态(就是要做成什么样子,有什么功能)和创建一个项目计划。计划可以使用图表,布局设计挥着文字方式呈现。
- 实现:项目经理创建和分配工作给开者,开发者根据任务和在设计阶段定义的目标进行开发代码。依据项目的大小和复杂程度,可以需要数月或更长时间才能完成。
- 测试:测试人员进行代码测试 ,包括功能测试、代码测试、压力测试等。
- 进化:最后进阶段就是对产品不断的进化改进和维护阶段,根据用户的使用情况,可能需要对某功能进行修改,bug修复,功能增加等
二、开发模式
1.敏捷开发 (Agile Development)
核心是迭代开发与增量开发
2.迭代开发 (Iterative Development)
对于大型软件项目,传统的开发方式是采用一个大周期(比如一年)进行开发,整个过程就是一次"大 开发";迭代开发的方式则不一样,它将开发过程拆分成多个小周期,即一次"大开发"变成多次"小开 发",每次小开发都是同样的流程,所以看上去就好像重复在做同样的步骤。
3.增量开发 (Incremental Development)
软件的每个版本,都会新增一个用户可以感知的完整功能。也就是说,按照新增功能来划分迭代。
三、持续集成(CI)持续交付(CD)持续部署(CD)
1.持续集成( Continuous integration )
持续集成是软件开发周期的一种实践,把代码仓库(Gitlab或者Github)、构建工具(如Jenkins)和测试工具(SonarQube)集成在一起,频繁的将代码合并到主干然后自动进行构建和测试。持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。通过持续集成,团队可以快速的从一个功能到另一个功能。在持续集成的过程当中主要包括以下步骤:提交、测试、构建(容器需要构建, 编译型语言编译)、部署及回滚。
1)持续集成要素
- 一个自动构建过程,从检出代码、编译构建、运行测试、结果记录、测试统计等都是自动完成的,无需人工干预 。
- 一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库,一般使用SVN或Git。
- 一个持续集成服务器, Jenkins 就是一个配置简单和使用方便的持续集成服务。
2)持续集成的好处
- 降低风险,由于持续集成不断去构建,编译和测试,可以很早期发现问题,所以修复的代价就少
- 对系统健康持续检查,减少发布风险带来的问题
- 减少重复性工作
- 持续部署,提供可部署单元包
- 持续交付可供使用的版本
- 增强团队信心
2.持续交付( Continuous Delivery )
持续交付,简称CD,是在CI的基础进行了扩展,在CI环节完成了软件构建和测试工作并形成了新的版本,那么接下来就要进行交付,而这里的交付并不是交付到生产环境,而是类生产环境(STAGING),我们可以理解为灰度环境或者预发环境,进而接受部分真实流量的测试。如果没有问题的话则通过手动的方式部署到生产环境。
3.持续部署( Continuous Deployment )
持续部署,简称CD,它是在持续交付的基础上打通最后一公里的工作,就是把手动部署到生产环境的方式升级为自动部署。看下图和上图在最后部署到生产环境中的区别。
四、部署代码到服务器的方式
- 第一种方式:将代码上传到服务器,然后解压
- 第二种方式:将代码上传到服务器中,然后通过软连接的方式部署
以上两种方式都无法实现批量部署,无法实现批量回滚,更无法实现批量测试。
-
实现自动集成(java、golang)、自动部署、自动测试: DevOps
-
实现自动集成、自动部署:Jenkins
-
代码类型:
编译型语言:需要编译,后运行
脚本型语言:直接运行
-
工具种类:
代码管理工具:gitlab、github、gitee 都是基于git的
五、代码管理工具Git
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而是一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必有服务器端软件支持。
1.安装Git
#1.安装git
[root@docker ~]# yum install git -y
[root@docker ~]# git --version #查看版本
git version 1.8.3.1
2.仓库
仓库对应的就是一个目录,这个目录中的所有文件被git管理起来。以后会将一个项目的根目录,作为仓库。仓库中的每个文件的改动 都由git跟踪。
#1.新建一个data仓库
[root@docker ~]# mkdir data
[root@docker ~]# cd data/
#2.初始化代码仓库
[root@docker data]# git init
初始化空的 Git 版本库于 /root/data/.git/
[root@docker data]# ll -a
总用量 0
drwxr-xr-x 3 root root 18 3月 24 06:02 .
dr-xr-x---. 6 root root 222 3月 24 06:02 ..
drwxr-xr-x 7 root root 119 3月 24 06:02 .git
[root@docker data]# cd .git/ #这里存放的都是git的配置文件
[root@docker .git]# ll
总用量 12
drwxr-xr-x 2 root root 6 3月 24 06:02 branches
-rw-r--r-- 1 root root 92 3月 24 06:02 config
-rw-r--r-- 1 root root 73 3月 24 06:02 description
-rw-r--r-- 1 root root 23 3月 24 06:02 HEAD
drwxr-xr-x 2 root root 242 3月 24 06:02 hooks
drwxr-xr-x 2 root root 21 3月 24 06:02 info
drwxr-xr-x 4 root root 30 3月 24 06:02 objects
drwxr-xr-x 4 root root 31 3月 24 06:02 refs
3.远程仓库
# github gitee gitlab
#1.下载远程仓库
[root@docker ~]# git clone https://gitee.com/elaina-fang/data.git
正克隆到 'data'...
Username for 'https://gitee.com': 13612090654
Password for 'https://13612090654@gitee.com':
warning: 您似乎克隆了一个空版本库。
#2.设置用户名和邮箱
[root@docker data]# git config --global user.name "elaina_fang"
[root@docker data]# git config --global user.email "1353421063@qq.com"
#3.查看信息
[root@docker data]# git config --get user.name
elaina_fang
[root@docker data]# git config --get user.email
1353421063@qq.com
4.提交代码
#1.-创建源代码文件
[root@docker data]# touch index.html
[root@docker data]# ll
总用量 0
-rw-r--r-- 1 root root 0 3月 24 06:09 index.html
[root@docker data]# git status #查看状态
# 位于分支 master
#
# 初始提交
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# index.html
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
#注:此时的源代码还没有交给git管理,如果删除源代码文件,git不会有报错信息,代码会被彻底删除
#2.将代码提交到git暂存区
[root@docker data]# git add index.html
[root@docker data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: index.html
#注:此时源代码文件已经提交到git,如果此时删除源代码,文件不会被彻底删除,git查看会有报错信息,还可以使用git移回文件
#3.将代码提交到git缓冲区
[root@docker data]# git commit -m 'init' . #-m参数是添加注释
[master(根提交) 425fb32] init
1 file changed, 1 insertion(+)
create mode 100644 index.html
#注:添加到暂存区代码是可以修改的,修改后可以将修改的内容重新添加后暂存区。从暂存区添加到缓存区内容是不可以修改的。
#4.查看修改内容(+代表添加,-代表删除)
[root@docker data]# git diff index.html
diff --git a/index.html b/index.html
index 07465ad..b287882 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,5 @@
fhjvhjnklljjn
+huhkm;
+jhhjk
+hhuih
+
[root@docker data]# vim index.html
[root@docker data]# git add index.html
[root@docker data]# git status #修改后再查看会显示修改字样
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 修改: index.html
4.回滚
#1.查看提交代码历史记录
[root@docker data]# git log
commit 6d1fa6fa1f3b90655f6170a4afde0e22f72d8fc7
Author: elaina_fang <1353421063@qq.com>
Date: Wed Mar 24 08:16:49 2021 +0800
init
commit 425fb32d50f71f8f4a78e7037f58ff8869b40f7c
Author: elaina_fang <1353421063@qq.com>
Date: Wed Mar 24 08:02:01 2021 +0800
init
#2.回滚
[root@docker data]# git reset --hard 425fb32d50f71f8f4a78e7037f58ff8869b40f7c
HEAD 现在位于 425fb32 init
5.将本地代码提交到远程仓库
#1.下载远程仓库
[root@docker ~]# git clone https://gitee.com/elaina-fang/data.git
正克隆到 'data'...
Username for 'https://gitee.com': 13612090654
Password for 'https://13612090654@gitee.com':
warning: 您似乎克隆了一个空版本库。
#2.设置用户名和邮箱
[root@docker data]# git config --global user.name "elaina_fang"
[root@docker data]# git config --global user.email "1353421063@qq.com"
#3.查看信息
[root@docker data]# git config --get user.name
elaina_fang
[root@docker data]# git config --get user.email
1353421063@qq.com
#4.将本地代码提交到远程仓库
[root@docker data]# git push -u origin master
Username for 'https://gitee.com': 13612090654
Password for 'https://13612090654@gitee.com':
Counting objects: 3, done.
Writing objects: 100% (3/3), 220 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
To https://gitee.com/elaina-fang/data.git
* [new branch] master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。
#5.使用SSH将我们的代码提交到远程仓库
[root@docker data]# vim .git/config #修改配置文件
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@gitee.com:elaina-fang/data.git #将http修改成ssh方式
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[root@docker data]# ssh-keygen -t rsa #生成密钥
[root@docker data]# cat /root/.ssh/id_rsa.pub #查看公钥,复制公钥到gitee上添加公钥(如下图)
[root@docker data]# git push -u origin master #免密提交
The authenticity of host 'gitee.com (212.64.62.183)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.
ECDSA key fingerprint is MD5:27:e5:d3:f7:2a:9e:eb:6c:93:cd:1f:c1:47:a3:54:b1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitee.com,212.64.62.183' (ECDSA) to the list of known hosts.
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 291 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
To git@gitee.com:elaina-fang/data.git
925babb..b2ab42c master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。
6.拉取远程仓库代码
[root@alvin-test-os data]# git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
From gitee.com:chenyang0910/data
dd584e3..78fd071 master -> origin/master
Updating dd584e3..78fd071
Fast-forward
index.html | 6 ++++++
1 file changed, 6 insertions(+)
#git pull 和 git clone 之间有什么不同?
- git pull 是更新代码:在现有的仓库里将远程修改过的代码更新到本地仓库
- git clone 是下载代码:需要创建仓库,本地仓库与远程仓库连接起来
7.分支(不同分支之间是相对隔离的)
#1.查看本地分支
[root@docker data]# git branch
* master #默认的master分支
#2.查看远程分支
[root@docker data]# git branch -a
* master
remotes/origin/master
#3.创建分支
[root@docker data]# git checkout -b test
切换到一个新分支 'test'
[root@docker data]# git branch
master
* test
#4.将本地分支同步到远程分支
[root@docker data]# git branch #前提要保证当前在要同步的分支上
master
* test
[root@docker data]# git push -u origin test
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-5.0]
remote: Create a pull request for 'test' on Gitee by visiting:
remote: https://gitee.com/elaina-fang/data/pull/new/elaina-fang:test...elaina-fang:master
To git@gitee.com:elaina-fang/data.git
* [new branch] test -> test
分支 test 设置为跟踪来自 origin 的远程分支 test。
#5.切换分支
[root@docker data]# git checkout master
切换到分支 'master'
[root@docker data]# git branch
* master
test
8.标签(是一种特殊的分支,只能删除不能修改)
#代码上传之后打上标签
#1.本地创建
git tag -a [tag名称] -m "解释"
[root@docker data]# git tag -a v1-stable -m '第一个标签'
[root@docker data]# git tag
v1-stable
#2.远程仓库创建鼠标点点
#3.拉取指定标签内容
git clone -b [标签名称|分支名称] [仓库地址]
[root@docker data]# git clone -b master git@gitee.com:elaina-fang/data.git
正克隆到 'data'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
接收对象中: 100% (7/7), done.
六、练习
创建本地仓库,关联上远程仓库,并实现脚本通过标签部署discuz
#1.创建本地仓库
[root@devops ~]# mkdir data1
[root@devops ~]# cd data1
[root@devops data1]# git init
初始化空的 Git 版本库于 /root/data1/.git/
#2.将本地仓库关联上远程仓库(前提要有远程仓库)
[root@devops data1]# cat .git/config #未关联远程仓库之前的配置文件
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[root@devops data1]# git remote add origin git@gitee.com:elaina-fang/data.git #关联命令
[root@devops data1]# cat .git/config #关联远程仓库后的配置文件
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@gitee.com:elaina-fang/data.git #远程仓库的地址
fetch = +refs/heads/*:refs/remotes/origin/*
#3.准备discuz包
[root@k8s-master1 ~]# cd data1/
[root@k8s-master1 data1]# rz -E
rz waiting to receive.
[root@k8s-master1 data1]# mkdir discuz
[root@k8s-master1 data1]# mv Discuz_X3.4_SC_UTF8_20210320.zip discuz/
[root@k8s-master1 data1]# cd discuz/
[root@k8s-master1 discuz]# ll
总用量 12172
-rw-r--r-- 1 root root 12330468 4月 7 2021 Discuz_X3.4_SC_UTF8_20210320.zip
-rw-r--r-- 1 root root 17886 3月 20 10:36 LICENSE
-rw-r--r-- 1 root root 31040 1月 19 17:18 qqqun.png
drwxr-xr-x 2 root root 124 3月 22 19:44 readme
-rw-r--r-- 1 root root 71107 1月 19 17:20 readme.html
drwxr-xr-x 13 root root 4096 3月 22 19:44 upload
drwxr-xr-x 4 root root 94 3月 22 19:44 utility
[root@k8s-master1 discuz]# mv upload/* /root/data1/
[root@k8s-master1 discuz]# cd ..
[root@k8s-master1 data1]# ll
总用量 68
-rw-r--r-- 1 root root 2834 3月 22 19:44 admin.php
drwxr-xr-x 9 root root 135 3月 22 19:44 api
-rw-r--r-- 1 root root 727 3月 22 19:44 api.php
drwxr-xr-x 2 root root 23 3月 22 19:44 archiver
drwxr-xr-x 2 root root 90 3月 22 19:44 config
-rw-r--r-- 1 root root 1040 3月 22 19:44 connect.php
-rw-r--r-- 1 root root 106 3月 22 19:44 crossdomain.xml
drwxr-xr-x 12 root root 178 3月 22 19:44 data
drwxr-xr-x 5 root root 140 4月 6 06:39 discuz
-rw-r--r-- 1 root root 5558 3月 20 10:36 favicon.ico
-rw-r--r-- 1 root root 2245 3月 22 19:44 forum.php
-rw-r--r-- 1 root root 821 3月 22 19:44 group.php
-rw-r--r-- 1 root root 1280 3月 22 19:44 home.php
-rw-r--r-- 1 root root 6472 3月 22 19:44 index.php
drwxr-xr-x 5 root root 64 3月 22 19:44 install
drwxr-xr-x 2 root root 23 3月 22 19:44 m
-rw-r--r-- 1 root root 1025 3月 22 19:44 member.php
-rw-r--r-- 1 root root 2371 3月 22 19:44 misc.php
-rw-r--r-- 1 root root 1788 3月 22 19:44 plugin.php
-rw-r--r-- 1 root root 977 3月 22 19:44 portal.php
-rw-r--r-- 1 root root 582 3月 22 19:44 robots.txt
-rw-r--r-- 1 root root 1155 3月 22 19:44 search.php
drwxr-xr-x 10 root root 168 3月 22 19:44 source
drwxr-xr-x 7 root root 86 3月 22 19:44 static
drwxr-xr-x 3 root root 38 3月 22 19:44 template
drwxr-xr-x 7 root root 106 3月 22 19:44 uc_client
drwxr-xr-x 13 root root 241 3月 22 19:44 uc_server
[root@k8s-master1 data1]# rm -rf discuz/
#4.将diacuz所有文件添加到远程仓库
[root@k8s-master1 data1]# git add . #代表当前目录下的所有文件提交到暂存区
[root@k8s-master1 data1]# git config --global user.name "13612090654"
[root@k8s-master1 data1]# git config --global user.email "1353421063@qq.com"
[root@k8s-master1 data1]# git commit -m 'init' .
#5.将公钥添加到gitee
[root@k8s-master1 data1]# cat ~/.ssh/id_rsa.pub
复制粘贴公钥内容到gitee设置内添加
#6.推送到远程仓库
[root@k8s-master1 data1]# git push -u origin master
Counting objects: 3799, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3770/3770), done.
Writing objects: 100% (3798/3798), 10.50 MiB | 9.71 MiB/s, done.
Total 3798 (delta 502), reused 0 (delta 0)
remote: Resolving deltas: 100% (502/502), done.
remote: Powered by GITEE.COM [GNK-5.0]
To git@gitee.com:elaina-fang/data.git
b2ab42c..109193b master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。
#7.代码推送成功后可以在gitee上创建一个标签,代码就无法修改了
#8.编写部署脚本
[root@k8s-master1 mnt]# mkdir -pv /usr/share/nginx/html
mkdir: 已创建目录 "/usr/share/nginx"
mkdir: 已创建目录 "/usr/share/nginx/html"
[root@k8s-master1 mnt]# vim discux.sh
#/bin/bash
REPOASITORY=discuz-`date+%F_%H:%M:%S`
REPOASITORY_URL="git@gitee.com:elaina-fang/data.git"
REPOASITORY_TAG=$1
CURRENT_DIR=pwd #当前路径
git clone -b ${REPOASITORY_TAG} ${REPOASITORY_URL} ${REPOASITORY}
rm -rf /usr/share/nginx/html
ln -s ${CURRENT_DIR}/${REPOASITORY} /usr/share/nginx/html
#9.执行脚本
[root@k8s-master1 mnt]# sh discux.sh v1-stable
正克隆到 'discuz-2021-04-06_07:48:44'...
remote: Enumerating objects: 3807, done.
remote: Counting objects: 100% (3807/3807), done.
remote: Compressing objects: 100% (3274/3274), done.
remote: Total 3807 (delta 502), reused 3798 (delta 502), pack-reused 0
接收对象中: 100% (3807/3807), 10.50 MiB | 8.63 MiB/s, done.
处理 delta 中: 100% (502/502), done.
Note: checking out '3df4a4203e5f610d156bb9a5fc55e602e45da5df'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
#10.查看是否挂载成功
[root@k8s-master1 mnt]# ll /usr/share/nginx/
总用量 0
lrwxrwxrwx 1 root root 30 4月 6 07:48 html -> pwd/discuz-2021-04-06_07:48:44