代码上线

pipeline流水线方式

1.创建流水线项目

2.介绍pipeline如何使用

示例1
pipeline{
    agent any    #机器,这里表示所有机器
    stages{       #区块
        stage("get code"){   #小区块,第一步干什么
           steps{
               echo "steps具体执行的命令是什么"
           }
        }
        stage("package"){   #小区块,第二步干什么
            steps{
               echo "steps具体执行的命令是什么"
            }
        }
        stage("deploy"){   #小区块,第三步干什么
            steps{
               echo "steps具体执行的命令是什么"
            }
        }
    }
}

3.在gtilab的game项目中创建Jenkinsfile文件

image-20250222224044695
image-20250222224138253

stage(“get code”)第一步,已经页面配置自己拉取代码了,所以这里直接写了个echo

stage(“unit test”)第二步,推送到sonarqube上质量检测

stage(“package”) 第三步,打包代码${BUILD_ID}变量表示构建号,就是构建了几次的号码

stage(“deploy”)第四部,部署底阿妈

pipeline {
    agent any
    stages {
        stage("get code") {
            steps {
                echo "get code"
            }
        }
        stage("unit test") {
            steps {
                sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=html -Dsonar.projectName=${JOB_NAME} -Dsonar.sources=.'
            }
        }
        stage("package") {
            steps {
                sh 'tar zcf /opt/web-${BUILD_ID}.tar.gz ./*'
            }
        }
        stage("deploy") {
            steps {
                sh 'ssh 10.0.0.7 "cd /code/ && mkdir web-${BUILD_ID}"'
                sh 'scp /opt/web-${BUILD_ID}.tar.gz 10.0.0.7:/code/web-${BUILD_ID}'
                sh 'ssh 10.0.0.7 "cd /code/web-${BUILD_ID} && tar xvf web-${BUILD_ID}.tar.gz && rm -rf web-${BUILD_ID}.tar.gz"'
                sh 'ssh 10.0.0.7 "cd /code && rm -rf game && ln -s web-${BUILD_ID} /code/game"'
            }
        }
    }
}
image-20250222230258937

java项目发布,maven编译

1.maven介绍

  • 用来编译java代码的,不编译无法运行
  • Maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。
  • 开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期。
  • Apache的开源项目主要服务于JAVA平台的构建、依赖管理、项目管理。
  • Project Object Model,项目对象模型。通过xml格式保存的pom.xml文件。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。该文件是由开发维护,我们运维人员可以不用去关心。

2. 安装 maven

  1. 下载 maven3 安装包
  • 官方:http://maven.apache.org/download.cgi
  • 清华:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/
  1. 解压即用
[root@jenkins ~]# tar xf apache-maven-3.3.9-bin.tar.gz -C /usr/local/
[root@jenkins ~]# ln -s /usr/local/apache-maven-3.3.9/ /usr/local/maven
  1. 添加命令变量
  • $PATH是之前的所有变量,组合起来
[root@jenkins ~]# echo export PATH="/usr/local/maven/bin/:$PATH"  >> /etc/profile
[root@jenkins ~]# source /etc/profile
  1. 测试
  • 有这个命令,能输出版本号就正常变量配置正常,这个命令可以用
[root@jenkins ~]# mvn -v

3. 使用 maven

  1. 上传一个 java 项目
  • pom.xml当前代码配置文件局部生效,maven 有一个配置文件全局生效
[root@jenkins ~]# tree hello-world-war/
hello-world-war/
├── dist
│   └── hello-world.war
├── pom.xml                
├── README.md
└── src
    └── main
        └── webapp
            ├── index.jsp
            └── WEB-INF
                └── web.xml
  1. maven 如何使用
  • 进入目录执行打包命令
    • validate(验证):验证项目正确,并且所有必要信息可用。
    • compile(编译):编译项目源码
    • test(测试):使用合适的单元测试框架测试编译后的源码。
    • package(打包):源码编译之后,使用合适的格式(例如 JAR 格式)对编译后的源码进行打包。
    • integration-test(集成测试):如果有需要,把包处理并部署到可以运行集成测试的环境中去。
    • verify(验证):进行各种测试来验证包是否有效并且符合质量标准。
    • install(安装):把包安装到本地仓库,使该包可以作为其他本地项目的依赖。
    • deploy(部署):在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。
    • mvn clean (清除) :清除上次编译的结果
    • mvn package -Dmaven.test.skip=true 跳过测试用例
  1. 进入代码目录并使用mvn package编译
  • 编译时默认去官网下载依赖编译
