Idea搭建SpringCloud(三)------Ribbon实现负载均衡及其⾃
定义算法策略
SpringCloud中提供了⼀个组件Ribbon,Spring Cloud Ribbon是⼀个基于Http和TCP的客服端负载均衡⼯具,它是基于Netflix Ribbon 实现的。
对于SpringCloud来说为什么要实现负载均衡?负载均衡对于集或者是分布式来说都是⼀种常见的⼿段⽤于减轻服务器压⼒,并不单单针对于微服务,⽽在另外的⼀套分布式架构Zookeeper,Dubbo,常⽤的软负载均衡是nginx。在SpringCloud中,服务提供者可能会有多个,⽽⽤户同过消费者去访问提供者,⾃然⽽然要需要负载均衡去实现各服务器平均分担压⼒。下⾯我们在构建负载均衡的微服务之前,先来搭建Eureka和Ribbon的整合,达到真正的通过rest访问微服务名称来调⽤微服务。
对于消费者来说,它是访问的⼊⼝,所以它要加上Ribbon的依赖,⽽Ribbon要需要依赖于Eureka,所以也要把Eureka的依赖加上:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
在l中加上:
server:
springboot推荐算法port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: localhost:7001/eureka/,localhost:7002/eureka/,localhost:7003/eureka/
端⼝号为80端⼝,配置与Eureka服务注册中⼼连接,这⾥配上连接主要是消费者会先从Eureka中获取提供者的信息,包括服务应⽤名称,IP地址,端⼝号等等。
启动类:
@SpringBootApplication
@EnableEurekaClient
public class EurekaServerConsumerApplication {
public static void main(String[] args)  {
SpringApplication.run(EurekaServerConsumerApplication.class, args);
}
}
然后关键的⼀点来了! 在我们之前搭建的项⽬中,消费者通过RestTempete的具体url去访问提供者,⽽对于真正的微服务来说,这是不合规范的,⽽实现负载均衡也不能这样写,应该是通过微服务应⽤名称去访问提供者。
⾸先在RestTemplate上加上@LoadBanlanced注解,加上这个注解后RestTemplate才能识别出微服务应⽤名称去访问提供者,否则不能访问。
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
通过微服务应⽤名称访问,微服务应⽤名称/url,这⾥我设置的微服务名称为EUREKA-SERVER-PROVIDER
@RequestMapping("/consumer/test3")
public String test3(){
ForObject("EUREKA-SERVER-PROVIDER/provider/test",String.class);
}
这样Eureka与Ribbon整合实现通过微服务应⽤名称去访问提供者就成功了。
上⾯只是实现了通过微服务应⽤名称去访问提供者,但是并没有实现负载均衡,因为负载均衡就要基于通过微服务应⽤名称去访问提供者实现的,所以我们上⼀步的搭建是为了实现负载均衡打得铺垫。下⾯我们来实现负载均衡。
我们创建并启动三个服务提供者,分别为8001,8002和8003,并且设置它们的微服务应⽤名称且⼀致。
8001配置⽂件,8002和8003的配置⽂件都与8001的类似,只是设置的端⼝号不同:
server:
port: 8001
eureka:
client:
service-url:
defaultZone: eureka7001:7001/eureka/,eureka7002:7002/eureka/,eureka7
003:7003/eureka/  #Eureka Server url
instance-id: eureka-server-provider-test #修改主机名称
prefer-ip-address: true  #设置主机ip映射
spring:
application:
name: eureka-server-provider #该微服务应⽤名称
然后我们回过头来看看消费者的配置⽂件,我们上⾯在消费者的l中设置了
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: localhost:7001/eureka/,localhost:7002/eureka/,localhost:7003/eureka/
这个设置⾮常重要,我们可以尝试⼀旦不设置,⽤户通过消费者访问就会发⽣下⾯的错误:
我们可以看到有这么⼀句No instances available for EUREKA-SERVER-PROVIDER,意思就是不到名称为EUREKA-SERVER-PROVIDER的微服务,那么我们去注册中⼼中看看这个微服务到底存不存在
可以发现,这个微服务是存在的,那么可以证明消费者在访问前是要通过查询注册中⼼中提供者的信息,⽐如微服务应⽤名称,ip地址,端⼝号等等这些信息, 然后通过获取到的微服务应⽤名称才能去访问到提供者,⽽怎样去注册中⼼中获取到这些信息的就是要配置上⾯的与注册中⼼的连接了。
⾔归正传,在8001,8002和8003服务提供者中加⼊下⾯的RequestMapping进⾏测试。
8001:
@RequestMapping("/provider/test")
public String test(){
return "这是provider01";
}
8002:
@RequestMapping("/provider/test")
public String test(){
return "这是provider02";
}
8003:
@RequestMapping("/provider/test")
public String test(){
return "这是provider03";
}
然后我们把Eureka集701,7002和7003,服务提供者8001,8002和8003,以及服务消费者80启动,通过消费者访问
localhost/consumer/test
第⼀次访问:
第⼆次访问:
第三次访问:
然后下⾯每⼀次访问都是02,01,03(轮询算法,Ribbon默认),所以我们的负载均衡实现成功了。
总结:我们上⾯启动了7个微服务进程,其中3个Eureka注册中⼼组成⼀个集,3个服务提供者(微
服务应⽤名称都想同的是⼀组服务提供者),⼀个服务消费者,服务消费者启动后会连接Eureka注册中⼼获取到注册成功的服务提供者的微服务应⽤名称(还有其他信息),然后保存到本地,下次⽤户通过消费者去访问提供者的时候,根据之前保存的多个提供者的信息(微服务应⽤名称)去访问提供者,根据@LoadBanlanced注解实现负载均衡的⽬的,⽽如果提供者宕机后,注册中⼼会通知到消费者及时更新之前保存的提供者的信息,这样,服务消费者,注册中⼼,服务提供者就能协同起来⼀起⼯作了。
下⾯上⼀张图说明上⾯的总结:
更换Ribbon默认的负载均衡策略
在Ribbon中默认的负载均衡策略是通过轮询的⽅式进⾏的,⽽轮询算法策略是通过实现的IRule接⼝
在Ribbon中还有其他Ribbon已经帮我们实现的算法策略,分别是:
RoundRobinRule 轮询
RandomRule 随机
AvailabilityFilteringRule 会先过滤掉由于多次访问故障⽽处于断路器跳闸状态的服务,还有并发的连接数超过阈值的服务,然后对剩余的服务列表进⾏轮询
WeightedResponseTimeRule 权重 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越⼤被选中的概率越⾼。刚启动时,如果统计信息不⾜,则使⽤轮询策略,等信息⾜够,切换到 WeightedResponseTimeRule
RetryRule 重试 先按照轮询策略获取服务,如果获取失败则在指定时间内重试,获取可⽤服务
BestAvailableRule 选过滤掉多次访问故障⽽处于断路器跳闸状态的服务,然后选择⼀个并发量最⼩的服务
ZoneAvoidanceRule 符合判断server所在区域的性能和server的可⽤性选择服务
所以如果我们想要更换算法策略,就要告诉Ribbon我们需要的策略。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。