微服务面试题

微服务治理包含什么内容

微服务治理(Microservices Governance)是指在微服务架构中,对服务的生命周期、服务间交互、服务的健康状态、监控、日志管理、安全性等多个方面进行管理和优化的过程。微服务治理的目的是确保微服务系统的可靠性、可扩展性、灵活性和可维护性。它涵盖了很多技术和管理手段,具体包括以下几个方面:

1. 服务注册与发现

  • 服务注册:微服务在启动时将自身的信息(如IP地址、端口、元数据等)注册到服务注册中心(如 Nacos、Consul、Eureka等)。
  • 服务发现:服务消费者通过服务注册中心发现并访问其他微服务,避免硬编码服务地址,使得服务可以动态扩展或缩减。

关键技术:Nacos、Eureka、Consul、Zookeeper

2. 负载均衡

  • 客户端负载均衡:服务消费者通过负载均衡算法(如轮询、随机、加权等)选择多个服务实例中的一个来进行请求。
  • 服务器端负载均衡:使用 API 网关或负载均衡器(如 Nginx、HAProxy)在请求到达服务之前进行负载均衡。

关键技术:Ribbon、Nginx、HAProxy

3. 服务间通信

  • 同步通信:大部分微服务间的通信通过 HTTP(REST)、gRPC 或其他协议进行同步调用。
  • 异步通信:为了提高性能,异步消息队列(如 Kafka、RabbitMQ、ActiveMQ)可以用于微服务间的消息传递,减少服务间的耦合。

关键技术:HTTP REST、gRPC、消息队列(Kafka、RabbitMQ)

4. 服务容错与降级

  • 断路器:当某个微服务不可用或超时时,断路器会停止请求该服务,避免造成级联故障。
  • 服务降级:在服务不可用或负载过高时,提供备用方案或返回预设的默认值。
  • 超时与重试:设置请求超时限制并在失败时进行重试,以提高系统的鲁棒性。

关键技术:Hystrix、Resilience4j、Sentinel

5. 服务监控与日志管理

  • 监控:实时监控微服务的健康状况、性能、响应时间等,确保微服务系统的可用性和性能。
  • 日志管理:集中化日志管理,用于收集、存储、查询和分析微服务的运行日志,帮助排查问题。
  • 追踪与链路分析:通过分布式追踪工具跟踪请求在各个服务间的流转路径,帮助诊断性能瓶颈和故障。

关键技术:Prometheus、Grafana、ELK(Elasticsearch、Logstash、Kibana)、Zipkin、Jaeger

6. 服务安全

  • 认证与授权:微服务之间的通信需要验证身份,确保服务间的安全调用。常用的认证方法包括基于 Token(如 JWT)的认证。
  • 加密:为了保护敏感数据,服务间的通信需要使用 HTTPS 等加密协议。
  • 防火墙与限流:通过设置防火墙和限流规则来防止恶意攻击或服务过载。

关键技术:OAuth 2.0、JWT、Spring Security、API Gateway、Rate Limiting

7. 配置管理

  • 集中化配置:将微服务的配置文件集中管理,支持动态刷新和管理。这样可以在不中断服务的情况下,修改和更新配置。
  • 环境隔离:不同环境(开发、测试、生产)之间的配置要进行隔离,保证配置的安全和稳定性。

关键技术:Nacos、Apollo、Consul、Spring Cloud Config

8. 数据管理与事务处理

  • 分布式事务:由于微服务架构的分布式特性,传统的单体事务已无法满足需求,需要通过分布式事务机制来保证数据的一致性。
  • Saga 模式:通过一系列本地事务和补偿操作来确保最终一致性。
  • Event Sourcing 和 CQRS:通过事件驱动的架构和命令查询职责分离模式,确保服务间的数据一致性和高性能。

关键技术:Seata、Atomikos、Saga、Event Sourcing、CQRS

9. API 网关与路由管理

  • API 网关:微服务架构中,所有外部请求都通过 API 网关统一接入,API 网关可以进行请求路由、负载均衡、认证、限流等操作。
  • 路由管理:动态管理请求路由规则,支持服务版本控制和灰度发布。

关键技术:Kong、Zuul、Spring Cloud Gateway

