整合RestTemplate
对RestTemplate进行增强,支持负载均衡
package com.czxy.nacos.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class RestTemplateConfig { @LoadBalanced //负载均衡 @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
通过服务名
调用服务提供者
package com.czxy.nacos.controller; import com.czxy.nacos.feign.TestFeign; 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; import javax.annotation.Resource; @RestController public class TestController { @Resource private 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); } }
整合WebClient
WebClient和RestTemplate
- RestTemplate 是 spring 3.0 引入的,底层IO模型是阻塞IO模型 Http客户端。
- WebClient 是 spring 5.0 引入的,作为非阻塞式Reactive Http客户端,用于取代RestTemplate。
响应式IO模型
- SpringMVC或Struct等框架都是基于Servlet的,其底层IO模型是阻塞IO模型。
- Spring社区为了解决SpringMVC的阻塞模型在高并发场景下的性能瓶颈,推出了Spring WebFlux,WebFlux底层实现是久经考验的Netty非阻塞IO通信框架。
- 其实WebClient处理单个HTTP请求的响应时长并不比RestTemplate更快,但是它处理==并发==的能力更强。 所以响应式非阻塞IO模型的核心意义在于,提高了单位时间内有限资源下的服务请求的并发处理能力,而不是缩短了单个服务请求的响应时长。
- 总结:WebClient --> Spring WebFlux --> Netty
WebClient入门
添加 webflux 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
编写配置类
package com.czxy.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; @Component public class WebClientConfig { @Bean @LoadBalanced public WebClient.Builder webClientBuilder() { return WebClient.builder(); } }
编写测试类
package com.czxy.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import javax.annotation.Resource; @RestController @RequestMapping("/client") public class TestClientController { @Resource private WebClient.Builder webClientBuilder; @GetMapping("/echo/{str}") public Mono<String> echo(@PathVariable("str") String str) { return webClientBuilder.build() // 创建WebClient实例 .get() // 请求方式 .uri("http://service-provider/echo/{1}", str) // 请求url .retrieve() // 获取响应结果 .bodyToMono(String.class); // 将结果转换为指定类型 } }
测试
API详解
请求方式
方法 | 描述 | 等效 |
build().get() | get请求 | build().method(HttpMethod.GET) |
build().post() | post请求 | build().method(HttpMethod.POST) |
build().put() | put请求 | build().method(HttpMethod.PUT) |
build().delete() | delete请求 | build().method(HttpMethod.DELETE) |
响应类型
类型 | 描述 | 方法 |
Mono | 包含0个或1个元素 | bodyToMono(String.class) |
Flux | 包含1个或多个元素 | .bodyToFlux(String.class) |
整合Feign
概述
- RestTemplate和WebClient都是Spring自己封装的工具
- Feign 是 Spring Cloud 的成员
- Spring Cloud Alibaba 支持对Feign的调用
整合Feign
添加坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
编写feign
package com.czxy.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // @FeignClient(value = "服务名", path = "controller配置的路径" ) @FeignClient(value = "service-provider") public interface EchoFeign { // 与 nacos-provider-2.1>EchoController声明的方法的完全一致 @GetMapping("/echo/{string}") public String echo(@PathVariable String string); }
编写测试类
package com.czxy.controller; import com.czxy.feign.EchoFeign; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @RequestMapping("/feign") public class TestFeignController { @Resource private EchoFeign echoFeign; @GetMapping("/echo/{str}") public String echo(@PathVariable String str) { return echoFeign.echo(str); } }
修改启动类
package com.czxy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient //服务发现 @EnableFeignClients //远程调用 public class TestNacosConsumerApplication { public static void main(String[] args) { SpringApplication.run(TestNacosConsumerApplication.class, args ); } }