面试题答案
一键面试Ribbon默认负载均衡策略
Ribbon默认的负载均衡策略是轮询(Round Robin)。它会按顺序依次选择服务实例,从列表的第一个实例开始,每次请求时选择下一个实例,循环往复。例如,假设有三个服务实例A、B、C,第一次请求选择A,第二次选择B,第三次选择C,第四次又回到A,以此类推。
自定义负载均衡策略以根据请求来源地区进行负载均衡
- 创建自定义负载均衡策略类:
继承
AbstractLoadBalancerRule
类,并重写choose
方法。import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import java.util.List; import java.util.Map; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; public class RegionBasedLoadBalancerRule extends AbstractLoadBalancerRule { @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // 初始化配置 } @Override public Server choose(Object key) { ILoadBalancer lb = getLoadBalancer(); List<Server> servers = lb.getAllServers(); // 获取请求来源地区,这里假设请求头中有一个'region'字段表示地区 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes!= null) { String region = attributes.getRequest().getHeader("region"); for (Server server : servers) { // 假设Server对象中有一个方法可以获取实例所在地区 if (region.equals(server.getMetaInfo().getRegion())) { return server; } } } // 如果没有匹配的地区实例,使用默认的轮询策略 return super.choose(key); } }
- 配置自定义负载均衡策略:
- 在
application.yml
文件中配置:
这里<服务名>: ribbon: NFLoadBalancerRuleClassName: com.example.demo.RegionBasedLoadBalancerRule
<服务名>
是需要应用自定义负载均衡策略的服务名称,NFLoadBalancerRuleClassName
指定自定义策略类的全限定名。- 或者通过Java配置类配置:
然后在启动类上添加import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RibbonConfig { @Bean public IRule ribbonRule() { return new RegionBasedLoadBalancerRule(); } }
@RibbonClient
注解,指定服务名称和配置类:
这样就完成了根据请求来源地区进行负载均衡的自定义策略配置。import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.ribbon.RibbonClient; @SpringBootApplication @RibbonClient(name = "<服务名>", configuration = RibbonConfig.class) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
- 在