SpringBoot的运维实用篇:
(1)打包和运行:
打包 : 实用SpringBoot的话 , 直接打开maven, 实用maven的声明周期方法 : Package 进行打包
打包之前 , 先进行clean , 确保项目是一个纯净的项目 , 然后打包 , 会生成一个target目录 , 在此目录下边 , 会生成一个 项目名字.jar的包 ,
windows下运行程序:
在对应的target包下 , 使用cmd指令 :
java -jar jar包的名称
注意事项 :
<!--jar支持命令行启动需要依赖maven插件的支持 , 请确认打包时是否具有SpringBoot对应的Maven插件-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
注意 : SpringBoot在进行打包的时候 , 会先进行测试 , 如果你的test里边写的有测试的代码 , 它会先执行测试的代码 , 所以在上线运行之前 , 一定要记得将测试代码删除
- 在idea的maven中 , 有一个按钮 , 可以跳过测试阶段 : 点击之后 , test上就会打一个横线 , 再进行打包的时候 , 就会跳过测试
如果打包之后 , 运行的时候 ,出现没有主清单属性 , 说明你打包的时候 , 没有使用maven的插件 , 在 jar中的META-INF的目录下 , 有一个MANIFEST.MF文件 , 这里边有整个项目的关键配置 , 不使用插件打包的话是没有这个配置的
key | value |
---|---|
Main-Class | 这个方法会找到主启动方法 |
Start-Class | 主启动类 |
SpringBoot为了让你的工程能够独立运行 , 将项目依赖的所有jar包都存放在了lib目录下 , 这些jar包是从maven仓库中获取的 , 依赖于你的pom文件
BOOT-INF : 包下的classes , 存放的你所有的程序 , lib存放的项目所有的依赖jar包
META-INF : 包下的maven存放的是项目的pom文件 , MANIFEST.MF文件里有整个项目的关键属性
org包下 : 存放的是SpringBoot的一个工具 , 用来提供项目独立运行的 , 里边是一套类加载器
Linux下运行这个程序 :
-
将文件对应的包上传到Linux系统上 :
-
使用后台的方式运行程序 ,
-
nohup java -jar 程序的名称.jar
-
一旦你执行了这个操作 , 程序就是在后台进行的 , 不会显示在前台 , 这个时候就看不到对应的日志文件了 ,
-
在执行的时候 , 指定一个日志文件
-
nohup java -jar 程序的名称.jar > 日志文件 2>&1 &
关闭服务 : 使用linux的关闭的指令 , 查找对应的进程的id , 然后直接杀死进程
(2)SpringBoot的配置高级 :
1.临时属性:
(1)如果运行程序的时候 , 端口号被另一个重要的进程占用 ,这个时候 , 在原有的启动程序后边 ,
java -jar 程序的名称.jar --server.port=8080
这就是临时的属性操作 , 如果想修改更多的属性 , 在后边加一个空格 , 然后 –属性 即可
2.属性加载的优先顺序 :
从上到下 , 优先级越高 , 命令行配置在第11 , 而我们的文件配置是在第3 , 所以命令行的配置要比文件中的配置优先级要高
3.怎么在项目环境中测试临时属性是否生效 :
在右上角的程序配置中 :
点击Modify options --> 选择Program arguments , 然后在添加的一行中设置对应的命令属性即可
4.断开读取外部临时配置对应的入口
SpringBoot在启动主启动类的时候 , 会将命令行的参数都存放在 主启动类 的参数 args中 , 我们可以直接在主启动类中 , 设置一个arg的数组 , 把我们想要的参数都存在里面 , 然后就不用往run方法中传args了, 直接传这个数组即可
public static void main(String[] args) {
String[] arg = new String[1];
arg[0] = "--server.port=9090";
SpringApplication.run(SSMPApplication.class, arg);
}
这么做可以在启动boot的时候断开读取外部临时配置对应的入口 , 也就是去掉读取外部参数的形参
5.配置文件的四级分类
我们开发完项目之后 , 上线运营的时候 , 根据情况的不同可能会出现修改配置的情况 , 这个时候 ,SpringBoot提供了一个机制 , 能够设置一个配置文件, 其中的配置可以覆盖掉原有的程序员自己写的配置 , 从而来帮助运维人员 , 修改对应的配置 , 而不用修改原有的配置 .
- 在resources包下 , 新建一个目录 config , 其中放一个新配置文件和原有的配置文件同名 , 在这里边设置的配置 , 可以覆盖掉原有的配置属性
- 对于安全等级较高的配置 ,比如密码等信息 , SpringBoot提供了新的配置文件
将SpringBoot的配置文件放在和项目的jar包同级的目录中 , Spring就会读取这个配置文件覆盖掉别的配置信息
配置文件级别 | 位置 | 使用者 |
---|---|---|
1级配置(最高级) | 在项目的jar包同级的目录中的config中的配置文件 | 服务于运维经理整体调控 |
2级配置 | 在项目的jar包的同级目录中的配置文件 | 服务于运维人员配置涉密线上环境 |
3级配置 | 在resources包下的config目录中的配置文件 | 服务于项目经理整体调控 |
4级(最低级) | 直接在resources的包下的配置文件 | 服务于开发人员本机开发与测试 |
作用 :
- 1级和2级留作系统打包后设置通用属性 , 1级常用于运维经理进行线上整体项目部署方案调控
- 3级和4级用于系统开发阶段设置通用属性 , 3级常用于项目经理进行整体项目属性调控
设置的时候 , 给不同的目录设置不同的密码 , 从而设置不同的访问权限
6.防止程序留有后门 , 导致配置文件失效
(1)修改配置文件的名称 : 在Idea的设置中指定配置文件
(2)在临时属性设置文件的名称
--spring.config.name=指定的配置文件的名称
(3)在临时属性设置文件的路径
--spring.config.location=文件所在的位置的全路径名
自定义配置文件—重要说明
- 单服务器项目 : 使用自定义配置文件需求较低
- 多服务器项目 : 使用自定义配置文件需求较高 , 将所有配置放在一个目录中 , 统一管理
- 基于SpringCloud技术 : 所有服务器将不再设置配置文件 , 而是通过配置中心进行设定 , 动态加载配置信息
(3)多环境开发 :
- 多个环境之间 , 用三个**—** 分隔
#应用环境
#公共配置
spring:
profiles:
active: dev #设置使用那个配置
#设置环境
#生产环境
--- #多个环境之间 , 用三个---分隔
spring:
config:
activate:
on-profile: pro #给环境配置别名
server:
port: 80
#开发环境
---
spring:
config:
activate:
on-profile: dev
server:
port: 81
#测试环境
---
spring:
config:
activate:
on-profile: test
server:
port: 82
多环境开发之多配制文件 :
一个配置文件中配置多个环境会导致信息安全的问题 , 可以将这些信息分开配置
设置环境的配置文件的名称为application-别名.yml
注意 , 别名前边必须加一个 " - "
在主配置文件中直接使用上边设置应用环境即可
spring:
profiles:
active: dev #设置使用那个配置 , 这里写文件的后缀别名即可
在独立的文件中定义的一般是定义的冲突的属性
(4)多环境开发–properties
properties的配置和yml的使用规则是一致的
多环境开发独立配置文件的书写技巧 :
一般是根据实际功能对配置文件中的信息进行拆分 , 并配置成独立的配置文件 , 命名规则如下
application-devDB.yml
application-devRedis.yml
application-devMVC.yml
这里边 , devDB , devRedis , devMVC 是**原本包含在dev配置文件中**的配置 , 现在是将其拆分开了
然后使用 include 属性在激活指定环境的情况下 , 同时对多个环境进行加载 , 使其生效 , 多个环境间使用 , 分隔
spring:
profiles:
active: dev
include: devDB,devRedis
后加载的会覆盖先加载的配置文件
- 主环境dev与其他环境有相同属性的时 , 主环境配置生效
- 其他环境中有相同的属性时 , 后加载的生效
属性名 | 代表的含义 |
---|---|
active | 指定环境的主配置 , 这里指定那个 , 下边的include中就要指定那些配置环境 |
include | 指定环境的独立配置文件 , 必须使用和active指定命名做前缀 |
group | 指定环境的独立配置文件 组 , 必须使用和active指定命名做前缀 |
多环境开发分组管理 :
开发中实际应用 , 使用group
在SpringBoot中现在进行配置一般是使用多个配置环境 , 指定一个环境每次还要进行更改 ,
所以SpringBoot 2.4之后的版本 , 取消使用了include的属性 , 而是使用 group 指定对应的属性组 , 一次指定一个属性组 , 在加载的时候 , 一次加载一个组的属性
spring:
profiles:
active: dev
group:
"dev": devDB,devRedis
"pro": proDB,proRedis
"test": testDB,testRedis
加载的顺序是 :
这里也是后加载的覆盖先加载的
多环境开发控制使用Maven控制 :
当Maven和SpringBoot共同存在的话 , 优先以Maven的配置为主 ,
<profiles>
<!--属性一-->
<profile>
<!--id是必须设置的-->
<id>env_dev</id>
<properties>
<profile.active>dev</profile.active> <!--尽量都使用这个值 , 后边可以直接在yml文件中引用这个属性值 , 从而达到从maven控制yml文件的操作-->
</properties>
<!--设置默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--属性二-->
<profile>
<id>env_pro</id>
<properties>
<profile.active>pro</profile.active>
</properties>
</profile>
</profiles>
在yml文件中引用这个值 :
spring:
profiles:
active: @profile.active@
idea中的这里也可以选择要使用的默认值
注意 : 有时候 , idea会因为缓存的bug , 导致不管你是否换默认值 , 最后 , 都无法切换这个属性值
这个时候 , 使用clean也无法生效 , 解决方法 ; 在clean之后 , 执行一次compile
(4)日志
1.日志基础
- 编程期调试代码
- 运营期记录信息
- 记录日常运营重要信息 (峰值流量 , 平均响应时间)
- 记录应用的报错信息 (错误堆栈)
- 记录运维过程数据 (扩容 , 宕机 , 报警…)
从上往下 , 级别依次增加 ,
系统默认使用的是info及以上级别
可以在yml文件中配置 , 开启debug级别 (值默认为false)
debug: true
一般不推荐使用这种形式 : 而是:
#设置日志的级别, 指定当前项目根路径下所有的日志级别为debug , 所有的类的debug信息都会打印出来
logging:
#设置分组 , 对某个组设置日志级别
group:
#指定多个小包 , 名字可以自定义
ebank: com.sichen.controller,com.sichen.service
#指定一个大包
inservice: com.sichen
level:
root: debug
#设置某个包的日志级别
com.sichen.controller: debug
#设置分组 , 对某个组设置日志级别
ebank: warn
推荐使用分组的形式
日志级别 | 功能 |
---|---|
trace | 运行堆栈信息,使用率低 |
debug | 调试级别 |
info (默认级别) | 正常运行的级别 |
warn | 警告级别 |
error | 错误级别 |
fatal | 记录的是系统崩溃的级别 , 一般这个级别的话 , 根本无法记录,因为系统已经崩溃了 |
//创建记录日志的对象
private static final Logger log = LoggerFactory.getLogger(BookController.class);
2.快速创建日志对象 :
普通的代码实现 : 让需要输出日志的类 , 继承下边的类即可
public class BaseClass {
private Class clazz;
public static Logger Log;
public BaseClass(){
//谁调用谁就是这个this
clazz = this.getClass();
Log = LoggerFactory.getLogger(clazz);
}
}
lombok提供了一个注解,来快速获取日志对象,减少日志对象的声明操作
@SLf4j //在类的上边写上这个注解
日志对象的名称就叫做 /* Log */
3.日志输出格式的控制
设置日志输出格式 :
logging:
pattern:
console: "%d - %m%n"
SpringBoot默认的日志格式 :
logging:
pattern:
console: "%d %p "
格式 | 效果 | 使用规则 |
---|---|---|
%d | 日期 | %d |
%p | 日志级别 | %p |
%m | 消息 | %m |
%n | 换行 | %n |
%5p | 设置占用的总宽度为5 | %5p |
%clr | 设置使用颜色 | %clr(%p) |
%clr(%p){颜色的名称} | 设置颜色的样式 | %clr(%p){颜色的名称} |
%t | 当前线程名 | %t |
%c | 所属的类名 | %c |
设置宽度前用 - 号 | 设置属性是左对齐 | %-40c |
设置宽度后边加 .宽度 | 设置内容的截取宽度(超出的话只考虑类名完全,包名能截就截) | %-40.40c |
4.输出日志到文件
logging:
#单个日志文件
file:
name: server.log
#设置滚动日志(就是多个日志文件)
logback:
rollingpolicy:
#指定日志文件的大小
max-file-size: 4KB
#指定文件的命名规则 , %i是从0开始的 , 依次递增
file-name-pattern: server.%d{yyyy-MM-dd}.%i.log
%t
%c
所属的类名
%c
设置宽度前用 - 号
设置属性是左对齐
%-40c
设置宽度后边加 .宽度
设置内容的截取宽度(超出的话只考虑类名完全,包名能截就截)
%-40.40c
4.输出日志到文件
logging:
#单个日志文件
file:
name: server.log
#设置滚动日志(就是多个日志文件)
logback:
rollingpolicy:
#指定日志文件的大小
max-file-size: 4KB
#指定文件的命名规则 , %i是从0开始的 , 依次递增
file-name-pattern: server.%d{yyyy-MM-dd}.%i.log