0%

前言

在微服务架构中,能快速更新和迭代是其最大的特点之一,而在重启或更新的过程中,为了确保现有请求的完整性以及最小化对业务的影响,“优雅关闭”就显得十分重要了。

本文将结合源码一起来学习下在 Dubbo 中,“优雅关闭”是如何实现的。

阅读全文 »

前言

在 Dubbo 中,默认协议使用单一长连接进行通信,这可以避免每次调用都新建 TCP 连接,从而降低延迟、提高调用的响应速度,但长连接的稳定性受环境、服务端等影响可能会断开,所以如何及时检测连接是否可用并进行重连(保活),对于通信框架而言是非常重要的话题。

阅读全文 »

前言

在前面我们学习到 Kafka 生产者在发送时,消息会先流入到消息收集器 RecordAccumulator,随后再由另外的线程—— Sender 线程将累积的消息发往 Kafka 服务端。本篇文章一起学习下 Sender 线程的工作流程。

Sender 线程的启动可以在 KafkaProducer 的构造函数中找到:

1
2
3
4
5
6
//...
this.sender = newSender(logContext, kafkaClient, this.metadata);
String ioThreadName = NETWORK_THREAD_PREFIX + " | " + clientId;
this.ioThread = new KafkaThread(ioThreadName, this.sender, true);
this.ioThread.start();
//...
阅读全文 »

前言

前面我们提到,当通过 KafkaProducer#send 方法发送消息时,消息会先被写入到消息收集器—— RecordAccumulator 中缓存,当缓存的消息满足一定的条件后,将由 Sender 线程获取批量消息并将其发往 Kafka ,这样的好处是能够减少网络请求的次数,从而提升网络吞量。本篇文章一起来学习下 RecordAccumulator 的内部实现。

阅读全文 »

我们都知道,在使用 Kakfa 客户端发送消息时,只需要指定主题和消息的内容,再调用发送方法即可。那发送方法中具体包含了哪些逻辑呢,本文结合源码一起来看下。

1
2
3
4
// 构建消息
ProducerRecord<String, String> record = new ProducerRecord<>(topic, "value");
// 发送
producer.send(record);
阅读全文 »

前言

在使用 Dubbo 进行服务间的调用时,如果 Provider 服务端抛出了特定异常,但在 Consumer 调用端可能拿到的并不是我们预期的异常类型,那Dubbo 对于服务端的异常是如何处理的呢?如果我们希望在调用端也能获取到对应的异常信息,可以怎么做呢?本文一起来看下。

阅读全文 »

问题的出现和定位

测试环境中,有测试同学反馈说接口请求慢,超时了也没有数据返回。

首先从测试同学那里了解到具体慢的接口,排查了对应的服务的状态,确定了服务的状态是正常在线的。

进入该服务对应的容器内,用 jstat -gctil 命令查看了服务进程的 GC 情况,发现不管是内存占用,或是 GC 的频率和时间占比,都不高。

然后又通过 top 看了下 CPU 的使用率,发现服务的进程整体使用率到了 90% 以上,随即通过 top -Hp 1 指定进程,定位到了占用的的具体线程id是 196

阅读全文 »

前言

在 Kafka 中,有许多地方都需要用到延时操作,如延时生产、延时拉取等。Kafka 作为一个高性能的消息队列,并没有使用 JDK 中自带的 DelayQueue 来实现延时的功能,而是基于时间轮的概念实现了一个更高效的数据结构。

阅读全文 »

前言

在微服务架构中,为了避免单点故障,一个服务通常会部署多个实例,而对于服务消费者而言,则需要考虑如何选择一个可用的实例,以及调用失败的情况如何处理。在 Dubbo 中,针对这些问题,Dubbo 也提供了多种集群容错策略。

阅读全文 »

在 Spring Boot/Cloud 中,配置是应用环境的一部分,而环境有一个专属的类 —— “Environment”。

Environment 是 Spring 对环境的抽象,它封装了应用运行时的所有配置属性,这些属性可以来自不同的来源,如本地配置文件、系统属性、环境变量、命令行参数、配置中心等,而 Environment 则提供了一个统一的接口来访问这些属性。

那这些不同来源的配置文件是如何加载并生效的呢?本文一起来看看。

阅读全文 »