Ribbon负载均衡
(一)前言
在之前的文章中我们介绍了Eureka服务发现,服务注册中心,用于管理多个服务的多个实例;
那么如何访问同一个服务的不同实例,来实现负载均衡呢?
Spring Cloud Ribbon是一个基于HTTP 和 TCP 的客户端负载均衡工具,它基于Netflix Ribbon实现,
通过Spring Cloud 的封装,可以轻松的面向服务的REST模板请求自动转换成客户端负载均衡的服务调用;
Spring Cloud Ribbon并不像服务注册中心、配置中心一样需要独立的部署服务,它是一个工具类框架,
几乎存在于每一个SpringCloud构建的服务和基础设施中.因为服务间的调用,API网关请求的转发等都是通过Ribbon来
实现的;
负载在系统架构中是非常重要的内容,负载均衡是系统的高可用,网络压力的环节和处理能力扩容重要手段之一;
我们所说的负载均衡指的都是服务端的负载均衡,其中分为硬件负载均衡和软件负载均衡;硬件负载均衡主要通过在服务器
节点安装用于负载均衡的设备,如F5;软件负载均衡指在服务器安装具有负载均衡的软件完成请求分发工作,如Nginx;
(二)Spring Cloud Ribbon使用
SpringCloud Ribbon 使用主要通过使用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用;
(三)项目搭建
在之前我们测试了服务注册中心的客户端,我们在新建一个ApplicationClientTwo的服务客户端,除端口号设置为9002外
其余的配置完全一样,这样我们就有了一个服务提供端有两个实例提供服务;
在两个服务客户端ApplicationClient分别添加对外访问接口用于测试负载均衡时调用:
@RestController
public class ApplicationRest {
@RequestMapping(value = "testResponse",method = RequestMethod.POST)
public String getResponse(String params){
//ApplicationTwo的返回职位From Client ApplicationTwo用于区分到底是哪个服务返回的结果;
return params + "From Client ApplicationOne";
}
}
我们在新建一个module,名字成为RibbonServer,注意Ribbon并不是一个服务,它是服务调用方里面的一个调用工具而已;
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>CloudServer</artifactId>
<groupId>com.river</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Ribbon-Server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--断路器依赖,之后会用到,当前可不用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
</project>
application.yaml
eureka:
client:
register-with-eureka: true
service-url:
defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/
instance:
prefer-ip-address: true
spring:
application:
name: ribbon-server
server:
port: 9201
启动类:
package com.river.ribbon.server;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringCloudApplication
public class RibbonServer {
@Bean
@LoadBalanced //restTemplate模板bean,用于调用外部服务
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String\[\] args) {
SpringApplication.run(RibbonServer.class, args);
}
}
service类,调用外部服务的出口类:
@Service
public class ServiceIm {
@Resource
private RestTemplate restTemplate;
public String get(String params) {
//这里通过服务名调用对应的服务,restTemplate有很多方法可以使用,这里不详细介绍,自己点出来看看,用法一目了然;
//服务名后面的testResponse为调用服务端的接口地址,params为入参,String.class为接口返回值类型;
return this.restTemplate.postForObject("http://applicationClient/testResponse", params, String.class);
}
}
对外接口类:
@RestController
public class MovieController {
@Resource
private ServiceIm serviceIm;
@RequestMapping(value = "getResp")
public String get(String params) {
return serviceIm.get(params);
}
}
这时我们启动服务,访问接口http://localhost:9201/getResp,会得到返回值,每次访问返回结果都不一样,可以明显看出是哪个服务返回的; 通过多次调用我们可以看得出负载均衡采用的是轮训策略;
(四)说明
查看IRule接口的实现类,我们可以看到很多的负载策略,我们也可以自定义策略; 如: https://my.oschina.net/u/3220575/blog/1863632 是一个直连的策略实现类作为例子,仅供参考!