Ribbon service
Ribbon 提供了负载均衡和重试功能, 它底层是使用 RestTemplate 进行 Rest api 调用
RestTemplate
RestTemplate is a Rest remote call tool provided by SpringBoot
Its common methods:
The previous system structure is that the browser directly accesses the background service
Later, we will demonstrate Spring Cloud remote invocation through a Demo project
After using RestTemplate, the load on the server is significantly reduced. SpringCloud's ribbon optimizes RestTemplate and the effect is improved several times.
接下来使用Ribbon来远程调用和负载均衡
ribbon load balancing and retry
Ribbon的底层包含RestTemplate远程调用工具
Ribbon load balancing
Steps:
- New ribbon project
- pom.xml add dependency
- application.yml add configuration
- Main program
- controller
- Start, and visit the test
1-Create project
创建项目是有两个依赖,如果使用eureka的话 加入eureka的依赖
2 - pom.xml
Add ribbon start-up dependency (optional)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
3 - application.yml
spring:
application:
name: ribbon
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
4-Main program
创建 RestTemplate 实例
RestTemplate is a tool class used to call other microservices. It encapsulates remote calling code and provides a set of template methods for remote calling, such as getForObject(), postForObject(), etc.
@EnableDiscoveryClient
@SpringBootApplication
public class Sp06RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(Sp06RibbonApplication.class, args);
}
@LoadBalanced //负载均衡注解
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
RestTemplate 设置 @LoadBalanced
@LoadBalanced load balancing annotation will encapsulate the RestTemplate instance, create a dynamic proxy object, and cut into the (AOP) load balancing code to distribute the request to the servers in the cluster
5 - RibbonController
访问路径设置为服务id
@RestController
public class RibbonController {
@Autowired
private RestTemplate rt;
@GetMapping("/item-service/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
//这里服务器路径用 service-id 代替,ribbon 会向服务的多台集群服务器分发请求
return rt.getForObject("http://item-service/{1}", JsonResult.class, orderId);
}
@PostMapping("/item-service/decreaseNumber")
public JsonResult decreaseNumber(@RequestBody List<Item> items) {
return rt.postForObject("http://item-service/decreaseNumber", items, JsonResult.class);
}
6-Access test
Start the ribbon server
访问测试,ribbon 会把请求分发到 8001 和 8002 两个服务端口上
Ribbon retry
What is retry?
Retry is an error mechanism, if
请求后台服务出错
, or服务器故障
, you can retry access to another server
rely:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
Application.yml configure ribbon to retry:
spring:
application:
name: ribbon
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
ribbon:
MaxAutoRetriesNextServer: 2
MaxAutoRetries: 1
OkToRetryOnAllOperations: true
MaxAutoRetriesNextServer-the number of times to replace the instance (2 times is enough)
MaxAutoRetries —— The number of retries for the current instance, if the attempt fails, the next instance will be replaced (1 time is enough)
OkToRetryOnAllOperations=true —— By default, only GET requests are retried, when set to true, all types of requests such as POST are retried
The main program sets the timeout of RestTemplate's request factory
@SpringBootApplication
@EnableDiscoveryClient
public class Sp06RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(Sp06RibbonApplication.class, args);
}
@LoadBalanced //负载均衡注解
@Bean
public RestTemplate restTemplate(){
SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
f.setConnectTimeout(1000);
f.setReadTimeout(1000);
return new RestTemplate();
}
}
Use SimpleClientHttpRequestFactory API to set the timeout
setConnectTimeout(1000) —— link timeout 1000 milliseconds
setReadTimeout(1000) —— pause time 1000 milliseconds
Access, test the ribbon retry mechanism
In order to test, we add delay code to the ItemController of tem-service to test the retry mechanism of the ribbon (delete after the test is completed)
@Slf4j
@RestController
public class ItemController {
@Autowired
private ItemService itemService;
@Value("${server.port}")
private int port;
@GetMapping("/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId) throws Exception {
log.info("server.port="+port+", orderId="+orderId);
///--设置随机延迟
if(Math.random()<0.6) {
long t = new Random().nextInt(5000);
log.info("item-service-"+port+" - 暂停 "+t);
Thread.sleep(t);
}
///~~
List<Item> items = itemService.getItems(orderId);
return JsonResult.ok(items).msg("port="+port);
}
-
Access item-service through ribbon, when timeout, ribbon will retry to request other servers in the cluster
- http://localhost:3001/item-service/35