[root@jenkins ~]# cd /root/hello-world-war/
[root@jenkins ~/hello-world-war]# mvn package
  1. 部署 war 包到 tomcat
  • 编译成功之后会生成一个target目录,war 包在里面
[root@web01 /usr/local/tomcat/webapps/ROOT]# pwd
/usr/local/tomcat/webapps/ROOT
[root@web01 /usr/local/tomcat/webapps/ROOT]# rm -rf *   #删除原来的项目,准备好war包放到这个目录,自动解压。或者unzip手动解压
[root@web01 /usr/local/tomcat/webapps/ROOT]# unzip hello-world-war-1.0.0.war
[root@web01 /usr/local/tomcat/webapps/ROOT]# ls 
index.jsp  META-INF  WEB-INF
  1. 测试
  • 或者浏览器页面访问查看
[root@web01 ~]# curl 10.0.0.7:8080
<html>
<head>
<title>Hello World!</title>
</head>
<body>
    <h1>Hello World! v1.0</h1>
    <p>
        It is now
        Sun Feb 23 15:59:31 CST 2025</p>
    <p>
        You are coming from 
        10.0.0.7</p>
</body>
[root@web01 ~]# 

1.清除上一次的编译

[root@jenkins ~/hello-world-war]# ll
drwxr-xr-x 2 root root  29 May 23  2014 dist
-rw-r--r-- 1 root root 931 May 14  2024 pom.xml
-rw-r--r-- 1 root root 213 May 23  2014 README.md
drwxr-xr-x 3 root root  18 May 23  2014 src
drwxr-xr-x 4 root root  90 Feb 23 15:46 target     #使用clean清除,target就清除了
[root@jenkins ~/hello-world-war]# mvn clean 
[root@jenkins ~/hello-world-war]# ll
drwxr-xr-x 2 root root  29 May 23  2014 dist
-rw-r--r-- 1 root root 931 May 14  2024 pom.xml
-rw-r--r-- 1 root root 213 May 23  2014 README.md
drwxr-xr-x 3 root root  18 May 23  2014 src

4.jar包如何运行

java -jar xxxx.jar 参数1  参数2....

5. 将默认的 maven 仓库源修改为国内的

  1. 修改配置文件
  • 使用 vim 编辑 /usr/local/maven/conf/settings.xml 文件,在 <mirrors> 标签里,大概 158 行下面插入以下内容:
</mirror>
     -->
    <mirror>
            <id>nexus-aliyun</id>
            <mirrorOf>*</mirrorOf>
            <name>Nexus aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
</mirrors>
  1. 重新编译并验证
  • 重新编译项目,查看仓库是否为阿里云的:
[root@jenkins ~]# cd /root/hello-world-war/
[root@jenkins ~/hello-world-war]# mvn package
  1. 注意事项
  • 如果公司部分 Java 代码不需要配置 Nexus 私服,只需要将 Maven 配置文件仓库指向阿里云仓库。
  • 如果公司是大型 Java 项目,则需要搭建私有的仓库 Nexus。

6.将maven集成到jenkins

1.新建一个gitlab项目,并推送代码

image-20250223162613962
[root@jenkins ~/hello-world-war]# ll -a    #发现已经有.git了origin,需要删除从新配置成我们的
drwxr-xr-x  5 root root   91 Feb 23 16:26 .
dr-xr-x--- 13 root root 4096 Feb 23 16:16 ..
drwxr-xr-x  2 root root   29 May 23  2014 dist
drwxr-xr-x  8 root root  166 Oct 15  2019 .git
-rw-r--r--  1 root root   42 May 23  2014 .gitignore
-rw-r--r--  1 root root  931 May 14  2024 pom.xml
-rw-r--r--  1 root root  213 May 23  2014 README.md
drwxr-xr-x  3 root root   18 May 23  2014 src
[root@jenkins ~/hello-world-war]# git remote 
origin
[root@jenkins ~/hello-world-war]# git remote remove origin 
[root@jenkins ~/hello-world-war]# git remote add origin git@10.0.0.201:hsc/java.git
[root@jenkins ~/hello-world-war]# 
[root@jenkins ~/hello-world-war]# git config --global user.name  "haoshuaicong"
[root@jenkins ~/hello-world-war]# git config --global user.email  "haoshuaicong@mail.com" 
[root@jenkins ~/hello-world-war]# git config --global color.ui  true
[root@jenkins ~/hello-world-war]# git config --list
[root@jenkins ~/hello-world-war]# git add .
[root@jenkins ~/hello-world-war]# git commit -m "java-job v1.0" 
[root@jenkins ~/hello-world-war]# git push -u origin master

2.配置jenkins

image-20250223162349903
image-20250223163550185
image-20250223164045946
image-20250223164328600
image-20250223170209092

