/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String port;
@GetMapping("{id}")
public Map findById(@PathVariable Integer id){
return new HashMap(){{
put("flag",true);
put("message","查询成功"+ip+":"+port);
put("statusCode","200");
put("id",id);
}};
}
}
启动两个Order服务,访问:http://localhost:9001/item/findOrderById/1
多次访问,查看是否有轮询效果;
5.2.2 自定义服务列表
当我们在 RestTemplate
上添加 @LoadBalanced
注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,关系如下:
有的时候我们希望Ribbon可以跳过Eureka,直接使用IP+端口的方式调用服务,这样的我们就不需要借助Eureka提供的服务名来远程调用了(测试环境用),我们可以自定义服务列表来实现负载均衡;
关闭Ribbon与Eureka的集成:
ribbon:
eureka:
enabled: false # 关闭与Eureka的集成
ribbon-order-service: # 自定义服务名称
ribbon:
listOfServers: localhost:9001,localhost:9002 # 服务的主机列表
注意:默认情况下Ribbon与Eureka的集成为开启状态,在开启状态下,只能使用服务名调用;而在关闭状态下,只能使用IP+端口来调用,如果指定IP+端口的方式来调用,那么必定不能提供负载均衡的功能;如果想使用负载均衡功能,那么必须自定义服务名称,并为该服务配置主机列表;
- ItemController:
@GetMapping("/findOrderById/{orderId}")
public Map findOrderById(@PathVariable Integer orderId){
// 使用自定义的服务名称
Map resultMap = restTemplate.getForObject("http://ribbon-order-service/order/" + orderId, Map.class);
return resultMap;
}
- OrderController:
package com.cloud.order.controller;
import com.cloud.order.entity.Order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.\*;
import java.util.HashMap;
import java.util.Map;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String port;
@GetMapping("{id}")
public Map findById(@PathVariable Integer id) {
return new HashMap() {{
put("flag", true);
put("message", "查询成功" + ip + ":" + port);
put("statusCode", "200");
put("id", id);
}};
}
}
5.3 Ribbon的配置
5.3.1 Ribbon 的属性配置
Ribbon的所有的默认配置可以去com.netflix.client.config.DefaultClientConfigImpl
类下找:
关于Ribbon的所有配置在com.netflix.client.config.CommonClientConfigKey
中定义:
5.3.2 Ribbon常用配置
5.3.2.1 连接配置
ribbon:
ConnectTimeout: 2000 # 请求连接的超时时间
ReadTimeout: 5000 # 请求处理的超时时间
- ConnectTimeout:是指请求发送到服务,两端连接所需要的时间
- ReadTimeout:是指建立连接后从服务端读取到可用资源所用的时间
5.3.2.2 懒加载配置
Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易出现第一次调用超时,之后就调用正常的现象;
ribbon:
eager-load:
enabled: true # 开启立即加载客户端
clients: ribbon-order-service,ribbon02-order-service # 选择指定的服务开启立即加载
5.3.2.3 并发调整
ribbon:
MaxTotalConnections: 500 # 最大连接数
MaxConnectionsPerHost: 100 # 每个host最大连接数
5.3.3 Ribbon 配置策略
Ribbon的配置分为全局配置和指定客户端配置,两种配置格式不同;
全局配置针对于所有的服务,客户端配置只针对于具体服务使用;
- 全局配置:
ribbon:
ConnectTimeout: 20000 # 请求连接的超时时间
ReadTimeout: 5000 # 请求处理的超时时间
- 客户端配置:
ribbon-order-service: # 自定义服务名称
ribbon:
listOfServers: localhost:9001,localhost:9002 # 服务的主机列表
ConnectTimeout: 20000
ReadTimeout: 5000
Tips:全局配置只针对集成Eureka时的调用,不能作用于自定义微服务名称调用;
5.4 Ribbon的负载均衡策略
5.4.1 Ribbon负载均衡策略
不难发现,我们之前使用Ribbon的负载均衡策略都是轮询;在Ribbon中,除了轮询策略外,还提供有其他几种策略,内部负责负载均衡的顶级接口为com.netflix.loadbalancer.IRule
:
-
com.netflix.loadbalancer.RoundRobinRule
:- **轮询策略;**以轮询的方式进行负载均衡。
-
com.netflix.loadbalancer.WeightedResponseTimeRule
:- **权重策略;**会计算每个服务的权重,响应速度越快的实例选择权重越大,越高的被调用的可能性越大。
-
com.netflix.loadbalancer.ResponseTimeWeightedRule
:- **权重策略;**作用和WeightedResponseTimeRule一致,后来改名为 WeightedResponseTimeRule
-
com.netflix.loadbalancer.BestAvailableRule
:- **最佳策略;**首先过滤掉故障实例,在没有故障的实例中,选择一个压力最小(并发量)的服务
-
com.netflix.loadbalancer.ZoneAvoidanceRule
:- **回避策略;**使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 来判断是否选择某个 Server,前一个判断判定一个 Zone 的运行性能是否可用,剔除不可用的 的所有 Server,AvailabilityPredicate 用于过滤掉连接数过多的 Server。
-
com.netflix.loadbalancer.AvailabilityFilteringRule
:- **过滤策略;**过滤掉故障和请求数超过阈值的服务实例,再从剩下的实例中轮询调用。
-
com.netflix.loadbalancer.RandomRule
:- **随机策略;**在服务列表中随机选择一个服务调用;
-
com.netflix.loadbalancer.RetryRule
:- **重试策略;**在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内服务未响应,则继续使用轮询方式访问其他服务;
5.4.1 修改Ribbon负载均衡策略
写在最后
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里
[外链图片转存中…(img-Ke8hvZ3r-1716217311785)]
[外链图片转存中…(img-XD3A6F9B-1716217311786)]
[外链图片转存中…(img-3qt7OsUS-1716217311786)]