目录
作业: 老师给的参考流程图
要求
解答
知识扩展
Feign基础原理
接口定义
代理对象生成
请求调用
请求发送
响应处理
容错与熔断
总结
作业: 老师给的参考流程图
pdf版本 【金山文档 | WPS云文档】 Feign
https://kdocs.cn/l/ctbagIyxN348
要求
结合上面的Feign调用流程总结,画图描述订单服务调用用户服务的完整流程
解答
Feign代理流程图-ProcessOn
知识扩展
Feign基础原理
Feign是一个声明式的HTTP客户端,它允许开发者通过定义接口和使用注解来简化远程服务的调用。Feign的工作原理主要涉及以下几个关键步骤:
接口定义
开发者通过定义带有Feign注解的Java接口来描述HTTP请求规范,例如使用@RequestLine
注解指定HTTP方法和URL模板。
代理对象生成
当Spring Cloud应用启动时,Feign会扫描带有@FeignClient
注解的接口,并为其生成动态代理对象。
特别注意的是需要在Springboot启动项中允许开启FeignClinet代理
package cn.tedu.charging.order;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
//在启动类让spring-boot帮忙开启feignClients
// 多个client
@EnableFeignClients
public class ChargingOrderApplication {public static void main(String[] args) {SpringApplication.run(ChargingOrderApplication.class,args);}
}
根据我上面的作业要求 订单调用用户服务 这边直接在订单项目写了feign包,包下写了一个接口 UserClinet
package cn.tedu.charging.order.feign;import cn.tedu.chaging.common.pojo.UserInfoVO;
import cn.tedu.chaging.common.web.JsonResult;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;//userService要和nacos服务列表里的服务名称一致
@FeignClient("userService")
public interface UserClient {//String url = "http://localhost:8083/user/info/"+userId;@GetMapping("/user/info/{userId}")JsonResult<UserInfoVO> getUserInfo(@PathVariable("userId") Long userId);}
JsonResult是响应的返回体,这边我限制了其返回数据为UserInfoVo
package cn.tedu.chaging.common.web;import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;/*** //状态码 自定义的码 2000 表示成功 2001 表示失败* //提示消息 保存失败* //具体的数据 比如查询订单 需要把查出的订单数据返回给前端*/
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class JsonResult<T> {/*** 状态码*/Integer code;/*** 提示消息*/String msg;/*** 具体的数据*/T data;/*** 正常返回 入参 有数据和消息* @param data* @param msg* @return*/public static JsonResult ok(Object data,String msg) {JsonResult jsonResult = new JsonResult();jsonResult.setCode(2000);jsonResult.setData(data);jsonResult.setMsg(msg);return jsonResult;}/*** 正常返回 入参只有数据* @param data* @return*/public static JsonResult ok(Object data) {JsonResult jsonResult = new JsonResult();jsonResult.setCode(2000);jsonResult.setData(data);return jsonResult;}
}
其请求参数 UserId
响应参数获取CarId
package cn.tedu.chaging.common.pojo;import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;/*** 用户基本*/
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserInfoVO {/*** 车辆id*/Integer carId;}
SpringCloud
请求调用
调用代理对象的方法时,实际上是在触发Feign预先设定好的HTTP请求逻辑。传入的参数会被填入到URL模板中,形成完整的HTTP请求。
我是用nacos进行服务注册的,其中我在application.yml文件写了注册名和注册地址,
为了之后的订单服务能够选择调用用户服务,可以用户服务可以改接口再次启动
order-charging包下的application.yamlspring:application:name: orderServicecloud:nacos:server-addr: 127.0.0.1:8848
user-charging包下的application.yaml
server:port: 8086
spring:application:# 服务名称 这个会在nacos服务列表里显示name: userServicecloud:nacos:#服务注册地址server-addr: 127.0.0.1:8848
HTTP请求
请求发送
Feign利用Ribbon进行负载均衡选择目标服务器,然后通过HTTP客户端(如Apache HttpClient或OkHttp)发送实际的HTTP请求。
测试一下传入参数
package cn.tedu.charging.order;import cn.tedu.chaging.common.web.JsonResult;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.pojo.dto.CarInfoDto;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class FeignTests {@Autowiredprivate UserClient userClient;@Testpublic void testGetUserInfo(){JsonResult userInfo =userClient.getUserInfo(1L);System.out.println(userInfo);}
}
响应处理
收到HTTP响应后,Feign会根据配置的解码器将其解析成相应的Java对象,然后返回给调用者。
OrderService 中Service层调用Feign返回响应数据
/*** 通过feign的方式调用用户服务* @param userId* @return*/private CarInfoDto getCarInfoByFeign(Long userId){JsonResult<UserInfoVO> userInfo = userClient.getUserInfo(userId);if (userInfo != null) {UserInfoVO data = userInfo.getData();if (data != null) {CarInfoDto carInfoDto = new CarInfoDto();BeanUtils.copyProperties(data, carInfoDto);return carInfoDto;}}return null;}
容错与熔断
Feign可以与Hystrix配合,通过设置开启熔断功能,当服务出现故障时,可以快速失败,避免连锁反应影响整个系统的稳定性。
总结
Feign的负载均衡实现主要依赖于Ribbon组件,Ribbon是一个客户端负载均衡器,而Feign则集成了Ribbon,因此当我们在Spring Cloud应用中使用Feign进行服务间调用时,自然具备了负载均衡的能力.