1、ribbon负载均衡
在gateway工程添加ribbon相关依赖:
1、添加依赖
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.1.0.RELEASE</version>
</dependency></pre>
2、修改配置文件,增加或者修改见红色部分
server:
port: 8080
spring:
application:
name: gateway_server
cloud:
gateway:
default-filters:
routes:
- id: my_route
uri: lb://my-load-balanced-service
predicates:
- Path=/gateway/**
filters:
- StripPrefix=1
my-load-balanced-service:
ribbon:
listOfServers: localhost:1001, localhost:1002
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule**</pre>
3、重启gateway服务,不断访问 http://localhost:8080/gateway/hello,发现可以不断访问的时候在两个服务中来回切换,达到衡的目的。上面我们使用了轮询的负载均衡策略。
注意:
- listOfServers:配置的微服务的服务器ip端口
- NFLoadBalancerRuleClassName:使用的负载均衡策略,默认提供了几种,也可以自己实现(后续讲解),默认提供的如下:
疑问:
如果上面listOfServers中的任何一个服务关闭了,然后使用gateway访问,会出现什么情况?
事实是这样的:
比如provider1003服务宕机。那么使用轮询算法的时候,不断访问gateway,会出现:
provider1001 正常,provider1002 异常
provider1002已经宕机,但是请求还是不断转发到该服务上,导致服务访问的过程中,部分请求异常。
我们需要有这样的功能,如果某个服务宕机,那么请求就不会发送到该服务器上,如果宕机的服务器恢复了,那么请求又可以发送到该服务器上,要实现这个功能,需要ribbon对服务进行健康检查。
(1)首先微服务需要有个rest接口,就叫做heath接口吧,调用heath接口返回ok表明服务正常。
(2)gateway需要有调用heath接口的功能,并且配置到ribbon可以不断调用该接口,时刻检查服务的状态,如果有服务器挂掉,可以很快感知到,并把该服务剔除可用服务列表。
2、健康检查
1、provider1001,provider1002增加一个rest接口HealthController
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController;
@RestController
public class HealthController
{
@GetMapping("/heath")
@ResponseBody public String heath()
{ return "ok";
}
}
2、在gateway工程里面做如下修改
(1)新建一个Config类
package com.yefengyu.gateway.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration
public class MainConfig
{
@Bean public RestTemplate restTemplate()
{ return new RestTemplate();
}
}
(2)新建一个健康检查的类,主要是调用heath接口。
package com.yefengyu.gateway.loadbanlance; import com.netflix.loadbalancer.IPing; import com.netflix.loadbalancer.Server; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate;
@Component
public class HealthExamination implements IPing
{
@Autowired private RestTemplate restTemplate;
@Override public boolean isAlive(Server server)
{
String url = "http://" + server.getId() + "/heath"; try {
ResponseEntity<String> heath = restTemplate.getForEntity(url, String.class); if (heath.getStatusCode() == HttpStatus.OK)
{
System.out.println("ping " + url + " success and response is " + heath.getBody()); return true;
}
System.out.println("ping " + url + " error and response is " + heath.getBody()); return false;
} catch (Exception e)
{
System.out.println("ping " + url + " failed"); return false;
}
}
}
上面代码继承IPing接口,判断服务是否可用。我们在微服务中增加heath接口,在gateway中调用该接口,如果返回正常则认为微服务可用。
(3)修改配置文件,注意最后一行,这是唯一增加的。
server:
port: 8080 spring:
application:
name: gateway_server
cloud:
gateway: default-filters:
routes: - id: my_route
uri: lb://my-load-balanced-service predicates: - Path=/gateway/** filters:
- StripPrefix=1
my-load-balanced-service:
ribbon:
listOfServers: localhost:1001,localhost:1002,localhost:1003
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule NFLoadBalancerPingClassName: com.yefengyu.gateway.loadbanlance.HealthExamination
3、重新启动微服务和gateway服务,然后通过网关访问,可以看到可以正常访问,如果此时把某一台微服务停掉,访问的时候开始可能会报错,但是随着健康检查的运行,检测到该服务不可用,则会把该服务剔除,以后只会访问正常运行的服务。当宕机的服务重启,健康检查还会把该服务加入到可用服务列表,下次请求就会再次发送到该服务上。
网友评论