小菜鸟

java菜鸟号正在起航

Hystrix:分布式系统的容错守护者

在微服务架构中,服务间依赖错综复杂,一个服务的故障可能引发连锁反应,导致服务雪崩(某服务不可用→依赖其的服务资源耗尽→更多服务不可用)。Hystrix 作为 Netflix 开源的容错框架,通过熔断、降级、隔离等机制,为分布式系统提供了弹性保护,避免级联故障的扩散。

Hystrix 的核心目标:解决服务雪崩

服务雪崩的本质是 “依赖服务不可用导致调用方资源耗尽”。例如:

  • 服务 A 调用服务 B,服务 B 调用服务 C;
  • 服务 C 响应超时或崩溃,导致服务 B 的线程阻塞等待;
  • 服务 B 线程耗尽后,服务 A 的调用请求也被阻塞,最终整个调用链崩溃。

Hystrix 通过以下手段解决雪崩问题:

  • 超时控制:为每个依赖调用设置超时,避免线程无限期阻塞;
  • 熔断机制:当依赖失败率过高时,自动 “跳闸” 停止调用,快速失败;
  • 资源隔离:为每个依赖分配独立线程池,避免单个依赖耗尽所有资源;
  • 降级策略:调用失败时返回预设的备用结果,保证调用方正常运行。

Hystrix 的核心原理与设计

1. 基于命令模式(HystrixCommand)

Hystrix 通过HystrixCommand封装对依赖的调用逻辑,将同步调用转换为可控的命令执行:

阅读全文 »

Feign 进阶特性与实践

Feign 作为 Spring Cloud 生态中重要的服务调用组件,除了基础的声明式接口调用外,还有许多进阶特性可以优化服务间通信的效率、可靠性和可维护性。以下从多个维度展开介绍:

依赖

<!-- feign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

配置启动类

@SpringBootApplication
@EnableEurekaClient
// 启动feign,会进行对FeignClient的扫描加载
@EnableFeignClients(basePackages = "com.zhanghe.study")
public class ConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class,args);
    }
}

Feign 配置自定义

Feign 允许通过配置类自定义其核心组件(如编码器、解码器、日志级别等),实现更灵活的调用控制。

1. 全局配置与局部配置

  • 全局配置:通过 @Configuration 注解定义配置类,并在启动类的 @EnableFeignClients 中指定 defaultConfiguration 参数,对所有 Feign 客户端生效。

    @Configuration
    public class FeignGlobalConfig {
        // 配置日志级别
        @Bean
        public Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL; // 打印所有请求细节
        }
        
        // 替换默认 HTTP 客户端为 Apache HttpClient(需引入对应依赖)
        @Bean
        public CloseableHttpClient httpClient() {
            return HttpClientBuilder.create().build();
        }
    }
    
    // 启动类指定全局配置
    @EnableFeignClients(defaultConfiguration = FeignGlobalConfig.class)
  • 局部配置:在 @FeignClientconfiguration 属性中指定配置类,仅对当前客户端生效,优先级高于全局配置。

    @FeignClient(value = "SERVICE-PROVIDER", configuration = FeignLocalConfig.class)
    public interface ProviderClient { 
      
    		@RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET)
        public Dept get(@PathVariable("id") long id);
    
    }

2. 核心配置项说明

阅读全文 »

Ribbon 负载均衡算法:内置实现与自定义实践

Ribbon 的核心能力在于其灵活的负载均衡算法,通过预设或自定义的规则将请求合理分配到服务实例。本文详细解析 Ribbon 的内置算法、配置方式及自定义实现,帮助理解其负载均衡的底层逻辑。

Ribbon 内置负载均衡算法详解

Ribbon 提供了 7 种内置负载均衡算法,每种算法针对不同场景设计,核心接口为IRule,所有算法均实现该接口。

1. RoundRobinRule(轮询算法)

  • 原理:按顺序轮流选择服务实例(如实例 A→实例 B→实例 C→A…)。
  • 特点:
    • 实现简单,公平性强,不依赖实例状态;
    • 缺点是未考虑实例负载差异(如某实例响应慢仍会被分配等量请求)。
  • 适用场景:所有服务实例配置相同、负载均匀的场景(如无状态服务)。

2. RandomRule(随机算法)

  • 原理:通过随机函数从可用实例中随机选择一个。
  • 特点:
    • 实现简单,避免轮询的周期性波动;
    • 短期可能出现负载不均,但长期概率接近轮询。
  • 适用场景:对负载均衡的 “均匀性” 要求不高,或实例性能差异较小的场景。

