springcloud学习第三篇

一、客户端负载均衡组件Ribbon

1.添加依赖

<!-- 添加ribbon 依赖 -->
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

2.添加配置类

@Configuration
public class MyConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3.使用

@RestController
public class Controller {
	@Autowired
    private RestTemplate restTemplate;
    
    public string function() {
        ResponseEntity responseEntity = restTemplate.getForEntity("http://service-name/other/interface");
    }
}

4.常见负载均衡策略

默认轮询

4.1.随机

@Configuration
public class MyConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * 随机算法的负载均衡
     * @return 结果
     */
    @Bean
    public IRule MyRule(){
        return new RandomRule();
    }
}

4.2.自定义

import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;

public class CustomRule extends AbstractLoadBalancerRule {

    @Override
    public Server choose(Object key) {
        // 获取所有可达的服务实例
        List<Server> reachableServers = getLoadBalancer().getReachableServers();
        
        if (reachableServers.isEmpty()) {
            return null;
        }
        
        // 示例:自定义过滤逻辑 - 只选择端口为 8081 的实例
        List<Server> filteredServers = reachableServers.stream()
            .filter(server -> server.getPort() == 8081)
            .collect(Collectors.toList());
        
        if (filteredServers.isEmpty()) {
            // 回退到随机选择
            return new Random().nextInt(reachableServers.size());
        }
        
        // 从过滤后的列表中选择
        return filteredServers.get(new Random().nextInt(filteredServers.size()));
    }
}

5.缺点

参数需要拼接到url上面

二、客户端负载均衡组件Feign

1.添加依赖

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

2.开启openFeign

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients(basePackages = "com.jhk")
public class AppUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(AppUserApplication.class, args);
    }
}

3.使用

// 调用其他服务
@FeignClient(name="service-name")
public interface serviceApi{
	
	@RequestMapping("/getData")
	String getData();
}

三、Feign源码

EnableFeignClients
org.springframework.cloud.openfeign.EnableFeignClients
	>org.springframework.cloud.openfeign.FeignClientsRegistrar # @Import({FeignClientsRegistrar.class}) 通过import注解方式加载FeignClientsRegistrar到容器
		>org.springframework.cloud.openfeign.FeignClientsRegistrar#registerBeanDefinitions # 将Bean 注册到 FeignClientsRegistrar
			>org.springframework.cloud.openfeign.FeignClientsRegistrar#registerFeignClients
				>org.springframework.cloud.openfeign.FeignClientsRegistrar#registerClientConfiguration # 扫描EnableFeignClients标签中的配置信息并注册
				>org.springframework.cloud.openfeign.FeignClientsRegistrar#registerFeignClient # 扫描所有@FeignClient注解的类注入spring容器
					>org.springframework.cloud.openfeign.FeignClientFactoryBean # 接口的代理Bean
						>org.springframework.cloud.openfeign.FeignClientFactoryBean#getObject
							>org.springframework.cloud.openfeign.FeignClientFactoryBean#getTarget
								>org.springframework.cloud.openfeign.FeignClientFactoryBean#loadBalance # 如果feignClient中没有url属性,会调用loadBalance完成自动负载调用
					>org.springframework.beans.factory.support.BeanDefinitionBuilder#genericBeanDefinition(java.lang.Class<?>) # 创建每个feignClient接口的代理Bean
						>org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition # 注册到bena容器中

本文来自博客园,作者:TheLifelongLearner,转载请注明原文链接:https://www.cnblogs.com/The-Lifelong-Learner/p/20490144

posted @ 2026-06-13 00:12  TheLifelongLearner  阅读(10)  评论(0)    收藏  举报