10. 服务治理与调度

  • 服务健康检查:微服务在注册到服务注册中心时,需要定期进行健康检查,确保服务的可用性。
  • 服务版本管理与灰度发布:通过服务的版本控制和灰度发布策略,逐步将新版本推广到生产环境。
  • 自动扩展与缩减:根据服务负载自动调整服务实例的数量,确保资源的高效利用。

关键技术:Kubernetes、Docker Swarm、Spring Cloud Kubernetes、Consul


11. 版本控制与灰度发布

  • 服务版本管理:微服务的不同版本可能同时存在,需要管理和协调服务版本。
  • 灰度发布与蓝绿发布:通过逐步发布新版本,确保服务升级时的平滑过渡,避免对现有系统造成影响。

关键技术:Istio、Argo CD、Spring Cloud Bus


12. 微服务的可观察性

  • 分布式跟踪:微服务架构中,单个请求可能会跨多个服务,分布式跟踪可以帮助追踪请求在服务间的流转路径,定位性能瓶颈和故障。
  • 日志聚合与分析:集中化日志管理,帮助开发和运维人员快速定位问题。

关键技术:Zipkin、Jaeger、ELK Stack


13. 容器化与服务调度

  • 容器化:通过 Docker 等容器技术将微服务进行打包,确保服务的跨平台一致性和灵活性。
  • 服务调度:使用容器编排工具(如 Kubernetes)来自动化部署、扩展和管理微服务。

关键技术:Docker、Kubernetes、Docker Compose


总结

微服务治理是一个综合的体系,涵盖了多个方面的管理与优化。一个健康的微服务治理架构不仅关注服务注册与发现、负载均衡等基础设施,还应确保服务的安全、可靠、可监控、可扩展。通过使用合适的工具和框架来实现微服务治理,可以有效地提升微服务系统的稳定性、灵活性和可维护性。

Dubbo

dubbo怎么定位的,在微服务中扮演什么角色,与Eureka区别

dubbo远程调用原理

动态代理

功能:服务治理(服务注册与发现,远程调用,熔断+重试,负载均衡(轮询/随机/权重/活跃度))

Dobbuo实现服务注册与发现有借助其他组件吗,还是他自己实现的

Dubbo 在实现 服务注册与发现 时,既有自己实现的部分,也可以通过借助外部组件(注册中心)来完成。实际上,Dubbo 主要依赖外部的 注册中心 来进行服务的注册与发现。服务注册与发现的过程是 Dubbo 分布式架构中关键的一部分,帮助实现服务的高可用和负载均衡。

1. Dubbo 自己的实现

Dubbo 的早期版本(特别是在 2.x 之前),曾经内置了一些简单的服务注册与发现机制,但这些机制比较原始、简单,且功能有限。因此,Dubbo 并不依赖自己完整的服务注册与发现实现,而是希望将这部分职责交给更强大的分布式注册中心。

2. 依赖外部组件:服务注册与发现

Dubbo 2.x 开始,Dubbo 默认使用外部的服务注册中心来完成服务的注册与发现。常见的外部组件有:

  • Zookeeper:这是 Dubbo 默认支持的服务注册与发现组件。Dubbo 利用 Zookeeper 提供的分布式协调功能,来进行服务注册、发现和监控。
  • Nacos:在 Dubbo 2.7 版本及以后,Dubbo 也支持 Nacos 作为注册中心。Nacos 提供了更丰富的功能,如动态配置管理、服务治理等。

此外,Dubbo 还支持其他一些注册中心的插件,如 ConsulEtcd 等。

3. 服务注册与发现过程

  • 服务注册

    • 服务提供者启动时,会将自己的服务信息(如服务接口、服务实现类、IP、端口等)注册到注册中心(如 Zookeeper 或 Nacos)。
    • 这些信息通常是 以树形结构存储,注册中心会为每个服务暴露一个唯一的路径,表示该服务的实例信息。
  • 服务发现

    • 服务消费者在调用服务之前,会查询注册中心,获取可用的服务提供者信息(如服务的 IP 地址、端口、负载均衡策略等)。
    • 注册中心根据客户端的请求返回可用的服务实例,消费者可以通过这些信息调用相应的服务。

4. 为什么选择外部注册中心

