Spring cloud Ribbon 客户端负载均衡

Ribbon几乎存在于每一个Spring cloud构建的微服务和基础设施中,因为微服务之间的调用,API网关的请求转发等内容实际上都是通过Ribbon来实现的,是一个客户端负载均衡的工具类框架。

通过Spring Cloud Ribbon的封装,在微服务架构中使用客户端负载均衡调用很简单,只需要两个步骤:

1、服务提供者只需要启动多个服务实例并注册到注册中心

2、服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用

在《Spring cloud Eureka服务治理 (1)》中使用了RestTemplate实现了最简单的服务访问,下面介绍一下RestTemplate针对几种不同请求类型和参数类型的服务调用实现;

GET请求

在 RestTemplate 中, 对 GET 请求可以通过如下两个方法进行调用实现。

(1)getForEntity

该方法返回的是 ResponseEntity, 该对象是 Spring 对 HTTP 请求响应的封装, 其中主要存储了 HTTP 的几个重要元素, 比如 HTTP 请求状态 码的枚举对象 HttpStatus (也就是我们常说的 404、 500 这些错误码)、 在它的父类 httpEntity 中还存储着 HTTP 请求的头信息对象 HttpHeaders 以及泛型类型的请求体 对象。 比如下面的例子, 就是访问 USER-SERVER 服务的/user 请求, 同时最后一个参数 didi 会替换 url 中的{ 1} 占位符, 而返回的 ResponseEntity 对象中的 body 内容类型 会根据第二个参数转换为 String 类型

Res七Template restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER­ SERVICE/user?name= {1}", String.class, "didi");
String body = responseEntity. getBody();

还有三种不同的重载方法:

getForEntity(String url, Class responseType, Object... urlVariables):

getForEntity(String url, Class responseType, Map urlVariables):  map中以键值对的方法存放参数

getForEntity(URI url, Class responseType)

(2)getForObject

getForObject (String url, Class responseType, Object... urlVariables):

getForObject(String url, Class responseType, Map urlVariables)

getForObject(URI url, Class responseType)

RestTemplale restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);

POST请求:

 RestTemplate restTemplate = new RestTemplate(); 
User user = new User("didi", 30); 
ResponseEntity<String> responseEntity =
restTemplate.postForEntity("http://USER-SERVICE/user", user, String.class);
String body = responseEntity.getBody();

postForEntity函数也实现了三种不同的重载方法:

postForEntity(String url, Object request, Class responseType, Object... uriVariables)

postForEntity(String url, Object request, Class responseType, Map uriVariables)

postForEntity(URI url, Object request, Class responseType)

postForObject 函数。 该方法也跟getForObject 的类型类似, 它的作 用是简化postForEntity的后续处理

RestTemplate restTemplate = new RestTemplate();
User user = new User("didi", 20);
String postResult = restTempla七e.postForObject("http://USER-SERVICE/user", user,
String.class);

postForObjec七函数也实现了三种 不同的重载方法:

• postForObject(String url, Object request, Class responseType, Object... uriVariables)

• postForObject(String url, Object request, Class responseType, Map uriVariables)

• postForObject(URI url, Object request, Class responseType)

User user = new User("didi", 40);
URI responseURI = restTemplate.postForLocation("http://USER-SERVICE/user", user);

postForLocation函数也实现了三种不同的重载方法:

postForLocation(Stringurl, Object request, Object...urlVariables)

postForLocation(String url, Object request, Map urlVariables)

postForLocation(URI url, Object request)

PUT请求:

RestTemplate restTemplate = new RestTemplate ();
Long id = 100011;
User user = new User("didi", 40); 
restTemplate.put("http://USER-SERVICE/user/{l}", user, id);

put函数也实现 了三种不同的重载方法:

• put(String url, Object request, Object... urlVariables)

• put(String url, Object request, Map urlVariables)

• put(URI url, Object request)

DELETE请求:

RestTemplate restTemplate = new RestTemplate();
Long id= 10001L; 
restTemplate.delete("http://USER-SERVICE/user/{1)", id);

delete函数也实现了三种不同的重载方法:

• delete(String url, Object ... urlVariables)

• delete(String url, Map urlVariables)

• delete(URI url)

Spring cloud Ribbon自动化配置:

IclientConfig:Ribbon的客户端配置

IRule:Ribbon的负载均衡策略

IPing:Ribbon的实例检查策略

ServiceList<Server>:服务实例清单的维护机制

ServerListFilter<Server>:服务实例清单过滤机制

ILoadBalancer:负载均衡器

自定义负载均衡策略

两种方式,

第一,代码方式:

新建一个类,加上@Configration注解,并且包含一个返回IRule的Bean:

@Configuration
public class RibbonRuleConfiguration {

    @Bean
    public IRule ruleStyle(){
        //        return new BestAvailableRule(); //选择一个最小的并发请求的server
//        return new WeightedResponseTimeRule(); //根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
//        return new RetryRule(); //对选定的负载均衡策略机上重试机制。
//        return new RoundRobinRule(); //roundRobin方式轮询选择server
//        return new RandomRule(); //随机选择一个server
//        return new ZoneAvoidanceRule(); //复合判断server所在区域的性能和server的可用性选择server
        return new RandomRule();
    }
}

上面是使用了随机策略,

然后再application上加注解@RibbonClients,表示对调用的所有服务使用这个策略。

@EnableDiscoveryClient
@SpringBootApplication
@RibbonClients(defaultConfiguration = RibbonRuleConfiguration.class)
public class RibbonApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }
}

如果想要指定单个服务的策略:

@RibbonClient(name="server-hi",configuration = RibbonRuleConfiguation.class)

上面就是只对server-hi使用了此策略。

但是使用上诉的方式,如果调用的服务太多,那么就会有很多configuration类,application中也很臃肿,所以还有一种配置文件方式:

helloservice-1.ribbon.NFLoadBalancerRuleClassNam=com.netflix.loadbalancer.RandomRule

helloservice-1 是服务名,等号后面就是负载均衡策略。

重试机制:

Eureka为了更高的服务可用性,牺牲了一定的一致性,在极端情况下,宁愿接受故障实例,也不要丢掉实例,当服务注册中心的网络发生故障断开时, 由于所有 的服务实例无法维持续约心跳, 在强调AP的服务治理中将会把所有服务实例都剔除掉, 而Eureka则会因为超过85%的实例丢失心跳而会触发保护机制,注册中心将会保留此时的 所有节点, 以实现服务间依然可以进行互相调用。

以之前的服务helloservice-1为例,可以在配置文件中增加以下内容:

helloservice-1.ribbon.ConnectTimeOut=250
#请求连接的超时时间
helloservice-1.ribbon.ReadTimeOut=1000
#请求处理的超时时间
helloservice-1.ribbon.OkToRetryOnAllOperations=true
#对所有服务都进行重试
helloservice-1.ribbon.MaxAutoRetriesNextServer=2
#切换实例重试的次数
helloservice-1.ribbon.MaxAutoRetries=1
#单个实例重试的次数

猜你喜欢

转载自blog.csdn.net/qiuhao9527/article/details/81097582
今日推荐