文章目录
用在消费者80模块,用来负载均衡调用生产者多个模块
1. Ribbon负载均衡(进程内LB)
Ribbon官网:https://github.com/Netflix/ribbon,根据官网信息,可以看到Ribbon现在进入了维护模式,替换方案是Loadbalancer。
LB负载均衡(Load Balance)是什么
负载均衡的表现就是,将用户的请求分摊到多个服务器上,从而达到高可用的目的。常见的负载均衡软件有:Nginx、LVS、硬件F5等。
Ribbon负载均衡 VS Nginx负载均衡
Nginx是服务器端负载均衡(集中式LB),客户端的请求都发给Nginx,Nginx实现分发,将请求发送到不同的服务器上。
Ribbon是本地负载均衡(客户端,进程内LB),在调用微服务接口的时候,会在注册中心拿到注册信息服务列表缓存到本地JVM,从而在本地实现RPC远程服务调用技术。
集中式LB和进程内LB
集中式LoadBalancer:在服务的消费方和提供方之间使用的独立LoadBalancer设备(可以是硬件,如F5,也可以是软件,如Nginx),由该设施负责把请求通过某种策略转发至服务的提供方。
进程内LoadBalancer:将LoadBalancer集成到消费方,消费者从服务注册中心获取到可用地址,自己再从这些地址中,选择要访问的服务器(如这个微服务器名称下有多个生产者的微服务,端口8001、8002、8003,进行轮循)。Ribbon就属于进程内LoadBalancer,它只是一个类库,集成消费者进程,消费者通过它获取服务提供方的地址。
Ribbon目前也进入维护,基本上不准备更新了
Ribbon就是负载均衡+RestTemplate
2. 使用Ribbon
1.默认我们使用eureka的新版本时,它默认集成了ribbon
这个starter中集成了reibbon了
2.我们也可以手动引入ribbon
放到order消费者模块中,因为只有order访问pay生产者时需要负载均衡
3. RestTemplate类
之前,我们好像并没有加入Ribbon的依赖,也实现了负载均衡,其实在spring-cloud-starter-netflix-eureka-client
坐标下,是引入了spring-cloud-starter-netflix-ribbon
的,所以,我们仅仅只需要添加一个@LoadBalanced就可以实现负载均衡。
RestTemplate常见的方法有getForObject()、getForEntity()、postForObject()、postForEntity()方法。其中
-
ForObject()方法返回对象为响应体中数据转换成的对象,基本理解为JSON。
-
ForEntity()方法返回对象是ResponseEntity对象,包含了响应中的信息,比如响应头,响应状态码,响应体等。
将cloud-eureka-server7001、cloud-eureka-server7002的配置文件改成集群模式,让7001和7002互相注册,将cloud-provider-payment8001、cloud-provider-payment8002的配置文件改成集群模式,将cloud-consumer-order80的配置文件改成集群模式。
在cloud-consumer-order80模块中的OrderController里,添加两个方法,分别调用getForEntity()和postForEntity()方法。
@GetMapping("/consumer/payment/getForEntity/{id}")
public CommonResult getPaymentById2(@PathVariable("id") Long id) {
ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
System.out.println("status code=" + entity.getStatusCode());
System.out.println("headers=" + entity.getHeaders());
if (entity.getStatusCode().is2xxSuccessful()) {
return entity.getBody();
} else {
return new CommonResult(404, "查找失败");
}
}
@GetMapping("/consumer/payment/create2")
public CommonResult create2(Payment payment) {
return restTemplate.postForEntity(PAYMENT_URL + "/payment/create", payment, CommonResult.class).getBody();
}
RestTemplate的:
xxxForObject()方法,返回的是响应体中的数据
xxxForEntity()方法.返回的是entity对象,这个对象不仅仅包含响应体数据,还包含响应体信息(状态码等)
先启动Eureka注册中心,再启动两个生产者,最后启动消费者,浏览器发送请求来调用ForEntity()方法进行测试。在浏览器端,可以看到port的值,不断在8001和8002之前进行切换。
3. Ribbon常用负载均衡算法
IRule接口,Riboon使用该接口,根据特定算法从所有服务中,选择一个服务,
Rule接口有7个实现类,每个实现类代表一个负载均衡算法
使用Ribbon
这里使用eureka的那一套服务
也就是不能放在主启动类所在的包及子包下
1,修改order 80模块
2,额外创建一个包
3,创建配置类,指定负载均衡算法
这个Rule配置类不能在主启动类所在的包及其子包
如果不指定负载均衡算法,则默认使用轮循算法,现在自定义为随机算法
4,在80主启动类上加一个注解(使用指定的算法)
@RibbonClient中 name
是生产者微服务名称(地址),表明负载均衡用在生产者服务上;
configuration = MySelfRule.class
是调用自定义的负载均衡配置类(使用自定义的随机算法)
表示,访问CLOUD_pAYMENT_SERVICE的服务时,使用我们自定义的负载均衡算法
负载均衡算法:
1. ribbon的轮询算法原理
2. 自定义负载均衡算法
1.pay生产者模块(8001,8002)
controller方法添加一个方法,返回当前节点端口
2. 修改order 80消费者模块
(1)在配置类config中去掉@LoadBalanced注解(自带的负载均衡机制)
(2)在80模块中自定义接口
具体的算法在实现类中实现
(3)接口实现类
(4)修改controller