irpas技术客

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

大大的周 5314

文章目录 1. 名词解释1.1 什么是RestTemplate1.2 Nacos1.3 负载均衡 2. 用法一 直接访问ip+port3. 用法二和用法三 使用注册中心+负载均衡3.1 手工的负载均衡3.2 @LoadBalanced自动完成3.2.1 @LoadBalanced原理 参考 相关文章: 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.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Cloud #进阶之路 #使用 #resttemplate