spring-cloud-starter-loadbalancer使用


1:pom.xl

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>3.0.3</version>
</dependency>

2.FeignLoadBalancerConfig

/**
 * 是有缓存的,默认是35s,如修改缓存时间,可做如下配置
 * spring.cloud.loadbalancer.cache.ttl=5s
 */
@ConditionalOnDiscoveryEnabled
public class FeignLoadBalancerConfig {

    @Bean
    @ConditionalOnMissingBean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new HashLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }

}


3.FeignConfig

public class FeignConfig {
    @Bean
    public Retryer getRetryBean() {
        return Retryer.NEVER_RETRY;
        // return new Retryer.Default();// 可将服务端设置超时,可看到多次进入服务端请求
    }

}


4.HashLoadBalancer

@Slf4j
public class HashLoadBalancer implements ReactorServiceInstanceLoadBalancer {

    private final String serviceId;

    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;

    private final AtomicInteger position;

    public HashLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
        this(serviceInstanceListSupplierProvider, serviceId, new Random().nextInt(1000));
    }

    public HashLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId, int seedPosition) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
        this.position = new AtomicInteger(seedPosition);
    }


    @SuppressWarnings("rawtypes")
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
                .getIfAvailable(NoopServiceInstanceListSupplier::new);
        return supplier.get(request).next()
                       .map(serviceInstances -> processInstanceResponse(request, supplier, serviceInstances));
    }

    private Response<ServiceInstance> processInstanceResponse(Request request, ServiceInstanceListSupplier supplier,
            List<ServiceInstance> serviceInstances) {
        Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(request, serviceInstances);
        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
            ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
        }
        return serviceInstanceResponse;
    }

    private Response<ServiceInstance> getInstanceResponse(Request request, List<ServiceInstance> instances) {
        if (instances.isEmpty()) {
            if (log.isWarnEnabled()) {
                log.warn("No servers available for service: " + serviceId);
            }
            return new EmptyResponse();
        }

        // 节点实例
        if (null != request.getContext() && request.getContext() instanceof RequestDataContext) {
            // 获取请求头sharding属性值
            List<String> sharingIds = ((RequestDataContext) request.getContext()).getClientRequest().getHeaders().get(ClientConstant.sharingId);
            String shardingId = Optional.ofNullable(sharingIds).map(m -> m.get(0)).orElse(null);
            if (null != shardingId) {
                if (log.isDebugEnabled()) {
                    log.debug("getInstanceResponse shardingId = {} instances = {}", shardingId, instances.stream().map(e -> e.getInstanceId()).collect(Collectors.toList()));//todo
                }
                return new DefaultResponse(instances.get(HashKeyUtil.getIndex(shardingId, instances.size())));
            }
        }
        // instance为空说明未配置sharingId,走默认路由规则
        int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
        return new DefaultResponse(instances.get(pos % instances.size()));
    }

}


5:HashKeyUtil

public class HashKeyUtil {

    //@Autowired
    //private DiscoveryClient discoveryClient;
    // discoveryClient.getInstances("service-name"); 获取在线服务

    public static int getIndex(String key, int serviceSize) {
        return 0 == serviceSize ? 0 : hashLh(key) % serviceSize;
    }

    public static int hashLh(String key) { // 耗时和均布,相对适中
        int h;
        int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        return hash & Integer.MAX_VALUE;
    }

    public static int hashLong(String key) {
        return (int) (Long.parseLong(key) / 10);
    }

    public static int hashOnly(String key) {
        return key.hashCode() & Integer.MAX_VALUE;
    }
}


6:DemoClient

@FeignClient(name = ExchangeCoreClientConstants.SERVICE_NAME, path = "/inner/exchange/core/asset", configuration = FeignConfig.class)
@LoadBalancerClient(value = ExchangeCoreClientConstants.SERVICE_NAME, configuration = FeignLoadBalancerConfig.class)
public interface DemoClient {

    @PostMapping(value = "/transfer-in")
    ResponseResult transferIn(@RequestBody RequestCommon<TransferTraceAccountInDTO> toDto, @RequestHeader(ClientConstant.sharingId) long sharingId);
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值