一緒に創造し、成長するために一緒に働きましょう!「ナゲッツデイリー新プラン・8月アップデートチャレンジ」参加30日目、イベント詳細はこちら
プレリュード: Java VisualVM について話しましょう
Java VisualVMは、 JVMを監視できるjdk に付属するグラフィカル ツールです。
$JAVA_HOME/bin
ディレクトリで、直接実行できます。
リモート サーバー上の Java プログラムを監視するには、プロジェクトの開始時にjmx起動パラメーターを追加します.spring-boot-admin-server-0.0.1-SNAPSHOT.jar
事前に jar パッケージを準備し、それを Linux サーバーにアップロードし、jmx起動パラメーターを追加して起動します:
java -jar -Djava.rmi.server.hostname=192.168.242.112 -Dcom.sun.management.jmxremote.port=1888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false spring-boot-admin-server-0.0.1-SNAPSHOT.jar
复制代码
jvisualvmを開くと、プログラムを監視するのは次のように簡単です。
接続後、プログラムを監視でき、さまざまなインジケーターが一目でわかります。
単一のプロジェクトの場合、jvisualvmで監視するだけで十分です!
プレリュード: Spring Boot アクチュエータの監視
Spring BootのActuatorは、独自のアプリケーション情報を監視および管理するためのモジュールです. このモジュールの使用は非常に簡単で、spring-boot-starter-actuator
依存関係です:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
复制代码
SpringCloudAlibabaDemo
project の下にサブプロジェクトを作成しspring-boot-admin-server
、上記の依存関係を導入してから、プロジェクトを開始して以下にアクセスしますhttp://localhost:8082/actuator
。
初期設定でアクチュエータにアクセスした場合の情報です。
Actuator 端点(Endpoints)可以监视应用程序并与之交互。 Spring Boot 包含许多内置端点,并允许添加自己的端点。例如,health
端点提供基本的应用程序健康信息。
每个单独的端点都可以通过 HTTP 或 JMX 启用或禁用和远程访问。大多数应用程序选择通过 HTTP 对外暴露信息,访问端点的 URL 由 /actuator
前缀以及端点的 ID 组成。例如,默认情况下,health
端点映射到 /actuator/health
,即查看应用程序的健康状况可以访问 URL http://localhost:8082/actuator/health
:
返回信息:
{
"status": "UP"
}
复制代码
UP 表示当前应用处于健康状态,如果是 DOWN 则表示不健康,增加 management.endpoints.health.show-details=ALWAYS
可以查看应用健康状况的详细信息:
management:
endpoint:
health:
show-details: always
复制代码
Actuator 提供了很多端点信息,如下所示:
HTTP方法 | 端点路径 | 含义 | 是否默认暴露 |
---|---|---|---|
GET | /actuator/configprops | 显示所有 @ConfigurationProperties 的配置列表。 | false |
GET | /actuator/beans | 查看 Bean 及其关系列表 | false |
GET | /actuator/heapdump | 下载堆栈信息 | false |
GET | /actuator/env | 查看所有环境变量 | false |
GET | /actuator/health | 查看应用的健康指标 | true |
GET | /actuator/info | 查看应用信息 | false |
GET | /actuator/mappings | 查看所有 URL 映射 | false |
GET | /actuator/httptrace | 追踪信息 | false |
GET | /actuator/loggers | loggers 配置 | false |
GET | /actuator/scheduledtasks | 显示定时任务 | false |
GET | /actuator/threaddump | 显示线程信息 | false |
GET | /actuator/sessions | 允许从 Spring Session 支持的会话存储中检索和删除用户会话 | false |
完整列表见 Spring 官网:docs.spring.io/spring-boot… 。注意选择的 Spring Boot 版本信息。
从这个表可以看出,大部分的端点默认是不暴露的,我们可以通过如下配置进行合理的端点暴露(多个用逗号分开):
management:
endpoints:
web:
exposure:
include: beans,threaddump
复制代码
暴露全部的话,直接进行如下配置即可:
management:
endpoints:
web:
exposure:
include: '*'
复制代码
当然,我们也可以扩展 actuator 端点,拿 health
端点为例,我们先看一下其返回的结果:
{
"status": "UP",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 18238930944,
"free": 11510571008,
"threshold": 10485760,
"exists": true
}
},
"ping": {
"status": "UP"
}
}
}
复制代码
可以看到,返回结果中有 components
下的 diskSpace
,我们从 spring-boot-actuator
源码中找到该返回结果的定义,在 spring-boot-actuator
中搜 diskSpace
关键字:
进入 DiskSpaceHealthIndicator 类:
可以看到该类继承 AbstractHealthIndicator 类,并在 doHealthCheck()
方法中定义了返回详情,那么我们自定义一个自己的健康检查类,输出自定义的信息的话,我们也创建一个 Component
,让他继承 AbstractHealthIndicator 实现输出自定义的信息。
/**
* 博客:https://chendapeng.cn - 行百里者半九十,凡是善始善终,吾将上下而求索!
* 公众号:行百里er
*
* @author 行百里者
* @date 2022-08-28 17:13
*/
@Component
public class ChenDapengHealthIndicator extends AbstractHealthIndicator {
/**
* 自定义健康检查输出信息
*/
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
builder.up()
.withDetail("status", "Oj8K!")
.withDetail("whoami", "外星人")
.withDetail("uptime", new Date());
}
}
复制代码
再次访问健康状况,结果如下:
高潮:Spring Boot Admin
有了 Actuator 的监控信息,我们总不能每次都站在干岸上看那些无聊的 JSON 数据吧?当然不能委屈自己,目下就有一个能够将 Actuator 的信息进行图形化展示的监控管理软件,没错,他就是 Spring Boot Admin 。
更让人兴奋的是,Spring Boot Admin 还能监控注册中心中的所有微服务的情况,并且还提供实时警报功能,这个使用 jvisualvm 就没办法搞了。
Spring Boot Admin 是一个开源项目,项目地址:github.com/codecentric… 。
创建 Spring Boot Admin Server
Spring Boot Admin 分为 Server
端和 Client
端。
Server
端引入 spring-boot-admin-starter-server
的依赖:
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.5.1</version>
</dependency>
复制代码
并且在启动类上加 @EnableAdminServer
注解:
@SpringBootApplication
@EnableAdminServer
public class SpringBootAdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminServerApplication.class, args);
}
}
复制代码
启动项目后,输入 http://localhost:8082/
访问:
这样一个 admin server
就起来了。
将微服务注册到 Spring Boot Admin
Spring Boot Admin 怎么去监控服务呢,得有服务注册到 Admin Server 上来才行,所以我们将之前的几个微服务注册进来。
需要注册到 Admin Server 上的服务我们暂且称之为客户端,那么客户端需要怎么做呢?
1, 每个需要注册到 Admin Server 的服务都引入如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.5.1</version>
</dependency>
复制代码
2, 配置连接到 Admin Server 的 url :
spring:
boot:
admin:
client:
url: http://localhost:8082
复制代码
3, 配置对外暴露所有 Actuator 端点:
management:
endpoints:
web:
exposure:
include: '*'
复制代码
启动服务:
然后看监控:
what!竟然全部灰色,意思是全部离线,可是我的所有服务都正常启动了啊,点进去看一下:
看这个提示,应该能明白的差不多了,应该需要我们把应用的 url 在 admin 中显示为 ip 地址应该就可以了,果然有这个配置:
spring:
boot:
admin:
client:
url: http://localhost:8082
# 注册时 admin 中显示IP地址不显示主机名
prefer-ip: true
复制代码
然后再重启:
舒服了,全部在线!找一个服务点进去看细节:
这个图是不是似曾相识啊!
没错,这个如就是和前面我们提到的 jvisualvm 的监控界面差不多,都有对 进程
、线程
、垃圾回收
、内存
等的监控,还有 JVM
各种指标的监控,想要康的东西应有尽有!
开启 Spring Boot Admin 认证
Spring Boot Admin 服务很有可能需要在外网访问,不可能让所有人输入一个网址就能随随便便看到我们服务的信息,因此需要登录功能。
Spring Boot Admin 官方说,由于有多种方法可以解决分布式 Web 应用程序中的身份验证和授权,因此 Spring Boot Admin 没有提供默认方法。我们借助于 spring-boot-starter-security
就可以实现开启登录认证功能。
1, 引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
复制代码
2, 在 application.yml
配置文件中配置:
spring:
security:
user:
name: admin
password: admin123
复制代码
3, 自定义安全配置类:
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
private final AdminServerProperties adminServer;
private final SecurityProperties security;
public MySecurityConfig(AdminServerProperties adminServer, SecurityProperties security) {
this.adminServer = adminServer;
this.security = security;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeRequests(
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll()
.antMatchers(this.adminServer.path("/actuator/info")).permitAll()
.antMatchers(this.adminServer.path("/actuator/health")).permitAll()
.antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated()
).formLogin(
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and()
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults())
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminServer.path("/instances"),
HttpMethod.POST.toString()),
new AntPathRequestMatcher(this.adminServer.path("/instances/*"),
HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))
))
.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
}
// Required to provide UserDetailsService for "remember functionality"
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(security.getUser().getName())
.password("{noop}" + security.getUser().getPassword()).roles("USER");
}
}
复制代码
该配置类是 Spring Boot Admin 官网提供的:codecentric.github.io/spring-boot…
再次访问 admin 的时候,就需要登录了:
最后,需要注意的是,既然 admin server 开启了登录认证,那么向 server 中注册的服务也必须得提供用户名密码才能注册上去,在客户端添加如下配置即可:
spring.boot.admin.client:
username: admin
password: admin123
复制代码
集成 Nacos 进行服务发现
不知道大家发现了没有,我们要想让 Admin Server 监控我们的微服务,所有的微服务都得引入 admin 的相关依赖并且都得配置 admin server 的地址,用户名,密码等。这样太繁琐了!
其实我们可以将 admin server 也注册到 Nacos 注册中心,然后 admin server 自动从 Nacos 中获取服务信息来统一查看。
在 admin server 中引入 nacos 依赖,以及配置注册中心地址:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
复制代码
sping:
cloud:
nacos:
discovery:
# Nacos 集群
server-addr: 192.168.242.112:81
复制代码
这样就不用每个客户端都要写一大堆的配置了!
小结:为啥要监控?
因为面试官可能会问:“你平时是怎么调优的?” 呵呵,当然不是。
ただし、通常の作業では、OOM のトラブルシューティングやプロジェクト パラメーターの調整など、実際に問題が発生した場合は、次のことを行う場合があります。
- 単一プロジェクトの場合は、JDKに付属のjvisualvm監視ツールを使用してプロジェクトを監視し、スレッド数やスレッドの実行時間など、インストールされているクラスの数を確認することで、どのクラスが通過しているかを簡単に見つけることができます。クラスは多くのメモリを占有し、特定の問題を特定します。
- 複数のプロジェクトがある場合は、 Spring Boot Adminなどのツールを使用してマイクロサービス プロジェクトを監視し、レジストリ (Nacos など) に登録されているすべてのサービスの状態を確認して、特定の問題を分析できます。
問題をトラブルシューティングして解決するには、プログラムを最適化するために監視が必要です。