Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Jar包部署为linux系统服务

Jar包部署为linux系统服务

作者头像
公众号iOS逆向
发布于 2024-06-27 05:37:43
发布于 2024-06-27 05:37:43
39800
代码可运行
举报
文章被收录于专栏:iOS逆向与安全iOS逆向与安全
运行总次数:0
代码可运行

引言

需求:部署Java应用为自启动服务(添加开机启动项)

以部署xx_SOAP_NANSHA.jar 为例子。

I 以系统服务的方式部署(推荐)

服务器信息

1.1 创建systemd服务

systemctl 新增服务:

进入system目录创建service启动文件.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd /usr/lib/systemd/system
#cd /etc/systemd/system
touch nansha.service

配置service:vi nansha.service

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Unit]
Description=nansha
After=syslog.target network.target

[Service]
Type=simple
#ExecStart=/home/JarRun/nansha/start.sh
ExecStart=/usr/bin/nohup /usr/local/btjdk/jdk8/bin/java -Xms1024m -Xmx1024m -Xmn256m -XX:MaxDirectMemorySize=5G -jar  /home/JarRun/nansha/xxx_SOAP_NANSHA-0.0.1-SNAPSHOT.jar  > /home/JarRun/nansha/PUSHAPI.log 2>&1 & echo $! > /home/JarRun/nansha/PUSHAPI.txt
#ExecStop=/home/JarRun/nansha/stop.sh
Restart=always
RestartSec=300
StartLimitBurst=3
User=root 
Group=root
#配置工作目录,默认是~。服务产生得文件、日志信息会存入到工作目录
WorkingDirectory=/home/JarRun/nansha
[Install]
WantedBy=multi-user.target

开机启动systemctl enable nansha

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost system]# systemctl enable nansha
Created symlink from /etc/systemd/system/multi-user.target.wants/nansha.service to /usr/lib/systemd/system/nansha.service.

启动服务: systemctl start nansha重启服务systemctl restart nansha查看该服务的状态:systemctl status nansha停止服务并从自启动项中删除

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo systemctl stop nansha
sudo systemctl disable nansha

查看服务日志信息:journalctl -xe

查看启动进程: ps -ef |grep xxx.jar

1.2 SSH上传jar包,并重启服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/sh
# ssh-copy-id -i ~/.ssh/mac_id_rsa.pub root@192.168.0.14
# 定义远程服务器的用户名和IP地址
REMOTE_HOST="25"
#path
REMOTE_PATH="/home/JarRun/nansha/_SOAP_NANSHA-0.0.1-SNAPSHOT.jar"
LOCAL_PATH="/Users/feitong/Downloads/zkn-es/CT_SOAP_NANSHA/target/_SOAP_NANSHA-0.0.1-SNAPSHOT.jar"

scp -o StrictHostKeyChecking=no $LOCAL_PATH $REMOTE_HOST:$REMOTE_PATH #1. 上传jar包
# 要执行的远程命令
REMOTE_COMMAND=" systemctl restart nansha"
#echo $REMOTE_COMMAND
ssh -o StrictHostKeyChecking=no $REMOTE_HOST $REMOTE_COMMAND # 2. 重启服务

# 脚本执行完毕,退出状态为0
exit 0

1.3 收集自定义systemd服务的日志【可选】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#nohup command & # 在后台运行command,忽略挂起信号
nohup  /usr/bin/journalctl -f -u gd_push.service >> /home/JarRun/PUSHAPI/log.txt 2>&1 &
 nohup  /usr/bin/journalctl -f -u changle_kafka.service  >> /home/JarRun/PUSHAPI_Kafka/log.txt 2>&1 &
# journalctl 持续监听新的日志条目,可以添加-f参数

II 脚本部署方式(不推荐)

2.1 启动脚本