Dubbo 使用外部注册中心来实现服务注册与发现,主要有以下几个原因:

  • 高可用与容错性:外部注册中心如 Zookeeper、Nacos 提供了高可用和容错机制,能够处理服务实例的动态变化(如上线、下线、网络故障等)。
  • 分布式环境支持:注册中心为 Dubbo 提供了强大的分布式协调能力,尤其是在大规模分布式系统中,注册中心能够管理成千上万的服务实例,并确保服务发现的可靠性。
  • 负载均衡和容错:通过服务注册中心,Dubbo 可以实现更加灵活和智能的负载均衡和故障转移机制,避免直接在服务之间做硬编码。
  • 多种协议支持:注册中心可以同时支持不同类型的服务(如 Dubbo 服务、HTTP 服务等),使得 Dubbo 在多协议场景下的兼容性更强。

5. 服务注册与发现的流程

服务注册流程
  1. 服务提供者启动:服务提供者启动时,Dubbo 会将服务接口、服务实现、IP、端口等信息通过配置文件或注解的方式传递给注册中心。
  2. 注册中心保存信息:注册中心(如 Zookeeper)会在特定的节点路径下存储服务的信息,确保该服务的可用性。
  3. 服务提供者心跳:为了保证服务的健康状态,服务提供者定期向注册中心发送心跳,确保自己在注册中心的信息是有效的。
服务发现流程
  1. 服务消费者查询:服务消费者启动时,会查询注册中心,获取指定服务的地址和信息。
  2. 注册中心返回服务实例信息:注册中心返回可用的服务实例(如服务提供者的 IP、端口等)。
  3. 调用远程服务:服务消费者通过网络请求(如 HTTP、Dubbo 协议等)调用远程服务。

6. Dubbo与Zookeeper/Nacos的集成

  • Zookeeper 集成

    • Zookeeper 作为一个分布式协调框架,提供了类似分布式文件系统的机制,Dubbo 使用 Zookeeper 进行服务注册和发现。
    • 服务提供者将服务信息注册到 Zookeeper 的某个节点,而消费者则从 Zookeeper 查询该节点,获得可用服务的列表。
    • Zookeeper 支持数据一致性和分布式事务,能够高效地管理服务的动态变化。
  • Nacos 集成

    • Nacos 是阿里巴巴开源的动态服务发现与配置管理平台,提供了类似 Zookeeper 的服务注册与发现功能。
    • 与 Zookeeper 相比,Nacos 在用户体验、配置管理、健康检查等方面更加灵活、简便。
    • Nacos 支持服务的 动态注册与发现,并且可以实现更加细粒度的服务管理。

7. 总结

  • Dubbo 本身并没有完全实现服务注册与发现,而是将这一功能交给外部的注册中心(如 ZookeeperNacos 等)来处理。
  • 通过注册中心,Dubbo 实现了服务的动态注册与发现,能够支持分布式架构中的服务高可用、负载均衡和容错等重要功能。
  • 使用外部注册中心的好处包括高可用性、灵活的服务治理、分布式协调能力等。

因此,Dubbo 并不依赖自己实现服务注册与发现,而是借助成熟的注册中心组件来完成这些任务。

限流

网关

安全性 ,如黑名单

Nacos

nacos实现远程调用方案

Nacos 是一个开源的 服务发现配置管理 平台,常用于微服务架构中的服务注册与发现以及配置管理。它本身并不直接提供远程调用(如 Dubbo 或 gRPC 提供的服务调用),但可以与其他远程调用框架结合使用,在微服务架构中实现服务间的远程调用。

下面我将详细介绍如何通过 Nacos + Spring CloudNacos + Dubbo 实现远程调用。


1. Nacos + Spring Cloud 实现远程调用

在 Spring Cloud 微服务架构中,Nacos 通常作为服务注册与发现的中心,服务间的远程调用通过 Spring Cloud FeignSpring Cloud RestTemplate 来实现。

步骤:
  1. 服务注册与发现

    • 各个微服务注册到 Nacos。
    • Nacos 充当服务注册中心,提供服务发现功能。
  2. 服务提供者

    • 在 Spring Boot 服务中使用 @EnableDiscoveryClient 注解开启服务发现。
    • 使用 @RestController@Service 暴露远程调用接口。
  3. 服务消费者

    • 服务消费者同样需要启用 @EnableDiscoveryClient 来从 Nacos 获取服务列表。
    • 可以使用 Feign ClientRestTemplate 来调用其他微服务。