7.nexus私服配置

1. 下载 nexus 包

官网:https://www.sonatype.com/download-oss-sonatype

2. 安装 jdk

[root@nexus ~]# rpm -ivh jdk-8u181-linux-x64.rpm

3. 安装 nexus

[root@nexus ~]# tar xf nexus-3.13.0-01-unix.tar.gz -C /usr/local/
[root@nexus ~]# ln -s /usr/local/nexus-3.13.0-01/ /usr/local/nexus

4. 启动 nexus

[root@nexus ~]# /usr/local/nexus/bin/nexus start

5. 浏览器访问

  • 地址:10.0.0.204:8081
  • 账号:admin
  • 密码:admin123

6. 在 maven上配置nexus

  • 配置步骤
[root@jenkins /usr/local/maven/conf]# pwd
/usr/local/maven/conf
[root@jenkins /usr/local/maven/conf]# mv settings.xml settings.xml.bak
[root@jenkins /usr/local/maven/conf]# cp settings.xml.bak settings.xml
[root@jenkins /usr/local/maven/conf]# vim settings.xml

Nexus 安装成功后,接下来需要修改 Maven 的配置文件(settings.xml),整合 Nexus。

1.找到<servers>标签,添加 Nexus 默认认证信息
<server>   
    <id>my-nexus-releases</id>   
    <username>admin</username>   
    <password>admin123</password>   
</server>   
<server>   
    <id>my-nexus-snapshot</id>   
    <username>admin</username>   
    <password>admin123</password>   
</server>
2.找到<mirrors>标签,添加镜像
<mirror>
  <!--This sends everything else to /public -->
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://localhost:8081/nexus/content/groups/public/</url>
</mirror>
3.找到<profiles>标签,添加仓库信息
image-20250223173955582
<profile>
  <id>nexus</id>
  <!--Enable snapshots for the built in central repo to direct -->
  <!--all requests to nexus via the mirror -->
  <repositories>
    <repository>
      <id>central</id>
      <url>http://central</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
 <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <url>http://central</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</profile>
4.激活仓库
<activeProfiles>
  <!--make the profile active all the time -->
  <activeProfile>nexus</activeProfile>
</activeProfiles>

配置完成后保存,并重启 nexus 服务。

重启 nexus 服务完成后,在命令行窗口进入一个使用 Maven 构建的项目,输入mvn package clean命令。查看家目录下.m2文件有一些jar包就是依赖

5.如果编译不过去

可能是不同项目依赖冲突,删除家目录的依赖包重新编译即可

