spug上线服务踩坑记

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: spug是一款优秀的自动化运维平台, 这让我们想自动化又向前迈了一步.

20210708171010330.pngspug是一款优秀的自动化运维平台,  这让我们想自动化又向前迈了一步.

在过程中遇到的问题,记录在这里供各位看官参考.

一、远程执行命令问题


利用spug打好包之后,如何分发到应用最终跑的那台主机上去。

这里有三个想法:

1、ssh 发布主机后 执行命令,

例如:

ssh 10.50 "ln -snf /opt/qwert-$SPUG_GIT_TAG.war /opt/eqwe_fi_-spug.war"

对于内置命令不需要写命令的绝对路径,

ssh 10.50 "setsid /usr/lcal/jdk1.8.0_121/bin/java -Xms512m -Xmx1024m ....

对非内置命令需要写绝对路径,这是为何? 这是和 环境变量有关的

2、ssh之后去执行命令

在spug 常规发布中,在目标主机上ssh 发布主机,ssh IP "ls /opt"  这个可以执行出来 。但是 先ssh IP 再执行其他命令就不行

这是在非登录SHELL里执行的。

尝试使用ssh -tt 强制分配一个tty也不行

3、EOT End Of Text.

看下面这个例子,登录到目标主机上去,执行完命令后退出,使用这种方式在需要发布的主机上把打好的包copy过去,然后开始启动流程

ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT

这段shell 写的不是很好,硬编码严重,逻辑也有不严谨的地方。后续持续改进

echo "开始修改包名..............:"
mv /opt/MPP/target/MPP.jar /opt/MPP/target/MPP_array_fi_$SPUG_GIT_TAG.jar
echo "修改中..............:"
sleep 1s
if [ $? -eq 0 ]
then
echo "修改成功.............."
else 
echo "修改失败,请确认.............."
fi
echo "开始移动包到指定服务器..............:"
#todo  2021年7月6日10:03:21 自动免密验证
# ssh 192.168.10.168 /bin/bash << 'EOT'
# if [ -d /opt/servers/MPP4 ];then
# echo "目录已存在"
# else
# mkdir -p /opt/servers/MPP4/
# echo "目录创建成功"
# fi
# EOT
scp /opt/MPP/target/MPP_array_fi_$SPUG_GIT_TAG.jar 192.168.10.168:/opt/servers/MPP4
ssh 192.168.10.168 "ln -snf /opt/servers/MPP4/MPP_array_fi_$SPUG_GIT_TAG.jar /opt/servers/MPP4/MPP-spug.jar"
# --------------------------------------------- ssh by sscripts start 2021年7月27日09:01:05 
ssh root@192.168.10.168 /bin/bash <<'EOT'
cd /opt/servers/MPP4/
echo "当前目录为:"
pwd
PID=$(ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}')
PID_CNT=$(ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}'|wc -l)
if [ $PID_CNT -eq 1 ];then
echo "进程已存在,pid: $PID..............:"
echo "重启中..............:"
ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}'|xargs kill -9
sleep 10s
date +%H:%M:%S
PID_CNT1=$(ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}'|wc -l)
   if [ $PID_CNT1 -eq 0 ];then
   echo "......启动命令$$........:"
       setsid /usr/local/jdk1.8.0_191/bin/java -Djava.rmi.server.hostname=192.168.10.168 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=18999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xms1024m -Xmx4096m -jar -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:/aplog/MPP/agc.log -Dspring.profiles.active=prod /opt/servers/MPP4/MPP-spug.jar --server.port=8066 --mq.quartzFlg=Y --etl.quartzFlg=N --mq.alarmQuartzFlg=N --mq.shopId=QQQ >/dev/null &
        PID1=$(ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}')
        echo "重启成功,pid: $PID1..............:"
   fi
else
date +%H:%M:%S
echo "当前目录为:"
pwd
echo "启动中..............:"
date +%H:%M:%S
     setsid /usr/local/jdk1.8.0_191/bin/java -Djava.rmi.server.hostname=192.168.10.168 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=18999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xms1024m -Xmx4096m -jar -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:/aplog/MPP/agc.log -Dspring.profiles.active=prod /opt/servers/MPP4/MPP-spug.jar --server.port=8066 --mq.quartzFlg=Y --etl.quartzFlg=N --mq.alarmQuartzFlg=N --mq.shopId=QQQ >/dev/null &
PID2=$(ps -ef|egrep "MPP"|grep -v egrep|awk '{print $2}')
date +%H:%M:%S
echo "启动成功,PID为 $PID2..............:"
fi
EOT
date +%H:%M:%S

二、软连接的问题


进入一个软连接目录,如果该目录被重新指向新的链接。