chmod a+x start.sh

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash
# 写Java命令的绝对路径,方便SSH远程操作。/usr/local/btjdk/jdk8/bin/java
nohup /usr/local/btjdk/jdk8/bin/java -Xms1024m -Xmx1024m -Xmn256m -XX:MaxDirectMemorySize=5G -jar  SOAP-0.0.1-SNAPSHOT.jar > PUSHAPI.log 2>&1 & echo $! > PUSHAPI.txt

推荐使用绝对路径,方便ssh远程执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash
echo "start"
/usr/bin/nohup /usr/local/btjdk/jdk8/bin/java -Xms1024m -Xmx1024m -Xmn256m -XX:MaxDirectMemorySize=5G -jar  /home/JarRun/nansha/xx_SOAP_NANSHA-0.0.1-SNAPSHOT.jar  > /home/JarRun/nansha/PUSHAPI.log 2>&1 & echo $! > /home/JarRun/nansha/PUSHAPI.txt
#exit 0
echo "start done"

2.2 关闭脚本

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash
PID=$(cat PUSHAPI.txt)
kill -9 $PID
#如果想要不报错,在后面加上其他指令即可:
echo "执行完毕"

推荐使用绝对路径,方便ssh远程执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/bash
PID=$(cd /home/JarRun/nansha && cat PUSHAPI.txt)
/usr/bin/kill -9 $PID 2>devnull ||  echo "done"
exit 0

2.3 SSH上传jar包,并重启服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/bin/sh
# ssh-copy-id -i ~/.ssh/mac_id_rsa.pub root@192.168.0.14
# 定义远程服务器的用户名和IP地址
REMOTE_HOST="25"
#path
REMOTE_PATH="/home/JarRun/nansha/_SOAP_NANSHA-0.0.1-SNAPSHOT.jar"
LOCAL_PATH="/Users/feitong/Downloads/zkn-es/CNFT_SOAP_NANSHA/target/_SOAP_NANSHA-0.0.1-SNAPSHOT.jar"

scp -o StrictHostKeyChecking=no $LOCAL_PATH $REMOTE_HOST:$REMOTE_PATH
# 要执行的远程命令
REMOTE_COMMAND=" /home/JarRun/nansha/stop.sh &&  /home/JarRun/nansha/start.sh"
#echo $REMOTE_COMMAND
ssh -o StrictHostKeyChecking=no $REMOTE_HOST $REMOTE_COMMAND

# 脚本执行完毕,退出状态为0
exit 0

III 打包

3.1 build中的plugins中标签的含义

build中的plugins,它定义了 spring-boot-maven-plugin 插件的使用,用于将项目打包成可执行的 JAR 文件,并执行其他与 Spring Boot 相关的任务。

1:<plugin> 标签:这是 Maven 构建工具用来定义插件的起始标签。在这个标签内,可以配置插件的详细信息; 2:<groupId> <artifactId>:这两个标签指定了插件的坐标(Coordinates),即插件的唯一标识符。在这里,org.springframework.boot 是插件的 Group ID,spring-boot-maven-plugin 是插件的 Artifact ID。这些信息用于在 Maven 仓库中定位并下载插件。3:<configuration> 标签:这个标签包含了插件的配置信息。

<mainClass>标签:指定了 Spring Boot 应用程序的主类,主类是 Spring Boot 应用程序的入口点,即可执行 JAR 文件的入口点,当你运行 JAR 文件时,这个类的 main 方法会被执行。在这个例子中,主类是 com.lucky.PracticeApplication

3.2 jar中没有主清单属性

一个JAR文件通常包含一个名为MANIFEST.MF的清单文件,这个文件定义了关于JAR文件的各种元数据

没有包含BOOT-INF

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/

解决方式: maven打包是配置信息不能跳过,去掉configuration标签的skip

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.xxx.xx_soap_nansha.SoapNanshaApplication</mainClass>
<!--                    <skip>true</skip>-->
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Archiver-Version: Plexus Archiver
Built-By: Administrator
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.xx.soap.SoapApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.7.6
Created-By: Apache Maven 3.8.1
Build-Jdk: 1.8.0_91
Main-Class: org.springframework.boot.loader.JarLauncher

