负载均衡

概念:

简单来说,就是把服务分散在不同的服务器上,让根据负载均衡算法实现服务器的选择;

spring cloud ribbon

依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>

一个是spring-cloud-starter-ribbon,一个是spring-cloud-starter-eureka

使用服务的名字去访问服务,而不是通过http的地址来访问;

1.首先使用的微服务的话,就需要使用RestTemplate,我们只要在注入的时候添加 @LoadBalanced就可以实现负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.saxon.springcloud.configuration;

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 config {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate () {
return new RestTemplate ();
}
}

2.配置文件application.yaml

1
2
3
4
5
6
7
8
server:
port: 80

eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost7002.com:7002/eureka/,http://localhost7003.com:7003/eureka/,http://localhost7003.com:7003/eureka/

defaultZone里面的就是服务的位置;

3.服务消费端,地址改为使用服务名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.saxon.springcloud.controller;

import com.saxon.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
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
public class ConsumerDept {
@Autowired
RestTemplate restTemplate;

public static final String REQUEST_URL="http://SAXON";

@GetMapping("/consumer/dept/get/{id}")
public Dept queryDeptById(@PathVariable("id") long id){
return restTemplate.getForObject (REQUEST_URL+"/get/ "+id,Dept.class,Long.class);
}
}

整合以后,不用担心访问的地址和端口号,使用服务名称直接访问,Rabbon会自动去这个服务下面找到相应的服务;

使用ribbon实现负载均衡

第一步、三个服务

创建三个数据库,库的什么都一样,就是最后的db_scource代表的是数据库的名字,我们可以从结果看出来他是哪一个数据库查询出来的;

第二步、分别修改端口号为8001,8002,8003

但是需要注意的是,我们虽然端口号不一样,但是我们application.name是一样的,应为是同一个服务,有robbin自己的算法决定使用那个作为自己的实际使用的服务;

第三步、启动所有的服务

我启动了7个服务,可以使用出现下面的几种结果;

image-20201025154043186

image-20201025154057594

image-20201025154110061

服务后的注册中心

image-20201025154214945

ribbon负载均衡算法:

(1)RoundRobinRule:轮询;

(2)RandomRule:随机;

(3)AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;

(4)WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快的服务权重越大被选中的概率越大。刚启动时如果统计信息不足,则使用RoundRobinRule(轮询)策略,等统计信息足够,会切换到WeightedResponseTimeRule;

(5)RetryRule:先按照RoundRobinRule(轮询)策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用的服务;

(6)BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;

(7)ZoneAvoidanceRule:复合判断Server所在区域的性能和Server的可用性选择服务器;

当然也可以直接自己写一个负载均衡算法,这里就不赘述了