[root@jenkins ~/.m2/repository]# pwd 
/root/.m2/repository
[root@jenkins ~/.m2/repository]# rm -rf *
6.以下是改好的配置文件
image-20250223173955582
[root@jenkins /usr/local/maven/conf]# cat settings.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!--
 | This is the configuration file for Maven. It can be specified at two levels:
 |
 |  1. User Level. This settings.xml file provides configuration for a single user,
 |                 and is normally provided in ${user.home}/.m2/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -s /path/to/user/settings.xml
 |
 |  2. Global Level. This settings.xml file provides configuration for all Maven
 |                 users on a machine (assuming they're all using the same Maven
 |                 installation). It's normally provided in
 |                 ${maven.home}/conf/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -gs /path/to/global/settings.xml
 |
 | The sections in this sample file are intended to give you a running start at
 | getting the most out of your Maven installation. Where appropriate, the default
 | values (values used when the setting is not specified) are provided.
 |
 |-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->

  <!-- interactiveMode
   | This will determine whether maven prompts you when it needs input. If set to false,
   | maven will use a sensible default value, perhaps based on some other setting, for
   | the parameter in question.
   |
   | Default: true
  <interactiveMode>true</interactiveMode>
  -->

  <!-- offline
   | Determines whether maven should attempt to connect to the network when executing a build.
   | This will have an effect on artifact downloads, artifact deployment, and others.
   |
   | Default: false
  <offline>false</offline>
  -->

  <!-- pluginGroups
   | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
   | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
   | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
   |-->
  <pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
  </pluginGroups>

  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
  </proxies>

  <!-- servers
   | This is a list of authentication profiles, keyed by the server-id used within the system.
   | Authentication profiles can be used whenever maven must make a connection to a remote server.
   |-->
  <servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     |
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->

    <!-- Another sample, using keys to authenticate.
    <server>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    -->
     <server>   
     <id>my-nexus-releases</id>   
     <username>admin</username>   
     <password>admin123</password>   
     </server>   
     <server>   
     <id>my-nexus-snapshot</id>   
     <username>admin</username>   
     <password>admin123</password>   
     </server>
  </servers>

  <!-- mirrors
   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
   |
   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
   | However, this repository may have problems with heavy traffic at times, so people have mirrored
   | it to several places.
   |
   | That repository definition will have a unique id, so we can create a mirror reference for that
   | repository, to be used as an alternate download site. The mirror site will be the preferred
   | server for that repository.
   |-->
  <mirrors>
  <mirror>
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://10.0.0.204:8081/repository/maven-public/</url>
</mirror>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
  </mirrors>

  <!-- profiles
   | This is a list of profiles which can be activated in a variety of ways, and which can modify
   | the build process. Profiles provided in the settings.xml are intended to provide local machine-
   | specific paths and repository locations which allow the build to work in the local environment.
   |
   | For example, if you have an integration testing plugin - like cactus - that needs to know where
   | your Tomcat instance is installed, you can provide a variable here such that the variable is
   | dereferenced during the build process to configure the cactus plugin.
   |
   | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
   | section of this document (settings.xml) - will be discussed later. Another way essentially
   | relies on the detection of a system property, either matching a particular value for the property,
   | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
   | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
   | Finally, the list of active profiles can be specified directly from the command line.
   |
   | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
   |       repositories, plugin repositories, and free-form properties to be used as configuration
   |       variables for plugins in the POM.
   |
   |-->
  <profiles>
    <!-- profile
     | Specifies a set of introductions to the build process, to be activated using one or more of the
     | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
     | or the command line, profiles have to have an ID that is unique.
     |
     | An encouraged best practice for profile identification is to use a consistent naming convention
     | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
     | This will make it more intuitive to understand what the set of introduced profiles is attempting
     | to accomplish, particularly when you only have a list of profile id's for debug.
     |
     | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
    <profile>
      <id>jdk-1.4</id>

      <activation>
        <jdk>1.4</jdk>
      </activation>

      <repositories>
        <repository>
          <id>jdk14</id>
          <name>Repository for JDK 1.4 builds</name>
          <url>http://www.myhost.com/maven/jdk14</url>
          <layout>default</layout>
          <snapshotPolicy>always</snapshotPolicy>
        </repository>
      </repositories>
    </profile>
    -->

    <!--
     | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
     | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
     | might hypothetically look like:
     |
     | ...
     | <plugin>
     |   <groupId>org.myco.myplugins</groupId>
     |   <artifactId>myplugin</artifactId>
     |
     |   <configuration>
     |     <tomcatLocation>${tomcatPath}</tomcatLocation>
     |   </configuration>
     | </plugin>
     | ...
     |
     | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
     |       anything, you could just leave off the <value/> inside the activation-property.
     |
    <profile>
      <id>env-dev</id>

      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>

      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
    -->
<profile>
  <id>nexus</id>
  <repositories>
    <repository>
      <id>central</id>
      <url>http://10.0.0.204:8081/repository/maven-public/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
 <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <url>http://10.0.0.204:8081/repository/maven-public/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</profile>
  </profiles>

  <!-- activeProfiles
   | List of profiles that are active for all builds.
   |
  <activeProfiles>
    <activeProfile>alwaysActiveProfile</activeProfile>
    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
  </activeProfiles>
  -->
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>

7.配置nexus中央仓库为阿里云

maven编译–>依赖找nexus,nexus没有–>找中央仓库

image-20250223174704293

8.编译测试查看是不是自己仓库

[root@jenkins ~/hello-world-war]# mvn clean && mvn package

配置jenkins的分布式

1.分布式jenkins介绍

如果项目需要定期集成,同时每次集成都需要较长时间。如果都运行在master服务器上,会消耗过多资源,导致其他项目搁置无法集成,这时就需要在建立多台设备,并配置作为slave机器来为master提供负载服务。

2. 部署分布式服务器,准备

1. 配置 slave 端服务器

  • 找一台或者目前已有的服务器配置为 slave 端(当前使用 lb02),将该服务器作为 slave 测试。
  • 在 lb02 上安装 Java JDK、Git 和 Sonar 客户端(如已安装则跳过)。
[root@lb02:~]# rpm -ivh jdk-17_linux-x64_bin.rpm

2. Jenkins 服务器操作

  • 注意带版本号做软链接。
[root@jenkins:~]# ssh-copy-id 10.0.0.6
[root@jenkins:~]# scp -r /usr/local/sonar-scanner 10.0.0.6:/usr/local/
[root@jenkins:~]# scp -r /usr/local/maven/ 10.0.0.6:/usr/local/

3. 拷贝 shell 脚本到 lb02

