首页 > 系统相关 >java:使用supervisor优雅的管理SpringBoot进程

java:使用supervisor优雅的管理SpringBoot进程

时间:2023-01-01 10:32:44浏览次数:63  
标签:java SpringBoot boot usr 进程 supervisor supervisord

(目录)

1、创建 SpringBoot 项目

通过 https://start.spring.io/ 创建一个 SpringBoot 项目

项目结构

$ tree -I target
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo
    │   │               ├── Application.java
    │   │               └── controller
    │   │                   └── IndexController.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── example
                    └── demo
                        └── ApplicationTests.java

完整依赖 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

项目启动类 Application.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

控制器 IndexController.java

package com.example.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class IndexController {
    @GetMapping("/")
    public String index() {
        log.info("IndexController");
        return "Hello";
    }
}

2、手工部署项目

# 打包
$ mvn package

# 上传,此处上传至docker
$ docker cp target/demo-0.0.1-SNAPSHOT.jar centos7:/usr/local

# 运行
java -jar /usr/local/demo-0.0.1-SNAPSHOT.jar

查看容器端口号映射

$ docker port centos7
3306/tcp -> 0.0.0.0:8086
8080/tcp -> 0.0.0.0:8082

所以我们通过 8082 端口就可以访问到容器中的 SpringBoot 项目

http://localhost:8082/

如果在 Linux 环境,需要检查防火墙是否开放 8080 端口

firewall-cmd --zone=public --list-ports

3、部署优化

  • 后台运行
  • 日志输出到文件

nohup 不挂断运行

英文全称:no hang up

语法

nohup command [args...] [&]

参数说明

  • command 要执行的命令
  • args 参数
  • & 让命令后台运行

举例

# 后台运行java -jar命令,并将日志输出到文件hello.log
nohup java -jar demo-0.0.1-SNAPSHOT.jar &> hello.log &

# 查看日志
tail -f hello.log

停止 SpringBoot 程序

# 查找进程
ps -ef | grep 'java -jar'

# 结束进程
kill -9 <pid>

4、通过 shell 脚本自动部署项目

自动部署步骤

  1. 在 Linux 中安装 Git
  2. 在 Linux 中安装 maven
  3. 编写 shell 脚本(拉取代码、编译、打包、启动)
  4. 为用户授予执行 shell 脚本的权限
  5. 执行 shell 脚本

代码操作过程

本地开发环境
    -- push -->
Git仓库
    -- pull -->
Linux服务器

4.1、在 Linux 安装 Git

通过yum安装git

# 搜索git
yum list git

# 安装git
yum install -y git

克隆代码

cd /usr/local

git clone https://gitee.com/mouday/helloworld.git

4.2、在 Linux 安装 Maven

下载地址 https://maven.apache.org/download.cgi

安装步骤

# 1、下载解压
wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz

tar -zxvf apache-maven-3.8.6-bin.tar.gz

# 2、添加环境变量
vim /etc/profile.d/env.sh

# maven
export MAVEN_HOME=/usr/local/apache-maven-3.8.6
export PATH=$PATH:$MAVEN_HOME/bin

# 3、执行生效
source /etc/profile.d/env.sh

# 4、查看版本号
mvn -version
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /usr/local/apache-maven-3.8.6
Java version: 1.8.0_351, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_351/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "4.19.76-linuxkit", arch: "amd64", family: "unix"

# 5、修改配置
vim /usr/local/apache-maven-3.8.6/conf/settings.xml

<localRepository>/usr/local/repo</localRepository>

4.3、为用户授权

chmod 全称:change mode 控制用户对文件权限

  • 权限:读 r、写 w、执行 x
  • 调用权限:文件所有者(owner)、用户组 group、其他用户 other users
  • 只有文件的所有者和超级用户可以修改文件或目录的权限
- rwx rwx rwx

文件类型 -/d
owner
group
other users

