相关文章推荐

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account
  • 简单的服务通过打包.jar,上传至服务器,nohup java -jar xxx.jar 也能启动,为何需要Jenkins?
    答:Jenkins可以实现一次push代码到git,一键部署,打包成jar包、启动服务等
  • Jenkins的功能边界是什么?多个服务通过虚拟环境都用8080端口,需要其它什么组件?
    答:后者单用Jenkins做不到,估计是Docker
  • TODO: 芋道 Spring Boot 持续交付 Jenkins 入门 中有介绍如何优雅的上下线一个SpringBoot服务,需要用到 Tengine,可以玩一下
  • 目标:将 https://github.com/peteryuanpan/spring-demo/tree/master/springboot-tswork-2001 中的代码通过Jenkins部署到Ubuntu云服务器上

    参考: 芋道 Jenkins 极简入门

    1.进入Jenkins下载界面,选择2.204.1版本,链接: http://mirrors.jenkins.io/war-stable/2.204.1/ ,下载 .war 文件,下载链接: http://mirrors.jenkins.io/war-stable/2.204.1/jenkins.war
    2.执行命令:nohup java -jar jenkins.war
    3.tail nohup.out

    2021-02-10 15:02:30.207+0000 [id=25]    INFO    jenkins.install.SetupWizard#init:
    *************************************************************
    Jenkins initial setup is required. An admin user has been created and a password generated.
    Please use the following password to proceed to installation:
    eda079c95f0b406db321369fae5276e5
    This may also be found at: /home/ubuntu/.jenkins/secrets/initialAdminPassword
    *************************************************************
    

    4.云主机防火墙 以及 宝塔界面(8888端口)均放行8080端口
    5.访问 http://150.158.175.76:8080/ ,跳转到如下界面
    6.点击安装推荐的插件
    7.等待下载完成
    8.创建第一个管理员用户,点击保存并完成,一路点击下去
    9.来到Jenkins主页面
    10.点击 Manage Jenkins - Manage Plugins - 可选插件
    选择5个插件:Maven Integration、Maven Info、Publish Over SSH、Extended Choice Parameter、Git Parameter
    点击直接安装,等待安装完成
    11.回到首页,点击Manage Jenkins - Global Tool Configuration
    点击新增安装,取消自动安装,输入别名、JAVA_HOME,点击保存
    12.回到首页,点击Manage Jenkins - Configure System - 配置
    找到SSH Servers,点击高级,填写信息,注意Remote Directory要填写一个/,最后点击Test Configuration,测试连接,点击保存

    13.到此,芋芋文章中介绍了 远程服务器配置 推荐的目录格式

    在 /work/projects 下创建一个项目文件夹,比如 springboot-tswork-2001,格式如下

    ls -ls total 18852 4 drwxr-xr-x 2 root root 4096 Jan 13 21:21 backup 4 drwxr-xr-x 2 root root 4096 Jan 13 21:14 build 18840 -rw-r--r-- 1 root root 19288579 Jan 13 21:21 lab-41-demo01.jar 4 drwxr-xr-x 2 root root 4096 Jan 13 21:16 shell

    在 shell 目录下,有一个 deploy.sh,后续有用

    这个.sh 是芋芋自己写出来的,值得学习!
    工作中能自己简单实现shell脚本解决问题,是一个很厉害的技能,在许多招聘简介中,都有写要求掌握至少一种脚本语言(shell、python等)

    我改版后的deploy.sh:#196 (comment)

    14.回到首页,选择新建Item,输入任务名,选择构建一个maven项目,点击确定
    然后会进入一个非常详细的配置界面

    具体配置过程看芋芋的文档吧,我这里就不一一贴了,但这个过程是最重要的!!

    贴一些关键配置

    15.配置完成后,回到主页,点击具体项目名,点击Build With Parameters

    下面了记录一下build过程中遇到的坑

    1.maven报错
    报错:ERROR: A Maven installation needs to be available for this project to be built.Either your server has no Maven installations defined, or the requested Maven version does not exist.
    原因:jenkins上maven安装配置不正确
    解决办法,参考 https://blog.csdn.net/weixin_43843104/article/details/102599031

    2.shell/deploy.sh出错
    原因:.sh文件不适配
    中途有许多报错,逐一修改后,得到的deploy.sh版本
    deploy.sh:#196 (comment)

    3.Jenkins线上nohup无效
    本地可以,但线上nohup没有启动
    解决办法,参考 https://blog.csdn.net/u011781521/article/details/80210985
    在shell/deploy.sh中改为

        export BUILD_ID=dontKillMe
        nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME*.jar --spring.profiles.active=$PROFILES_ACTIVE &
        sleep 10s

    deploy.sh:#196 (comment)

    部署完成后,访问链接
    path1: 1613144671177

    与代码对应

    package com.peter.controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    @RequestMapping("/demo")
    public class DemoController {
        @GetMapping("/path1")
        public String path1() {
            return "path1: " + System.currentTimeMillis();
    # export JAVA_HOME=/work/programs/jdk/jdk1.8.0_181
    # export PATH=PATH=$PATH:$JAVA_HOME/bin
    # export CLASSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    DATE=$(date +%Y%m%d%H%M)
    # 基础路径
    BASE_PATH=~/work/projects/springboot-tswork-2001
    # 编译后 jar 的地址。部署时,Jenkins 会上传 jar 包到该目录下
    SOURCE_PATH=$BASE_PATH/build
    # 服务名称。同时约定部署服务的 jar 包名字也为它。
    SERVER_NAME=springboot-tswork-2001
    PROFILES_ACTIVE=prod
    # 健康检查 URL
    HEALTH_CHECK_URL=http://127.0.0.1:8078/actuator/health/
    # heapError 存放路径
    HEAP_ERROR_PATH=$BASE_PATH/heapError
    # JVM 参数
    JAVA_OPS="-Xms128m -Xmx128m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH"
    # JavaAgent 参数。可用于配置 SkyWalking 等链路追踪
    JAVA_AGENT=
    function backup() {
        # 如果不存在,则无需备份
        if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then
            echo "[backup] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过备份"
        # 如果存在,则备份到 backup 目录下,使用时间作为后缀
            echo "[backup] 开始备份 $SERVER_NAME ..."
            cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jar
            echo "[backup] 备份 $SERVER_NAME 完成"
    # 最新构建代码 移动到项目环境
    function transfer() {
        echo "[transfer] 开始转移 $SERVER_NAME.jar"
        # 删除原 jar 包
        if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then
            echo "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除"
            echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成"
            rm $BASE_PATH/$SERVER_NAME.jar
        # 复制新 jar 包
        echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...."
        cp $SOURCE_PATH/$SERVER_NAME*.jar $BASE_PATH
        echo "[transfer] 转移 $SERVER_NAME.jar 完成"
    function stop() {
        echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME"
        PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')
        # 如果 Java 服务启动中,则进行关闭
        if [ -n "$PID" ]; then
            # 正常关闭
            echo "[stop] $BASE_PATH/$SERVER_NAME 运行中,开始 kill [$PID]"
            kill -15 $PID
            # 等待最大 60 秒,直到关闭完成。
            for ((i = 0; i < 60; i++))
                    sleep 1
                    PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}')
                    if [ -n "$PID" ]; then
                        echo -e ".\c"
                        echo '[stop] 停止 $BASE_PATH/$SERVER_NAME 成功'
                        break
            # 如果正常关闭失败,那么进行强制 kill -9 进行关闭
            if [ -n "$PID" ]; then
                echo "[stop] $BASE_PATH/$SERVER_NAME 失败,强制 kill -9 $PID"
                kill -9 $PID
        # 如果 Java 服务未启动,则无需关闭
            echo "[stop] $BASE_PATH/$SERVER_NAME 未启动,无需停止"
    function start() {
        # 开启启动前,打印启动参数
        echo "[start] 开始启动 $BASE_PATH/$SERVER_NAME"
        echo "[start] JAVA_OPS: $JAVA_OPS"
        echo "[start] JAVA_AGENT: $JAVA_AGENT"
        echo "[start] PROFILES: $PROFILES_ACTIVE"
        # 开始启动
        export BUILD_ID=dontKillMe
        nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME*.jar --spring.profiles.active=$PROFILES_ACTIVE &
        sleep 10s
        echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成"
    # 健康检查
    function healthCheck() {
        # 如果配置健康检查,则进行健康检查
        if [ -n "$HEALTH_CHECK_URL" ]; then
            # 健康检查最大 60 秒,直到健康检查通过
            echo "[healthCheck] 开始通过 $HEALTH_CHECK_URL 地址,进行健康检查";
            for ((i = 0; i < 60; i++))
                    # 请求健康检查地址,只获取状态码。
                    result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"`
                    # 如果状态码为 200,则说明健康检查通过
                    if [ "$result" == "200" ]; then
                        echo "[healthCheck] 健康检查通过";
                        break
                    # 如果状态码非 200,则说明未通过。sleep 1 秒后,继续重试
                        echo -e ".\c"
                        sleep 1
            # 健康检查未通过,则异常退出 shell 脚本,不继续部署。
            if [ ! "$result" == "200" ]; then
                echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功";
                tail -n 10 nohup.out
                exit 1;
            # 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。
                tail -n 10 nohup.out
        # 如果未配置健康检查,则 slepp 60 秒,人工看日志是否部署成功。
            echo "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 60 秒";
            sleep 60
            echo "[healthCheck] sleep 60 秒完成,查看日志,自行判断是否启动成功";
            tail -n 50 nohup.out
    function deploy() {
        cd $BASE_PATH
        # 备份原 jar
        backup
        # 停止 Java 服务
        # 部署新 jar
        transfer
        # 启动 Java 服务
        start
        # 健康检查
        #healthCheck
    deploy
     
    推荐文章