SBA可以通过客户端上报,也可以通过配置中心自动获取上报信息。
目前统一采用nacos注册中心方式获取服务地址并获取上报信息。
SBA环境搭建
客户端
客户端指需要使用arthas的微服务。具体操作如下:
1.添加监控maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>xx.xx.xx</version>
</dependency>
2.配置监控信息
management.metrics.tags.application=${spring.application.name}
management.auditevents.enabled=true
management.endpoint.auditevents.enabled=true
management.endpoint.auditevents.cache.time-to-live=5
management.endpoints.web.exposure.include=*
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.beans.enabled=true
management.endpoint.beans.cache.time-to-live=0ms
management.endpoint.shutdown.enabled=true
其中有其他很多属性和配置方式,请参照官方文档
3.即时日志配置
如果要在SBA监控中输出实时日志,添加一下配置
###springbootAdmin 开启日志打印
management.endpoint.logfile.enabled=true
management.endpoint.logfile.external-file=/opt/logs/xy-rbac/xy-rbac.log
management.endpoint.logfile.cache.time-to-live=0ms
服务端
服务端指SBA的监控平台。具体操作如下:
1.创建一个标准的springboot项目并添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>${spring-boot-admin-starter-server.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.开启服务端监控功能
@EnableWebSecurity
@EnableAdminServer
@SpringBootApplication
@EnableDiscoveryClient
public class ApmAdminApplication {
public static void main(String[] args) {
SpringApplication.run(ApmAdminApplication.class, args);
}
}
3.配置spring security安全框架
/**
* @author jack.li
*/
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
// successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.antMatchers(adminContextPath + "/actuator/**").permitAll()
// .antMatchers(adminContextPath + "/instances/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf().disable();
}
}
效果如下:
SBA集成Arthas 控制台
客户端
客户端指需要使用arthas的微服务。具体操作如下:
1.添加maven依赖
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.5.4</version>
</dependency>
版本号根据各自项目需要做调整
2.配置arthas console
## 客户端连接的唯一标识
arthas.agent-id=xy-rbac
## 使用tunnel-server所在服务器ip
arthas.tunnel-server=ws://127.0.0.1:7777/ws
服务端
服务端指SBA的监控平台。具体操作如下:
1.下载启动arthas console
在官网下载arthas-tunnel-server-3.5.4-fatjar.jar
通过如下命令启动即可:
java -jar arthas-tunnel-server-3.5.4-fatjar.jar
其启动参数根据需要自行解决。
2.配置扩展UI
spring.boot.admin.ui.external-views[0].label=Arthas Console
spring.boot.admin.ui.external-views[0].url=http://localhost:8080/
spring.boot.admin.ui.external-views[0].order=1800
spring.boot.admin.ui.external-views[0].iframe=true
external-views以List的方式配置。
效果如下:
自定义报警
SBA提供了基于mail的报警,但是mail的延迟太高,不易及时处理,所以需要自定义一个报警。直接贴代码:
/**
* <p>自定义报警</p >
*
* @author jack.li
* @version 1.0
* @date 2021/10/27 12:39 下午
*/
@Slf4j
public class XyStatusChangeNotifier extends AbstractStatusChangeNotifier {
private final MessageComponent messageComponent;
public XyStatusChangeNotifier(InstanceRepository repository, final MessageComponent messageComponent) {
super(repository);
this.messageComponent = messageComponent;
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
if (event instanceof InstanceStatusChangedEvent) {
InstanceStatusChangedEvent statusChangedEvent = (InstanceStatusChangedEvent) event;
boolean down = statusChangedEvent.getStatusInfo().isDown();
boolean offline = statusChangedEvent.getStatusInfo().isOffline();
boolean up = statusChangedEvent.getStatusInfo().isUp();
boolean unknown = statusChangedEvent.getStatusInfo().isUnknown();
//TODO
}
String serviceName = instance.getRegistration().getName();
String serviceUrl = instance.getRegistration().getServiceUrl();
String status = instance.getStatusInfo().getStatus();
Map<String, Object> details = instance.getStatusInfo().getDetails();
StringBuilder str = new StringBuilder();
str.append("监控报警 : 【" + serviceName + "】");
str.append("【服务地址】" + serviceUrl);
str.append("【状态】" + status);
str.append("【详情】" + JSONObject.toJSONString(details));
log.info(">>>>>>>>sent message:" + str.toString());
return Mono.fromRunnable(() -> messageComponent.send(MessageType.Alarm_Message, str.toString()));
}
}
/**
* <p>description</p >
*
* @author jack.li
* @version 1.0
* @since 2021/10/27 1:31 下午
*/
@Configuration
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AlarmConfig {
private final MessageComponent messageComponent;
@Bean
public XyStatusChangeNotifier statusChangeNotifierToLark(InstanceRepository repository) {
return new XyStatusChangeNotifier(repository, messageComponent);
}
/**
* 当服务不可用时,需要持续发告警消息。以下仅定义服务状态为{"DOWN", "OFFLINE"}时持续告警
@Primary
@Bean(initMethod = "start", destroyMethod = "stop")
public RemindingNotifier remindingNotifier(InstanceRepository repository) {
RemindingNotifier notifier = new RemindingNotifier(statusChangeNotifierToLark(repository), repository);
notifier.setReminderStatuses(new String[]{"DOWN", "OFFLINE"});
notifier.setEnabled(true);
notifier.setReminderPeriod(Duration.ofSeconds(60));
notifier.setCheckReminderInverval(Duration.ofSeconds(60));
return notifier;
}
/**
* 开启web http trace跟踪
*
* @return
*/
@Bean
public InMemoryHttpTraceRepository getInMemoryHttpTrace() {
return new InMemoryHttpTraceRepository();
}
}