互联网应用主流框架整合之Spring Boot运维体系

先准备个简单的系统,配置和代码如下

# 服务器配置
server:# 服务器端口port: 8001# Spring Boot 配置
spring:# MVC 配置mvc:# Servlet 配置servlet:# Servlet 的访问路径path: /sbd# 应用程序配置application:# 应用程序名称name: SpringBootDeployment# 配置数据源datasource:hikari:transaction-isolation: 2# 驱动类driver-class-name: com.mysql.jdbc.Driver# 数据库连接url: jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&useSSL=false# 用户名username: root# 密码password: Ms123!@#
package com.sbd;import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** Spring Boot 应用程序的主类。* 使用@SpringBootApplication 注解标记这个类是一个 Spring Boot 的启动类。* scanBasePackages 属性指定了 Spring Boot 自动扫描组件的包路径。* @RestController 注解表示这个类是一个 REST 风格的控制器,用于处理 HTTP 请求。*/
@SpringBootApplication(scanBasePackages = {"com.sbd"})
@RestController
public class SpringBootDeploymentApplication {/*** 处理 GET 请求的测试方法。* 该方法使用 @GetMapping 注解来指定处理所有的 GET 请求。* 方法返回一个字符串 "Hello World!",这个字符串将作为 HTTP 响应的内容返回给客户端。* @param request HttpServletRequest 对象,代表当前的 HTTP 请求。虽然在这个方法中没有使用,但它可以用于访问请求的相关信息。* @return 字符串 "Hello World!",作为 HTTP 响应的内容。*/@GetMapping("/test")public String test(HttpServletRequest request){return "Hello World!";}/*** 应用程序的入口点。* 这个方法使用 SpringApplication.run() 来启动 Spring Boot 应用程序。* @param args 命令行参数,这些参数在启动应用程序时可以提供。*/public static void main(String[] args) {SpringApplication.run(SpringBootDeploymentApplication.class, args);}
}

打包部署和运行SpringBoot项目

打包SpringBoot项目

假设MVN的系统环境已经配置好了,在命令行执行命令mvn clean package即可打包

