Spring Cloud Ribbon:封装于Netflix Ribbon, [ˈrɪbən],带状物
功能:负载均衡(服务选取)
原理:@LoadBalanced、@FeignClient 底层都调用了Ribbon组件
服务调用之 RestTemplate
方式一:使用 LoadBalancerClient 选取服务实例
@Autowired
private LoadBalancerClient lbc; // Eureka Client 应用的容器中 有 这个 Bean
RestTemplate rt = new RestTemplate();
ServiceInstance si = lbc.choose("SERVICE_NAME"); // 选取服务实例
String url = String.format("http://%s:%s",si.getHost(), si.getPort()) + "/api";
String response = rt.getForObject(url, String.class); // 使用RestTemplate 调用服务
方式二:使用 @LoadBalanced 选取服务实例
1、装配 RestTemplate
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60*60*1000); // 提交超时时间
requestFactory.setReadTimeout(60*60*1000); // 下载超时时间
RestTemplate restTemplate = new RestTemplate(requestFactory);
restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter()); // 格式转换器
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
}
2、使用
@Autowired
private RestTemplate restTemplate;
/* Get请求 */
// 得到对象,Response 为自定义的POJO;要求response body 得是JSON格式,否则 Response 只能是 String
Response response = restTemplate.getForObject(url, Response.class);
// 得到Entity,包含response header 和 response body,其中body被转换成 Response 实例
ResponseEntity<Response> responseEntity = restTemplate.getForEntity(url, Response.class);
// 无论response body是什么格式,都可以用String来接
String response = restTemplate.getForObject(url, String.class);
/* Get请求 带header */
HttpHeaders headers = new HttpHeaders();
HttpEntity requestEntity = new HttpEntity(null, headers);
ResponseEntity<Response> responseEntity = restTemplate.exchange(user_url, HttpMethod.GET, requestEntity, Response.class);
Response response = responseEntity.getBody();
/* Post请求,提交表单格式 */
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap();
map.add("filed_1", "**");
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity(map, headers);
// 发送MultiValueMap,得到对象,同getForObject
Response response = restTemplate.postForObject(url, requestEntity, Response.class);
// 得到Entity,同getForEntity
ResponseEntity<Response> responseEntity = restTemplate.postForEntity(url, requestEntity, Response.class);
/* Post请求,提交JSON格式 */
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 可以明确指定 Accept
List<MediaType> acceptList = new ArrayList<>(1);
acceptList.add(MediaType.APPLICATION_JSON);
headers.setAccept(acceptList);
// 发送 HttpEntity 包装的 ObjectNode 字符串
ObjectNode objectNode = new ObjectMapper().createObjectNode();
objectNode.put("field_1", "**");
HttpEntity<String> requestEntity = new HttpEntity(objectNode.toString(), headers);
Response response = restTemplate.postForObject(url, requestEntity, Response.class);
// 或者 发送 HttpEntity 包装的 POJO实例
HttpEntity requestEntity = new HttpEntity(request, headers);
Response response = restTemplate.postForObject(url, requestEntity, Response.class);
// 或者 直接发送POJO实例,默认的 content-type 就是 application/json
Response response = restTemplate.postForObject(url, request, Response.class);
/*Post请求,提交XML格式*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> requestEntity = new HttpEntity<>(xml, headers);
// 发送 xml 字符串
ResponseEntity<Response> responseEntity = restTemplate.postForObject(url, requestEntity, Response.class);
服务调用之 OpenFein
1、配置Maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.2.RELEASE</version> <!-- 与Spring Cloud版本不同,需要指明版本 -->
</dependency>
2、注解主类:@EnableFeignClients
3、定义Fein Client 接口
@FeignClient(name= "Eureka-Client") // 服务名不支持下划线
public interface Client {
// 与Controller里的写法相同
@GetMapping("/my/send2") // @GetMapping相当于@RequestMapping( method=RequestMethod.GET)
String getMsg();
}
4、调用
@Autowired
private Client client;
String response = client.getMsg();
负载均衡算法
配置 application.yml
SERVICE_NAME:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 默认为轮询,这里改成随机
ribbon负载均衡算法实现类查找方法:IRule 的实现类
网友评论