比如监控日志的时候并不会对所有的服务都进行监控
而是独立一个服务汇总所有的运行信息,然后监控这个一个服务就行了。
源码和对应的版本号具体在GitHub可以查看
不是spring官方开发的,所以spring官方集成,所以版本号还是需要写的。
开源社区项目,用于管理和监控SpringBoot应用程序。
客户端注册到服务端后,通过Http请求方式,服务端定期从客户端获取对应的信息,并通过UI界面展示对应信息。
可以直接在创建模块的时候勾选功能。在Ops中勾选
有客户端有服务端。如果通过这种方式添加的依赖会自动会给你将版本号添加上
意思就是给你控制了版本号而已,
<properties>
<spring-boot-admin.version>2.6.8</spring-boot-admin.version>
</properties>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
springboot admin的版本号虽然不是官方开发的,但是版本差不多都是和springboot对应的,你springboot什么版本,这个admin依赖差不多就是什么版本,有的版本如果没有的话就用上一个,不影响
- 是多想被纳入Spring鱼塘
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.6.8</version>
</dependency>
还需要配置一个端口,自定义
server:
port: 8080
@EnableAdminServer
开启admin server服务
@SpringBootApplication
// 开启服务
@EnableAdminServer
public class SpringbootServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootServerApplication.class, args);
}
}
访问8080端口 : http://localhost:8080/
依赖也可以选择,具体导入后的内容见上文服务端中。
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.6.8</version>
</dependency>
server:
port: 8081
spring:
boot:
admin:
client:
url: http://localhost:8080 # 提供监控服务的地址
还是访问 http://localhost:8080 发现现在被监控的应用中多了一个了,就是我们刚刚启动的客户端。
management:
endpoint: # 这种一个一个设置
health:
show-details: always # 针对 health 端点,显示健康详情
endpoints: # 这种批量设置
web:
exposure:
# include: health # 默认是health
# include: health,info # 设置多个
include: "*" # * 表示查看全部 注意一定要加引号
exclude: info # 要排除的 排除的优先级高 就算include中设置了也会排除 无论书写先后顺序
endpoint
: 可以精细化控制要被监控的端点,前提需要在**endpoints
**中写了,否则无效!
endpoints
: 表示端点是否被监控,如果不写默认有一个health
如果是* 一般有13个端点: 启动服务时日志信息如下:
endpoint
和endpoints
****不存在优先级关系没有优先级的关系,!!!!!!!!!
只有**endpoints
**中开启后 endpoint
才可以进行精细化控制,否则无效。
这类错误通常出现在 Spring Boot Actuator 配置中,表示你需要至少启用 health
或 status
端点,才能正常使用 Actuator 的功能
在 Spring Boot Actuator 中,health
和 status
是应用程序状态的重要监控端点。如果它们都被禁用,那么 Actuator 将无法提供基本的健康和状态信息,这会导致上面的错误
如果监控多个客户端(微服务)的时候,如果不给微服务起名字,微服务都是没有名字的,此时微服务都会被当做无名的应用的多个实例
# 服务1中
spring:
application:
name: client01
# 服务2中
spring:
application:
name: client02
发现client01这个应用有两个实例,这两个实例可以分别进行监控,只需要点进去就可以看该实例的详细信息。
- 我们可以通过请求路径来获取数据。
使用info.自定义名字 来自定义 info端点中的属性。
- 除了info是指定的名字外,其他的key value都是自定义的
info:
appName: "我是客户端02"
company: "阿栩公司"
author: "axuxu"
在项目中高版本的springboot中可能定义了属性但是在平台中还是没有显示
在较高版本的 Spring Boot(如 2.5.x 或更新版本)中,Spring Boot Actuator 对 info
端点的配置进行了增强和更加严格的控制,导致某些默认信息不再自动暴露。如果你希望在 /actuator/info
端点中显示环境相关的信息,确实需要通过配置 management.info.env.enabled: true
来手动启用它。
management:
info:
env:
enabled: true
这个是 Spring Boot Actuator 的一个配置项,它允许将应用程序的环境变量信息暴露到 Actuator 的 /actuator/info
端点中。
但是由于可能敏感信息会暴露,所以通常建议在生产环境中谨慎使用,或者限制此信息的暴露
上边的哪一种虽然可以,但是如果是一个复杂的配置,在yml中很难进行配置,比如说,value是一个对象的话,此时在yml也能配置,但是很麻烦
InfoContributor
接口 并实现 contribute
方法 然后通过@Component
加入spring容器的管理即可。/**
* 但是使用把此类创建一个bean加入spring管理的时候
* 不能再yml中启动 management.info.env.enabled: true
* 否则会报错,因为如果为true spring会自动创建一个bean 此时就冲突了
*/
@Component
public class EnvInfoContributor implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
// 添加一组键值对 其中value是Object类型 可以为任何数据
builder.withDetail("welcome","hello");
// value为一个map
Map<String, Object> envDetails = new HashMap<>();
envDetails.put("JAVA_HOME", System.getenv("JAVA_HOME"));
envDetails.put("USER_HOME", System.getProperty("user.home"));
// 定义key value 其中value可以是一个map等
builder.withDetail("environment", envDetails);
// value为一个对象
// 是一个对象也可以,且会自定进行转化,不用实现序列化接口
Book book =new Book(1,"数学",12.34);
builder.withDetail("book",book);
// 批量添加键值对,把map集合中的全部添加进来
Map<String,Object> map =new HashMap<>();
map.put("username","axuxu");
map.put("age",18);
map.put("birthday",new Date());
builder.withDetails(map);
}
}
使用把此类创建一个bean加入spring管理的时候,不能再yml中启动 management.info.env.enabled: true 否则会报错,因为如果为true spring会自动创建一个bean 此时就冲突了
即:现在常用的springboot2.5.X及以上版本中
因为application.yml的方式需要设置 management.info.env.enabled: true
所以application.yml的方式和通过javaBean的方式只能存在一种
否则就会报错
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2024-09-09 17:52:27.752 ERROR 39472 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'envInfoContributor', defined in class path resource [org/springframework/boot/actuate/autoconfigure/info/InfoContributorAutoConfiguration.class], could not be registered. A bean with that name has already been defined in file [E:\JavaCode\SpringBoot2AndUseJDK8\springboot-client02\target\classes\cn\axuxu\springbootclient02\contributor\EnvInfoContributor.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
已与地址为 ''127.0.0.1:6435',传输: '套接字'' 的目标虚拟机断开连接
进程已结束,退出代码为 1
http://localhost:8083/actuator/info
{
"welcome": "hello",
"environment": {
"USER_HOME": "C:\\Users\\zhang",
"JAVA_HOME": "D:\\jdk8"
},
"book": {
"id": 1,
"name": "数学",
"price": 12.34
},
"birthday": "2024-09-09T09:39:38.372+00:00",
"age": 18,
"username": "axuxu"
}
这个端点指标显示的是你的组件的运行状况。
- 在yml中不能自定义控制
@Component
public class HealthContributor extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
Map<String,Object> map =new HashMap<>();
map.put("username","axuxu");
map.put("age",18);
map.put("birthday",new Date());
builder.withDetails(map);
}
}
此时运行结果
@Component("MyHealth")
public class HealthContributor extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
Map<String,Object> map =new HashMap<>();
map.put("username","axuxu");
map.put("age",18);
map.put("birthday",new Date());
builder.withDetails(map);
// 设置状态 一共四种 up down unknown outOfService
builder.up();
}
}
if (true){
...操作...
}else {
//这个是控制整个实例的状态
builder.status(Status.OUT_OF_SERVICE);
}
@Service
public class BookService {
private Counter counter;
// 也可以通过Set注入,但是为了直接创建一个计数器,我们使用构造注入测试方便点
// @Autowired
// MeterRegistry meterRegistry;
public BookService(MeterRegistry meterRegistry){
counter = meterRegistry.counter("用户操作次数:");
}
public double add(){
//在想要计数的地方可以进行计数
counter.increment();
return counter.count();
}
}
@RestController
@RequestMapping("books")
public class BookController {
@Autowired
BookService bookService;
@PostMapping
public double add(){
return bookService.add();
}
}
在性能中有一个用户操作次数的选项
发几次请求http://localhost:8083/books 刷新一下
发现实时监控。这个可以用来计算普通用户操作的免费次数,到次数必须充值vip 啊,恶龙竟是我自己。
@Component
/* 如果是自定义端点,必须添加注解声明自己为端点
id为端点的名字,enableByDefault表示是否自动开启,默认为true 所以可以不写
* */
@Endpoint(id = "pay",enableByDefault = true)
public class PayEndpoint {
@ReadOperation
public Object getPay(){
System.out.println("正在支付.......");
// 也可以返回map等任何数据 返回值类型也是自己定义的
return new User(1,"张三","Svip会员","已经充值20000元");
}
@WriteOperation
public Object post(){
return "post请求执行的方法";
}
@DeleteOperation
public Object del(){
return "delete请求执行的方法";
}
}