RestTemplate
springboot 提供的远程调用工具
类似于 HttpClient,可以发送 http 请求,并处理响应。RestTemplate简化了Rest API调用,只需要使用它的一个方法,就可以完成请求、响应、Json转换。
方法API:
- getForObject(url, 转换的类型.class, 提交的参数)
- postForObject(url, 协议体数据, 转换的类型.class)
RestTemplate 和 Dubbo 远程调用的区别:
- RestTemplate:
- http调用
- 效率低
- Dubbo:
- RPC调用,Java的序列化
- 效率高
Ribbon
Springcloud集成的工具,作用是负载均衡,和重试
Demo
前置环境:
1.商品,用户,订单三个业务服务
2.两个eureka服务器构建成的eureka集群
目标:
通过新建测试工程远程调用订单服务,返回订单信息
路径:http://localhost:8001/{orderId}
1.新建springboot模块,添加spring web,eureka 和ribbonl依赖如下:
2.配置application.yml
# 应用名称
spring:
application:
name: ribbon
server:
prot: 3001
# 连接eureka,从eureka发现其他服务的地址
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
3.在主启动类中创建RestTemplate实例
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class Sp06RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(Sp06RibbonApplication.class, args);
}
/**
* 创建RestTemplate实例
* 放入spring容器
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
4.创建controller包,新建RibbonController类进行远程调用
package cn.tedu.sp06.controller;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import javax.ws.rs.Path;
import java.util.List;
@RestController
@Slf4j
public class RibbonController {
@Autowired
private RestTemplate rt;
@GetMapping("/item-service/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId){
//使用远程调用工具RestTemplate,远程调用商品服务
//http://localhost:8001/{orderId}
//{1}-RestTemplate定义的一种占位符格式
return rt.getForObject("http://localhost:8001/{1}", JsonResult.class,orderId);
}
@PostMapping("/item-service/decreaseNumber")
public JsonResult<?> decreaseNumber(@RequestBody List<Item> items){
return rt.postForObject("http://localhost:8001/decreaseNumber",
items, JsonResult.class);
}
}
5.测试,启动eureka集群,商品服务,测试服务
打开浏览器,输入url:http://localhost:3001/item-service/35,出现以下界面,调用成功。
http://localhost:3001/item-service/decreaseNumber
使用postman,POST发送以下格式数据:
[{“id”:1, “name”:“abc”, “number”:23},{“id”:2, “name”:“def”, “number”:11}]
测试成功!
Ribbon
Springcloud集成的工具,作用是负载均衡,和重试
负载均衡
Ribbon 对 RestTemplate 做了封装,增强了 RestTemplate 的功能
- 获得地址表
- 轮询一个服务的主机地址列表
- RestTemplate负责执行最终调用
添加负载均衡:
- ribbon依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
-
@LoadBalanced 注解,对 RestTemplate 进行功能增强
-
修改调用地址,使用 服务id,而不是具体主机地址
Ribbon 重试
一种容错机制,当调用远程服务失败,可以自动重试调用
添加重试:
- 添加 spring-retry 依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
-
配置重试参数
- 在yml中配置
- MaxAutoRetries:单台服务器的重试次数
- MaxAutoRetriesNextServer:更换服务器的次数
#配置Ribbon重试次数
ribbon:
#次数参数没有提示,会有黄色警告,重试次数一般建议为0,1
MaxAutoRetires: 1
MaxAutoRetriesNextServer: 2
- 在java代码中设置
- ConnectTimeout:与远程服务建立网络连接的超时时间
- ReadTimeout:连接已建立,请求已发送,等待响应的超时时间
启动类配置中添加代码如下:
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
//设置调用超时时间,超时后认为调用失败
SimpleClientHttpRequestFactory factory=new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(1000);//建立连接等待时间
factory.setReadTimeout(1000);//连接建立后,发送请求后,等待接收响应时间
return new RestTemplate(factory);
}