跨微服务请求优化——注册中心+OpenFeign(第二篇)

目录

前言

[一、纯 RestTemplate 方案存在的缺陷](#一、纯 RestTemplate 方案存在的缺陷)

二、注册中心模式介绍

三、注册中心技术:Nacos

[3.1 Docker部署Nacos](#3.1 Docker部署Nacos)

[3.2 服务注册](#3.2 服务注册)

[3.3 服务发现](#3.3 服务发现)

四、代码优化:OpenFeign工具

[4.1 OpenFeign快速入门](#4.1 OpenFeign快速入门)

[4.2 连接池的必要性](#4.2 连接池的必要性)

[4.3 抽取服务、最佳实践](#4.3 抽取服务、最佳实践)

[4.4 日志配置](#4.4 日志配置)

五、服务注册与调用巩固


前言

前面通过微服务基础入门,我们大致了解的微服务的拆分。并且发现了跨微服务的请求调用问题。当时我们使用RestTemplate进行请求发送。也发现了一个比较大的问题------请求的url需要开发者人为提供,这种硬编码的方式无论是在什么项目里都应该被避免。更何况如果一个微服务分布在好几台服务器上,我们又该如何做负载均衡呢?因此本篇主要针对跨微服务的优化问题提出解决方案的学习。

一、纯 RestTemplate 方案存在的缺陷

  • item-service这么多实例,cart-service如何知道每一个实例的地址

  • http请求要写url地址,cart-service服务到底该调用哪个实例呢

  • 如果在运行过程中,某一个item-service实例宕机,cart-service依然在调用该怎么办

  • 如果并发太高,item-service临时多部署了N台实例,cart-service如何知道新实例的地址

因此,对于新方案,必须要有以下几个优势:

  1. 只需关注有无实例有该功能调用?无需关注调用实例的地址

  2. 拥有负载均衡策略,可以在多实例间自动进行策略切换

  3. 自动监控实例健康状态,及时切断异常实例的连接

  4. 允许实例动态变化,何时注册何时即可投入使用。

二、注册中心模式介绍

所谓注册中心模式可以理解为 "中介模式",拿房屋中介来举例子吧:

房东【服务提供者 】只需要把自己的房屋信息**告诉(注册)**中介,不需要自己去找租客。

租客【服务消费者 】只需要到房屋中介处**寻找(调用)**自己需要的房屋,不需要满大街找房东。

而中介负责整合房屋资源**(注册服务列表)** ,同时在租客寻找的时候提供对应的房源**(提供调用)**

注意到我上面举例的用词了吧,在微服务中也是一样的。在微服务远程调用的过程中,包括两个角色:

  • 服务提供者 :提供接口供其它微服务访问,比如item-service

  • 服务消费者 :调用其它微服务提供的接口,比如cart-service

注册中心模式的整体流程如下:

  • 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

  • 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)

  • 调用者自己对实例列表负载均衡,挑选一个实例

  • 调用者向该实例发起远程调用

如何实现宕机实例、异常实例的检测?

  • 引入心跳检测机制【类似Redis的哨兵机制】
  • 所有注册到中心的实例,每隔一段时间必须向中心发送信号,证实自己是健康状态
  • 当注册中心长时间收不到提供者的心跳时,会认为该实例宕机,将其从服务的实例列表中剔除

如何实现宕机通知、新添实例通知?

  • 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表

  • 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表。

如何实现负载均衡策略?

  • 成功获取到实例列表后,调用者可以根据一定的策略(随机、轮询等)挑选任意一个实例发送请求

三、注册中心技术:Nacos

目前开源的注册中心框架有很多,国内比较常见的有:

  • Eureka:Netflix公司出品,目前被集成在SpringCloud当中,一般用于Java应用

  • Nacos:Alibaba公司出品,目前被集成在SpringCloudAlibaba中,一般用于Java应用

  • Consul:HashiCorp公司出品,目前集成在SpringCloud中,不限制微服务语言

其中Nacos上手快、配置简单、并且有详细的中文文档提供学习。因此本次实验采取Nacos进行。

Nacos 快速开始https://nacos.io/zh-cn/docs/quick-start.html

3.1 Docker部署Nacos

部署步骤

  • 导入nacos数据库文件
  • 修改nacos配置文件,并上传到服务器
  • 执行容器创建命令
  • 确保启动顺序:必须先启动数据库,再启动nacos
  • 测试访问http://192.168.186.140:8848/nacos/ 账号密码均为 nacos

首先Nacos需要管理服务列表,必然是依赖数据库的。本次实验采取先前Docker布置好的MySQL。

第一步: 导入nacos数据库文件

第二步:修改nacos配置文件,并上传到服务器

第三步: 执行容器创建命令

8848 是用于客户端与服务通信的主要端口。

9848 是 gRPC 端口,用于与 Nacos 的 gRPC 通信(如果需要)。

9849 是 Raft 端口,用于 Nacos 集群中节点之间的通信(如果运行集群模式)。

bash 复制代码
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

第四步:确保启动顺序:必须先启动数据库,再启动nacos

第五步:测试访问http://192.168.186.140:8848/nacos/ 账号密码均为 nacos

3.2 服务注册

  • 导入坐标依赖
  • 配置nacos的访问地址和服务名称
  • 使用nacos

3.2.1 导入坐标依赖

在需要注册服务的模块中,导入nacos的坐标

3.2.2 配置nacos的访问地址和服务名称

3.2.3 使用nacos

将服务注册到nacos,我们拿item-service为例,启动多个实例,模拟多服务器部署:

启动后查看nacos网站--服务列表

测试服务宕机后,nacos服务列表是否会更新:

3.3 服务发现

  • 导入坐标依赖
  • 配置nacos的访问地址和服务名称
  • 发现并调用服务

3.3.1 导入坐标依赖

我们在cart-service中的pom.xml中添加nacos的依赖:

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

可以发现,这里Nacos的依赖于服务注册时一致,这个依赖中同时包含了服务注册和发现的功能。因为任何一个微服务都可以调用别人,也可以被别人调用,即可以是调用者,也可以是提供者。

因此,等一会儿cart-service启动,同样会注册到Nacos

3.3.2 配置nacos的访问地址和服务名称

cart-serviceapplication.yml中添加nacos地址配置:

XML 复制代码
spring:
  application:
    name: cart-service
  cloud:
    nacos:
      server-addr: 192.168.186.140:8848

3.3.3 发现并调用服务

到此为止,我们还需要准备负载均衡策略。以最简单的随机策略为例。

为了能够发现服务,获取实例列表,这里还需要使用SpringCloud提供的服务发现工具:DiscoveryClient

该工具被SpringCloud自动注入装配,我们只需要注入就可以使用,我们利用它修改我们原先的代码逻辑:

RestTemplase实现代码:

使用DiscoveryClient工具 + Nacos后代码

3.3.4 发现服务测试

3.3.5 完整代码

java 复制代码
 // 注入服务发现工具
    @Resource
    private DiscoveryClient discoveryClient;


    /**
     * DiscoveryClient
     * @param vos
     */
    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
        // 2.1 发现item-service服务的请求实例
        List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
        if(CollUtils.isEmpty(instances)) {
            throw new BizIllegalException("商品服务不可用");
        }
        //2.2 负载均衡选择一个实例
        ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));

        //2.3 构建请求、发送请求
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                instance.getUri() + "/items?ids={ids}", // 请求路径
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() {},
                Map.of("ids", CollUtil.join(itemIds, ","))
        );

        //2.4 解析响应对象
        if(!response.getStatusCode().is2xxSuccessful()) {
            // 查询失败
            return;
        }
        // 2.5 获取查询商品对象
        List<ItemDTO> items = response.getBody();

        // 3.构建商品id与商品对象的映射
        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.setStock(item.getStock()); // 库存
            v.setStatus(item.getStatus()); // 状态
        }
    }

四、代码优化:OpenFeign工具

到这里我们已经解决了跨微服务请求的难题了,是不是挺简单的。确实,SpringCloud给我们提供了太多好用的工具了,使用DiscoveryClient + Nacos + RestTemplate解决了这个问题。

但是回看我们写的完整代码。是不是感觉有些复杂啊,想要构建一个简单的请求。我们先是去寻找服务,接着手写负载均衡选择实例、然后才是利用RestTemplate构建请求......

如何能够优化项目代码,减少开发者的工作量呢?这一节我们使用另一个工具------OpenFegin来解决这个问题。

4.1 OpenFeign快速入门

以cart-service中的查询我的购物车为例。因此下面的操作都是在cart-service中进行。

使用步骤

  • 引入OpenFeign依赖 和 loadBalancer负载均衡依赖
  • 启动类下添加 @EnableFeignClients 依赖 启动 OpenFeign服务
  • 编写client接口,用于实现请求发送(这一步就跟你编写业务controller很像很像)
  • 实现类中注入client接口
  • 使用client接口中的方法发送请求

4.1.1 引入依赖

XML 复制代码
        <!--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>

4.1.2 添加启动注解

在cart-service启动类下添加@EnableFeignClients 依赖 启动 OpenFeign服务

4.1.3 编写client接口

无需编写实现类,SpringCloud帮我们动态生成

4.1.4 实现类注入client接口

4.1.5 使用client定义的接口方法

你看看,现在的代码是不是简单暴了。完全不需要再手动找服务、手动完成负载均衡、手动编写restTemplate发送请求了。

java 复制代码
    /**
     * OpenFeign实现
     * @param vos
     */
    private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        // 2.查询商品
        List<ItemDTO> items = itemClient.queryItemByIds(itemIds); // openfeign调用

        // 3.构建商品id与商品对象的映射
        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.setStock(item.getStock()); // 库存
            v.setStatus(item.getStatus()); // 状态
        }
    }