示例:Nacos + Spring Cloud + Feign + 远程调用

服务提供者

java 复制代码
// Application.java
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }
}

// Controller.java
@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping("/greet")
    public String greet() {
        return "Hello from Service Provider!";
    }
}

服务消费者

java 复制代码
// Application.java
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }
}

// Feign 客户端接口
@FeignClient(name = "service-provider")
public interface HelloClient {

    @GetMapping("/hello/greet")
    String greet();
}

// 服务消费者调用
@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private HelloClient helloClient;

    @GetMapping("/call")
    public String callService() {
        return helloClient.greet();
    }
}

application.properties 配置文件:

复制代码

spring.application.name=service-consumer spring.cloud.nacos.discovery.server-addr=localhost:8848 spring.application.name=service-provider spring.cloud.nacos.discovery.server-addr=localhost:8848

解释:
  1. @EnableDiscoveryClient:在服务提供者和消费者中启用服务发现功能,使得它们能够与 Nacos 进行交互。
  2. @FeignClient(name = "service-provider"):Feign 用于通过服务名称调用服务,Feign 会自动处理服务发现与调用。
  3. spring.cloud.nacos.discovery.server-addr=localhost:8848:配置 Nacos 注册中心的地址。
Feign 优势:
  • 简洁:Feign 是声明式的 HTTP 客户端,服务间调用只需要通过接口进行,不需要关心底层的 HTTP 请求细节。
  • 负载均衡:Spring Cloud 提供的 Feign 支持客户端负载均衡,可以自动通过 Ribbon 来实现负载均衡。

2. Nacos + Dubbo 实现远程调用

Dubbo 是一个高性能的 RPC 框架,适用于服务间的远程调用。Nacos 可以与 Dubbo 集成,作为服务注册与发现的中心,Dubbo 用于处理具体的远程调用过程。

步骤:
  1. 服务注册与发现

    • Dubbo 服务在启动时将自身注册到 Nacos。
    • Dubbo 服务消费者通过 Nacos 查找服务提供者。
  2. 服务提供者

    • 在 Dubbo 服务中,通过 Nacos 作为注册中心进行服务注册。
  3. 服务消费者

    • 服务消费者通过 Dubbo 与 Nacos 进行集成,进行服务的发现和远程调用。
示例:Nacos + Dubbo + 远程调用

服务提供者

java 复制代码
// Application.java
@SpringBootApplication
public class ServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }
}

// 服务接口
public interface HelloService {
    String sayHello();
}

// 服务实现
@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello() {
        return "Hello from Dubbo Service Provider!";
    }
}

服务消费者

java 复制代码
// Application.java
@SpringBootApplication
public class ServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }
}

// 服务消费者调用
@DubboReference
private HelloService helloService;

@GetMapping("/call")
public String callService() {
    return helloService.sayHello();
}

application.properties 配置文件:

复制代码

# Nacos 配置 spring.cloud.nacos.discovery.server-addr=localhost:8848 spring.dubbo.registry.address=nacos://localhost:8848 spring.dubbo.application.name=service-consumer spring.dubbo.registry.id=nacos

解释:
  1. spring.dubbo.registry.address=nacos://localhost:8848:配置 Dubbo 的注册中心为 Nacos。
  2. @DubboReference:注解用于注入 Dubbo 服务接口,自动从 Nacos 获取服务提供者并执行远程调用。

3. Nacos 配置管理与远程调用

除了服务注册与发现,Nacos 还可以作为配置中心来管理远程调用中的配置。你可以通过 Nacos 动态加载服务的配置,从而在运行时调整服务间的调用方式、负载均衡策略等。

配置管理:
  1. 动态配置:通过 Nacos 提供的配置管理功能,可以动态调整服务间调用的配置。例如,负载均衡策略、调用超时时间等都可以通过 Nacos 配置中心进行管理。
  2. 环境隔离:Nacos 可以支持多环境配置,如开发、测试、生产环境的隔离,确保不同环境下的远程调用使用不同的配置。

