前言
代码路径:https://github.com/Jackpy-node/springboot.git
遇到的问题解决:Linux下mysql经常自动停止挂掉重启的完美解决方式
新建项目
1、新建SpringBoot项目
2、项目类型默认Maven Project,包类型选择生成War或者Jar
3、选择Spring Web项目,并选择SpringBoot版本,点击【next】,完成新建项目
4、项目目录结构
5、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.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kpy</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 这里打成war包 若打jar,需将war改为jar -->
<packaging>war</packaging>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 使用logback记录日志时,必须导入slf4j-api、logback-core、logback-classic -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- Jpa数据Java持久层API时,需导入spring-boot-starter-data-jpa、commons-dbcp -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
6、日志配置文件logback.xml
<?xml version="1.0" encoding="utf-8" ?>
<!-- 从高到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志-->
<!--属性描述:
scan:性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 定义日志文件 输入位置 -->
<property name="logPath" value="./logs"/>
<!-- 日志最大的历史 30天 -->
<property name="maxHistory" value="30"/>
<!-- 配置项, 通过此节点配置日志输出位置(控制台、文件、数据库)、输出格式等-->
<!--
name:标签名,为了让其他标签调用的唯一标示
class:引用的类,从此类中可以看出该appender标签定义的是日志输出的位置
-->
<!-- 时间滚动输出 level为 CONSOLE 日志 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 常用
%-数字xxx 分隔多少,不要和属性分开写,不挨着会报错
%d{HH……} | d 日期,分开会报错
%thread 线程
%level | p | le 显示级别
%logger{数字} | c | lo 类文件,虽然和class一样,但是如果包.类很长,这个可以获取简约长度展示
%class | c 输出同上
%file | F 是哪个.java文件
%m | msg | message 输出信息
%M 方法
%line | L 错误的行号,少用
%caller{数字} 输出信息深度
-->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%-5level] %logger.%method:%L -%msg%n</pattern>
</encoder>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender-->
<!-- 滚动策略,它根据时间来制定滚动策略.既负责滚动也负责触发滚动 -->
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!– 输出路径 –>
<fileNamePattern>${logPath}/info/%d{yyyy-MM-dd}.log</fileNamePattern>
<!– 日志文件保留天数 –>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>-->
<!-- rollingPolicy按照固定窗口模式生成归档日志文件,当文件大于20MB时,生成新的日志文件。窗口大小是1到3,当保存了3个归档文件后,将覆盖最早的日志。
同一个RollingFileAppender中,rollingPolicy只能存在一个有效的-->
<!--<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${logPath}/%d{yyyy-MM-dd}/.log.%i.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>-->
<!-- 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender触发当前活动文件滚动 -->
<!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${logPath}/info/%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- each file should be at most 5MB, keep 30 days worth of history, but at most 20GB -->
<maxFileSize>5MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %method:%L -%msg%n</pattern>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logPath}/error/%d{yyyy-MM-dd}.log</fileNamePattern>
<!– 日志文件保留天数 –>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<!– 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender触发当前活动文件滚动 –>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>-->
<!-- 日志格式为${logPath}/error/%d{yyyy-MM-dd}.%i.log时,需要按照以下配置:-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${logPath}/error/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 5MB, keep 30 days worth of history, but at most 20GB -->
<maxFileSize>5MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %method:%L -%msg%n</pattern>
</encoder>
<!-- 此日志文件只记录error级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logPath}/debug/%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<!-- 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender触发当前活动文件滚动 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %method:%L -%msg%n</pattern>
</encoder>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logPath}/warn/%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志文件保留天数 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<!-- 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender触发当前活动文件滚动 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %method:%L -%msg%n</pattern>
</encoder>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<!-- 根节点,表名基本的日志级别,里面可以由多个appender规则 -->
<!-- level="info"代表基础日志级别为info -->
<!-- 从高到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<root level="DEBUG">
<!-- 引入控制台输出规则 -->
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO" />
<appender-ref ref="ERROR" />
<appender-ref ref="DEBUG" />
<appender-ref ref="WARN" />
</root>
</configuration>
7、application.properties属性文件,在属性文件中指定数据库配置信息,服务器端口【重要】
设置服务器访问端口
# 服务器HTTP端口
server.port= 8080
设置数据库连接池信息
spring.datasource.max-active=50
#是否在自动回收超时连接的时候打印连接的超时错误
spring.datasource.log-abandoned=true
#是否自动回收超时连接
spring.datasource.remove-abandoned=true
##<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
spring.datasource.max-wait=1000
spring.datasource.test-while-idle=true
#检测数据库的查询语句
spring.datasource.validation-query=select 1 from dual
spring.datasource.test-on-borrow=true
#每隔五分钟检测空闲超过10分钟的连接
spring.datasource.min-evictable-idle-time-millis=600000
spring.datasource.time-between-eviction-runs-millis=300000
#服务器配置较低时,需要调整,连接池配置
#Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=12
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000
spring.datasource.hikari.auto-commit=true
完整 application.properties
#Thymeleaf路径
spring.thymeleaf.prefix=classpath:/templates/
#Thymeleaf后缀
spring.thymeleaf.suffix=.html
#Thymeleaf编码
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML5
#JDBC数据库配置
spring.datasource.initialization-mode=never
spring.datasource.url=jdbc:mysql://49.235.145.140:3306/kpy
spring.datasource.username=root
spring.datasource.password=199489
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.max-active=50
#是否在自动回收超时连接的时候打印连接的超时错误
spring.datasource.log-abandoned=true
#是否自动回收超时连接
spring.datasource.remove-abandoned=true
##<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
spring.datasource.max-wait=1000
spring.datasource.test-while-idle=true
#检测数据库的查询语句
spring.datasource.validation-query=select 1 from dual
spring.datasource.test-on-borrow=true
#每隔五分钟检测空闲超过10分钟的连接
spring.datasource.min-evictable-idle-time-millis=600000
spring.datasource.time-between-eviction-runs-millis=300000
#服务器配置较低时,需要调整,连接池配置
#Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=12
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000
spring.datasource.hikari.auto-commit=true
# 服务器HTTP端口
server.port= 8080
8、修改启动Application文件继承SpringBootServletInitializer,实现configure方法【重要】
package com.kpy.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class SpringbootApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
// SpringBootServletInitializer 实现configure 方便打war 外部服务器部署。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringbootApplication.class);
}
}
9、注意:修改pom.xml
10、可以直接到项目根目录下面:运行 maven package
命令,打包;我个人直接使用Idea集成的打包工具
11、上传项目至服务器指定目录下
云服务器部署
1、进入安全组,配置安全组规则
2、配置安全组规则,访问的IP和端口
3、进入服务器,查看防火墙状态,确认防火墙已关闭
1、查看firewall服务状态
systemctl status firewalld
出现Active: active (running)切高亮显示则表示是启动状态。
出现 Active: inactive (dead)灰色表示停止,看单词也行。
2、查看firewall的状态
firewall-cmd --state
3、开启、重启、关闭、firewalld.service服务
# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
4、查看防火墙规则
firewall-cmd --list-all
5、查询、开放、关闭端口
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
4、进入服务器,项目war包所在路径下启动项目
nohup java -jar springboot-0.0.1-SNAPSHOT.war & #将项目启动并且成为守护进程
启动:
启动成功:
启动完整之后查看8080端口是否被监听
#8080端口是否被监听
netstat -an | grep 8080
查看后台守护进程是否正常
#查看守护进程
ps -ef | grep java
页面访问:
总结
整个项目部署过程中,出现问题比较多的是项目启动过程中mysql数据库异常,具体【前言】部分的第二篇文章