[root@lb02:~]# mkdir /server/scripts -p
[root@jenkins:~]# scp /server/scripts/* 10.0.0.6:/server/scripts/

4. Jenkins 服务端添加从节点 lb02

  • 注意:把 lb02 的公钥上传至 GitLab,使其拥有下载代码的权限。
  • 操作步骤:点击系统管理 -> 节点管理 -> 新建节点。
[root@lb02:~]# ssh-keygen
[root@lb02:~]# cat .ssh/id_rsa.pub
image-20250223190013922

5.node从节点跟web服务器免密

[root@lb02:~]#ssh-copy-id 10.0.0.8

3.配置 jenkins添加从节点lb02

image-20250223190203239
image-20250223190300821
image-20250223190520070
image-20250223191257113
image-20250223191436904
image-20250223191518448
image-20250223191701432
image-20250223192126968
image-20250223192349166
image-20250223192508834

代码发布方式

01.直接发布

直接发布是最简单的方式,它指的是直接将代码部署到生产环境。这种方式适用于小型项目或紧急修复场景。以下是直接发布的一些特点:

特点

  • 快速部署 :代码修改完成后,立即部署到生产环境,无需复杂的流程,减少了上线时间。
  • 简单易行 :没有复杂的发布步骤,只需简单的操作即可完成部署,适合对发布流程要求不高的场景。
  • 用户体验影响 :如果直接发布存在bug或问题,将直接影响所有用户,用户体验受到较大影响。例如,在一个电商网站中,直接发布一个新的支付模块,如果存在漏洞,可能导致用户无法正常支付,从而影响整个购物体验。
  • 回滚困难 :一旦出现问题,回滚到之前的版本可能需要耗费较多时间和精力。因为直接发布的代码已经覆盖了旧版本的文件,如果无法快速定位问题或者没有完善的备份机制,回滚可能会出现困难,进一步加剧了问题的复杂性。

适用场景

  • 开发和测试环境 :在开发和测试阶段,直接发布可以快速验证代码的正确性和功能完整性。例如,开发人员在本地对代码进行修改后,直接发布到测试环境,测试人员可以立即对新功能进行测试,发现并反馈问题,加快了开发和测试的进度。
  • 对用户影响较小的系统 :如果系统对用户的实时性要求不高,或者用户群体较小,直接发布的影响范围相对可控。例如,一个内部使用的员工管理系统,其功能升级或修复对日常业务的影响较小,可以通过直接发布来快速更新系统,提高工作效率。
  • 初创型公司 :初创型公司通常面临资源有限和市场竞争激烈的情况,快速推出产品和功能对于吸引用户和抢占市场份额至关重要。直接发布方式可以帮助他们以最快的速度将产品推向市场,及时获取用户反馈,并根据反馈进行快速迭代和优化,从而不断提升产品的竞争力。
  • 流量较低的业务 :如果业务的流量较低,在流量低谷期进行直接发布,即使出现问题,对用户的影响也相对有限。例如,一个小型的博客网站,平时的访问量较低,在夜间进行直接发布新文章页面的更新,对用户的访问体验影响较小,同时也便于开发人员在低峰期观察系统的运行情况,及时发现和解决问题。

02.金丝雀发布

金丝雀发布是一种渐进式的发布方式。它通过先将新版本部署到一小部分服务器上,观察其运行情况,再逐步扩大部署范围,以降低风险。以下是金丝雀发布的一些特点:

特点

  • 降低风险 :通过小范围的部署,只有部分用户会受到新版本的影响。例如,在一个视频网站中,对部分用户发布的新的推荐算法,如果出现问题,可以通过监控数据及时发现问题,比如用户点击率下降或页面加载时间变长,然后迅速进行调整或回滚,避免对所有用户造成不良影响,保证大部分用户的正常使用。
  • 可观察性 :可以观察新版本在小范围内的运行指标,如响应时间、错误率等。比如,在一个电商网站中,金丝雀发布新版本的登录功能后,可以观察登录成功率、登录请求的响应时间等指标,如果发现登录成功率下降或响应时间变长,可以及时分析和解决问题,确保系统的稳定性和可靠性。
  • 用户体验影响小 :只有部分用户的体验会受到影响,而且可以通过回滚快速恢复。例如,在一个社交网络平台中,对部分用户发布新的消息推送机制,如果出现问题,比如推送消息延迟或遗漏,可以通过回滚机制迅速恢复到旧版本,仅对这部分用户造成短暂的影响,避免对整个平台的用户造成广泛的不满和流失。
  • 自动化程度较高 :金丝雀发布通常需要一定的自动化工具支持,如自动化的流量控制和监控。例如,通过自动化工具可以将新版本的流量从5%逐步增加到100%,同时通过监控指标和日志实时分析新版本的运行状况,一旦发现异常情况,可以自动触发告警或回滚机制,提高发布的效率和可靠性,减少人工干预的成本和风险。