此时在当前目录看到的文件仍旧是旧文件.

cd出去,重新进入该目录文件才更新.

20210716113930544.png

20210716113947549.png

参考:

linux - Pseudo-terminal will not be allocated because stdin is not a terminal - Stack Overflow

三、jdk 版本问题


启动java程序时报如下错误

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/navi/RtmApplication : Unsupported major.minor version 52.0
  at java.lang.ClassLoader.defineClass1(Native Method)
  at java.lang.ClassLoader.defineClass(ClassLoader.java:803)
  at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
  at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
  at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
  at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
  at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:46)
  at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
  at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
  at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

打包机器的的JDK版本和AP服务器的JDK版本不一致导致的

打包环境: /usr/local/jdk1.8.0_144/bin/java

运行环境: /usr/local/jdk1.8.0_191/bin/java

打包环境jdk版本是向下兼容,如果运行环境的版本比打包的新则会报如上错误.

20210817172144665.png2021081717212311.png解决: 使用同一个jdk版本打包

--update 2022年8月10日09:57:40

今天在执行脚本模板的时候也同样报这个错误, 这仅仅是远程执行脚本 为何会对jdk版本有要求呢?  

其实是因为启动脚本中没有使用java的绝对路径导致的。f80ae3d40ba24b889d558666922d0877.png参考: JAVA版本号的问题 Java版本号与JDK版本_renhq-CSDN博客_jdk与java版本

四、ssh远程连接中传递变量


问题:

解决:

注意双引号才会有变量替换,再复习下shell的解析

五、解决spug 上版卡一直卡主的问题


上版的时候一直卡在检出后发布

这是在检出前打印配置信息d955cd114356456c90154351c062c8b1.png解决:

仔细观察发现打印配置文件卡主的地方是第一次出现中文注释的地方。

可以在cat 的时候直接转码

echo "当前配置列表 ......"
# iconv -f GBK -t UTF-8 用于转换中文乱码问题
cat ./chot-configs/src/main/resources/application-production.properties | iconv -f GBK -t UTF-8
echo "done"
iconv命令 是用来转换文件的编码方式的,比如它可以将UTF8编码的转换成GB18030的编码,反过来也行。JDK中也提供了类似的工具native2ascii。Linux下的iconv开发库包括iconv_open,iconv_close,iconv等C函数,可以用来在C/C++程序中很方便的转换字符编码,这在抓取网页的程序中很有用处,而iconv命令在调试此类程序时用得着。
-f encoding :把字符从encoding编码开始转换。 
-t encoding :把字符转换到encoding编码。 
列出当前支持的字符编码: 
iconv -l 
将文件file1转码,转后文件输出到fil2中: 
iconv file1 -f EUC-JP-MS -t UTF-8 -o file2 
这里,没-o那么会输出到标准输出。

六、新建应用踩坑记


模板已经算很完善了,为啥还会报错呢?发现是新建的应用中有一个空格,导致后面的命令执行失败。linux中对于名称这类的建议不要使用空格。如果非要用,那引用的时候需要加上引号。这个win是完全不同的9819d8196220423a9eaaf4956b672f08.png

七、docker 容器重启登录报错的问题


docker 容器重启之后提示mysql报错。很明显chot这个账户访问mysql的权限被拿掉了,不知谁何时拿掉了chot的访问权限。acfc4eb180224bc8b9818aed589a7ccb.jpg解决:

1、进入容器查看自定义mysql配置

 more /data/spug/spug_api/spug/overrides.py
DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1']
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'spug',
        'USER': 'chot',
        'PASSWORD': '',
        'HOST': '10.50.10.180',
        'OPTIONS': {
            'charset': 'utf8mb4',
            'sql_mode': 'STRICT_TRANS_TABLES',
        }
    }
}

2、查看mysql数据库的user表权限分配。

SELECT Host, `User`, Password, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv, Repl_client_priv, Create_view_priv, Show_view_priv, Create_routine_priv, Alter_routine_priv, Create_user_priv, Event_priv, Trigger_priv, Create_tablespace_priv, ssl_type, ssl_cipher, x509_issuer, x509_subject, max_questions, max_updates, max_connections, max_user_connections, plugin, authentication_string, password_expired
FROM mysql.`user`;
delete from mysql.user where host='10.50.10.185' AND `User` = 'root' ;
# 该语句用于为 root 用户授予所有权限,其中 *.* 表示所有数据库及表,'%' 表示任意主机,123456 是该用户的密码,grant with grant option 允许 root 用户给其它用户授权。
grant all privileges on *.* to chot@'10.50.10.185' identified by 'chot123' with grant option;
flush privileges;

