2026/2/16 15:28:32
网站建设
项目流程
农林牧渔行业网站建设,做创意礼品定制的网站,一起做网店官网下载,成都推广系统OpenFeign 详解#xff1a;调用机制、连接池、公共模块与日志配置完整指南#xff08;基于黑马商城项目#xff09; 前置条件#xff0c;nacos的实现#xff1a;nacos的部署详解 #x1f4da; 目录#xff08;点击跳转对应章节#xff09;
一、OpenFeign 的核心思想 二…OpenFeign 详解调用机制、连接池、公共模块与日志配置完整指南基于黑马商城项目前置条件nacos的实现nacos的部署详解 目录点击跳转对应章节一、OpenFeign 的核心思想二、快速接入 OpenFeign完整流程三、OpenFeign 底层调用执行流程四、Feign 连接池配置性能关键五、Feign 客户端抽取为公共模块六、Feign 扫描不到接口的问题七、Feign 日志配置排障必备八、总结什么时候必须用 Feign在微服务架构中服务之间通过 HTTP 进行远程调用是最基础的能力之一。如果直接使用 RestTemplate 进行调用通常需要手动拼接 URL处理参数解析返回值编写大量样板代码远程调用代码和业务逻辑混在一起可读性和维护性都不理想而且调用方式与本地方法差异很大。OpenFeign 的目标很明确让远程 HTTP 调用像本地方法调用一样简单。它通过接口 注解 动态代理的方式把远程调用彻底声明化。一、OpenFeign 的核心思想一次 HTTP 远程调用本质只包含四个要素请求方式GET/POST/PUT/DELETE请求路径请求参数返回值类型OpenFeign 的做法是使用 SpringMVC 注解描述请求信息启动时为接口创建动态代理调用接口方法时自动发起 HTTP 请求开发者只需要写接口不需要写实现类。示例FeignClient(item-service)publicinterfaceItemClient{GetMapping(/items)ListItemDTOqueryItemByIds(RequestParam(ids)CollectionLongids);}调用时itemClient.queryItemByIds(ids);形式与本地方法调用完全一致。二、快速接入 OpenFeign完整流程示例场景cart-service 调用 item-service 查询商品信息。1. 引入依赖!-- OpenFeign --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!-- 负载均衡 --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependency说明openfeign提供声明式 HTTP 客户端loadbalancer根据服务名选择实例并负载均衡Feign 负责怎么发请求LoadBalancer 负责选哪个实例。2. 启用 Feign 功能启动类添加EnableFeignClients作用开启 Feign 自动配置扫描 FeignClient 接口为接口生成代理对象并注册为 Bean不加这个注解Feign 接口不会生效。3. 编写 Feign 客户端接口FeignClient(item-service)publicinterfaceItemClient{GetMapping(/items)ListItemDTOqueryItemByIds(RequestParam(ids)CollectionLongids);}关键点说明FeignClient声明远程服务名称必须与注册中心服务名一致实际访问时会通过服务发现解析真实地址GetMapping指定请求方式指定请求路径必须与服务端 Controller 保持一致RequestParam指定查询参数参数名必须与服务端一致集合类型会被编码为多个参数/items?ids1ids2ids3返回值类型Feign 会自动完成JSON → Java对象通过 Decoder 使用 Spring 消息转换器完成反序列化。4. 在业务代码中使用AutowiredprivateItemClientitemClient;ListItemDTOitemsitemClient.queryItemByIds(ids);Feign 自动完成服务发现实例选择负载均衡HTTP 请求构建参数编码JSON 转换无需再使用 RestTemplate。三、OpenFeign 底层调用执行流程在此不详细说明而是只展示底层调用流程相关代码可以自行查看源码Feign 的执行链路非常清晰调用链路接口方法调用 → JDK动态代理InvocationHandler → SynchronousMethodHandlerInvocationHandler 的实现 → 解析方法元数据FeignClient 接口的方法信息 → 构建 RequestTemplate根据方法元数据填充请求信息 → LoadBalancer 选择实例根据服务名获取实例列表再根据负载均衡策略选择一个实例 → Client 发送 HTTP 请求根据 RequestTemplate 构建 HTTP 请求 → Decoder 解析响应根据响应体和返回值类型使用 Spring 消息转换器完成反序列化 → 返回 Java 对象根据返回值类型使用 Spring 消息转换器完成序列化核心组件说明SynchronousMethodHandler负责拦截接口方法调用并驱动整个请求流程。RequestTemplate封装请求方法URL参数HeaderBodyFeignBlockingLoadBalancerClient负责根据服务名获取实例列表负载均衡选择一个实例四、Feign 连接池配置性能关键Feign 本身不提供连接池它依赖底层 HTTP 客户端。默认客户端问题默认实现HttpURLConnection特点无连接池每次新建连接高并发性能差生产环境不推荐使用。可选客户端支持连接池的实现Apache HttpClientOKHttp实际项目中 OKHttp 使用更广泛。使用 OKHttp引入依赖dependencygroupIdio.github.openfeign/groupIdartifactIdfeign-okhttp/artifactId/dependency开启配置feign:okhttp:enabled:true五、Feign 客户端抽取为公共模块问题场景多个服务都需要调用 item-servicecart-servicetrade-service如果各写一份 FeignClient会产生重复代码。抽取策略选择两种方案方案一统一公共模块优点结构清晰缺点服务耦合偏高方案二每服务单独模块优点解耦更好缺点结构复杂由于黑马商城将模块放在一个hamll包下所以选择方案一且下列讲解也是基于方案一。抽取方案创建公共模块hm-api包含FeignClient 接口DTO 对象Feign 配置类公共模块依赖openfeign loadbalancer swagger-annotations使用方式其它服务只需依赖 hm-apidependencygroupIdcom.heima/groupIdartifactIdhm-api/artifactId/dependency即可直接注入使用。六、Feign 扫描不到接口的问题常见错误No qualifying bean of type ItemClient原因FeignClient 不在启动类扫描路径内。解决方式一指定扫描包EnableFeignClients(basePackagescom.hmall.api.client)解决方式二指定接口类EnableFeignClients(clientsItemClient.class)七、Feign 日志配置排障必备Feign 默认日志级别NONE不输出任何请求信息。四种日志级别NONE不输出日志BASIC方法 URL 状态码 耗时HEADERS包含请求头和响应头FULL包含请求体和响应体定义日志级别配置publicclassDefaultFeignConfig{BeanpublicLogger.LevelfeignLogLevel(){returnLogger.Level.FULL;}}让配置生效局部生效FeignClient(valueitem-service,configurationDefaultFeignConfig.class)全局生效EnableFeignClients(defaultConfigurationDefaultFeignConfig.class)日志开启的前提必须同时满足Feign Logger.Level 已配置FeignClient 所在包日志级别为 DEBUG例如logging:level:com.hmall.api.client:DEBUG八、总结什么时候必须用 Feign在微服务体系中只要满足以下条件就应该优先使用 Feign服务间 HTTP 调用频繁需要负载均衡希望调用方式统一需要良好的可读性需要减少样板代码一句话总结Feign 不是为了“少写代码”而是为了让远程调用模型与本地调用模型一致从而降低系统复杂度。