当前位置: 首页 > news >正文

微服务远程调用(nacos及OpenFeign简单使用)

问题:在微服务中,每个项目是隔离开的,当有一个项目请求其他项目中的数据时,必须发起网络请求,本文即对此问题展开讨论。

1.使用restTemplate发送请求

        //发送请求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, ",")));//解析响应体,判断是否成功发送if (!response.getStatusCode().is2xxSuccessful()){return;}List<ItemDTO> items = response.getBody();

在程序中注入类时,可以不用@Autowired注解,直接定义变量(必须用final修饰),在类上加上@RequiredArgsConstructor注解即可实现自动装配。

2.使用nacos实现远程调用

问题:restTemplate中代码中的路径是写死的,若一个服务有多个实例只能访问到一个,无法做到负载均衡。

1.注册中心原理

2.nacos注册中心

将nacos部署到docker中。

3.服务注册

服务在启动时将自己的信息提交到nacos,此为服务注册。

1.添加依赖

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2.在配置文件中中添加nacos地址配置:

spring:application:name: item-service # 服务名称cloud:nacos:server-addr: 192.168.145.129:8848 # nacos地址

操作完后就已经完成了服务的注册。

ps:当我们要启动一个项目的多个实例,需要在idea中按alt+8出现如下界面,点击复制配置:

如此配置,即可将同一项目的多个实例配置在不同的端口中,此配置优先级大于项目中的yaml配置文件。

4.服务发现

服务发现为服务的调用者去拉取别的服务的列表。

1.添加依赖

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2.在配置文件中中添加nacos地址配置:

spring:application:name: item-service # 服务名称cloud:nacos:server-addr: 192.168.145.129:8848 # nacos地址

3.配置好后即可去调用别的服务

若一个服务有好几个实例,那么可以使用负载均衡的算法,从多个实例中挑选一个去访问。

常见的负载均衡算法有:

  • 随机

  • 轮询

  • IP的hash

  • 最近最少访问

首先注入DiscoveryClient

private final DiscoveryClient discoveryClient;

调用nacos发起请求

         //利用nacos发送请求访问,获取实例        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");//使用随机的算法从实例中挑选一个实例    ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));// 2.查询商品List<ItemDTO> items = itemService.queryItemByIds(itemIds);//发送请求ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(instance.getUri()+"/items?ids={ids}",HttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ",")));//解析响应体if (!response.getStatusCode().is2xxSuccessful()){return;}List<ItemDTO> items = response.getBody();

3.OpenFeign

问题:使用nacos和restTemplate发送请求操作仍然过于繁琐,因此需要使用openfeign。

OpenFeign是一个声明式的http客户端,是SpringCloudEureka公司开源的Feign基础上改造而来。官方地址:GitHub - OpenFeign/feign: Feign makes writing java http clients easier

其作用就是基于SpringMVC的常见注解,帮我们优雅的实现http请求的发送。

1.基本使用

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.在启动类上加上注解@EnableFeignClients

ps:当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。

定义的FeignClient在另一个项目中,即使在项目中引入了pom文件,有这个类型,但是没有这个bean,因为在项目中spring扫描的包是本项目的文件,因此就接收不到这个bean。

有两种方式解决:

方式一:指定FeignClient所在包

@EnableFeignClients(basePackages = "com.hmall.api.clients")

方式二:指定FeignClient字节码

@EnableFeignClients(clients = {UserClient.class})

3.定义接口,编写代码

@FeignClient("item-service")
public interface ItemClient {@GetMapping("/items")List<ItemDTO> queryItemByids(@RequestParam("ids") Collection<Long> ids);
}
  • @FeignClient("item-service") :声明服务名称

  • @GetMapping :声明请求方式

  • @GetMapping("/items") :声明请求路径

  • @RequestParam("ids") Collection<Long> ids :声明请求参数

  • List<ItemDTO> :返回值类型

4.当项目需要发起请求时,即可导入ItemClient类调用方法实现。

2.连接池

问题:openfeign使用的HttpURLConnection效率太低。

OpenFeign底层发起http请求,依赖于其它的框架。这些框架可以自己选择,包括以下三种:        

        HttpURLConnection:默认实现,不支持连接池

        Apache HttpClient :支持连接池

        OKHttp:支持连接池

此处使用okhttp替换默认的。

1.引入依赖:

<!--ok-http-->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>

2.开启连接池功能

feign:okhttp:enabled: true # 开启OKHttp连接池支持

3.日志

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

        NONE:不记录任何日志信息,这是默认值。

        BASIC:仅记录请求的方法,URL以及响应状态码和执行时间

        HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息

        FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

由于Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。

1.要自定义日志级别需要声明一个类型为Logger.LevelBean,在其中定义日志级别:

public class defaultfeignconfig {@Beanpublic Logger.Level feignconfig(){return Logger.Level.FULL;}
}

2.1 局部配置

但此时这个Bean并未生效,要想配置某个FeignClient的日志,可以在@FeignClient注解中声明:

@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class) 

2.2 全局配置

如果想要全局配置,让所有FeignClient都按照这个日志配置,则需要在@EnableFeignClients注解中声明:

@EnableFeignClients(defaultConfiguration = myDefaultFeignConfig.class) 
http://www.lryc.cn/news/447565.html

相关文章:

  • Protobuf vs Thrift: 高性能序列化框架的对比与分析
  • LeetCode Hot100 C++ 哈希 1.两数之和
  • Windows下安装Neo4j流程
  • Spring IDEA 2024 自动生成get和set以及toString方法
  • 部署my2sql
  • Android Studio 真机USB调试运行频繁掉线问题
  • 如何通过费曼技巧理解复杂主题
  • Golang优雅关闭gRPC实践
  • Maven笔记(一):基础使用【记录】
  • [vulnhub] Jarbas-Jenkins
  • js设计模式(26)
  • 数据库中, drop、delete与truncate的区别?
  • 2024年项目经理不能错过的开源项目管理系统大盘点:全面指南
  • MATLAB基本语句
  • 委托的注册及注销+观察者模式
  • Jetpack02-LiveData 数据驱动UI更新(类似EventBus)
  • Redis 的 Java 客户端有哪些?官方推荐哪个?
  • 工作笔记20240927——vscode + jlink调试
  • Python | Leetcode Python题解之第433题最小基因变化
  • opengauss使用遇到的问题,随时更新
  • 从环境部署到开发实战:消息队列 RocketMQ
  • 【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版
  • 渗透测试-文件上传绕过思路
  • 等保测评中的密码学应用分析
  • LCR 007. 三数之和
  • 【入门01】arcgis api 4.x 创建地图、添加图层、添加指北针、比例尺、图例、卷帘、图层控制、家控件(附完整源码)
  • STL迭代器标签
  • 容器学习之SparseArray源码解析
  • 信创改造技术介绍
  • 【可见的点——欧拉函数】