3.3 java项目中的classpath到底是什么

开发时期的项目里,src/main/下面的java和resources文件夹都被(编译)打包到了生产包的WEB-INF/classes/目录下;而原来WEB-INF下面的views和web.xml则仍然还是在WEB-INF下面。同时由maven引入的依赖都被放入到了WEB-INF/lib/下面。最后,编译后的class文件和资源文件都放在了classes目录下。

IV 预备知识:Systemd服务

lib/systemd/system /run/systemd/system /etc/systemd/system 这三个目录的配置文件优先级依次从低到高,如果同一选项三个地方都配置了,优先级高的会覆盖优先级低的。

系统安装时,默认会将unit文件放在/lib/systemd/system目录。

在/usr/lib/systemd/system目录自动存放启动文件的配置,里面一般包含有*.service的文件:

如果想要修改系统默认的配置,比如nginx.service,一般有两种方法:

1、在/etc/systemd/system目录下创建nginx.service文件,里面写上我们自己的配置。

在/etc/systemd/system下面创建nginx.service.d目录,在这个目录里面新建任何以.conf结尾的文件,然后写入自己的配置。推荐这种做法。

2、/run/systemd/system这个目录一般是进程在运行时动态创建unit文件的目录,一般很少修改,除非是修改程序运行时的一些参数时,即Session级别的,才在这里做修改。

4.1 文件的基本结构

[Unit]:服务的全局信息和依赖性声明,如服务名称、描述等。

[Service]:指定服务的具体配置,如服务执行的命令、工作目录等。

[Install]:指定服务的安装方式,如服务的启动级别等。

4.2 [Unit]字段的配置

Description:对服务的简短描述。

Before:定义服务在其他服务之前启动。

After:定义服务在其他服务之后启动。

Requires:定义服务启动需要哪些其他服务已启动,否则无法启动。

PartOf:定义该服务是其他服务的一部分,如果其他服务停止,该服务也会停止。

Wants:定义服务启动时可同时启动哪些其他服务。

Condition...:定义服务启动的条件,如ConditionPathExists表示某个路径存在时才启动该服务。

4.3 [Service]字段的配置

Type:服务类型,可以是simple、forking、ondemand、notify等。

ExecStart:服务启动命令,可以是单个命令、脚本文件、或者多个命令组成的脚本。

ExecStop:停止服务的命令。

User:定义服务运行的用户。

Group:定义服务运行的用户组。

PrivateTmp:将服务的/tmp目录挂载到私有的命名空间中,以增强安全性。

Restart:定义服务异常退出时如何重启。

WorkingDirectory:定义服务工作目录。

Environment:定义服务的环境变量等。

ProtectSystem:防止服务对系统文件进行修改。

NoNewPrivileges:防止服务通过setuid或setgid等提升权限。

4.4 [Install]字段的配置

WantedBy:定义在哪些系统运行级别下启用此服务。

RequiredBy:启动其他系统服务时必需启动此服务。

4.5 .service 文件示例

vi /etc/systemd/system/myservice.service

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Unit]
Description=MyService
After=network.target
  
[Service]
Type=simple
ExecStart=/usr/bin/myservice
WorkingDirectory=/var/myservice
User=myservice
Group=myservice
Restart=always
RestartSec=30
StartLimitInterval=400
StartLimitBurst=3
  
[Install]
WantedBy=multi-user.target

定义了一个名为"MyService"的服务,服务启动时执行/usr/bin/myservice命令,执行工作目录为/var/myservice,运行用户为myservice。如果服务异常退出,则每30秒尝试重新启动,最多尝试3次。最后,服务将在多用户运行级别下启用。

4.6 服务管理

