当前位置:   article > 正文

微服务间调用

微服务间调用

一、restTemplate

1、先将restTemplate注册成为一个bean

@Configuration
public class RemoteCallConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2、实现代码

private void handleCartItems(List<CartVO> vos) {
    // TODO 1.获取商品id
    Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
    // 2.查询商品
    // List<ItemDTO> items = itemService.queryItemByIds(itemIds);
    // 2.1.利用RestTemplate发起http请求,得到http的响应
    ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
            "http://localhost:8081/items?ids={ids}",
            HttpMethod.GET,
            null,
            new ParameterizedTypeReference<List<ItemDTO>>() {
            },
            Map.of("ids", CollUtil.join(itemIds, ","))
    ); 
    // 2.2.解析响应
    if(!response.getStatusCode().is2xxSuccessful()){
        // 查询失败,直接结束
        return;
    }
    List<ItemDTO> items = response.getBody();
    if (CollUtils.isEmpty(items)) {
        return;
    }
    // 3.转为 id 到 item的map
    Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));
    // 4.写入vo
    for (CartVO v : vos) {
        ItemDTO item = itemMap.get(v.getItemId());
        if (item == null) {
            continue;
        }
        v.setNewPrice(item.getPrice());
        v.setStatus(item.getStatus());
        v.setStock(item.getStock());
    }
}

二、openFeign

1、 引入依赖

  <!--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>

2、启用OpenFeign

SpringBoot启动类,加上注解@EnableFeignClients

3、编写openFeign客户端

//item-service微服务名称
@FeignClient("item-service")
public interface ItemClient {
	//yml中的,nacos配置的ip和端口(nacos,可以看我这个专栏),会自动拼上路径
	//ip+端口/items/ids= x,x , x,
    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

这里只需要声明接口,无需实现方法。接口中的几个关键信息:

  • @FeignClient(“item-service”) :声明服务名称
  • @GetMapping :声明请求方式
  • @GetMapping(“/items”) :声明请求路径
  • @RequestParam(“ids”) Collection ids :声明请求参数
  • List :返回值类型

有了上述信息,OpenFeign就可以利用动态代理帮我们实现这个方法,发送一个GET请求,携带ids为请求参数,并自动将返回值处理为List。
我们只需要直接调用这个方法,即可实现远程调用了。

4、使用接口

1、注入ItemClient
2、调用ItemClient 中的方法,接收返回值

5、连接池

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:

  • HttpURLConnection:默认实现,不支持连接池
  • Apache HttpClient :支持连接池
  • OKHttp:支持连接池
    因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http.

引入依赖

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

开启连接池

feign:
  okhttp:
    enabled: true # 开启OKHttp功能

6、openFeign最佳实践

思路分析

  • 思路1:抽取到微服务之外的公共module
  • 思路2:每个微服务自己抽取一个module


方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。
方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。

正常小型微服务项目可以选择,耦合度偏高的maven聚合工程

新建一个微服务module

新建之后,引入openFeign需要的坐标,以及负载均衡坐标,服务建立完毕后;
服务建立完毕后,在消费者的微服务模块,引入maven坐标,即可调用里面的方法;

消费者启动类扫描对应包

1、@EnableFeignClients(basePackages=“消费者调用生产者对应的报名”)
2、@EnableFeignClients(clients={生产者的字节码文件(也就是[a.class])})
例子:@EnableFeignClients(clients={A.class})

7、日志输出

OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:

  • NONE:不记录任何日志信息,这是默认值。
  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
    Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
logging:
	level:
		监控日志包名:debug

通用的module中定义日志级别

public class DefaultFeignConfig {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.FULL;
    }
}

消费者启动类加注解

平时不建议开启,在出现错误时候,可以开启排查错误

@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

三、httpClient

可以看我之前苍穹外卖的博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/1022243?site
推荐阅读
相关标签
  

闽ICP备14008679号