【SpringCloud】springcloud中RestTemplate三种使用方式(LoadBalancerClient、负载均衡、Nacos、Ribbon )


相关文章:
Nacos Spring Cloud 快速开始 nacos入门例子,里面用到了RestTemplate
springcloud中RestTemplate三种使用方式(LoadBalancerClient、负载均衡、Nacos、Ribbon ) 介绍RestTemplate的常见用法
RestTemplate与Ribbon结合原理(基于spring-cloud-starter-alibaba-nacos-discovery)

1. 名词解释

1.1 什么是RestTemplate

RestTemplate作用是发送http请求的客户端,功能类似httpclient,是spring原生的框架,用于2个服务之间的请求发送。

与其功能相似的是Spring Cloud Netflix桶的Feign技术。

package org.springframework.web.client;
  public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
  
 }

RestTemplate位于spring的web包,是spring web的基本模块。因此,一般通过spring-boot-starter-web来引入。

1.2 Nacos

Nacos是Spring Cloud Alibaba下的服务注册和发现框架,与之类似的技术是Spring Cloud Netflix桶的Eureka。

当然真正连接的时候,需要Nacos-client.jar、Eureka-client.jar之类的包,这样才能与注册中心进行交互。

1.3 负载均衡

负载均衡是一个策略,是一个规则,作用是提供压力解决方案,具体的实现技术包括 Ribbon(Spring Cloud Netflix桶)

Spring Cloud Alibaba桶下没有负载均衡器。

在SpringCloud的客户端负载均衡器LoadBalancerClient的默认实现RibbonLoadBalancerClient中,使用了Ribbon的ILoadBalancer接口来实现chooseServer即负载均衡功能。

2. 用法一 直接访问ip+port

特点是url参数是ip+port,直接明了:

package com.alibaba.nacos.example.spring.cloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author xiaojing
 */
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    EnableDiscoveryClient
    public static void main(String[] args) {
        SpringApplication.run(NacosConsumerApplication.class, args);
    }

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
           
         return restTemplate.getForObject("http://127.0.0.1:8070/echo/" + str, String.class);

        }
    }
}


这样存在什么问题呢?
就是当服务的ip或端口发生变化后,就不能访问了,需要重新编译重新部署。

3. 用法二和用法三 使用注册中心+负载均衡

细分为手工负载均衡和自动负载均衡

由于用法一存在缺陷,因此,比较好的解决发现就是利用注册中心,从注册中心查找可以用的服务,一般注册中心会和负载均衡策略搭配使用,因为同一个服务,可以有多个实例,都可以提供服务,那么选哪个实例呢,那么就由负载均衡策略提供具体方案。

3.1 手工的负载均衡

特点是手动处理替换port和ip,至少可以解决服务port和ip变化后仍然正常使用。

当然,前提是服务的名称不能发生变化。

我们先介绍个入门的负载均衡用法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

 @RestController
 public class TestController {
	@Autowired
	LoadBalancerClient loadBalancerClient;
    @Bean
	 public RestTemplate restTemplate() {
	     return new RestTemplate();
	 }
	 
	@GetMapping("getServerMsg")
	public String getServerMsg() {
		//第二种方式(使用LoadBalancerClient,先通过应用名称得到应用url,再使用RestTemplate):
		RestTemplate restTemplate = new RestTemplate();
		//CLIENT是服务的名称
		ServiceInstance serviceInstance = loadBalancerClient.choose("CLIENT");
		String url = String.format("http://%s:%s",serviceInstance.getHost(), serviceInstance.getPort()) + "/getMsg";
		System.out.println("url=="+url);
		String result = restTemplate.getForObject(url, String.class);

		return result;
    }
}

LoadBalancerClient是一个接口,全路径是“org.springframework.cloud.client.loadbalancer.LoadBalancerClient”,从包路径来看,是spring boot基础包的,也就是说需要有具体的实现类,实现类可以是spring boot的组件来提供,例如nacos方案:

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

然后通过@Autowired注入LoadBalancerClient的实现类。

再通过loadBalancerClient.choose(“CLIENT”),找到对应的服务,进而获取ip和port.

这样是不是有点low?没错,有更好的办法,帮助我们自动映射ip和port

当然,LoadBalancerClient需要配置,例如通过配置,往LoadBalancerClient内注入可以服务。这样,才能通过loadBalancerClient.choose(“CLIENT”)取出可用服务。

当然,也可以采用其他的方案,例如Eurka,这样注入的实现类就是EurekaDiscoveryClient:

在这里插入图片描述

3.2 @LoadBalanced自动完成

特点是自动从注册中心查找可用服务,并进行替换。

引入nacos-discovery作为注册中心:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.3.RELEASE</version>
</dependency>
package com.alibaba.nacos.example.spring.cloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author xiaojing
 */
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    EnableDiscoveryClient
    public static void main(String[] args) {
        SpringApplication.run(NacosConsumerApplication.class, args);
    }

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
         

        }
    }
}


service-provider会被自动解析替换为 127.0.0.1:8070.

3.2.1 @LoadBalanced原理

引入nacos-discovery注册中心后,其后台会自动提供RibbonLoadBalancerClient作为LoadBalancerClient接口的实现类。

原理和手动引入负载均衡相似,只不过把手动替换操作改为自动替换

此外,引入nacos作为注册中心后,自然需要有nacos的配置:

以客户端为例:

server.port=8080
spring.application.name=service-consumer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

这样就会从127.0.0.1:8848查询可以用的服务,作为LoadBalancerClient的源。

参考

SpringCloud学习笔记(三)–springcloud中RestTemplate三种使用方式
Spring Cloud 进阶之路 – 使用 RestTemplate 的三种方式及源码查看Ribbon负载均衡配置策略
使用DiscoverClien和、LoadBalancerClient配合RestTemplate完成微服务调用的步骤参考EurekaDiscoveryClient

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值