适用场景

  • 对用户体验要求较高的网站 :对于面向用户的网站,如电商、社交、金融等,金丝雀发布可以在保证大部分用户体验的前提下,对新功能进行验证。例如,一个大型电商网站在推出新的支付功能时,通过金丝雀发布先将其部署到一小部分用户的服务器上,观察新功能的性能和用户体验,如果出现问题,可以及时调整和回滚,避免对整个用户的购物体验造成不良影响,保障平台的稳定运营。
  • 缺乏足够自动化发布的公司 :如果公司没有非常成熟的自动化发布流程,金丝雀发布提供了一种相对可控的方式。例如,一些传统行业的公司,其IT系统和发布流程可能相对传统和复杂,通过金丝雀发布可以逐步引入新的功能和改进,从小范围的部署开始,逐步扩大范围,降低发布风险,同时在这个过程中不断完善和优化发布流程,逐步提高公司的自动化发布能力。
  • 需要验证新版本稳定性的场景 :当对新版本的稳定性和兼容性缺乏足够的信心时,金丝雀发布是一个很好的选择。例如,在一个大型企业内部的ERP系统升级时,新版本的软件可能存在与现有业务系统的兼容性问题或者性能问题,通过金丝雀发布将新版本部署到一部分业务部门的小范围服务器上,观察其运行情况,经过一段时间的稳定运行后,再逐步推广到整个企业,确保系统的稳定升级和业务的连续性。

03.滚动式发布

滚动式发布是一种自动化的发布方式,它通过逐步替换旧版本,实现无缝的发布过程。以下是滚动式发布的一些特点:

特点

  • 无缝升级 :用户在使用过程中几乎不会感受到升级带来的影响。例如,在一个在线音乐播放平台上,通过滚动式发布将新版本的音乐推荐算法逐步推送到各个服务器节点,用户在听歌、发现音乐等功能中可以及时体验到新的功能和优化,而不会因为升级过程导致服务中断或性能下降。
  • 用户体验好 :相比直接发布或金丝雀发布,滚动式发布对用户体验的影响最小。以一个在线游戏平台为例,游戏的更新和优化是用户体验的重要部分,通过滚动式发布,可以在游戏服务器的正常运行过程中,逐步将新版本的游戏内容和服务推送到各个服务器节点,确保玩家可以流畅地玩游戏,并且及时体验到新的游戏内容和功能,提升玩家的满意度和忠诚度。
  • 发布和回滚速度快 :由于是逐步替换,一旦发现问题,可以快速停止发布并回滚到之前的版本。例如,在一个云计算平台中,对虚拟机管理软件进行滚动式发布,如果在某个节点发现新版本的软件导致虚拟机的启动时间变长或资源利用率异常,可以迅速停止发布,并将问题节点回滚到旧版本,同时对其他节点继续进行发布或对问题进行修复,减少了问题的影响范围和处理时间。
  • 系统资源利用率高 :滚动式发布不需要额外的服务器资源,只是逐步替换旧版本,减少了资源浪费。例如,在一个大规模的分布式存储系统中,对存储节点的软件进行滚动式更新,可以充分利用已有的硬件资源,避免了额外采购服务器带来的成本增加,同时也保证了系统的高可用性和性能。

适用场景

  • 用户体验不能中断的业务 :对于一些需要7×24小时不间断服务的业务,如银行、在线支付等,滚动式发布可以确保业务的连续性。例如,银行的网上银行系统需要随时为客户提供账户查询、转账等服务,通过滚动式发布对系统软件进行更新换代,可以保证在更新过程中,用户的正常业务操作不受影响,维护客户对银行服务的稳定性和可靠性的信任。
  • 有一定复杂发布工具的研发能力 :滚动式发布需要比较复杂的发布工具和流程支持,适合有一定技术实力的团队。例如,大型互联网企业通常会自主研发或使用成熟的自动化发布工具来支持滚动式发布,通过这些工具可以实现对服务器节点的自动化监控、流量调度、软件部署和回滚等功能,提高发布效率和质量,降低发布风险。
  • 需要频繁发布新功能的场景 :对于需要频繁发布新功能的业务,滚动式发布可以快速将新功能推向市场。例如,在一个互联网媒体平台上,为了满足用户对新鲜资讯和多样内容的需求,需要不断推出新的专题、功能模块或内容推荐算法,通过滚动式发布可以迅速将新功能部署到服务器集群中,让用户及时体验到新的内容和功能,保持平台的活力和竞争力。