4.1.6 测试代码

4.2 连接池的必要性

4.2.1 HTTP连接 与 HTTP消息

目前我们已经将代码优化得非常好了。理论上日常开发做到这块就可以了。但如如何还要想优化的话,接下来我们需要考虑的就是开销方面的问题了。我们回忆一下,现在我们每次需要发送跨端请求时,都需要先建立服务器之间的连接,然后才会去发送http消息。但是:

两台服务器建立HTTP连接的过程复杂且耗时,特别是其中的3次握手和4次分手过程产生的开销,对于传输大量较小的HTTP消息来说,这种开销显得尤为显著。

于是乎为了减少建立HTTP连接的大开销,我们需要建立HTTP连接池。

4.2.2 HTTP客户端技术选型

主要用到的HTTP客户端技术包括以下三种,其中第一种是OpenFeign默认的底层实现:

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

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

由于HttpURLConnection不支持连接池,所有我们得更改其他的HTTP客户端技术,本次实验选取OKHttp。

HTTP客户端技术补充说明

HttpURLConnection

  • 概述

    HttpURLConnection是Java标准库中的一部分,用于发送HTTP请求和接收HTTP响应。它提供了一组简单的方法来发送HTTP请求和处理响应,使开发人员能够轻松地与服务器进行通信。

  • 特点

    • 简单易用:HttpURLConnection提供了直观的API,使得HTTP请求和响应的处理变得简单。
    • 线程安全:HttpURLConnection是线程安全的,可以在多线程环境下使用,而无需额外的同步措施。
    • 支持多种HTTP方法:如GET、POST、PUT、DELETE等,可以根据需要选择合适的方法进行请求。
    • 支持HTTPS:可以与HTTPS服务器建立安全连接,通过SSL/TLS协议进行数据传输,确保数据的安全性。
    • 跨平台:作为Java标准库的一部分,可以在各种Java平台上使用,具有良好的跨平台性。
  • 限制

    HttpURLConnection的默认实现不支持连接池,这意味着每次发送HTTP请求时都需要建立新的连接,这可能会导致性能下降,特别是在发送大量HTTP请求的情况下。