4.4、执行 shell 脚本

bootstart.sh

5、supervisor来管理进程

管理SpringBoot进程的方式

  • 通过nohup启动后台进程
  • 通过service/systemctl系统服务管理进程
  • 通过Python包supervisor管理进程
  • 通过Node.js包pm2管理进程

使用shell脚本的方式,不能很好的管理进程,如果进程挂掉也不会自动重启

可以采用 systemctl + supervisor的方式管理进程

  • systemctl 管理 supervisor
  • supervisor管理用户进程(SpringBoot)

一般情况下,系统都会自带Python2.7,所以我们采用Python包supervisor管理SpringBoot进程

5.1、检查Python环境

supervisor同时支持Python2.7和Python3

python -V
Python 2.7.5

5.2、检查pip

pip -V
pip 20.3.4 from /usr/lib/python2.7/site-packages/pip (python 2.7)

# 如果不存在就安装
# Python2.7
wget https://bootstrap.pypa.io/pip/2.7/get-pip.py

# 安装
python get-pip.py

5.3、安装supervisor

文档

pip install supervisor

生成配置文件

# 生成配置文件目录
mkdir -p /etc/supervisor/conf.d

# 初始化配置文件
echo_supervisord_conf > /etc/supervisor/supervisord.conf

修改配置

vim /etc/supervisor/supervisord.conf

下面几项是必须修改的

[unix_http_server]
;file=/tmp/supervisor.sock   ; (the path to the socket file)
file=/var/run/supervisor.sock ; 修改为 /var/run 目录,避免被系统删除

[supervisord]
;logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile=/var/log/supervisor.log ; 修改为 /var/log 目录,避免被系统删除

;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid ; 修改为 /var/run 目录,避免被系统删除

[supervisorctl]
; 必须和'unix_http_server'里面的设定匹配
;serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
serverurl=unix:///var/run/supervisor.sock ; 修改为 /var/run 目录,避免被系统删除

