03-服务调用详解

张开发
2026/4/11 12:58:16 15 分钟阅读

分享文章

03-服务调用详解
Spring Cloud 服务调用详解一、知识概述在微服务架构中,服务之间的调用是核心需求。Spring Cloud 提供了多种服务调用方式,包括 RestTemplate、WebClient 和 OpenFeign。其中 OpenFeign 是最常用的声明式 HTTP 客户端,它使得编写 Web 服务客户端变得简单。服务调用的核心需求:声明式调用:像调用本地方法一样调用远程服务负载均衡:自动分发请求到多个实例熔断降级:服务不可用时提供降级策略重试机制:失败后自动重试理解服务调用的原理和最佳实践,是构建微服务系统的关键技能。二、知识点详细讲解2.1 服务调用方式对比方式类型特点适用场景RestTemplate同步阻塞简单直接简单场景WebClient异步非阻塞响应式高并发OpenFeign声明式简洁优雅推荐使用2.2 OpenFeign 核心概念工作原理Feign Client 接口 ↓ 动态代理生成实现类 ↓ 解析注解(@RequestMapping 等) ↓ 构建 HTTP 请求 ↓ 负载均衡选择实例 ↓ 发送请求 ↓ 解析响应核心组件@FeignClient:声明 Feign 客户端Encoder:请求参数编码Decoder:响应结果解码Contract:注解契约Client:HTTP 客户端2.3 Feign 配置feign:client:config:default:connectTimeout:5000readTimeout:5000loggerLevel:basicuser-service:connectTimeout:10000readTimeout:10000compression:request:enabled:truemime-types:text/xml,application/xml,application/jsonresponse:enabled:true2.4 声明式调用优势代码简洁:只需定义接口易于维护:统一管理 API集成简单:与 Spring MVC 注解兼容扩展方便:支持自定义配置三、代码示例3.1 基础 Feign Clientimportorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.*;importjava.util.List;@FeignClient(name="user-service",path="/api/users")publicinterfaceUserClient{@GetMapping("/{id}")UserDTOgetUserById(@PathVariable("id")Longid);@GetMappingListUserDTOgetAllUsers();@PostMappingUserDTOcreateUser(@RequestBodyUserDTOuser);@PutMapping("/{id}")UserDTOupdateUser(@PathVariable("id")Longid,@RequestBodyUserDTOuser);@DeleteMapping("/{id}")voiddeleteUser(@PathVariable("id")Longid);}// 启用 Feign@SpringBootApplication@EnableFeignClientspublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}// 使用 Feign Client@ServicepublicclassOrderService{@AutowiredprivateUserClientuserClient;publicOrderDTOcreateOrder(LonguserId){// 像调用本地方法一样调用远程服务UserDTOuser=userClient.getUserById(userId);OrderDTOorder=newOrderDTO();order.setUserId(userId);order.setUserName(user.getName());returnorder;}}3.2 Feign 配置importfeign.*;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassFeignConfig{// 自定义日志级别@BeanpublicLogger.LevelfeignLoggerLevel(){returnLogger.Level.FULL;}// 自定义重试策略@BeanpublicRetryerfeignRetryer(){// 最大重试次数 3,初始间隔 100ms,最大间隔 1sreturnnewRetryer.Default(100,1000,3);}// 自定义请求拦截器@BeanpublicRequestInterceptorauthInterceptor(){returntemplate-{// 添加认证头Stringtoken=getCurrentToken();template.header("Authorization","Bearer "+token);};}// 自定义超时配置@BeanpublicRequest.OptionsrequestOptions(){returnnewRequest.Options(5000,// 连接超时 5s10000// 读取超时 10s);}privateStringgetCurrentToken(){// 从上下文获取当前 TokenreturnSecurityContextHolder.getContext().getAuthentication().getCredentials().toString();}}3.3 指定服务配置// 为特定服务配置@FeignClient(name="user-service",path="/api/users",configuration=UserServiceFeignConfig.class)publicinterfaceUserClient{// ...}@ConfigurationpublicclassUserServiceFeignConfig{@BeanpublicLogger.LeveluserLoggerLevel(){returnLogger.Level.FULL;}@BeanpublicRequest.OptionsuserRequestOptions(

更多文章