对我们来说,好消息是Spring Boot提供了收集最重要度量指标的内置机制。我们只需要设置一些配置文件来开启Spring Boot Actuator提供的预定义指标集。要使用Spring Boot Actuator,我们需要添加Spring Boot的启动依赖:
org.springframework.boot
spring-boot-starter-actuator
要启用Spring Boot Actuator的功能,我们必须将management.endpoint.metrics设置为true。现在,你可以通过调用GET /actuator/metrics来检查度量指标的完整列表。对我们来说,最重要的指标之一是http.server.requests,它展示了请求数量和响应时间的统计信息,并会自动记录下请求类型(POST、GET等)、HTTP状态码和uri。
度量指标必须被存储在某个地方。最流行的工具是InfluxDB和Prometheus。它们代表了两种不同的数据收集模型。Prometheus定期从应用程序的公开端点拉取数据,而InfluxDB提供了REST API,由应用程序来调用。Micrometer库提供了与InfluxDB、Prometheus和其他一些工具的集成方案。要启用对InfluxDB的支持,我们需要添加以下依赖项。
io.micrometer
micrometer-registry-influx
我们还需要在Spring Boot的application.yml中配置InfluxDB的URL和数据库名。
management:
metrics:
export:
influx:
db: springboot
uri: http://192.168.99.100:8086
要启用对Prometheus的支持,我们首先需要添加对应的Micrometer库,然后设置属性management.endpoint.metrics为true。
io.micrometer
micrometer-registry-prometheus
默认情况下,Prometheus每分钟尝试从定义的目标端点收集一次数据。可以在Prometheus的配置文件中设置这些参数,scrape_config部分负责指定一组目标和参数,以及如何与它们连接。
scrape_configs:
- job_name: ‘springboot’
metrics_path: ‘/actuator/prometheus’
static_configs:
- targets: [‘person-service:2222’]
有时候,为指标数据打上标签是非常有用的,特别是当我们在单个微服务系统中存在多个应用程序,并将指标数据发送给单个Influx数据库时。下面是代码示例。
@Configuration
class ConfigurationMetrics {
@Value(“${spring.application.name}”)
lateinit var appName: String
@Value(“${NAMESPACE:default}”)
lateinit var namespace: String
@Value(“${HOSTNAME:default}”)
lateinit var hostname: String
@Bean
fun tags(): MeterRegistryCustomizer {
return MeterRegistryCustomizer { registry ->
registry.config().commonTags(“appName”, appName).commonTags(“namespace”, namespace).commonTags(“pod”, hostname)
}
}
}
这是一张从Grafana中截取的监控视图,表示单个应用的http.server.requests指标。
不要忘记日志
======
日志记录在开发过程中不是很重要,但在维护过程中却非常重要。值得记住的是,在组织中,通过日志的质量可以间接判断应用程序的质量。通常,应用程序由支持团队维护,因此日志应该是非常重要的。不要试图把所有的事情都放在日志里,只有最重要的事件才应该被记录下来。
为微服务中的所有应用程序使用相同的日志格式也很重要。例如,如果要以JSON格式记录日志,那么对每个应用程序都应该用JSON格式。如果你使用标记appName来指示应用程序的名称或用instanceId来区分同一应用程序的不同实例,那么在任何地方都要这样做。为什么?你通常希望将微服务中收集的所有日志存储在一个单独的中央数据库中。最流行的工具(或者说是收集日志的工具)是Elastic Stack(ELK)。将中央数据库的优势发挥到最大,你应该确保查询条件和响应结构对于所有应用程序都是相同的,尤其是将不同微服务之间的日志关联起来。怎么做呢?当然是通过使用第三方库。我推荐你使用Spring Boot logging,要使用它,你需要添加如下依赖。
com.github.piomin
logstash-logging-spring-boot-starter
1.2.2.RELEASE
这个库将迫使你使用一些良好的日志记录实践,并自动与Logstash集成(ELK中负责收集日志的工具)。它的主要特点是:
-
能够记录完整的HTTP请求和HTTP响应,并使用适当的标签将这些日志发送到Logstash,这些标签标明了HTTP的请求类型和HTTP响应码
-
计算和存储每个请求的执行时间
-
当使用Spring RestTemplate调用的下游服务时,生成和传递correlationId
为了能够向Logstash发送日志,我们至少需要如下配置信息。
logging.logstash:
enabled: true
url: 192.168.99.100:5000
在添加了logstash-logging-spring-boot-starter之后,你就可以使用Logstash中的日志标记功能。下图是来自Kibana中的单条日志记录的截图。
我们还可以将库Spring Cloud Sleuth添加到我们的依赖项中。
org.springframework.cloud
spring-cloud-starter-sleuth
Spring Cloud Sleuth传递与Zipkin(一种流行的分布式跟踪工具)兼容的标头。它的主要特点是:
-
它将跟踪(相关请求)和span IDs添加到Slf4J MDC
-
它记录时间信息以帮助进行延迟分析
-
它修改了日志的格式,以添加一些信息,比如附加的MDC字段
-
它提供与其他Spring组件的集成,如OpenFeign、RestTemplate或Spring Cloud Netflix Zuul
让你的API易用
========
在大多数情况下,其他应用程序将通过REST API调用你的应用程序。因此我们需要小心的维护一份API文档。文档应该由代码生成。当然有一些工具可以做到这一点。其中最受欢迎的是Swagger。你可以使用SpringFox项目轻松地将Swagger 2集成到你的Spring Boot应用程序中。为了使用Swagger,我们需要添加如下依赖。第一个库负责从Spring MVC控制器代码中生成Swagger descriptor,而第二个库负责解析Swagger descriptor并在你的浏览器中展示页面。
io.springfox
springfox-swagger2
2.9.2
io.springfox
springfox-swagger-ui
2.9.2
我们还必须提供一些Bean来修改Swagger的默认行为。它应该只展示我们自己提供的REST API,而不展示Spring Boot Actuator的API。我们也可以通过定义UiConfiguration bean来定制UI外观。
@Configuration
@EnableSwagger2
public class ConfigurationSwagger {
@Autowired
Optional build;
@Bean
public Docket api() {
String version = “1.0.0”;
if (build.isPresent())
version = build.get().getVersion();
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo(version))
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex(“(/components.*)”))
.build()
.useDefaultResponseMessages(false)
.forCodeGeneration(true);
}
@Bean
public UiConfiguration uiConfig() {
return UiConfigurationBuilder.builder().docExpansion(DocExpansion.LIST).build();
}
private ApiInfo apiInfo(String version) {
return new ApiInfoBuilder()
.title(“API - Components Service”)
.description(“Managing Components.”)
.version(version)
.build();
}
}
下图是Swagger 2 UI的例子。
接下来是为所有微服务定义相同的REST API准则。如果你始终如一地为你的微服务构建API,那么对于外部和内部客户端,集成微服务要简单得多。指南应该包含如何构建API的说明,需要在请求和响应上设置哪些HTTP header,如何生成错误码等。这些准则应该与组织中的所有开发人员和供应商共享。有关为Spring Boot微服务生成Swagger文档(包括为API网关上的所有应用程序公开它)的更详细说明,您可以参考我的文章《Microservices API Documentation with Swagger2》。
不要害怕使用断路器
=========
如果你使用Spring cloud在微服务之间进行通信,你可以利用Spring Cloud Netflix Hystrix或Spring Cloud断路器来实现断路。然而,由于Netflix不再开发Hystrix,Pivotal团队已经将第一个解决方案转移到了维护模式。推荐的解决方案是构建在resilience4j项目之上的新的Spring Cloud断路器。
org.springframework.cloud
spring-cloud-starter-circuitbreaker-resilience4j
然后,我们需要为断路器设置所需的配置,方法是定义一个Customizer bean,该bean被传递给Resilience4JCircuitBreakerFactory。以下示例使用默认值。
@Bean
public Customizer defaultCustomizer() {
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(5)).build())
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.build());
}
有关将Hystrix断路器与Spring Boot应用程序集成的详细信息,请参阅我的另一篇文章:《Part 3: Creating Microservices: Circuit Breaker, Fallback and Load Balancing with Spring Cloud》。
使应用程序透明
=======
我们不应该忘记,迁移到微服务的最重要原因之一是持续交付的需求。今天,快速交付变更的能力在市场上具有优势。你甚至应该能够在一天内多次交付更改。因此,重要的是当前是什么版本,它在哪里发布,以及它包括哪些更改。
在使用Spring Boot和Maven时,我们可以很容易地发布诸如最后更改日期、Git的commit id或应用程序的多个版本等信息。要实现这一点,我们只需要在我们的pom.xml中包含以下Maven插件。
org.springframework.boot
spring-boot-maven-plugin
build-info
pl.project13.maven
git-commit-id-plugin
false
假设你已经启用了Spring Boot Actuator(参见第1节),你必须启用/info端点来显示所有有趣的数据。
management.endpoint.info.enabled: true
当然,我们有许多微服务组成的一个大系统,并且每个微服务都有一些正在运行的实例。最好是在一个应用程序中监视我们所有的实例——就像收集度量指标和收集日志一样。幸运的是,有一个专门用于Spring Boot应用程序的工具,它能够从所有Actuator端点收集数据并在UI中显示它们。它是由Codecentric开发的Spring Boot Admin。使用Spring Boot Admin最方便的方式是创建一个专门的Spring Boot应用程序,该程序需要添加Spring Boot Admin的依赖项和服务发现的依赖项,例如Spring Cloud Netflix Eureka。
de.codecentric
spring-boot-admin-starter-server
2.1.6
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
然后,我们应该通过使用@EnableAdminServer注解来启用Spring Boot Admin。
@SpringBootApplication
@EnableDiscoveryClient
@EnableAdminServer
@EnableAutoConfiguration
public class Application {
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
tion {
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-3dGqw5rA-1714962397688)]
[外链图片转存中…(img-PRdRWGLd-1714962397689)]
[外链图片转存中…(img-qKhHYeOq-1714962397689)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!