3. AvailabilityFilteringRule(可用性过滤算法)

  • 原理:先过滤掉 “不可用” 实例,再对剩余实例轮询:
    • 过滤 1:处于 “断路器跳闸状态” 的实例(多次访问失败被标记为不可用);
    • 过滤 2:并发连接数超过阈值的实例(通过ActiveConnectionsLimit配置)。
  • 特点:
    • 主动规避故障实例和过载实例,提高调用成功率;
    • 依赖断路器(如 Hystrix)和连接数统计。
  • 适用场景:需要规避故障实例的场景(如服务稳定性要求高的核心业务)。
阅读全文 »

Ribbon:客户端负载均衡的经典实现

Ribbon 是 Netflix 开源的客户端负载均衡工具,主要用于在微服务架构中实现服务间的负载均衡调用。它通过在客户端维护服务实例列表,基于预设的负载均衡算法选择合适的服务实例,从而避免单点故障并优化资源利用率。

Ribbon 的核心定位与价值

Ribbon 是客户端负载均衡器,与 Nginx 等集中式负载均衡不同:

  • 集中式负载均衡(如 Nginx):请求先经过负载均衡器,再转发到服务实例,负载均衡逻辑独立部署;
  • 客户端负载均衡(Ribbon):负载均衡逻辑集成在客户端,客户端直接从服务注册中心获取实例列表,自主选择实例发起请求。

Ribbon 的核心价值:

  • 减少中间环节:客户端直接调用服务实例,无需经过额外负载均衡节点,降低网络延迟;
  • 灵活的负载策略:支持轮询、随机、加权等多种负载均衡算法,且允许自定义;
  • 内置容错机制:提供连接超时、重试等配置,提升服务调用的稳定性。

Ribbon 的依赖与配置

1. 引入依赖

根据 Spring Cloud 版本选择对应的 Ribbon 依赖:

  • Spring Cloud F 版及以上(推荐):

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
  • 旧版本(如 Edgware 及之前):

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>

注意:若项目已引入spring-cloud-starter-openfeign,无需单独引入 Ribbon 依赖,OpenFeign 默认集成了 Ribbon。

2. 启用负载均衡

通过@LoadBalanced注解标记RestTemplate,使其具备负载均衡能力:

阅读全文 »

Lucene 分析器(Analyzer):文本处理的核心组件

Lucene 的分析器(Analyzer)是文本预处理的核心模块,负责将原始文本转换为可用于索引和检索的词项(Term)。它由字符映射器(Character Mapper)分词器(Tokenizer)过滤器(Filter) 三部分组成,三者按顺序协同工作,形成完整的文本处理流水线。

字符映射器(Character Mapper):文本预处理

字符映射器是分析器的第一个环节,作用于原始文本字符流,在分词前进行字符级别的预处理,确保后续分词和过滤的准确性。

核心功能

  • 字符编码转换:将非 Unicode 编码(如 GBK)的文本转换为 Unicode,避免字符乱码。
  • 非法字符过滤:移除不可打印字符(如控制字符、特殊符号)或自定义过滤规则(如过滤 emoji)。
  • 字符标准化:统一字符形式(如将全角字符 “a” 转换为半角 “a”,或将 “℃” 转换为 “c”)。

特点

  • 仅处理单个字符,不涉及词的拆分,是文本处理的 “第一道净化工序”。
  • Lucene 中通常通过 CharFilter 抽象类实现,常见实现如 HTMLStripCharFilter(移除 HTML 标签)。

分词器(Tokenizer):文本拆分为词条

分词器是分析器的核心环节,负责将预处理后的字符流拆分为词条(Token)—— 即包含词项文本及附加信息的单元。

核心功能

  • 按规则拆分文本:根据语言特性或自定义规则拆分(如英文按空格 / 标点拆分,中文按词库拆分)。
  • 记录词条元信息:为每个词条添加偏移量(在原始文本中的起止位置)、长度、类型(如 “数字”“英文单词”)等信息,用于后续检索和高亮显示。

常见实现

  • StandardTokenizer:Lucene 默认分词器,支持多语言,能识别字母、数字、邮箱、IP 等格式,按非字母 / 数字字符拆分。
  • WhitespaceTokenizer:仅按空格拆分,不处理标点(如 “hello,world” 拆分为 “hello,world”)。
  • CJKTokenizer:针对中日韩语言的分词器,按双字拆分(如 “中国”→“中国”,“北京”→“北京”)。
  • 自定义分词器:结合词库或机器学习模型(如 Jieba 分词的 Lucene 适配版),提升中文等复杂语言的分词精度。

过滤器(Filter):词条流的精细化处理

过滤器接收分词器输出的词条流,对每个词条进行二次处理,进一步优化词项质量,使索引更精准、检索更高效。多个过滤器可串联使用,形成 “过滤链”。

阅读全文 »
0%