远程调用
RestTemplate
Spring提供了RestTemplate工具,可以方便的实现HTTP请求的发送。
-
注入
RestTemplate到Spring容器
-
通过构造函数注入到
Service层@RequiredArgsConstructor:创建包含必须初始化(final)的属性的构造函数
-
发起远程调用
public <T> ResponseEntity</T> exchange(
String url, // 请求路径
HttpMethod method, // 请求方式
@Nullable HttpEntity<?> requestEntity, // 请求实体,可以为空
Class<T> responseType, // 返回值类型
Map<String, ?> uriVariables // 请求参数,jdk11的写法
)// jdk8的Map写法
String joinedIds = CollUtil.join(itemIds, ",");
// 创建一个临时的可变 Map
Map<String, String> tempMap = new HashMap<>();
tempMap.put("ids", joinedIds);
// 创建一个不可变的 Map
Map<String, String> map = Collections.unmodifiableMap(tempMap);
(OpenFeign)[https://github.com/OpenFeign/feign]
是一个声明式的http客观端,是SpringCloud在Eureka公司开源的Feign基础上改造而来。
基于SpringMVC的常见注解,实现http请 求的发送
-
引入依赖
<!--openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency> -
启动
OpenFeign使用
@EnableFeignClients注解@EnableFeignClients
@SpringBootApplication
public class Application {……} -
在
/client目录下新建ItemClient接口,编写FeignClient@FeignClient(value = "服务名,如item-service")
public interface ItemClient {
@GetMapping("路由,如/items")
List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
} -
使用
FeignClient,实 现远程调用List<ItemDTO> items = itemClient.queryItemByIds(List.of(1,2,3));
优化-连接池
Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:
- HttpURLConnection:默认实现,不支持连接池
- Apache HttpClient :支持连接池
- OKHttp:支持连接池
-
引入依赖
<!--OK http 的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency> -
开启连接池功能
feign:
okhttp:
enabled: true # 开启OKHttp功能
最佳实践
方案一:适合项目结构为Maven聚合,用一个统一的api模块暴露其他微服务需要的dto、api、biz等信息,耦合度比方案一高
方案二:适合项目结构为每个模块是独立的Project,在各自的模块下管理自己的dto、api、biz等

方案一
-
创建
api模块及需要暴露的信息--api
--src
--main
--java
--com.hmall
--api
--client
--dto
…… -
注入需要的依赖
例子:
<dependencies>
<!--openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
</dependencies> -
让同父模块下的模块可以扫描到
<!--feign模块-->
<dependency>
<groupId>com.heima</groupId>
<artifactId>hm-api</artifactId>
<version>1.0.0</version>
</dependency>在启动类上加声明
-
@EnableFeignClients(basePackages = "com.hmall.api.client") -
@EnableFeignClients(clients = {ItemClient.class})
-
日志配置
OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。
logging:
level:
com.hmall: debug
而且其日志级别有4级:
NONE:不记录任何日志信息,这是默认值。BASIC:仅记录请求的方法,URL以及响应状态码和执行时间HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
-
在
api下新建配置类,定义Feign的日志级 别// package com.hmall.api.config;
// DefaultFeignConfig
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL;
}
} -
配置类使日志生效
-
局部生效:在某个
FeignClient中配置,只对当前FeignClient生效@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class) -
全局生效:在
@EnableFeignClients中配置,针对所有FeignClient生效。@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
-