1.Ribbo增强 RestTemplate
/**
* 使用 Ribbon 之前的配置, 增强 RestTemplate
* */
@Component
public class RibbonConfig {
/**
* <h2>注入 RestTemplate</h2>
* */
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* 通过 Ribbon 调用 服务获取
* */
public JwtToken getTokenFromAuthorityServiceByRibbon(
UsernameAndPassword usernameAndPassword) {
// 注意到 url 中的 ip 和端口换成了服务名称
//ribbon 会根据服务id 自动获取host 和 端口
String requestUrl = String.format(
"http://%s/接口路径",
CommonConstant.AUTHORITY_CENTER_SERVICE_ID
);
log.info("login request url and body: [{}], [{}]", requestUrl,
JSON.toJSONString(xxx));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 这里一定要使用自己注入的 RestTemplate
return restTemplate.postForObject(
requestUrl,
new HttpEntity<>(JSON.toJSONString(xxx), headers),
xxx.class
);
}2.Ribbon 原生API
/**
* 使用原生的 Ribbon Api, 看看 Ribbon是如何完成: 服务调用 + 负载均衡
* */
public JwtToken thinkingInRibbon(UsernameAndPassword usernameAndPassword) {
String urlFormat = "http://%s/ecommerce-authority-center/authority/token";
// 1. 找到服务提供方的地址和端口号
List<ServiceInstance> targetInstances = discoveryClient.getInstances(
CommonConstant.AUTHORITY_CENTER_SERVICE_ID
);
// 构造 Ribbon 服务列表
List<Server> servers = new ArrayList<>(targetInstances.size());
targetInstances.forEach(i -> {
servers.add(new Server(i.getHost(), i.getPort()));
log.info("found target instance: [{}] -> [{}]", i.getHost(), i.getPort());
});
// 2. 使用负载均衡策略实现远端服务调用
// 构建 Ribbon 负载实例
BaseLoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder()
.buildFixedServerListLoadBalancer(servers);
// 设置负载均衡策略
loadBalancer.setRule(new RetryRule(new RandomRule(), 300));
String result = LoadBalancerCommand.builder().withLoadBalancer(loadBalancer)
.build().submit(server -> {
String targetUrl = String.format(
urlFormat,
String.format("%s:%s", server.getHost(), server.getPort())
);
log.info("target request url: [{}]", targetUrl);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String tokenStr = new RestTemplate().postForObject(
targetUrl,
new HttpEntity<>(JSON.toJSONString(usernameAndPassword), headers),
String.class
);
return Observable.just(tokenStr);
}).toBlocking().first().toString();
return JSON.parseObject(result, JwtToken.class);
}