• SpringCloud(CI/CDNexus+Gitea+Jenkins)


    SpringCloud(CI/CD-Nexus+Gitea+Jenkins)

    前面聊了SpringCloud-Netflix这一套,聊的同时,我自己搭建了一个一套SpringCloud-Netflix框架,其中包含了7个微服务,这还是我没有任何业务支撑的情况下。很显然,随着微服务数量的增加。像传统的那样打包jar,复制jar,并且发布jar(nohup java -jar ${APP_NAME} > ***.log 2>&1 &)到服务器上绝对不是一个好的办法。本篇,我将对我的微服务项目使用【Nexus(maven私服)+Gitea(代码托管工具)+Jenkins(持续集成)】进行部署,首先聊他们的搭建,然后结合我们的代码,最终完成自动化部署。

    搭建Nexus私服环境

    因为是多个微服务组成的一个项目,而且可能有多个项目组同时依赖某一个jar,那我们就需要把这个jar放在一个统一的地方进行管理。所以这里使用【nexus】进行一个中央仓库的搭建。

    搭建步骤:

    • 和咱们前面搭建jenkins一样,确保maven和jdk都已经安装
    • 下载地址:【https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.37.3-02-unix.tar.gz】,下载速度特别慢,有需要可以找我拿
    • 解压:tar -zxvf nexus-3.37.3-02-unix.tar.gz
    • 启动:进入到${NEXUS_HOME}\bin目录,执行【./nexus start】
    • 输入 http://192.168.43.3:8081/ 我是本地搭建的虚拟机,大家写自己的ip,但是默认端口是8081
    • 登录默认用户名admin,密码在/data/program/sonatypework/nexus3/admin.password文件中 
      •  

    tips:

    • 如果想配置 nexus 的应用在本地启动的 JVM参数,可以在 nexus.vmoptions
    • 如果想改变 nexus 的 端口号,可以在 nexus-default.properties,默认是8081
    • 他的日志在sonatype-work/nexus3/log,启动后去查询一下nexus是否启动,我启动的时候就是因为linux的root磁盘接近饱和,nexus要求最少有4096MB的磁盘空间,后面不得不去对磁盘从新扩容,查询磁盘大小命令【df -h】

    功能介绍:

    进入Nexus控制台的Browse菜单,可以看到四种仓库类型:

    • maven-central: maven中央库,默认从https://repo1.maven.org/maven2/拉取jar
    • maven-releases: 私库发行版jar
    • maven-snapshots:私库快照(调试版本)jar
    • maven-public: 仓库分组,把上面三个仓库组合在一起对外提供服务,在本地maven基 础配置settings.xml中使用。

    Nexus设置成系统服务

    • 修改${NEXUS_HOME}\bin\nexus这个脚本,增加【INSTALL4J_JAVA_HOME_OVERRIDE=/data/program/jdk1.8.0_241】
    • 设置软链接 ln -s /data/program/nexus-3.37.0-01/bin/nexus /etc/init.d/nexus
    • 通过chkconfig方式配置系统服务:
      • cd /etc/init.d sudo chkconfig --add nexus #添加nexus服务 sudo chkconfig --levels 345 nexus on #设置开启自启动
    • 启动和停止服务
      • sudo service nexus start #开启服务 service nexus status #查看服务状态

     搭建Gitea环境

    【普通版本】:首先必须要有git环境,之前我的虚拟机上已经有了,这里就不带搭建搭建了。按照官方给的文档就行( https://docs.gitea.io/zh-cn/install-from-binary/)

    【设置系统服务】:

    • 创建Git用户   注:git需放到 :/bin/git ,并且需要创建软连接【 ln -s /usr/local/git/bin/git /bin/git 】  
      • sudo useradd \
        --system \
        --shell /bin/bash \
        --comment 'Git Version Control' \
        --create-home \
        --home /home/git \
        git
        View Code
    • 下载二进制文件【wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64】
    • 把下载的文件移动到/usr/local/bin目录官方建议,因为我们的gitea.service中写的就是这个路径,并且下面我们也会为这个路径分配权限)
      • 【sudo mv /data/program/gitea /usr/local/bin】
    • 让二进制文件可以执行【chmod +x /usr/local/bin/gitea】
    • 按照命令创建必要目录并设置权限
      • sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
        sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
        sudo chown git: /var/lib/gitea/{data,indexers,custom,public,log}
        sudo chmod 750 /var/lib/gitea/{data,indexers,log}
        sudo mkdir /etc/gitea
        sudo chown root:git /etc/gitea
        sudo chmod 770 /etc/gitea
        View Code
    • 在/etc/systemd/system/中创建gitea.service文件,内容为    
      • [Unit]
        Description=Gitea (Git with a cup of tea)
        After=syslog.target
        After=network.target
        
        [Service]
        RestartSec=2s
        Type=simple
        User=git
        Group=git
        WorkingDirectory=/var/lib/gitea/
        ExecStart=/usr/local/bin/gitea/gitea web --config /etc/gitea/app.ini
        Restart=always
        Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
        
        [Install]
        WantedBy=multi-user.target
        View Code
    • 设置自动启动
      • systemctl enable
      • gitea systemctl start gitea
      • jenkins 实际上就是一个war,下载下来我们用命令启动就行(自行百度),我们关于它的一些内容我们之前聊过,这里不赘述了,
    • tips:
      • 第一个输入地址后,会让你对服务器地址等的填写,这里最好填写。如果没有填写,那可以通过修改app.ini文件进行修改(如果不修改这个的话,我们创建的项目ssh或或者http地址就是localhost,这样的话别人就无法访问了!!!)。在我们启动gitea的时候,这个文件地址则会被打印出来。相关配置请看 【https://docs.gitea.io/zh-cn/config-cheat-sheet/#server-server】
      •   

    项目中配置私服

    在maven的setting文件中,写上我们的nexus的服务器地址和端口,以及相关配置

    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>maven-public</mirrorOf>
            <url>http://192.168.43.3:8081/repository/maven-public/</url>
        </mirror>
      </mirrors>
    
      <profiles>
        <profile>
            <id>nexusRep</id>
            <repositories>
                <repository>
                    <id>nexus</id>
                    <url>http://192.168.43.3:8081/repository/maven-public/</url>
                    <layout>default</layout>
                    <releases>
                    <enabled>true</enabled>
                    <updatePolicy>always</updatePolicy>
                    </releases>
                </repository>
            </repositories>
            
            <pluginRepositories>
                <pluginRepository>
                    <!--插件地址-->
                    <id>nexus</id>
                    <url>http://192.168.43.3:8081/repository/maven-public/</url>
                    <snapshots>
                    <enabled>true</enabled>
                    </snapshots>
                    <releases>
                    <enabled>true</enabled>
                    </releases>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    
      </profiles>
      
        <activeProfiles>
            <activeProfile>nexusRep</activeProfile>
        </activeProfiles>
    View Code

    在springCloud的父项目中写上我们nexus的仓库地址

        <distributionManagement>
            <snapshotRepository>
                <id>snapshots</id>
                <name>Nexus Snapshot Repository</name>
                <url>http://192.168.43.3:8081/repository/maven-snapshots/</url>
            </snapshotRepository>
            <repository>
                <id>releases</id>
                <name>Nexus Release Repository</name>
                <url>http://192.168.43.3:8081/repository/maven-releases/</url>
            </repository>
        </distributionManagement>
    View Code

    重启idea后,我们的所有的jar则会同步到我们nexus上的中央仓库中,当然我们也可以自己配置aliyun仓库。

    注意:我们这个时候deploy的时候,可能有【Return code is: 401, ReasonPhrase: Unauthorized.】这样的错误, 这是因为我们权限,我们需要把nexus的密码和用户名维护在maven中的setting.xml中的servers标签中并且pom中的id和我们maven中维护账号密码的id需要一致!

        <server>
            <id>releases</id>
            <username>admin</username>
            <password>123456</password>
          </server>
          <server>
            <id>snapshots</id>
            <username>admin</username>
            <password>123456</password>
          </server>
    View Code

    然后我们使用maven进行deploy,则发现这些jar就发布到了nexus上SNAPSHOT中,但是release中没有,这是因为我们的pom中写version中写的都是

    <version>0.0.1-SNAPSHOT</version>

     配置Jenkins的环境变量

    在jenkins的【系统管理】中的【全局工具配置】中,配置maven,jdk,git

    在【系统配置】中的【插件管理】中 安装gitea、Git Parameter、Publish Over SSH、Maven Integration这些插件

    在全局配置中配置gitea的地址

    和配置发布目标服务器的地址

    构建项目

    创建一个maven项目,并且填写上我们的gitea中项目的地址,和gitea的账号和密码

    指定我们需要打包的pom,并且执行maven命令,对项目进行清理、打包、跳过检测,我们这里的root pom的名称的来由是从jenkins的工作目录下的项目中来的

     

    配置需要接收的目标服务器地址和目录,并且我们需要编写需要执行的脚本

    【 jenkins上的执行脚本】注意,脚本中我直接使用微服务的名称作为jar的名称,这是因为我在项目中的pom中的finalName标签中写了微服务的名称

    • 停止项目
    • 备份老的文件
    • 把转移传递过来的ja转移到和执行脚本在一起的目录
    • 执行启动脚本
    • 删除备份了5次以上的备份文件
    #! bin/sh -e
    export JAVA_HOME=/usr/local/jdk/jdk1.8.0_291
    export JRE_HOME=/usr/local/jdk/jdk1.8.0_291/jre
    export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
    export PATH=$JAVA_HOME/bin:$PATH
    source /etc/profile
    
    # define property
    JAR_PATH='/app/service/marking-service'
    TEMP_PATH='/app/service/temp'
    BACKUP_PATH='/app/service/backup'
    JAR_NAME=marking-service.jar
    FILE_NAME=marking-service
    
    # stop target service
    cd ${JAR_PATH}
    sh run-marking-service.sh stop
    sleep 2
    rm -rf $FILE_NAME.log
    
    # backup old jar if there is not the path then create a path 
    BACKUP_DATE=$(date +%Y%m%d_%H%M)
    if [ ! -d $JAR_PATH/backup/$FILE_NAME ];then
        mkdir -p $JAR_PATH/backup/$FILE_NAME
    fi
    
    # enter into the path  if there is a jar then move the jar to back path to backup 
    cd ${JAR_PATH}
    pwd
    if [ -f $JAR_NAME ];then
        mv -f ./$JAR_NAME ./backup/$FILE_NAME/$JAR_NAME$BACKUP_DATE
        sleep 1
    fi
    
    # start jar
    BUILD_ID=dontKillMe
    cd ${TEMP_PATH}
    mv -f $JAR_NAME $JAR_PATH
    cd ${JAR_PATH}
    # run the script to restart
    sh run-marking-service.sh restart
    # clear old backup
    cd ${JAR_PATH}/backup/$FILE_NAME
    ls -lt|awk 'NR>5{print $NF}' |xargs rm -rf
    ps -ef|grep java
    echo "=============deploy success========"
    
    
    #首先进入/app/service/marking-service
    #执行sh文件停止,并且睡2s,同时删除marking-service.log 文件
    #备份老的文件 如果不存在/app/service/marking-service/backup/marking-service这个文件,则创建一个文件
    #进入到/app/service/marking-service中,如果存在marking-service.jar,则把这个文件转移到./backup/marking-service/marking-service.jar$BACKUP_DATE中
    #进入到/app/service/temp中,把marking-service.jar转移到/app/service/marking-service中
    #进入到/app/service/marking-service中,
    #执行启动方法
    #进入到/app/service/marking-service/backup/marking-service中,删除一下备份文件
    #打印java的jar
    View Code

    目标服务器的执行脚本

    # 表示当前脚本采用/bin路径的bash程序来解释执行
    #!/bin/bash
    # 执行的jar包
    APP_NAME=marking-service.jar
    usage() {
        echo "执行操作命令 [start|stop|restart|status]"
        exit 1
    }
    #判断当前应用是否存在
    if_exist() {
        pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
        #判断进程是否为空
        if [ -z "${pid}" ]; then
         return 1
        else
         return 0
        fi
    }
    #启动
    start() {
        #判断是否启动
        if_exist
        #已经启动
        if [ $? -eq 0 ]; then
            #打印
            echo "${APP_NAME} already running . pid=${pid}"
        else
            #进行启动
            nohup java -jar ${APP_NAME} > marking-service.log 2>&1 &
            #启动后的pid
            npid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
            #打印
            echo "start ${APP_NAME} success, pid=${npid}"
        fi
    }
    #停止
    stop() {
        if_exist
        #如果存在
        if [ $? -eq 0 ]; then
            #停止
            kill -9 $pid
            #打印
            echo "stop $pid success".
        else
            #打印
            echo "${APP_NAME} is not running"
        fi
    }
    #查询状态
    status() {
        if_exist
        if [ $? -eq 0 ]; then
            echo "${APP_NAME} is running. pid is ${pid}"
        else
            echo "${APP_NAME} is not running "
        fi
    }
    #重启
    restart() {
        stop
        #休眠5s
        sleep 5
        start
    }
    
    case "$1" in
        "start")
        start
         ;;
        "stop")
        stop
         ;;
        "status")
         status
         ;;
        "restart")
        restart
         ;;
     *)
     #提示
     usage
     ;;
    esac
    View Code

    进行构建

     整体流程

    •  从我们的gitea上拉取代码
    •  开始去nexus上拉取jar
    •   
    •  maven打包结束
    •  发布jar到目标服务器
    • 目标服务器已经可以看见jar
    •  并且通过日志查砍项目自己启动完成

    当项目推送到gitea的时候进行自动构建解决方案

    我们有时候希望当我们某个分支有代码发布后,自动构建,那我们就可以采用webhook进行处理。

    安装Generic Webhook Trigger到jenkins中

    在项目配置中选择构建触发器,并且填写我们的token,他会给我们生成一个地址,我们需要把这个地址填写到我们gitea中

     这个时候我们我们提交一个代码给gitea,注意这个时候我们jenkins上是没有任何构建的任务的!!

    gitea上已经有我们的代码了

     

    Jenkins正在构建项目

     

    gitea上显示构建成功

    代码也已经传递到目标服务器中,并且启动成功

     

     我们后面的模块就可以按照这种方式进行构建,当新建一个构建项目的时候,jenkins提供复制功能,这可以为我们省去很多时间

     至此,nexus+Gitea+Jenkins自动化部署完成!

  • 相关阅读:
    FreeSWITCH一些需求应对
    CentOS 7安装Mysql并设置开机自启动
    RTP学习笔记
    SDP学习笔记
    Quartz实用二三事
    Quartz:ERROR threw an unhandled Exception
    CentOS 7一些常用配置
    Java获取音频文件(MP3)的播放时长
    使用Callable和Future接口创建线程
    join() 方法详解及应用场景
  • 原文地址:https://www.cnblogs.com/UpGx/p/15834308.html
Copyright © 2020-2023  润新知