文章目录
相关文章:
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