Apache HttpClient

  • 概述

    Apache HttpClient是Apache软件基金会的一个项目,是Java标准库之外的一个广泛使用的HTTP客户端库。它提供了丰富的功能和配置选项,可以满足各种复杂的HTTP请求场景。

  • 特点

    • 稳定可靠:Apache HttpClient是一个成熟稳定的HTTP客户端库,拥有长期的开发历史和广泛的用户基础。
    • 支持连接池:通过连接池技术,可以有效地复用已经建立的连接,减少连接建立和关闭的开销,提高性能。
    • 支持HTTP/2:最新版本的Apache HttpClient支持HTTP/2协议,可以提供更高的性能和效率。
    • 丰富的配置选项:提供了多种配置选项,以满足不同的HTTP请求需求。
  • 应用

    Apache HttpClient适用于需要处理复杂HTTP请求和响应的场景,如需要设置自定义请求头、处理重定向、管理Cookies等。

OKHttp

  • 概述

    OKHttp是一个开源的Java HTTP客户端库,由Square公司开发。它被广泛用于Android开发和Java后端开发。OKHttp提供了一个简洁的API,用于发送HTTP请求和处理HTTP响应。

  • 特点

    • 高性能:OKHttp的底层实现基于Java的Socket和线程池,使用了连接池和请求重用机制,可以高效地处理大量的并发请求,并减少网络延迟。
    • 支持连接池:与Apache HttpClient类似,OKHttp也支持连接池技术,可以复用已经建立的连接。
    • 支持同步和异步请求:OKHttp支持发送同步和异步的HTTP请求,可以根据需要选择合适的请求方式。
    • 拦截器机制:提供了拦截器机制,可以在发送请求和接收响应的过程中进行干预和操作,如添加公共头部、记录日志等。
    • 支持HTTP/2和SPDY:这些协议可以提高网络性能和效率,OKHttp会自动选择支持的协议进行通信。
  • 应用

    OKHttp适用于需要高性能和灵活配置的HTTP客户端场景,如需要处理大量并发请求、需要自定义请求和响应处理等。