PS D:\Programs\SpringBootDeployment\SpringBootDeployment> mvn clean package
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------------< com.sbd:sdd >-----------------------------
[INFO] Building SpringBootDeployment 0.0.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ war ]---------------------------------
[WARNING] The artifact mysql:mysql-connector-java:jar:8.0.33 has been relocated to com.mysql:mysql-connector-j:jar:8.0.33: MySQL Connector/J artifacts moved to reverse-DNS compliant Maven 2+ coordinates.
[INFO] 
[INFO] --- clean:3.3.2:clean (default-clean) @ sdd ---
[INFO] Deleting D:\Programs\SpringBootDeployment\SpringBootDeployment\target
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ sdd ---
[INFO] Copying 1 resource from src\main\resources to target\classes
[INFO] Copying 0 resource from src\main\resources to target\classes
[INFO]
[INFO] --- compiler:3.13.0:compile (default-compile) @ sdd ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 2 source files with javac [debug parameters release 17] to target\classes
[INFO] 
[INFO] --- resources:3.3.1:testResources (default-testResources) @ sdd ---
[INFO] skip non existing resourceDirectory D:\Programs\SpringBootDeployment\SpringBootDeployment\src\test\resources
[INFO]
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.sbd.SpringBootDeploymentApplicationTests
15:08:00.704 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.sbd.SpringBootDeploymentApplicationTests]: SpringBootDeploymentApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
15:08:00.785 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.sbd.SpringBootDeploymentApplication for test class com.sbd.SpringBootDeploymentApplicationTests.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.3.1)2024-06-25T15:08:01.083+08:00  INFO 15232 --- [SpringBootDeployment] [           main] c.s.SpringBootDeploymentApplicationTests : Starting SpringBootDeploymentApplicationTests using Java 17.0.1 with PID 15232 (started by EDY in D:\Programs\SpringBootDeployment\SpringBootDeployment)
2024-06-25T15:08:01.084+08:00  INFO 15232 --- [SpringBootDeployment] [           main] c.s.SpringBootDeploymentApplicationTests : No active profile set, falling back to 1 default profile: "default"
2024-06-25T15:08:01.843+08:00 ERROR 15232 --- [SpringBootDeployment] [           main] o.a.catalina.core.AprLifecycleListener   : An incompatible version [1.2.14] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34]
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2024-06-25T15:08:02.821+08:00  WARN 15232 --- [SpringBootDeployment] [           main] .s.s.UserDetailsServiceAutoConfiguration : Using generated security password: f87a8981-a777-4a00-9f08-5b1cdd3ba15eThis generated password is for development use only. Your security configuration must be updated before running your application in production.2024-06-25T15:08:02.834+08:00  INFO 15232 --- [SpringBootDeployment] [           main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2024-06-25T15:08:02.903+08:00  INFO 15232 --- [SpringBootDeployment] [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint beneath base path '/actuator'
2024-06-25T15:08:03.041+08:00  INFO 15232 --- [SpringBootDeployment] [           main] c.s.SpringBootDeploymentApplicationTests : Started SpringBootDeploymentApplicationTests in 2.147 seconds (process running for 2.859)
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.977 s -- in com.sbd.SpringBootDeploymentApplicationTests
[INFO] 
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- war:3.4.0:war (default-war) @ sdd ---
[INFO] Packaging webapp
[INFO] Assembling webapp [sdd] in [D:\Programs\SpringBootDeployment\SpringBootDeployment\target\sdd-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Building war: D:\Programs\SpringBootDeployment\SpringBootDeployment\target\sdd-0.0.1-SNAPSHOT.war
[INFO] 
[INFO] --- spring-boot:3.3.1:repackage (repackage) @ sdd ---
[INFO] Replacing main artifact D:\Programs\SpringBootDeployment\SpringBootDeployment\target\sdd-0.0.1-SNAPSHOT.war with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to D:\Programs\SpringBootDeployment\SpringBootDeployment\target\sdd-0.0.1-SNAPSHOT.war.original
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  38.456 s
[INFO] Finished at: 2024-06-25T15:08:36+08:00
[INFO] ------------------------------------------------------------------------

然后在target路径下就能看到打好的包
在这里插入图片描述
这里之所以是war包而不是jar包,来自于pom.xml文件的配置内容<packaging>war</packaging>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.sbd</groupId><artifactId>sdd</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><name>SpringBootDeployment</name><description>SpringBootDeployment</description><url/>

在编译器里也有相关的入口,直接操作也能编译,其实就是代替了命令行
在这里插入图片描述

运行SpringBoot项目

在命令行执行命令java -jar sdd-0.0.1-SNAPSHOT.war

PS D:\Programs\SpringBootDeployment\SpringBootDeployment\target> java -jar sdd-0.0.1-SNAPSHOT.war.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.3.1)2024-06-25T15:23:20.760+08:00  INFO 14836 --- [SpringBootDeployment] [           main] c.sbd.SpringBootDeploymentApplication    : Starting SpringBootDeploymentApplication v0.0.1-SNAPSHOT using Java 17.0.1 with PID 14836 (D:\Programs\SpringBootDeployment\SpringBootDeployment\target\sdd-0.0.1-SNAPSHOT.war started by EDY in D:\Programs\SpringBootDeployment\SpringBootDeployment\target)
2024-06-25T15:23:20.764+08:00  INFO 14836 --- [SpringBootDeployment] [           main] c.sbd.SpringBootDeploymentApplication    : No active profile set, falling back to 1 default profile: "default"
2024-06-25T15:23:21.589+08:00 ERROR 14836 --- [SpringBootDeployment] [           main] o.a.catalina.core.AprLifecycleListener   : An incompatible version [1.2.14] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34]
2024-06-25T15:23:21.928+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8001 (http)
2024-06-25T15:23:21.936+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-06-25T15:23:21.937+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.25]
2024-06-25T15:23:22.433+08:00  INFO 14836 --- [SpringBootDeployment] [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2024-06-25T15:23:22.498+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-06-25T15:23:22.499+08:00  INFO 14836 --- [SpringBootDeployment] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1673 ms
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.  
2024-06-25T15:23:23.231+08:00  WARN 14836 --- [SpringBootDeployment] [           main] .s.s.UserDetailsServiceAutoConfiguration :Using generated security password: cb547c22-4501-44e6-83f6-9391bee03cb8This generated password is for development use only. Your security configuration must be updated before running your application in production.2024-06-25T15:23:23.253+08:00  INFO 14836 --- [SpringBootDeployment] [           main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2024-06-25T15:23:23.332+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint beneath base path '/actuator'
2024-06-25T15:23:23.451+08:00  INFO 14836 --- [SpringBootDeployment] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8001 (http) with context path '/'
2024-06-25T15:23:23.463+08:00  INFO 14836 --- [SpringBootDeployment] [           main] c.sbd.SpringBootDeploymentApplication    : Started SpringBootDeploymentApplication in 3.116 seconds (process running for 3.46)

如果是需要部署到其他服务器上,例如Tomcat等等,直接将该war包复制过去,启动tomcat即可

项目的配置文件application.yml被打包到war包中,后续修改比较麻烦,不过Spring Boot 配置加载的优先级遵循一定的规则,以确保不同来源的配置能够合理地覆盖和互补。以下是Spring Boot配置加载的优先级列表,从高到低排列:

  • 命令行参数:通过命令行直接传递给应用程序的参数(如 --spring.profiles.active=prod)具有最高优先级
  • JVM系统属性:通过 -D 参数设置的Java系统属性(例如 -Dspring.datasource.url=jdbc:mysql://localhost/test
  • 环境变量:以 SPRING_APPLICATION_JSON形式存在的环境变量中的属性,这些属性通常以JSON格式定义
  • 应用以外的配置文件:
    • 当前目录下的 config子目录中的配置文件(比如 ./config/application.yml
    • 当前目录下的配置文件(如 ./application.yml
  • 打包内的配置文件:
    • classpath:/config/目录下的配置文件(项目 resources目录下的 config/文件夹中)
    • classpath:/根目录下的配置文件(项目 resources目录的根文件中,如 application.yml
  • 默认配置:Spring Boot自带的默认配置,位于其自动配置模块中

如果在多个位置都定义了相同的配置项,那么优先级高的配置会覆盖优先级低的配置。例如,如果在命令行参数中设置了某个属性,那么这个属性的值将覆盖所有其他位置的相同属性值。

此外,Spring Boot 支持多环境配置,通过命名约定(如 application-{profile}.yml)来区分不同环境的配置,其中{profile}是激活的配置文件名(如 dev、prod)。当激活特定的配置文件时,对应环境的配置会根据上述优先级规则进行加载,并且可以在不同环境之间进行切换而不需要更改主要的配置文件。

根据加载顺序,比较典型的场景就是命令行的参数优先级大于配置文件,那么在命令行添加参数是可以覆盖配置文件的
外部配置文件优先级大于war包内的配置文件,因此在war包同路径下再建一个application.yml,写进新的配置也可以覆盖war包内的配置文件的配置

Spring Boot Actuator

Spring Boot Actuator 是一种度量,可以实时监控SpringBoot项目的健康状况,通过请求Actuator的端点,可以查看项目运行时不同的信息,比如JVM运行情况,项目是否正常、项目的配置和SpringIoC容器的内容,要是用该工具需要引入如下依赖

        <!-- 引入Spring Boot的Actuator模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>

当我们引入了这个依赖到项目中后,SpringBoot就会提供对应的端点供我们查看项目运行的情况,在application.yml里还需要增加一个对应的配置

# 该文档描述了一个Spring Boot应用程序的部署信息
info:# 应用程序的标识部分,包含名称、描述和版本application:# 应用程序的名称name: SpringBootDeployment# 应用程序的描述,此处与名称相同,可能是为了强调description: SpringBootDeployment# 应用程序的版本号version: 1.0.0# 配置管理端点的暴露设置# 使用"*"表示暴露所有端点,可以根据实际需求调整包括的端点列表。
management:endpoints:web:exposure:# 表示除了env以外全部暴露include: "*"exclude: "env"# 信息配置部分,用于存储和管理应用程序的环境信息info:# 环境配置,定义了当前运行环境是否启用某些特定功能或设置env:# 是否启用,true表示启用,false表示禁用, 默认为false,在请求info端点的时候显示为空enabled: true

启动项目之后,访问页面/sdb/actuator/health便可以看到相关信息
在这里插入图片描述
在这里插入图片描述

Actuator端点

Actuator的端点会以ANT风格的路径/actuator/{端点}提供,如下是SpringBoot3.0的一些端点,这个东西很变态,每个版本都有所不同,例如是否默认启用,配置格式什么的
在这里插入图片描述

保护Actuator端点

有些端点不能随意暴露给别人看,但又需要暴露出来给需要的人看,因此需要增加一层安全机制,为此需要引入如下依赖

        <!-- 引入Spring Boot的Security模块,用于应用程序的安全性管理。 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 引入Tomcat的Jasper引擎,用于处理JSP页面。 --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId></dependency>

spring-boot-starter-security也需要tomcat-embed-jasper因此一起引入,然后需要编写一个安全认证类来限制请求的权限,代码如下

package com.sbd.config;import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;/*** 安全配置类,继承自WebSecurityConfigurerAdapter,用于配置Spring Security。*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();/*** 使用BCryptPasswordEncoder作为密码编码器。* @return 返回BCryptPasswordEncoder实例。*/@Bean // 密码编码器public PasswordEncoder passwordEncoder() {return passwordEncoder;}/*** 配置认证管理器,用于设置内存中的用户认证信息。* @param auth AuthenticationManagerBuilder的实例,用于配置认证信息。* @throws Exception 如果配置出错,抛出异常。*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 使用内存存储auth.inMemoryAuthentication()// 设置密码编码器.passwordEncoder(passwordEncoder)// 注册用户admin,密码为abc,并赋予USER和ADMIN的角色权限.withUser("admin")// 可通过passwordEncoder.encode("abc")得到加密后的密码.password(passwordEncoder.encode("a123456"))// 赋予角色ROLE_USER和ROLE_ADMIN.roles("ADMIN");}/*** 配置HTTP安全设置,用于定义哪些URL需要安全访问。* @param http HttpSecurity的实例,用于配置HTTP安全设置。* @throws Exception 如果配置出错,抛出异常。*/@Overrideprotected void configure(HttpSecurity http) throws Exception {// 限定签名后的权限http.authorizeRequests().antMatchers("/sbd/actuator/**", "/sbd/admin/**").hasAnyRole("ADMIN").anyRequest().permitAll().and().anonymous().and().formLogin();}
}

启动项目便会,再次访问端点,便会弹出登录窗口
在这里插入图片描述

自定义端点

有时候我们要加入自己的端点,例如DataSource端点,用于监控数据库的健康情况,代码如下

package com.sbd.endpoint;import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;@Component
@Endpoint(id = "database", enableByDefault = true)
public class DatabaseEndpoint {@Value("${spring.datasource.driver-class-name}")private String driverClassName = null;;@Value("${spring.datasource.url}")private String url = null;@Value("${spring.datasource.username}")private String username = null;@Value("${spring.datasource.password}")private String password = null;// 测试SQLprivate static final String TEST_SQL = "select 1 from dual";// 一个端点只能存在一个@ReadOperation标注的方法// 它代表的是HTTP的GET请求@ReadOperationpublic Map<String, Object> test() {Connection conn = null;Map<String, Object> msgMap = new HashMap<>();try {Class.forName(driverClassName);conn = DriverManager.getConnection(url, username, password);// 执行测试SQLconn.createStatement().executeQuery(TEST_SQL);msgMap.put("success", true);msgMap.put("message", "测试数据库连接成功");} catch (Exception ex) {msgMap.put("success", false);msgMap.put("message", ex.getMessage());} finally {if (conn != null) {try {conn.close(); // 关闭数据库连接} catch (SQLException e) {e.printStackTrace();}}}return msgMap;}
}

@Endpoint注解声明该类为Actuator的一个端点
@ReadOperation注解标识该端点为读取端点,对应HTTP的GET请求
@WriteOperation注解标识该端点为写入端点,对应HTTP的POST请求
@DeleteOperation注解标识该端点为删除端点,对应HTTP的DELETE请求

将自定义端点加入配置

management:endpoints:web:exposure:# 表示除了env以外全部暴露include: "*"exclude: "env"endpoint:database:enabled: true

访问该端点

在这里插入图片描述

健康指标项

health端点只显示服务器的状态,要显示更多的指标,需要进一步配置management.endpoint.health.showdetails,该配置项存在三个选项即neveralwayswhen-authorized,第一个为默认值,不显示指标项,第二个显示所有指标项,第三个需要认证后显示指标项

修改一下配置文件,将配置添加进去

# 配置管理端点的暴露设置# 使用"*"表示暴露所有端点,可以根据实际需求调整包括的端点列表。
management:endpoints:web:exposure:# 表示除了env以外全部暴露include: "*"exclude: "env"endpoint:database:enabled: truehealth:enabled: trueshow-details: when_authorizedroles: "ADMIN"

然后再次访问health端点即可
在这里插入图片描述
health端点还可以添加如下指标项,但需要在pom中引入对应的Spring Boot启动器(starter)最好对应的配置,指标才会自动启用
在这里插入图片描述

自定义指标项

package com.sbd.indicator;import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;import java.net.InetAddress;// 当配置项management.health.www.enabled为true时才展示指标项
@ConditionalOnEnabledHealthIndicator("www")/*** 指标项名称,是根据Bean名称来决定的,比如Bean名称为xxxHealthIndicator,那么指标项名称就为xxx。* 本例如果使用默认的类名为Bean名称,则指标项名称为internet* 这里重新定义Bean名称为wwwHealthIndicator,则指标项为名称为www*/
@Component(value="wwwHealthIndicator")
public class InternetHealthIndicator extends AbstractHealthIndicator {// 通过监测腾讯服务器,看能否访问互联网private final static String QQ_HOST = "www.qq.com";// 超时时间为5sprivate final static int TIMEOUT = 5000;@Overrideprotected void doHealthCheck(Health.Builder builder) throws Exception {// 监测腾讯服务器boolean status = ping();if (status) {// 健康指标为可用状态,并添加一个消息项builder.withDetail("message", "当前服务器可以访问万维网。").up();} else {// 健康指标为不再提供服务,并添加一个消息项builder.withDetail("message", "当前无法访问万维网").outOfService();}}// 监测腾讯服务器能够访问,用以判断能否访问万维网private boolean ping() throws Exception {try {// 当返回值是true时,说明host是可用的,是false则不可用return InetAddress.getByName(QQ_HOST).isReachable(TIMEOUT);} catch (Exception ex) {return false;}}
}

实现指标项的开发可以通过HealthIndicator接口或者继承抽象类AbstractHealthIndicator,而实际上AbstractHealthIndicator也实现了HealthIndicator接口
在这里插入图片描述

SpringBoot测试

基本的测试可参考文章单元测试系列[v1.0.0][SpringBootTest]

使用随机端口测试REST风格的请求

package com.sbd.controller;import com.sbd.SpringBootDeploymentApplication;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extensions;
import org.mockito.BDDMockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;// 驱动Spring Boot Test工作,并指明启动类
@SpringBootTest(// 入口类classes = SpringBootDeploymentApplication.class,// 使用随机端口webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class TestControllerTest {// 注入控制器@Autowiredprivate TestController testController = null;// 测试方法@Testpublic void testHello() {String result = testController.hello("Jim");System.out.println(result);Assert.notNull(result, "判定结果为空(null)");}// 注入TestRestTemplate对象@Autowiredprivate TestRestTemplate restTemplate = null;// 测试方法@Testpublic void testRestHello() {// 简写的URL,无需写出服务器IP和端口String url = "/sbd/test/hello/{name}";String value = "Jim";// 通过REST风格请求获取结果String result = restTemplate.getForObject(url, String.class, "Jim");System.out.println(result);Assert.notNull(result, "判定结果为空(null)");}}

Mock测试

package com.sbd.controller;import com.sbd.SpringBootDeploymentApplication;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.util.Assert;// 驱动Spring Boot Test工作,并指明启动类
@SpringBootTest(// 入口类classes = SpringBootDeploymentApplication.class,// 使用随机端口webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class MockControllerTest {// 注入TestRestTemplate对象@Autowired// 标注为Mock测试的对象@MockBeanprivate TestRestTemplate restTemplate = null;@Testpublic void testMock() {// 简写的URL,无需写出服务器IP和端口String url = "/sbd/mock/unsupport/{value}";// 虚拟结果对象String mockResult = "该方法未实现,有待后续再测";// 参数String value = "mock";// 对Mock对象进行声明调用的方法和参数BDDMockito.given(restTemplate.getForObject(url, String.class, value))// 使用自定义的虚拟对象,取代方法返回的结果.willReturn(mockResult);// 通过REST风格请求获取结果(会被虚拟结果对象取代)String result = restTemplate.getForObject(url, String.class, value);System.out.println(result);Assert.notNull(result, "判定结果为空(null)");}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/860512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第 133 场 LeetCode 双周赛题解

A 使所有元素都可以被 3 整除的最少操作数 遍历 n u m s nums nums &#xff0c;每有一个不被 3 3 3 整除的数&#xff0c;则操作数加 1 1 1 class Solution {public:int minimumOperations(vector<int>& nums) {int res 0;for (auto x : nums)if (x % 3 ! 0)res…

杂记 | 搭建反向代理防止OpenAI API被封禁(对于此次收到邮件提示7月9日后将被屏蔽的解决参考)

文章目录 重要声明&#xff08;免责&#xff09;01 OpenAI封禁API的情况02 解决方案及原理2.1 原因分析2.2 解决方案2.3 步骤概述 03 操作步骤3.1 购买一个海外服务器3.2 申请一个域名3.3 将域名指向代理服务器3.4 在代理服务器上安装nginx3.5 配置反向代理 重要声明&#xff0…

网工内推 | 深圳网工,国企,最高20k,六险一金,NA以上认证

01 沛顿科技&#xff08;深圳&#xff09;有限公司 &#x1f537;招聘岗位&#xff1a;网络工程师 &#x1f537;岗位职责&#xff1a; 1、负责网络设备管理及维护&#xff0c;确保网络系统的稳定运行&#xff1b; 2、负责有效规划及实施网络布线系统&#xff1b; 3、负责服务…

LV、古驰奢侈品跌落神坛!2024消费风向彻底变天!2024创业新风口!2024创业小成本项目!

LV下滑6%、古驰暴跌28%&#xff0c;奢侈品在华越来越卖不动&#xff0c;外媒开始着急了&#xff01;就在前段时间&#xff0c;美媒罕见发声&#xff0c;表示今年1季度特别困难&#xff0c;有奢侈品公司在华负增长高达30%。还说如何提升销量&#xff0c;是当下奢侈品牌在华的头等…

使用matlab开发stm32总结,stm32-matlab常见的问题处理以及报错合集

1&#xff0c; 问题&#xff1a;本来是好的&#xff0c;突然编译运行报错&#xff0c;说是确少包&#xff0c; 解决方案&#xff1a;重启以后好了 2&#xff0c;有完美的马鞍波&#xff0c;为什么不能够转动呢&#xff1f; 原因是我这里模型的问题&#xff0c;我计算出来的是占…

全省高等职业学校大数据技术专业建设暨专业质量监测研讨活动顺利开展

6月21日&#xff0c;省教育评估院在四川邮电职业技术学院组织开展全省高等职业学校大数据技术专业建设暨专业质量监测研讨活动。省教育评估院副院长赖长春&#xff0c;四川邮电职业技术学院党委副书记、校长冯远洪&#xff0c;四川邮电职业技术学院党委委员、副校长程德杰等出席…

PCL笔记二 之VS环境配置(不同版本Debug+Release编译)

PCL笔记二 之VS环境配置(不同版本Debug+Release编译) PCL官网:https://github.com/PointCloudLibrary/pcl/releases众所周知,PCL是一个用于点云处理并且依赖不少三方库的一个算法库,同时在编译配置环境时也很复杂,因此这里想整理一下不同版本对应的环境配置过程,版本如下…

力扣921. 使括号有效的最少添加

Problem: 921. 使括号有效的最少添加 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.定义int变量res、need分别记录需要插入的左括号数和所需与左括号配对的右括号数&#xff1b; 2.遍历字符串&#xff1a; 2.1.若当为左括号&#xff0c;则need&#xff0c;表示…

[word] 如何在word中插入地图? #学习方法#其他

如何在word中插入地图&#xff1f; 人事部门在给即将入职的新员工发送入职资料时&#xff0c;为了方便新员工能快速找到公司的具体位置&#xff0c;一般都会在word资料中插入公司所在位置的地图。今天&#xff0c;小编就分享一个在word中插入地图的方法。 第一步&#xff1a;…

企智汇软件:专业项目管理系统,一体化PaaS平台!快速落地项目!

在快速变化的市场环境中&#xff0c;项目管理不再是简单的任务分配和时间跟踪&#xff0c;它更是一门需要精准决策、高效沟通和智能协作的管理工具。然而&#xff0c;面对日益复杂的项目需求、跨部门的协作挑战以及海量的信息数据&#xff0c;传统的项目管理方式往往显得力不从…

数值分析笔记(三)函数逼近

最佳平方逼近 函数逼近是使用一种简单易算的函数来近似表示一个复杂函数。 该问题可转化为求解线性方程组 G n C F n ​ G_{n}CF_{n}​ Gn​CFn​​ 其中&#xff0c;系数 C ( c 0 , c 1 , ⋯ , c n ) T , F n ( ( f , φ 0 ) , ( f , φ 1 ) , ⋯ , ( f , φ n ) ) T C(c…

【Java】解决Java报错:IllegalMonitorStateException in Synchronization

文章目录 引言一、IllegalMonitorStateException的定义与概述1. 什么是IllegalMonitorStateException&#xff1f;2. IllegalMonitorStateException的常见触发场景3. 示例代码 二、解决方案1. 确保在同步代码块或方法中调用wait()、notify()和notifyAll()2. 使用同步方法3. 使用…

Linux系统学习——指令三

Linux系统学习——指令三 Linux系统学习——指令三chmod — 文件执行权限添加文件执行权限去除文件执行权限 查找文件中特定关键字使用vi编辑文件并查找特定关键字文本文件查找特定关键字1: 使用 grep 命令2: 使用 find 命令3: 使用 awk 命令4: 使用 sed 命令5: 使用 ag 命令&a…

非强化学习的对齐方法

在文章《LLM对齐“3H原则”》和《深入理解RLHF技术》中&#xff0c;我们介绍了大语言模型与人类对齐的“3H原则”&#xff0c;以及基于人类反馈的强化学习方法&#xff08;RLHF&#xff09;&#xff0c;本文将继续介绍另外一种非强化学习的对齐方法&#xff1a;直接偏好优化&am…

Vulnhub靶场DC-4练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 爆破登录2. 命令执行3. 反弹shell4. hydra爆破ssh5. 提权 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-4.zip 介绍&#xff1a; DC-4 is another purposely built …

交通信号灯控制系统的设计(仿真,汇编语言实现)——微机课设

计算机科学与技术 专业课程设计任务书 学生姓名 专业班级 学号 题 目 交通信号灯控制系统的设计 课题性质 A.工程设计 课题来源 自拟课题 指导教师 同组姓名 主要内容 初始状态用K1键控制&#xff0c;为两个黄灯闪烁&#xff1b; K2键控制红、黄、绿灯接…

Diffusion Mamba:用于CT到MRI转换的Mamba扩散模型

Diffusion Mamba&#xff1a;用于CT到MRI转换的Mamba扩散模型 提出背景拆解左侧&#xff1a;整体框架中间&#xff1a;Mamba块的细节右侧&#xff1a;螺旋扫描的细节 提出背景 论文&#xff1a;https://arxiv.org/pdf/2406.15910 代码&#xff1a;https://github.com/wongzbb…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十七)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 27节&#xff09; P27《26.Stage模型-UIAbility的启动模式》 本节讲解 UIAbility的启动模式&#xff1a;Stage模型的应用&#x…

策略模式-通过枚举newInstance替代工厂

策略模式-使用枚举newInstance 前言一、枚举类&#xff1a;MarkCheckDataTypeEnum二、抽象类&#xff1a;AbstractMarkChecker三、检查类&#xff1a;MarkPeopleChecker四、demo演示总结 前言 很久没写文章了~~ 吐槽下&#xff1a;入职新公司后&#xff0c;基本在搬砖&#xf…

这几个PR小技巧你Get到了吗?

学习是永无止境的&#xff0c;需要不间断地学习&#xff0c;获取新知识。今天带来了5个PR小技巧&#xff0c;可以先收藏起来Adobe Premiere Pro 2024的获取查看Baidu Cloud 1、双倍稳定画面更舒适 一般来说大型电视剧、电影使用的拍摄设备都是非常高端的&#xff0c;不像我们…