[include]
;指定应用程序配置文件目录
;files = relative/directory/*.ini
files = conf.d/*.ini

管理命令

# 查看supervisor监管的进程状态
supervisorctl status

# 启动XXX进程
supervisorctl start 进程名

# 停止XXX进程
supervisorctl stop 进程名

# 停止全部进程,注:start、restart、stop都不会载入最新的配置文件。
supervisorctl stop all

# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update

# 查看日志
supervisorctl tail -f spring-boot

5.4、开机启动

新建文件 supervisord.service

# supervisord.service

[Unit] 
Description=Supervisor daemon

[Service] 
Type=forking 
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl shutdown 
ExecReload=/usr/bin/supervisorctl reload 
KillMode=process
Restart=on-failure
RestartSec=42s

[Install] 
WantedBy=multi-user.target

启动服务

cp supervisord.service /usr/lib/systemd/system/

# 开机启动服务
systemctl enable supervisord      

# 验证一下是否为开机启动
systemctl is-enabled supervisord  

# 启动服务
systemctl start supervisord

systemctl status supervisord

systemctl stop supervisord

5.5、添加www用户组和用户

一般不能以root用户来运行程序,需要单独的一个用户来运行线上程序

# 添加用户组
$ groupadd www

# 添加用户
$ useradd -g www -s /sbin/nologin www

# 查看用户
$ id www
uid=1000(www) gid=1000(www) groups=1000(www)

# 或者
$ cat /etc/group
$ cat /etc/passwd

# 赋予权限
chown -R www:www helloworld

# 查看文件属性
ls -lh
drwxr-xr-x  5 www  www   4.0K Dec 30 03:34 helloworld

5.6、项目启动配置

supervisor.conf

[program:spring-boot]
;应用启动目录
directory=/usr/local/helloworld
;使用绝对路径
command=/usr/local/jdk1.8.0_351/bin/java -jar target/demo-0.0.1-SNAPSHOT.jar
;运行用户
user=www

启动进程

# 生成软链
ln -s /usr/local/helloworld/supervisor.conf /etc/supervisor/conf.d/spring-boot.conf

# 更新配置文件
supervisorctl update

# 查看运行进程
ps -ef|grep java
www        238    87 57 05:33 ?        00:00:10 /usr/local/jdk1.8.0_351/bin/java -jar target/demo-0.0.1-SNAPSHOT.jar

参考 Python编程:supervisor模块管理进程实例

6、通过Makefile整合命令

上面涉及到了很多命令,如果都记住有点困难

使用Makefile文件或者shell都可以整合命令

安装make

yum install -y make

Makefile 文件

# 操作命令

# 拉取代码
.PHONY: pull
pull:
	git pull

# maven打包
.PHONY: build
build:
	mvn clean package -Dmaven.test.skip=true

# 重启进程
.PHONY: restart
restart:
	supervisorctl restart spring-boot

# 启动进程
.PHONY: start
start:
	supervisorctl start spring-boot

# 停止进程
.PHONY: stop
stop:
	supervisorctl stop spring-boot

# 日志
.PHONY: log
log:
	supervisorctl tail -f spring-boot

# 部署
.PHONY: deploy
deploy:
	make pull
	make build
	make restart

重新部署项目

make deploy

标签:java,SpringBoot,boot,usr,进程,supervisor,supervisord
From: https://blog.51cto.com/mouday/5980173

相关文章

  • java中的ArrayList的add()源码解析
    使用无参构造器创建的ArrayList对象,示例代码如下:publicclassArrayListTest{publicstaticvoidmain(String[]args){Listlist=newArrayList();......
  • SpringBoot启动时报错 no main manifest attribute, in XXX1.0.0-SNAPSHOT.jar
    SpringBoot启动时报错nomainmanifestattribute,inXXX1.0.0-SNAPSHOT.jar 问题原因在pom.xml的build中添加plugin 解决方案在pom.xml文件中,添加如下内容:......
  • JavaScript(JS基础、变量)
    编程语言编程概念:让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。编程语言:机器语言汇编语言高级语言:C、C++、Java、C#等一、JavaScript1......
  • java基础语法2
    java基础语法2运算符算术运算符:+-*/%++--赋值运算符:=关系运算符:>,>,>=,<=,==,!=,instanceof逻辑运算符:&&,||,!位运算符:&,|,^,~,>>,<<,>>>......
  • 使用 JavaScript 检测用户是否在线
    有时你可能希望增强你的应用程序以通知用户他们可能已经失去了互联网连接。用户可能正在访问你的网站并收到缓存版本,因此通常看起来他们的互联网仍在工作。然而,他们失去了......
  • 基于Java+SpringBoot+vue等疫情期间在线网课管理系统详细设计实现
    目录​​一、前言介绍:​​​​1.1背景及意义      ​​​​1.2系统运行环境​​​​二、系统设计:​​​​2.1 系统架构设计​​​​2.2角色功能图​​​​2.3 登......
  • 第119篇: JavaScript 类
    好家伙,我们先来复习一下 关于Java,类的三大特征:1、封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏......
  • 未配置Datasource时, 启动 SpringBoot 程序报错的问题
    SpringBootwillshowerrorifthereisnodatasourceconfigurationinapplication.yml/application.properties22122911:14:44906mainWbServerApplicationCo......
  • Java数据类型及数据类型转换
    数据类型1、基本类型(PrimitiveType)(1)数值类型:整数类型:byte:占1个字节范围:-128-127short:占2个字节范围:-32768-32767int:占4个字节范围:-2147483648-2147483647long:占......
  • 快来领取你的JavaScript正则表达式速查表
    如果我们想对字符串进行相关(增、删、改、查、检索)操作,就可以用接下来的正则表达式实现 什么是正则表达式正则表达式是用于匹配字符串中字符组合的模式正则表达式通......