同样是负载均衡和ngix 有什么区别呢?
ngix是所有请求的,而ribbon是微服务的服务端的均衡,相同的服务多个负载。是某一个微服务的
ribbon主要是配合resttemplate 来实现的负载均衡。
ribbon具体是怎么工作的?
1️⃣集成在微服务的消费端
2️⃣从注册中心获取注册的服务列表
这两步是最重要的。
具体负载均衡的算法之后,直接用restTemplate 发送到具体的服务。
我们当初并没有引入ribbon啊,回想一下之前的负载均衡是怎么实现的?
看一下
org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.2.1.RELEASE
其实我们引入的eureka客户端中已经引入了ribbon 的jar
restTemplate关于entity的两个方法的使用
package home.controller;
import home.entity.MyResult;
import home.entity.Pay;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@Slf4j
public class OrderCon {
@Autowired
RestTemplate restTemplate;
@GetMapping(value = "/order/create")
public MyResult create(Pay pay) {//pay/create
log.info(pay + "");
// "http://localhost:8001/pay/create" 之前我们是写死,现在是多台的集群了。不能写死
return restTemplate.postForObject("http://PAY-SERVICE/pay/create", pay, MyResult.class);
}
@GetMapping(value = "/order/create/entity")
public MyResult createEntity(Pay pay) {//pay/create
log.info(pay + "");
// "http://localhost:8001/pay/create" 之前我们是写死,现在是多台的集群了。不能写死
ResponseEntity<MyResult> myResultResponseEntity = restTemplate.postForEntity("http://PAY-SERVICE/pay/create", (Object) pay, MyResult.class);
return myResultResponseEntity.getBody();
}
@GetMapping(value = "/order/get/{id}")
public MyResult get(@PathVariable(value = "id") int id) {
return restTemplate.getForObject("http://PAY-SERVICE/pay/get/" + id, MyResult.class);//这个返回的是你传入的返回值
}
@GetMapping(value = "/order/getEntity/{id}")
public MyResult getEntity(@PathVariable(value = "id") int id) {
ResponseEntity<MyResult> forEntity = restTemplate.getForEntity("http://PAY-SERVICE/pay/get/" + id, MyResult.class);
//这个返回的是一个封装了其他信息和你的返回值的对象
return forEntity.getBody();
}
}
就是两个带entity的两个方法的测试。使用差不多。主要在于返回。如果你想要状态码,头信息,可以用带entity的方法。
ribbon到底提供了几个算法?
IRule
算法都是实现了这个接口。
idea 查看类的继承关系 CTRL+h 可以看所有
如果看类图的关系 看上层的接口,以及抽象类用 类右键 Diagram 选java的。
如果还要看下层, CTRL+ALT+b 所有的下层子类和接口。 CTRL+a 可以全选。直接生成完整的类图。
idea 这个🐮
RoundRobinRule 默认规则,轮询
RetryRule 先按照轮询,失败会按照固定时间重试。
WeightedResponseTimeRule 对轮询的扩展,响应速度越快的实例,权重越大,越容易被选择。
RandomRule 随机
BestAvailableRule 先过滤掉熔断的,选择并发量最小的。
AvailabilityFilteringRule 先过滤掉故障的,然后选择并发最小的。
ZoneAvoidanceRule 复合判断server所在的区域的性能和可用性,选择, 高性能,可用性的复合。
有这么多,我想试试,怎么用呢?
package home.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTem {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public IRule irule(){
return new RandomRule();
}
}
这个是直接将负载均衡算法注入到整个项目。现在用的是RandomRule;
@LoadBalanced 用的就是默认的策略。 现在也就是用random了。
这样配置根据官方文档的说明,会导致所有的ribbon客户端都会使用到。我们的配置类不能喝主启动类一个包。不能被@CompoentScan所扫描到。
让其单独生效
在主启动类的包 同级创建一个包。
package my;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class bal {
@Bean
public IRule irule(){
return new RandomRule();
}
}
第二,在主启动类上引入。
package home;
import my.bal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@EnableEurekaClient
@RibbonClient(name = "PAY-SERVICE",configuration = bal.class) //也就是用这个注解引入这个bean 单独使用。
public class Order80 {
public static void main(String[] args) {
SpringApplication.run(Order80.class, args);
}
}
主要看类上的第一个注解。 就ok了。