项目offline发生了什么

2021-09-23 15:29:37 浏览数 (1)

Spring Boot Admin is a community project to manage and monitor your Spring Boot ® applications. The applications register with our Spring Boot Admin Client (via HTTP) or are discovered using Spring Cloud ® (e.g. Eureka, Consul). The UI is just a Vue.js application on top of the Spring Boot Actuator endpoints.

在 Spring Boot 项目中,Spring Boot Admin 作为 Server 端,由于我们用的eureka,基本上把SpringBootAdmin源码打开,对应的sample-eureka就可以用,至于这里面涉及到Spring Security等就不在这里展开说。

Spring Boot Admin server是怎样监控 Spring Boot 单体应用的呢?

spring-boot-starter-actuator它不是用来解决业务功能的,而主要作用是监控。

监控是微服务中必不可少的基础设施,Spring Boot 对其提供了底层支持,所以在系统中集成 spring-boot-starter-actuator 模块,将会使我们很容易获取到大量的监控信息。

在 Spring Boot 2.x 中默认的根路径有 /actuator,ip port/actuator/health。

该端点返回的状态标识该应用健康与否,状态是 UP 表示应用是健康的,如果应用不健康将会显示 DOWN,比如磁盘空间溢出、内存泄露都会返回 DOWN 状态。

  1. 依托 Spring Boot 实现监控需求只需要引入 spring-boot-starter-actuator 模块,如果不进行端点功能扩展,Actuator 模块本身就内置了很多关于监控端点的实现,
  2. 在使用的时候某些端点需要稍加配置,有的则直接使用
  3. 采用 HTTP 协议访问监控端点,其访问根路径是 /actuator,由于监控端点和业务功能是集成在一个微服务里面,建议业务访问的 REST 接口不要采用 Actuator 作为 URL 的前缀;
  4. Spring Boot 内置的监控端点其输出内容是可以扩展的,比如 /actuator/info 这个端点就可以在配置文件中进一步配置丰富其输出内容

当然actuator还提供很多endpoint,具体感兴趣的可以继续深入一下。监控状态主要有如下四个状态:某个组件的unknown装填不会使项目offline。

Spring Boot Actuator 默认提供 12 个 HealthIndicators。

  • DiskSpaceHealthIndicator:检查磁盘空间不足
  • CassandraHealthIndicator:检查 Cassandra 数据库是否启动
  • JmsHealthIndicator:检查 JMS 代理是否启动
  • DataSourceHealthIndicator:检查是否可以获得连接 DataSource
  • ElasticsearchHealthIndicator:检查 Elasticsearch cluster is up
  • RabbitHealthIndicator:检查 Rabbit 服务器是否启动
  • RedisHealthIndicator:检查 Redis 服务器是否启动
  • MailHealthIndicator:检查 mail server is up.
  • MongoHealthIndicator:检查 Mongo database is up
  • SolrHealthIndicator:检查 Solr server is up
  • InfluxDbHealthIndicator:检查 InfluxDB 服务器是否启动
  • Neo4jHealthIndicator:检查 Neo4j 服务器是否启动
  • CouchbaseHealthIndicator:Checks that a Couchbase cluster is up

具体的可以看一下对应的Indicator里面的doHealthCheck实现过程,像Db的话就是通过validationQuery里面的select 1去校验,ES的话通过_cluster/health/端口去校验集群状态。

Spring Boot内嵌服务器都是NIO的实现实现方式,说到NIO不得不说BIO和AIO,

BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

这个图很好的展示了一个请求,NIO Server的处理过程:

Feign的实现方式是同步阻塞,默认是CloseableHttpClient,不管你调用下游(应用,中间件),为什么要超时时间要短一点?如果下游服务的接口响应时间很慢,设置超时时间过大,那么将占有大量的连接,瞬间就会把连接(Queue Thread Pool)占用完,直接导致调用其他系统时,需要阻塞住等待获取连接,这样的话,整个上游的很多功能就都用不了了,下游的Selector Pool也会被撑爆掉。可以看到线程池隔离也是保护应用的一种方式。

非阻塞是实现高性能服务器的关键,通过IO多路复用,实现异步事件回调,事件异步回调和同步异步没有半毛钱关系。

通过IO复用监控非阻塞端口,完成事件的异步回调。非阻塞调用不能立刻得到结果之前,该调用不会阻塞当前线程。

当Blocked线程过多时候项目为什么会Offline?也没有线程的HealthIndicator,

是因为健康检查也是定时的http请求到对应Actuator endpoint线程阻塞,没有返回值,超时(默认请求时间间隔10s,超时时间10s).


每周一句:抽象就是做减法和做除法。通过舍弃非本质和无关紧要的部分,着眼于问题的本质,去粗取精;通过透过现象看本质,发现不同事物之间的共同之处,异中求同,同类归并,也就是做除法。

0 人点赞