使用systemctl重启服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo systemctl restart <服务名>
To force a start use "systemctl reset-failed nansha.service" followed by "systemctl start nansha.service" again.

重启服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
systemctl reset-failed nansha.service && systemctl start nansha.service

列出所有服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo systemctl list-unit-files --type=service

重载配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Warning: nansha.service changed on disk. Run 'systemctl daemon-reload' to reload units.

查看错误信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
journalctl -xe

4.7 收集自定义systemd服务的日志

systemd是Linux系统中广泛使用的系统和服务管理器,它以journal的形式记录系统和应用程序的日志。

持续监听新的日志条目,可以添加-f参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/usr/bin/nohup journalctl -f -u gd_push.service >> /home/JarRun/PUSHAPI/log.txt 2>&1

获取特定时间段的日志,可以使用--since和--until参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
journalctl -u my-custom-service.service --since "2023-03-01 00:00:00" --until "2023-03-02 00:00:00"
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS逆向 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
IDEA-SpringBoot项目利用docker实现一键打包部署运行
1. 开启docker远程访问 cd /lib/systemd/system sudo vim docker.service
devi
2021/08/19
1.1K0
IDEA-SpringBoot项目利用docker实现一键打包部署运行
linux部署jar包脚本和注册开机启动
之前开发了windows部署jar包为服务的工具在实际生产环境中使用非常简单方便,公司部分项目是部署在linux系统中的,所以决定整合一个通用的jar包部署脚本,并注册为开机启动服务,为开发实施的同事提供方便,以下操作实际系统环境为centos8
code2roc
2023/07/19
4680
_SpringBoot项目部署
SpringBoot项目是依赖于Maven构建的,但打包时如果只依赖Maven打包工具则会打包不完整,我们还需要在SpringBoot项目中引入SpringBoot打包插件 :
会洗碗的CV工程师
2023/11/16
7180
_SpringBoot项目部署
SpringBoot Jar包瘦身 - 跟大文件说再见!
SpringBoot部署起来配置非常少,如果服务器部署在公司内网,上传速度还行,但是如果部署在公网(阿里云等云服务器上),部署起来实在头疼、就是 编译出来的 Jar 包很大,如果工程引入了许多开源组件(SpringCloud等),那就更大了。这个时候如果想要对线上运行工程有一些微调,则非常痛苦
云扬四海
2019/08/06
1.8K0
SpringBoot详细研究-04部署测试与监控
这部分的内容实际就是devops的主要工作内容,当然一名合格的程序要也需要掌握这部分的知识。 热部署 简单来说,在开发时,修改了任何的代码,IDE将自动编译运行及发布;在发布时,当前发布不影
用户1216676
2018/01/24
1K0
Spring Boot - 瘦身大作战:优雅应对Spring Boot Fat Jar
通过启动参数loader.path配置外置依赖包的加载路径。 项目成功启动,说明我们配置的外包依赖包加载生效了
小小工匠
2023/11/26
9000
Spring Boot - 瘦身大作战:优雅应对Spring Boot Fat Jar
springboot(十六):使用Jenkins部署Spring Boot
jenkins是devops神器,本篇文章介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署分为三个步骤; 第一步,jenkins安装 第二步,插件安装和配置 第三步,Push SSH 第四步,部署项目 第一步 ,jenkins安装 准备环境: JDK:1.8 Jenkins:2.83 Centos:7.3 maven 3.5‘ jdk默认已经安装完成 配置maven 版本要求maven3.5.0 软件下载 wget http://mirror.bit.edu.cn/a
纯洁的微笑
2018/04/18
3.4K0
springboot(十六):使用Jenkins部署Spring Boot
SpringBoot 2.x项目jar包部署
如果此处不指定mainClass的话,很有可能就是项目可以打包成功,并且可以java -jar *.jar成功启动,但是访问不了任何服务。
程裕强
2019/05/27
1.6K0
Docker教程(九)部署Spring Boot项目
开启Docker远程连接后,在开发和学习时都能带来便利,但请不要将此方式用在外部网络环境,以免带来安全问题,下图是官方警告:
小东啊
2020/07/23
3.4K0
Docker教程(九)部署Spring Boot项目
Linux系统:第十五章:gitlab集成CI
集成gitlab的CI首先需要安装好docker和gitlab,大家可以参考我上一章节:Linux系统:第十四章:安装Docker,下载安装配置gitlab以及jenkins,图文讲解CI流程。
Java廖志伟
2022/03/07
8200
Linux系统:第十五章:gitlab集成CI
linux将jar包做成服务
在linux下,将jar包做成服务,实现开机自启动。 创建service vi /etc/systemd/system/app.service 编辑服务内容 注意ExecStart的命令执行路径即可 [Unit] Description=My App Service After=network.target [Service] ExecStart=/usr/local/java/jdk-11.0.2/bin/java -jar /root/app.jar WorkingDirectory=/root R
无敌小菜鸟
2023/05/22
1.8K0
Spring Boot-注册linux的服务
Linux下运行的软件通常我们可以将它注册服务,这样我们就可以通过命令开启,关闭,开机保持运行等功能。
全栈程序员站长
2022/06/29
8040
Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖?
“松哥,为什么我的 Spring Boot 项目打包成的 jar ,被其他项目依赖之后,总是报找不到类的错误?”
田维常
2019/07/16
1.3K0
Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖?
Spring Boot(十六):使用 Jenkins 部署 Spring Boot
Jenkins 是 Devops 神器,本篇文章介绍如何安装和使用 Jenkins 部署 Spring Boot 项目
纯洁的微笑
2019/09/19
8720
Spring Boot(十六):使用 Jenkins 部署 Spring Boot
Linux系统:第十四章:安装Docker,安装配置gitlab私有仓库以及jenkins自动化部署(图文)
#出现[Errno -1] 软件包与预期下载的不符。 建议:运行 yum --enablerepo=updates clean metadata正在尝试其它镜像。使用以下命令
Java廖志伟
2022/03/07
1.3K0
Linux系统:第十四章:安装Docker,安装配置gitlab私有仓库以及jenkins自动化部署(图文)
Linux操作指令随记
vim /etc/ssh/sshd_config 去掉22的注释.添加新的端口 Port 4365 重启sshd服务 测试是否可以连接 测试无问题 注释掉22端口(安全性)
java攻城狮
2021/01/18
1.2K0
我写的dubbo扩展jar包如何无侵入的给别人使用
有这么一个场景, 我写了一个dubbo spi扩展jar包 dubbo-ext.jar; 这个Jar包是不可执行包(没有main函数), 它的作用是对现有运行的dubbo服务做一些增强; 那么这样的一个扩展包,要符合即插即用的原则;要无侵入的增强;
石臻臻的杂货铺[同名公众号]
2021/07/14
1K0
SpringBoot打包部署解析:jar包的生成和结构
SpringBoot项目支持两种常见的打包形式: jar 包和 war 包。默认情况下创建的 Spring Boot项目是采用 jar 包形式,如果项目需要 war 包,可通过修改配置打成 war 包。
愿天堂没有BUG
2022/10/28
1.9K0
SpringBoot打包部署解析:jar包的生成和结构
spring boot 使用maven和fat jar/war运行应用程序的对比
上篇文章我们介绍了Spring boot的fat jar/war包,jar/war包都可以使用 java -jar 命令来运行,而maven也提供了mvn spring-boot:run 命令来运行应用程序,下面我们看看两者有什么不同。
程序那些事
2020/07/08
1.6K0
SpringBoot-Jar包分离
(1)按照正常的springboot项目打包方式,对项目进行打包package,其打包后目录如下:
星辰sea
2022/10/29
7270
SpringBoot-Jar包分离
推荐阅读
相关推荐
IDEA-SpringBoot项目利用docker实现一键打包部署运行
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验