刚开始再想是给容器ip的权限还是宿主机,后来发现给宿主机的ip访问权限即可。

八、spug 升级v3


注意三点

1、从私服镜像

2、需要docker compose环境

3、绑定挂载卷先创建,不要覆盖旧版本的目录。(切记)

mkdir -p /data/spugv3/{mysql,service,repos}

安装步骤

准备docker compose文件

vi docker-compose.yml

version: "3.3"
services:
  db:
    image: chot-harbor.prod.com/mariadb:10.8.2
    container_name: spug-db
    restart: always
    command: --port 3306 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - /data/spugv3/mysql:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=spug
      - MYSQL_USER=spug
      - MYSQL_PASSWORD=spug.cc
      - MYSQL_ROOT_PASSWORD=spug.cc
  spug:
    image: chot-harbor.prod.com/openspug/spug-service
    container_name: spug
    privileged: true
    restart: always
    volumes:
      - /data/spugv3/service:/data/spug
      - /data/spugv3/repos:/data/repos
    ports:
      # 如果80端口被占用可替换为其他端口,例如: - "8000:80"
      - "80:80"
    environment:
      - MYSQL_DATABASE=spug
      - MYSQL_USER=spug
      - MYSQL_PASSWORD=spug.cc
      - MYSQL_HOST=db
      - MYSQL_PORT=3306
    depends_on:
      - db

启动容器


docker-compose up -d

[root@p1edaspk02 /data/spugv3]#ll
total 16
-rw-r--r-- 1 root root      903 Feb 15 14:42 docker-compose.yml
drwxr-xr-x 6 ods  ssh_keys 4096 Feb 15 14:42 mysql
drwxr-xr-x 2 root root     4096 Feb 15 14:38 repos
drwxr-xr-x 7 root root     4096 Nov 22 22:40 service
[root@p1edaspk02 /data/spugv3]#docker-compose up -d
Pulling spug (10.50.10.185/spug/openspug/spug-service:)...
latest: Pulling from spug/openspug/spug-service
2d473b07cdd5: Pull complete
bdb0935e8d37: Pull complete
1d6205a807d3: Pull complete
59f34e576c77: Pull complete
02c1c97d4b1b: Pull complete
0c036ff8db69: Pull complete
d29ea661ea93: Pull complete
a771e1af3d9c: Pull complete
4c5ea51c617e: Pull complete
50f24e73c5d1: Pull complete
7a6fe3f468e0: Pull complete
5925d2f1942b: Pull complete
1725bcbd6235: Pull complete
6d9da4e99b24: Pull complete
Digest: sha256:56917efe2ab423698ab83d03abd3fc57ec33988003cba7e5634b28c04ab8bb5b
Status: Downloaded newer image for 10.50.10.185/spug/openspug/spug-service:latest
Creating spug-db ... done
Creating spug    ... done

以下操作会创建一个用户名为 admin 密码为 Admin123 的管理员账户,可自行替换管理员账户/密码。

docker exec spug init_spug admin Admin123456
#docker exec spug init_spug admin Admin123 
Migrations for 'account':
  data/spug/spug_api/apps/account/migrations/0001_initial.py
    - Create model History
    - Create model Role
    - Create model User
    - Add field created_by to role
Migrations for 'alarm':
  data/spug/spug_api/apps/alarm/migrations/0001_initial.py
    - Create model Alarm
    - Create model Group
    - Create model Contact
Migrations for 'config':
  data/spug/spug_api/apps/config/migrations/0001_initial.py
    - Create model Service
    - Create model Environment
    - Create model ConfigHistory
    - Create model Config
Migrations for 'exec':
  data/spug/spug_api/apps/exec/migrations/0001_initial.py
    - Create model Transfer
    - Create model ExecTemplate
    - Create model ExecHistory
Migrations for 'home':
  data/spug/spug_api/apps/home/migrations/0001_initial.py
    - Create model Navigation
    - Create model Notice
Migrations for 'host':
  data/spug/spug_api/apps/host/migrations/0001_initial.py
    - Create model Host
    - Create model HostExtend
    - Create model Group
Migrations for 'monitor':
  data/spug/spug_api/apps/monitor/migrations/0001_initial.py
    - Create model Detection
Migrations for 'notify':
  data/spug/spug_api/apps/notify/migrations/0001_initial.py
    - Create model Notify
Migrations for 'schedule':
  data/spug/spug_api/apps/schedule/migrations/0001_initial.py
    - Create model History
    - Create model Task
Migrations for 'setting':
  data/spug/spug_api/apps/setting/migrations/0001_initial.py
    - Create model Setting
    - Create model UserSetting
