长轮询
长轮询概述长轮询(Long Polling)是一种客户端从服务器获取数据的技术。它属于一种服务器推送技术(Server Push),旨在减少服务器和客户端之间的延迟即保证实时性。与传统的轮询不同,长轮询通过让服务器保持HTTP连接一段时间来等待有新数据时再响应客户端请求,从而减少频繁的请求和响应。
普通轮询(Polling)
客户端定时向服务器发送请求,询问是否有新数据。
每次请求无论是否有新数据,服务器都会立即响应。
频繁的请求会增加服务器的负担和网络流量。
长轮询(Long Polling)
客户端发送请求后,服务器不会立即响应,而是保持连接直到有新数据或达到超时。
当有新数据时,服务器立即响应并返回数据;如果超时则返回空响应。
减少了请求次数,从而降低服务器负担和网络流量。
优缺点优点
减少了客户端和服务器之间的频繁通信,降低了服务器负担。
相比普通轮询,长轮询能够更及时地向客户端推送数据,减少延迟。
实现相对简单,不需要额外的协议支持。
缺点
每个长轮询请求会保持一个HTTP连接,占用服务器资源,如果有大量的并发请求,可能导致服务器连接耗尽。
长时间保持连接可能对 ...
ThreadLocal跨线程共享
ThreadLocal跨线程共享概述在Java编程中,ThreadLocal是一种专门设计用于在线程内存储数据的机制,确保每个线程都能独立地访问各自的变量副本。由于其设计初衷是为了解决线程间数据共享问题,所以它本身并不直接支持跨线程的数据共享。然而,在某些场景下,跨线程共享ThreadLocal数据是必要的。以下是几种实现方案及其优缺点。
InheritableThreadLocalInheritableThreadLocal是ThreadLocal的子类,它允许子线程继承父线程的ThreadLocal变量值。这种方式最简单,但也有其局限性:
实现步骤:
使用InheritableThreadLocal代替ThreadLocal。
在线程启动之前,将需要共享的数据放入InheritableThreadLocal。
启动子线程,子线程将自动继承父线程的ThreadLocal值。
使用示例以下是一个简单的示例代码,展示了如何使用 InheritableThreadLocal 来在子线程中继承父线程的变量值:
1234567891011121314151617181920212223242 ...
JavaAgent & Instrumentation
JavaAgent & Instrumentation概述Java javaagent 和 JDK 中的 Instrumentation 是密切相关的两个概念,通常用于 Java 程序的字节码增强、监控和性能分析等方面。
JavaAgentjavaagent 是 Java 代理,它允许开发者在 JVM 启动时通过指定代理 JAR 包来增强应用程序的功能。具体来说,开发者可以通过实现 premain 或 agentmain 方法,定义在 JVM 启动或运行时修改 Java 字节码的逻辑。
premain:premain 是在 JVM 启动时 调用的,用于在 JVM 启动之前执行一些初始化操作。它是在 JVM 启动命令中通过 -javaagent 参数指定代理 JAR 时触发的。通常用于在 JVM 启动时进行类的字节码增强或者监控。
agentmain :agentmain 是 在 JVM 运行时 动态调用的,用于在应用程序已经运行的情况下动态加载或卸载代理。这通常通过Java Attach API 在应用程序运行时将代理附加到 JVM 进程中。
使用方式javaagent 在 ...
Etcd
Etcd概述etcd 是一个高可用的分布式键值存储系统,由CoreOS公司开发,主要用于配置共享和服务发现(k8s底层)。作为一个分布式一致性数据库,etcd在分布式系统中起到了核心作用,能够确保数据的一致性和可靠性,特别是在需要协调多个服务或节点的场景中。
特点作为维护分布式工作负载运行的数据并不是一项小任务。但etcd专为此任务而构建,从头开始设计,具备以下特点:
完全复制:etcd集群中的每个节点都可以访问完整的数据存储;
高度可用:etcd被设计为没有单一故障点,并且能够优雅地容忍硬件故障和网络分区;
可靠一致:每次数据“读取”都会返回所有集群中的最新数据“写入”;
快速:etcd 的性能经过测试,每秒可以写入10,000条数据;
安全:etcd支持自动的传输层安全性(TLS)以及可选的安全套接字层(SSL))客户端证书认证;由于etcd存储着重要且高度敏感的配置数据,管理员应在部署中实施基于角色的访问控制,并确保与etcd交互的团队成员的访问权限限制在执行其工作所需的最低特权级别;
简单:任何应用程序,从简单的Web应用到高度复杂的容器编排引擎(如Kubernetes),都 ...
Kafka调优
Kafka调优概述调优是为了满足系统常见的非功能性需求。在众多的非功能性需求中,性能绝对是我们最关心的那一个。不同的系统对性能有不同的诉求,比如对于数据库用户而言,性能意味着请求的响应时间,用户总是希望查询或更新请求能够被更快地处理完并返回。对 Kafka 而言,性能一般是指吞吐量和延时
吞吐量:也就是 TPS,是指 Broker 端进程或 Client 端应用程序每秒能处理的字节数或消息数,这个值自然是越大越好
延时:它表示从 Producer 端发送消息到 Broker 端持久化完成之间的时间间隔,也就是从Producer 发送消息到 Consumer 成功消费该消息的总时长,和 TPS 相反,我们通常希望延时越短越好
为了达到高吞吐低时延,将从以下4个方面进行调优:
应用程序层:它是指优化 Kafka 客户端应用程序代码。比如,使用合理的数据结构、缓存计算开销大的运算结果,抑或是复用构造成本高的对象实例等。这一层的优化效果最为明显,通常也是比较简单的
框架层:它指的是合理设置 Kafka 集群的各种参数。毕竟,直接修改 Kafka 源码进行调优并不容易,但根据实际场景恰当地 ...
Kafka保证有序性
Kafka保证消息有序性概述在消息队列里面,有序消息是指消费者消费某个 topic 消息的顺序,和生产者生产消息的顺序一模一样,它也叫做顺序消息。前面你应该注意到了,Kafka 并不能保证不同分区之间的顺序,所以需要特殊手段来实现有序消息。
一般消息有序性指的是某个 topic 内的消息有序,而不是跨 topic 的有序消息;
跨 topic 的有序消息:
这种场景在事件驱动的架构中更加常见。在复杂的事件驱动架构下,我们可能会倾向于使用不同的 topic 来代表不同的事件,那么就会遇到要求在不同的 topics 下消息依旧需要保持有序的问题。
这一类的问题是不能依赖于消息队列来解决的。要想支持这种跨 topic 的有序消息,一定要引入一个协调者,这个协调者负责把消息重组为有序消息。比如说,如果 msg2 先到了,但是 msg1 还没出来,那么这个协调者要有办法让 msg2 的消费者 B 停下来,暂时不消费 msg2。而在 msg1 来了之后,唤醒消费者 A 消费 msg1,并且在消费完 msg1 之后要再唤醒消费者 B 处理 msg2。
实现思路消息发送单分区要保证消息有 ...
Kafka-Kraft模式
Kafka-Kraft模式概述Kafka-Kraft模式(Kafka Raft)是Apache Kafka的一种新的运行模式,旨在替代传统的ZooKeeper模式。Kraft模式将Kafka的元数据管理从ZooKeeper移除,转而使用Raft协议在Kafka自身内部管理元数据。这种变化简化了Kafka的部署和管理,提高了系统的一致性和可靠性。
架构变化:
左图为 Kafka现有架构,元数据在 zookeeper 中,运行时动态选举 controller,由controller进行Kafka集群管理。
右图为kraft模式架构(实验性),不再依赖zookeeper集群,而是用三台controller节点代替zookeeper,元数据保存在controller中,由controller直接进行Kafka集群管理。
优点:
简化部署:不再需要单独部署和维护ZooKeeper集群,降低了运维复杂性和成本。
一致性和可靠性:Raft协议提供了强一致性保证,确保元数据在多个节点之间的一致复制,提高了系统的可靠性。
高可用性:通过控制节点的多数共识机制,在少数节点故障的情况下仍能保证集群的 ...
Kafka监控
Kafka监控概述Kafka监控对于确保Kafka集群的健康运行和高性能至关重要;但在监控 Kafka 时,如果我们只监控Broker 的话,就难免以偏概全。单个 Broker 启动的进程虽然属于 Kafka 应用,但它也是一个普通的 Java 进程,更是一个操作系统进程。因此,我觉得有必要从 Kafka 主机、JVM和 Kafka 集群本身这三个维度进行监控
监控维度Kafka 主机主机级别的监控是揭示线上问题的第一步,主要包括以下几个方面:
机器负载(Load):查看主机的负载情况,load average 的值可以揭示系统的整体负载状态。
CPU 使用率:监控 CPU 的使用率,可以使用 top 命令查看单个进程的 CPU 占用情况。
内存使用率:包括空闲内存(Free Memory)和已使用内存(Used Memory),这些指标帮助了解系统内存的使用情况。
磁盘 I/O 使用率:包括读使用率和写使用率,用于监控磁盘的读写性能。
网络 I/O 使用率:监控网络接口的使用情况,了解网络流量和性能。
TCP 连接数:查看系统中打开的 TCP 连接数量,判断网络连接的繁忙程度。
打 ...
Kafka的请求处理机制
Kafka的请求处理机制概述Kafka的请求处理机制是通过“请求/响应”的方式完成的,无论是客户端还是Broker端,它们之间的交互都是通过网络发送请求和接收响应来实现的。Kafka定义了一组协议来处理各种请求,例如PRODUCE请求用于生产消息、FETCH请求用于消费消息、METADATA请求用于请求Kafka集群的元数据信息
常用方法:
顺序处理请求与单独线程处理请求
处理请求的两种简单方法是顺序处理和每个请求使用单独线程处理。顺序处理的实现较为简单,但吞吐量较差,因为每个请求都必须等待前一个请求处理完毕。单独线程处理每个请求则完全异步,虽然避免了阻塞,但线程创建的开销很大,在高频请求场景下难以承受(24丨请求是怎么被处理的?)。
Reactor模式
Kafka使用Reactor模式处理请求,这是一种事件驱动架构,特别适用于多个客户端并发请求的场景。Reactor模式通过一个请求分发线程(Dispatcher)将不同请求分发到多个工作线程处理。Acceptor线程用于请求分发,不涉及具体逻辑处理,因此非常轻量级,具有很高的吞吐量
Kafka的Reactor架构
网络线程 ...
SpringBoot集成kafka
SpringBoot集成KafkaApache Kafka 是一个分布式流处理平台,广泛应用于实时数据处理、日志聚合、流式分析等场景。Spring Boot 提供了简便的方式来集成 Kafka,使得我们可以快速构建 Kafka 生产者和消费者应用。
基本使用
导入依赖:
1234<dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId></dependency>
编写配置文件:
12345678910spring: kafka: bootstrap-servers: ip1:9092 consumer: group-id: test key-deserializer: org.apache.kafka.common.serialization.StringDeserializer value-deserializer: org.apac ...