4.2.3 连接池的使用

  • 引入依赖
  • 开启线程池配置
  • 验证底层变化

第一步:引入依赖

cart-servicepom.xml中引入依赖:

XML 复制代码
<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

第二步: 开启线程池配置

cart-service的yml文件中引入

第三步:验证底层

4.3 抽取服务、最佳实践

呼!现在应该是最佳方案了吧.......是吧,其实还是有优化的(优化是无止境的哈哈)。你观察一下。其实微服务与微服务之间往往是双向调用的,假设有1000个微服务两两互相调用。按照我们这种写法,需要给每个微服务提供 999 个 client接口。那1000个微服务就要提供 999000个接口。喔喔喔,是不是特别吓人。而且这些接口文件大都是重复的呀。

所以我们能不能把接口抽取成一个顶层模块,其他微服务模块只需要"继承"该模块,就能获得其中的方法。哇是不是很可行,那咱们马上行动。

4.3.1 抽取思路分析

  • 思路1:抽取到微服务之外的公共modul

    • 第一种的就是将所有的需要Fegin的接口都放入这个hm-api中,不同模块都可以调用这个hm-api中的接口

    • **优点:**抽取更加简单,工程结构也比较清晰,不需要额外拷贝别的微服务的DTO。

    • **缺点:**耦合度比较高,每个模块都可能都需要调用hm-api。

  • 思路2:每个微服务自己抽取一个module

    • 第二种是将需要调用的接口放在自己的module下,耦合度没有那么高,但是实现相对麻烦,工程结构相对更复杂、而且要额外拷贝别的微服务的DTO。

4.3.2 .抽取Feign客户端实践

  • hmall下定义一个新的module,命名为hm-api

  • 导入依赖、导入实体对象、导入client接口

hmall下定义一个新的module,命名为hm-api

导入依赖、导入实体对象、导入client接口

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>hmall</artifactId>
        <groupId>com.heima</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hm-api</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!--open feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- load balancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- swagger 注解依赖 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.6</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

现在,任何微服务要调用item-service中的接口,只需要引入hm-api模块依赖即可,无需自己编写Feign客户端了。

4.3.3 配置扫描包

为什么要配置扫描包?

cart-service的启动类定义在com.hmall.cart包下,扫描不到ItemClient,我们必须配置扫描包,不然会报错。

使用步骤

  • 在cart-service的pom.xml中引入hm-api模块
  • 配置扫描包路径

在cart-service的pom.xml中引入hm-api模块**(模块调用模块)**

XML 复制代码
  <!--feign模块-->
  <dependency>
      <groupId>com.heima</groupId>
      <artifactId>hm-api</artifactId>
      <version>1.0.0</version>
  </dependency>