Migrations for 'app':
  data/spug/spug_api/apps/app/migrations/0001_initial.py
    - Create model App
    - Create model Deploy
    - Create model DeployExtend1
    - Create model DeployExtend2
Migrations for 'repository':
  data/spug/spug_api/apps/repository/migrations/0001_initial.py
    - Create model Repository
Migrations for 'deploy':
  data/spug/spug_api/apps/deploy/migrations/0001_initial.py
    - Create model DeployRequest
Operations to perform:
  Apply all migrations: account, alarm, app, config, deploy, exec, home, host, monitor, notify, repository, schedule, setting
Running migrations:
  Applying account.0001_initial... OK
  Applying alarm.0001_initial... OK
  Applying config.0001_initial... OK
  Applying app.0001_initial... OK
  Applying repository.0001_initial... OK
  Applying deploy.0001_initial... OK
  Applying exec.0001_initial... OK
  Applying home.0001_initial... OK
  Applying host.0001_initial... OK
  Applying monitor.0001_initial... OK
  Applying notify.0001_initial... OK
  Applying schedule.0001_initial... OK
  Applying setting.0001_initial... OK
初始化/更新成功
创建用户成功

登录

九、如何使用配置中心


配置中心的时候可以少创建很多应用,如果一个应用有很多环境,可以使用配置中心这个功能,在应用配置中动态获取配置。

目前项目中环境分类并不是很多,没有使用该功能。后续持续关注,必要时可以引入配置中心这个功能。

获取配置中心的数据 并写入环境变量
# 应用发布前
请求地址:/api/apis/config/
请求方法: GET
curl -so .env http://spug.prod:8099/api/apis/config/?apiToken=$SPUG_API_TOKEN 
curl "http://spug.prod:8099/config/?apiKey=JLV8IGO0DhoxcM7I&app=order&env=test"
如何获取?
/api/apis/config/
curl "http://spug.prod:8099/api/apis/config/?apiKey=JLV8IGO0DhoxcM7I&app=rptetl&env=container"


相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
6月前
|
小程序 JavaScript 开发者
小程序项目开发实战:从零到上线
小程序项目开发实战:从零到上线
106 0
|
6月前
|
SQL 运维 关系型数据库
阿里云DTS踩坑经验分享系列|数据不一致修复大法
阿里云数据传输服务DTS在帮助用户迁移数据、同步数据时,在某些复杂场景下会出现源库与目标库数据不一致的问题,造成数据错误,给用户带来困扰。由于数据不一致的问题很难完全避免,为了及时修复不一致的数据,DTS产品推出数据订正功能,保障用户在同步\迁移数据时的数据一致性。本文介绍了产生数据不一致的一些典型场景,并重点阐述了如何使用DTS数据订正功能来修复不一致的数据。
559 4
|
6月前
|
测试技术
项目上线后发现bug,该怎么办?
项目上线后发现bug,该怎么办?
163 0
|
监控 前端开发 测试技术
让项目顺利上线:做好转测试与上线准备
转测试是项目上线前最后一道坎,需求全部做完并自测后,项目就进入了转测试阶段
591 0
让项目顺利上线:做好转测试与上线准备
|
存储 视频直播 API
体育比赛直播软件开发难点,源码搭建和上线所需的关键资料
随着体育直播的普及,许多开发团队致力于开发稳定、功能丰富的体育直播APP。本文将探讨体育直播APP开发中的难点,并介绍利用东莞梦幻网络科技提供的体育直播源码搭建和上线所需的关键资料。
|
Web App开发 缓存 移动开发
企微开发踩坑指南
企微开发踩坑指南
362 0
|
测试技术 数据库
项目上线出bug怎么处理
项目上线出bug怎么处理
|
前端开发 JavaScript ice
flexiwan项目踩坑实践
flexiManage是以色列一家初创公司flexiWAN开源的基于SD-WAN平台的应用层的框架,包括flexiManage服务端框架以及硬件侧的flexiAgent框架,然而其并没有开源前端框架,为了验证其SD-WAN方案的可行性,需要快速搭建一个前端应用
271 0
|
XML SQL JavaScript
SpringBoot日记本系统全程直播09:项目一期完结
大家好,我是兔哥呀。我又来啦,这个SpringBoot日记本系统已经接近尾声了,目前已经完成的模块有日记本的增删改查,类型的增删改查,头像上传,还有个人中心。 最后一节呢,我们来做一个收尾工作哈。
179 0
|
缓存 移动开发 负载均衡
关于项目刚上线前后端所遇到主要问题的复盘
最近正在做的项目上线了,问题很多,有前端的问题也有后端的问题。最近也接触了一点公司的后端,顺便一起简单的总结一下。
186 0
下一篇
无影云桌面