总结

  1. Nacos + Spring Cloud

    • 利用 Nacos 作为服务注册与发现中心,服务消费者通过 Feign 或 RestTemplate 调用服务提供者。
    • Feign 简单易用,支持负载均衡和容错,适合大部分微服务架构中的服务调用。
  2. Nacos + Dubbo

    • 结合 Nacos 和 Dubbo,实现高性能的远程调用。
    • Dubbo 提供了丰富的远程调用功能,支持 RPC 通信、服务治理、负载均衡、容错等特性。
  3. Nacos 配置中心

    • Nacos 可以为远程调用提供配置管理功能,支持动态调整服务的行为(如负载均衡策略、超时设置等)。

通过这些集成方案,你可以利用 Nacos 作为中心来实现服务注册、发现、配置管理,并通过 Feign 或 Dubbo 进行高效的远程服务调用。

Feign与RestTemplate

在 Spring Cloud 微服务架构中,Nacos 通常作为服务注册与发现的中心,服务间的远程调用通过 Spring Cloud Feign 或 Spring Cloud RestTemplate 来实现。 二者区别是什么,代码举例说明

在 Spring Cloud 微服务架构中,Nacos 作为服务注册与发现的中心,Spring Cloud Feign 和 Spring Cloud RestTemplate 都可以用于实现服务间的远程调用,但它们有一些显著的区别。

1. Spring Cloud Feign

Feign 是一个声明式的 HTTP 客户端,可以通过接口方式来定义远程调用,Feign 会自动为你实现 HTTP 请求的细节。它结合了 Spring Cloud 的负载均衡(Ribbon)和服务发现(Eureka/Nacos),使得服务间调用变得非常简洁。

特点:
  • 声明式调用:通过接口方式定义远程调用,代码简洁。
  • 与 Spring Cloud 结合紧密:集成了负载均衡、服务发现、熔断等功能。
  • 自动处理 HTTP 请求:不需要手动编写 HTTP 请求的相关代码。
示例代码:

假设有一个用户服务(user-service)和一个订单服务(order-service)。

1. 添加依赖:pom.xml 中加入 Feign 和 Nacos 的相关依赖:

java 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2. 启用 Feign 客户端: 在 Spring Boot 启动类中启用 Feign 客户端:

java 复制代码
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

3. 定义 Feign 接口:

java 复制代码
@FeignClient(name = "user-service")  // user-service 是 Nacos 中注册的服务名称
public interface UserClient {
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id") Long id);
}

4. 使用 Feign 调用远程服务:

java 复制代码
@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private UserClient userClient;

    @GetMapping("/{orderId}")
    public String getOrderDetails(@PathVariable Long orderId) {
        User user = userClient.getUserById(123L);  // 调用 user-service 服务
        return "Order for user: " + user.getName();
    }
}

2. Spring Cloud RestTemplate

RestTemplate 是 Spring 提供的一个同步 HTTP 客户端,用于发起 HTTP 请求。在 Spring Cloud 中,它通常与 Ribbon 和 Nacos 结合使用,用于实现服务间的调用,但相较于 Feign,RestTemplate 更加低级,需要手动配置 URL 和请求。

特点:
  • 程序员控制更多细节:需要手动编写 URL 和处理请求。
  • 灵活性高:可以更加灵活地控制 HTTP 请求的细节。
  • 不如 Feign 简洁:相对于 Feign 需要更多的样板代码。
示例代码:

假设同样有 user-serviceorder-service

1. 添加依赖:pom.xml 中加入 RestTemplate 和 Nacos 的相关依赖:

java 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2. 定义 RestTemplate Bean:

java 复制代码
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

项目实战

Resttemplate配置

java 复制代码
remote.maxTotalConnect=200
remote.maxConnectPerRoute=100
remote.connectTimeout=50000
remote.readTimeout=50000
java 复制代码
package com.smcv.mall.tasks.configure;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @Author: shenjian
 * @Desription:
 * @Date: Created in 下午3:37 2017/11/24
 * @Modified By:
 */
@Configuration
@EnableCaching
@ConditionalOnClass(value = {RestTemplate.class, HttpClient.class})
@RefreshScope
public class RestTemplateConfiguration {

    @Value("${remote.maxTotalConnect}")
    private int maxTotalConnect; //连接池的最大连接数默认为0
    @Value("${remote.maxConnectPerRoute}")
    private int maxConnectPerRoute; //单个主机的最大连接数
    @Value("${remote.connectTimeout}")
    private int connectTimeout; //连接超时默认2s
    @Value("${remote.readTimeout}")
    private int readTimeout; //读取超时默认30s