04.双服务器组发布

双服务器组发布是通过两个独立的服务器组来实现发布和回滚。以下是双服务器组发布的一些特点:

特点

  • 快速切换 :通过负载均衡器可以快速将流量从旧版本切换到新版本。例如,在一个搜索引擎中,当新版本的搜索算法准备就绪时,通过负载均衡器将用户流量迅速切换到新版本的服务器组,实现了新版本的快速上线,大幅缩短了发布窗口时间,提高了业务的灵活性和响应速度。
  • 用户体验影响 :如果新版本出现问题,可以通过负载均衡器快速将流量切换回旧版本,对用户体验的影响较小。例如,在一个在线教育平台中,对新版本的课程学习系统进行双服务器组发布,如果新版本的课程播放功能出现故障,可以通过负载均衡器迅速将用户的访问请求切换回旧版本的服务器组,保护了用户的学习体验,同时为开发人员提供了充足的时间来修复新版本的问题。
  • 成本较高 :需要维护两组服务器资源,增加了硬件和维护成本。例如,对于一些中小规模的企业或业务,维护两组服务器的成本可能是一个不小的负担,包括服务器采购成本、机房托管费用、网络带宽费用以及运维人员的人力成本等,这需要在发布策略和成本之间做出权衡。
  • 简化发布流程 :发布和回滚过程相对简单,只需要通过负载均衡器切换流量即可。例如,在一个移动应用的后端服务发布中,通过双服务器组发布,开发人员可以专注于新版本的功能开发和测试,而将发布和回滚的复杂操作交给负载均衡器来处理,简化了发布流程,提高了发布效率,也减少了人为错误的可能性。

适用场景

  • 对发布稳定性要求较高的业务 :对于核心业务系统,如金融交易、医疗系统等,双服务器组发布可以确保发布过程的稳定性。例如,在一个证券交易系统中,新版本的交易引擎发布时,通过双服务器组发布可以将新版本的交易引擎部署到一个独立的服务器组,并通过负载均衡器将用户流量逐渐切换到新版本上。如果新版本出现任何问题,可以迅速将流量切换回旧版本的服务器组,避免交易中断或数据错误,保障金融市场的稳定运行。
  • 机器资源有富余或者可以按需分配 :适合拥有大量服务器资源或者能够快速获取新服务器资源的企业。例如,云计算服务提供商通常拥有丰富的服务器资源池,可以轻松地为客户提供双服务器组发布服务,确保他们能够平稳地进行应用发布和升级,而无需担心服务器资源的限制。
  • 需要快速回滚的场景 :如果业务对回滚的要求很高,双服务器组发布可以迅速实现回滚。例如,在一个高流量的电商平台上,对新版本的购物车功能进行发布时,如果发现新版本存在严重的兼容性问题,需要立即回滚到旧版本以保持平台的正常运营。通过双服务器组发布,可以快速将用户流量切换回旧版本的服务器组,同时保留新版本的服务器组用于问题修复和测试,确保业务的连续性和稳定性。

05.简历-彩蛋

项目经验:(看情况写)

代码自动化发布

项目需求:
1.运维配合开发测试占用大量的时间
2.快速实现CICD从而尽早发现代码或部署过程中存在的问题
3.使用参数化构建进行线上发布降低出错率、实现秒级回滚
4.发布结果通知相关人员

实现项目:
1.搭建Gitlab服务器并控制项目权限
2.搭建并配置Jenkins服务器
3.按项目需求创建
    TAG项目(为MASTER主干打标签)
    测试项目(快速CI CD及早发现问题并且配置自动触发不要运维干预)
    JAVA项目(jenkins集成mvn编译并发布测试环境)
    发布项目(利用tag标签进行线上发布和秒级回滚)
4.搭建SonarQube代码质量检测平台(Jenkins集成Sonar进行自动化代码分析检测)
5.搭建Nexus私服(java代码下载依赖快速编译)
6.编写Jenkins-pipeline流水线(看板方式快速定位问题)
7.Jenkins增加三台从节点实现分布式构建(提高项目的构建速度和稳定性)
8.Jenkins集成第三方插件发送构建结果到运维开发组

06.面试题

1.代码发布流程?

在上家公司,最初我们都是直接使用 FTP。我入职后,领导安排我负责部署相关流程。我为公司部署了 GitLab 以及 SonarQube 用于代码质量检测。具体流程是这样的:开发人员编写代码后,将其提交到 GitLab 中,先提交到自己的分支,然后发起合并请求,将代码合并到 master 分支。不过,这里的 master 分支被设置成了测试分支,专门用于测试相关操作。