配置扫描包路径方法一:声明扫描包

在cart-service的启动类上添加扫描 hm-api的声明

注意哈!由于删除了原本模块中的client、dto。导包部分要重新导

配置扫描包路径方法一:声明要用的FeignClient

在cart-service的启动类上添加声明要用的FeignClient

4.4 日志配置

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

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

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

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

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

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

4.4.1 定义日志级别

java 复制代码
package com.hmall.api.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;

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

4.4.2 日志配置生效

【局部生效】 在某个**FeignClient**中配置,只对当前FeignClient生效

java 复制代码
@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class)

全局生效 】在**@EnableFeignClients**中配置,针对所有FeignClient生效。

java 复制代码
@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

日志格式

vbnet 复制代码
22:26:25:336 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] ---> GET http://item-service/items?ids=100000006163 HTTP/1.1
22:26:25:336 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] ---> END HTTP (0-byte body)
22:26:25:518 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] <--- HTTP/1.1 200  (182ms)
22:26:25:518 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] connection: keep-alive
22:26:25:519 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] content-type: application/json
22:26:25:519 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] date: Fri, 01 Nov 2024 14:26:25 GMT
22:26:25:519 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] keep-alive: timeout=60
22:26:25:519 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] transfer-encoding: chunked
22:26:25:519 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] 
22:26:25:520 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] [{"id":"100000006163","name":"巴布豆(BOBDOG)柔薄悦动婴儿拉拉裤XXL码80片(15kg以上)","price":67100,"stock":10000,"image":"https://m.360buyimg.com/mobilecms/s720x720_jfs/t23998/350/2363990466/222391/a6e9581d/5b7cba5bN0c18fb4f.jpg!q70.jpg.webp","category":"拉拉裤","brand":"巴布豆","spec":"{}","sold":11,"commentCount":33343434,"isAD":false,"status":2}]
22:26:25:520 DEBUG 4716 --- [nio-8082-exec-1] com.hmall.api.client.ItemClient          : [ItemClient#queryItemByIds] <--- END HTTP (371-byte body)
22:26:26:007  INFO 4716 --- [ent-executor-12] com.alibaba.nacos.common.remote.client   : [64fa38f0-9dff-4673-8014-52dbf5095a2f] Receive server push request, request = NotifySubscriberRequest, requestId = 22
22:26:26:008  INFO 4716 --- [ent-executor-12] com.alibaba.nacos.common.remote.client   : [64fa38f0-9dff-4673-8014-52dbf5095a2f] Ack server push request, request = NotifySubscriberRequest, requestId = 22

五、服务注册与调用巩固

  1. 注册中心模式的角色有哪些?流程是什么?

  2. 注册中心模式是如何实现宕机实例、异常实例的检测的?

  3. 概述一下Nacos的使用流程?

  4. 微服务中的服务发现是如何实现的?

  5. 如何优化微服务远程调用的代码逻辑?(取代RestTemplate的工具)

  6. 谈谈OpenFeign工具的使用流程?

  7. OpenFeign底层的HTTP客户端技术是什么?有什么特点?

  8. 除了HttpURLConnection,还要哪些HTTP客户端技术,有何特点?

  9. 如何提高client接口代码的复用性。你有什么实现思路?

  10. 跨模块调用client接口方法的配置步骤?

相关推荐
花哥码天下32 分钟前
apifox登录后设置token到环境变量
java·后端
浩瀚地学1 小时前
【Java】常用API(二)
java·开发语言·经验分享·笔记·学习
hashiqimiya2 小时前
springboot事务触发滚动与不滚蛋
java·spring boot·后端
PPPHUANG2 小时前
一次 CompletableFuture 误用,如何耗尽 IO 线程池并拖垮整个系统
java·后端·代码规范
恩创软件开发2 小时前
创业日常2026-1-8
java·经验分享·微信小程序·小程序
想用offer打牌3 小时前
一站式了解Spring AI Alibaba的流式输出
java·人工智能·后端
Lonely丶墨轩3 小时前
从登录入口窥见架构:一个企业级双Token认证系统的深度拆解
java·数据库·sql
f***24113 小时前
高效自动化管理临时文件的技术方案
运维·自动化