    //创建HTTP客户端工厂
    private ClientHttpRequestFactory createFactory() {
        if (this.maxTotalConnect <= 0) {
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setConnectTimeout(this.connectTimeout);
            factory.setReadTimeout(this.readTimeout);
            return factory;
        }
        HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect).setMaxConnPerRoute(this.maxConnectPerRoute).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        factory.setConnectTimeout(this.connectTimeout);
        factory.setReadTimeout(this.readTimeout);
        return factory;
    }



    @Bean("getByBodyRestTemplate")
    @Primary
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(this.createFactory()));
        restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
        List<HttpMessageConverter<?>> converterList =  restTemplate.getMessageConverters();

        // 重新设置StringHttpMessageConverter字符集为UTF-8,解决中文乱码问题
        HttpMessageConverter<?> converterTarget = null;
        int index = 0;
        for (HttpMessageConverter<?> item : converterList) {
            if (StringHttpMessageConverter.class == item.getClass()) {
                converterTarget = item;
                break;
            }
            ++index;
        }
        if (null != converterTarget) {
            converterList.remove(converterTarget);
        }
        converterList.add(index, new StringHttpMessageConverter(StandardCharsets.UTF_8));

        // 加入日志打印
//        restTemplate.setInterceptors(Collections.singletonList((ClientHttpRequestInterceptor)restTemplateInterceptor));
        return restTemplate;
    }

}

3. 使用 RestTemplate 调用远程服务:

java 复制代码
@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${user.service.url}")
    private String userServiceUrl;

    @GetMapping("/{orderId}")
    public String getOrderDetails(@PathVariable Long orderId) {
        String userUrl = userServiceUrl + "/user/123";  // 构造 user-service 的 URL
        ResponseEntity<User> response = restTemplate.exchange(userUrl, HttpMethod.GET, null, User.class);
        User user = response.getBody();
        return "Order for user: " + user.getName();
    }
}

application.properties 中配置 user-service 的 URL:

复制代码

user.service.url=http://user-service

3. 两者的主要区别

特性 Spring Cloud Feign Spring Cloud RestTemplate
使用方式 基于接口定义,声明式调用 基于手动 URL 和 HTTP 请求,编程式调用
简洁性 更简洁,无需关心请求细节 需要手动编写请求细节
集成 自动集成负载均衡(Ribbon)、服务发现(Nacos)等 手动配置 Ribbon 和服务发现
灵活性 较低,主要针对常规的 RESTful 调用 高,可以自由处理更多的 HTTP 细节
可维护性 高,代码简洁易读 低,需要编写更多的样板代码

总结:

  • Feign 适合在微服务架构中需要频繁进行服务间通信时使用,它提供了声明式的 HTTP 调用方式,能够简化代码并与 Spring Cloud 的其他组件(如 Ribbon、Nacos)紧密集成。
  • RestTemplate 提供了更多的灵活性和控制,适合需要精细控制 HTTP 请求的场景,但相对来说代码较为繁琐,且需要手动处理更多的细节。

通常情况下,推荐使用 Feign,因为它更符合微服务的设计理念,简洁且易于维护。

Spring Cloud RestTemplate 手动配置 Ribbon 和服务发现 具体如何实现的

项目中没有看到这个注解 @LoadBalanced // 启用 Ribbon 负载均衡

相关推荐
KYGALYX8 小时前
服务异步通信
开发语言·后端·微服务·ruby
yunteng5219 小时前
通用架构(同城双活)(单点接入)
架构·同城双活·单点接入
麦聪聊数据10 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
程序员侠客行11 小时前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
bobuddy12 小时前
射频收发机架构简介
架构·射频工程
桌面运维家12 小时前
vDisk考试环境IO性能怎么优化?VOI架构实战指南
架构
一个骇客14 小时前
让你的数据成为“操作日志”和“模型饲料”:事件溯源、CQRS与DataFrame漫谈
架构
鹏北海-RemHusband15 小时前
从零到一:基于 micro-app 的企业级微前端模板完整实现指南
前端·微服务·架构
7哥♡ۣۖᝰꫛꫀꪝۣℋ15 小时前
Spring-cloud\Eureka
java·spring·微服务·eureka