我独立部署了 Jenkins,通过它搭建了几套流程,包括测试流程和发布流程。测试流程是这样的:Jenkins 会去拉取 GitLab 中 master 分支的代码,这里我使用了 Webhook 钩子,自动触发拉取操作。拉取完代码后,如果是 PHP 或 Python 代码,我会直接将其推送到 SonarQube 上进行代码质量检测。检测完成后,再调用 Shell 脚本或者 Jenkins,将代码发布到测试环境中,开发人员可以直接查看测试结果,如果存在问题,他们可以在原基础上修改代码并重新提交,系统会自动拉取代码,再次走测试流程。

对于 Java 项目,相较于 PHP 和 Python 项目,多了一个编译步骤。我们会创建 Maven 项目,在项目中进行编译和打包操作,打包完成后,将生成的文件推送到 Nexus 上,之后进行运行,或者拿到 jar 包后,放在业务服务器上,这些 Java 框架就可以直接运行我们的项目了。在编译过程中,由于网络问题,从外网下载依赖比较慢,所以我搭建了一个 Nexus 私服,并创建了一个代理,设置代理的 URL 指向国内的阿里云 Maven 仓库。

我还为公司部署了几套线上发布流程。测试完成后,我会给 master 分支打一个 tag,并将 tag 推送到 GitLab 中。通过 Jenkins 的 GitLab 插件,获取所有 tag 信息,底层使用 Shell 脚本进行判断,选择特定版本后,拉取对应版本的代码,推送到线上测试环境。如果线上测试环境没有问题,再发布到所有业务场景中。这个过程使用了 Git 参数化构建变量+shell脚本,如果出现问题,采用软连接方式,加了相关选项参数,可以实现秒级回退到上一个版本。另外,测试环境没有问题后,我会将其写成 Pipeline 流水线方式,使用看板展示,这样可以快速看到每个过程花费的时间,也能快速定位问题。

基于之前公司的业务情况,我搭建了这几套流程,目前使用起来还是比较稳定的。

2.jenkins都用过那些插件?

插件名称插件功能描述
GitLab Plugin用于Jenkins与GitLab之间的集成,支持GitLab的Webhooks,项目构建等。
Git Parameter Plugin提供Git相关的参数化构建选项,如选择Git分支、标签等。
Maven Integration Plugin用于Jenkins与Maven的集成,支持Maven项目的构建、测试和打包。
SonarQube Scanner Plugin用于将SonarQube的质量分析集成到Jenkins构建流程中。
Pipeline Plugin支持Jenkins Pipeline的定义和执行,实现持续交付流水线。
SSH Plugin通过SSH协议在远程服务器上执行命令,如部署、文件传输等。
Publish OverSSH允许通过SSH协议将文件发布到远程服务器。
Deploy to Container Plugin用于将应用程序部署到容器环境中,如Docker等。
Nexus Artifact UploaderPlugin将构建产物上传到Nexus仓库。
Email Extension Plugin提供丰富的邮件通知功能,支持HTML格式、附件等功能。
Blue Ocean Plugin提供现代化的Jenkins用户界面,以更直观的方式展示构建流程和结果。
插件名称用途功能/关键动作/典型结构
GitLab Plugin实现Jenkins与GitLab的无缝集成自动解析Merge Request、触发Webhook构建、查看代码变更记录
Git Parameter Plugin参数化构建时动态获取Git标签/分支通过下拉菜单选择Git Tag版本,支持生产发布场景
Maven Integration Plugin原生支持Maven项目构建自动识别pom.xml 、配置阿里云镜像代理、执行mvn clean package
SonarQube Scanner Plugin集成代码质量扫描与SonarQube服务器交互,执行代码质量分析(如mvn sonar:sonar)
Pipeline Plugin定义多阶段流水线支持agent any声明、分阶段构建(Build/Deploy等)、步骤脚本执行
SSH Plugin / Publish Over SSH通过SSH远程部署到测试/生产环境预置服务器密钥、定义文件传输路径、执行远程命令(如重启服务)
Deploy to Container Plugin自动化部署WAR包到Tomcat监听Nexus仓库新WAR包事件,自动触发容器部署
Nexus Artifact Uploader Plugin上传Maven构建产物至Nexus私服依赖settings.xml 配置镜像地址,实现构建产物版本管理
Email Extension Plugin定制化构建通知支持构建状态(成功/失败)触发邮件通知,自定义邮件主题和内容模板
Blue Ocean Plugin可视化流水线编辑与监控图形化展示构建阶段耗时、实时日志追踪、快速定位失败环节
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