Redis Stream 作为队列的使用方式(含延迟队列延伸)
Redis Stream 作为队列的定位Redis 做「队列」常见几种方式: List(LPUSH/BRPOP):简单 FIFO,但一条消息只能被一个消费者取走,无法多实例负载均衡,也没有「未 ACK 可重新投递」的语义。 Pub/Sub:广播,消息不落盘,订阅者不在就丢消息,不适合任务队列。 Stream:消息持久化、支持消费者组、每条消息有唯一 ID、支持 XACK 与 PEL(Pending Entries List),可实现多消费者负载均衡与至少一次消费,适合作为「队列」使用。 下文先说明把 Redis Stream 当队列 的核心概念与 Spring 用法,再在延伸里讲 基于 ZSET + Stream 的延迟队列 实现要点。 Stream 核心概念与命令基本结构 Stream:一个 key 对应一条日志流,每条记录有一个 消息 ID(默认毫秒时间戳-序号,如 1739123456789-0)和多个 field-value 对(类似 hash)。 生产者:XADD stream * field1 value1 field2 value2,* 表...
Spring Boot + Logback + MDC 实现分布式链路追踪
引言在微服务架构中,一个用户请求通常会流经多个服务。为了快速定位问题和分析系统瓶颈,我们需要一种方法来追踪这个请求在整个分布式系统中的调用链。分布式链路追踪应运而生,它通过为每个请求分配一个全局唯一的Trace ID,并将这个ID在服务调用间传递,使得我们可以将散落在各个服务中的日志串联起来。 Logback、Log4j等日志框架提供的MDC(Mapped Diagnostic Context,映射调试上下文)功能,是实现链路追踪的利器。MDC本质上是一个与当前线程绑定的ThreadLocal哈希表,我们可以在其中存入键值对(如Trace ID),并在日志格式中引用它,从而轻松地为该线程产生的所有日志都带上统一的追踪标识。 本文将详细介绍如何结合Spring Boot、Logback和MDC,从零开始实现一个轻量级的分布式链路追踪方案,并解决在多线程和跨服务HTTP调用场景下Trace ID丢失的问题。 MDC介绍MDC(Mapped Diagnostic Context) 是 Logback 和 Log4j 等日志框架提供的一种在多线程环境下进行诊断和调试的工具。其核心原理是利...
基于Micrometer和Prometheus实现度量和监控的方案
摘自:https://www.cnblogs.com/throwable/p/13257557.html 前提最近线上的项目使用了spring-actuator做度量统计收集,使用Prometheus进行数据收集,Grafana进行数据展示,用于监控生成环境机器的性能指标和业务数据指标。一般,我们叫这样的操作为"埋点"。SpringBoot中的依赖spring-actuator中集成的度量统计API使用的框架是Micrometer,官网是micrometer.io。在实践中发现了业务开发者滥用了Micrometer的度量类型Counter,导致无论什么情况下都只使用计数统计的功能。这篇文章就是基于Micrometer分析其他的度量类型API的作用和适用场景。全文接近3W字,内容比较干,希望能够耐心阅读,有所收获。 Micrometer提供的度量类库Meter是指一组用于收集应用中的度量数据的接口,Meter单词可以翻译为"米"或者"千分尺",但是显然听起来都不是很合理,因此下文直接叫Meter,直接当成一个专有名词,理解...
Spring Boot 使用虚拟线程
并发编程的演化线程总所周知,线程(Thread)是计算机中的最小执行单元,由操作系统直接进行调度,每个线程都有自己的执行路径和执行状态,可以独立地运行和并发执行多个任务。 线程是一种重量级的资源,线程的创建、销毁以及在多个线程之间切换都需要耗费 CPU 时间,一个系统可以同时创建、调度的线程数量有限。所以,现在应用基本上都会使用 线程池 来解决这个问题,通过池化线程,可以减少线程频繁 创建 和 销毁 的成本。 例如,Servlet 容器(Tomcat、Undertow、Jetty)的并发模型就是通过线程池,为每一个请求分配一个线程池中的线程进行处理。但是,一旦涉及到阻塞操作(IO、网络请求),当前线程就会被挂起进入等待状态,这个线程就不能去执行其他任务。这就导致了,使用传统线程池并发模型的服务器能同时处理的请求有限。 而,当代 Web 应用基本上都是 IO 密集形应用,请求中执行的业务往往涉及到与数据库进行交互、调用远程服务(Socket IO),本地磁盘文件读写等等,因此使用阻塞式线程是非常低效的。 异步非阻塞编程为了解决传统线程在执行 IO 操作时由于阻塞导致的低效,于是,开...
Spring Boot 参数校验及全局捕获处理
JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。 注意:JSR-303实现与 Hibernate ORM 没有任何关系。 JSR 303 用于对 Java Bean 中的字段的值进行验证。 Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中对表单提交的数据方便地验证。 @Valid注解使用使用步骤在Controller中使用 @Valid+BindingResult做参数校验非常好用。一般步骤如下: (1)引入pom依赖 123456789 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency><!-- @Js...
Spring Boot 整合 Kafka 多数据源
配置文件12345678910spring.kafka.wh.bootstrap-servers=192.168.1.130:9092,192.168.1.130:9093spring.kafka.wh.consumer.group-id=kafka_demospring.kafka.wh.consumer.enable-auto-commit=falsespring.kafka.es.consumer.auto-offset-reset=latestspring.kafka.es.bootstrap-servers=192.168.1.130:9094spring.kafka.es.consumer.group-id=kafka_demospring.kafka.es.consumer.enable-auto-commit=falsespring.kafka.es.consumer.auto-offset-reset=latestlog-topic-name=test KafkaWhConfig12345678910111213141516171819202122232425...
Spring Boot 整合 MySQL 多数据源
配置文件1234567891011121314151617181920212223242526272829#database1spring.datasource.wh.type=com.zaxxer.hikari.HikariDataSourcespring.datasource.wh.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.wh.jdbcUrl=jdbc:mysql://192.168.1.130:3306/wh?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8spring.datasource.wh.username=rootspring.datasource.wh.password=rootspring.datasource.wh.minimum-idle=1spring.datasourc...
Spring Boot 集成 Spring Data JPA 详细教程
SpringBoot集成SpringData JPA依赖引入SpringBoot项目工程,在pom.xml中引入相关依赖包即可: 12345678910<!-- 数据库相关操作 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope></dependency> 入口注解SpringData JPA提供了部分注解,可以添加在Application入口程序类上方,来满足相关诉...
Spring Boot 整合 Redis 多数据源
基于配置文件 实现 redis 动态数据源和动态数据库的切换 MultiRedisConnectionFactory123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.dao.DataAccessException;import org.springframework...
Spring Boot 获取 resources 目录资源文件的 9 种方法
参考:https://developer.aliyun.com/article/1346532 Springboot 获取 /resources 目录资源文件的 9 种方法 测试方法 - 根据文件路径按行读取文件内容12345678910111213141516171819202122/** * 根据文件路径按行读取文件内容 * * @param fileInPath * @throws IOException */public static void getFileContent(Object fileInPath) throws IOException { BufferedReader br = null; if (fileInPath == null) { return; } if (fileInPath instanceof String) { br = new BufferedReader(new FileReader(new File((String) fileIn...
