Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。
    Feign则是在Ribbon的基础上进行了一次改进采用接口的方式,将需要Feign客户端请求定义成抽象方法即可,不需要自己构建http请求。 :::info 服务中心由数据团队维护 ::: 略… :::info 生产者实例配置信息 :::

    1. service:
    2. eureka:
    3. instance:
    4. # 标注模块
    5. tagserver:
    6. name: ai-tagserver
    7. context-path: /aiFactoryServer/api/aiTagserver
    8. # 系统模块
    9. system:
    10. name: common-system
    11. context-path: /aiFactoryServer/api/system
    12. context-path2: /aiFactoryServer/system
    13. # 资源模块
    14. resource:
    15. name: ai-resource
    16. context-path: /aiFactoryServer/api/aiResource
    17. # 超市模块
    18. aiSupermarket:
    19. name: ai-supermarket
    20. context-path: /aiFactoryServer/api/aiSupermarket
    21. # 训练模块
    22. trainning:
    23. name: ai-trainning
    24. context-path: /aiFactoryServer/api/aiTraining
    25. # cmdb模块
    26. aiCmdb:
    27. name: ai-cmdb
    28. context-path: /aiFactoryServer/api/aiCmdb
    29. # storage模块
    30. aiStorage:
    31. name: ai-storage
    32. context-path: /aiFactoryServer/api/aiStorage
    33. # gateway模块
    34. gateway:
    35. name: ai-gateway
    36. context-path: /aiFactoryServer/api/aiGateway
    37. # inference模块
    38. inference:
    39. name: ai-inference
    40. context-path: /aiFactoryServer/inference
    41. aiDevCenter:
    42. name: ai-devcenter
    43. context-path: /aiFactoryServer/api/aiDevcenter

    :::info 消费者接口Fegin :::

    1. package com.iwhalecloud.aiFactory.aiResource.system.service;
    2. import com.iwhalecloud.aiFactory.common.util.ResponseUtil;
    3. import com.iwhalecloud.aiFactory.system.service.api.dto.request.UserListRequest;
    4. import com.iwhalecloud.aiFactory.system.service.api.dto.response.UserInfoDto;
    5. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
    6. import org.springframework.cloud.openfeign.FeignClient;
    7. import org.springframework.web.bind.annotation.GetMapping;
    8. import org.springframework.web.bind.annotation.RequestParam;
    9. import org.springframework.web.bind.annotation.PostMapping;
    10. import org.springframework.web.bind.annotation.RequestHeader;
    11. import org.springframework.web.bind.annotation.RequestBody;
    12. import java.util.Map;
    13. @ConditionalOnMissingClass("com.iwhalecloud.aiFactory.system.service.service.UserServiceImpl")
    14. @FeignClient(
    15. value = "${service.eureka.instance.system.name}",
    16. path = "${service.eureka.instance.system.context-path2:''}"
    17. )
    18. public interface YunUserService {
    19. /**
    20. * 使用用户编码+密码方式获取token
    21. * @param user
    22. * @param artifact
    23. * @return
    24. */
    25. @GetMapping("/session/getToken")
    26. ResponseUtil getTokenByArtifact(@RequestParam("user")String user, @RequestParam("artifact")String artifact);
    27. /**
    28. * 使用秘钥+用户编码方式获取token
    29. * @param accountCode
    30. * @param accountPwd
    31. * @return
    32. */
    33. @GetMapping("/session/getToken")
    34. ResponseUtil getTokenByPassword(@RequestParam("accountCode")String accountCode, @RequestParam("accountPwd")String accountPwd);
    35. /**
    36. * 添加新用户,用户类型可为空
    37. * @param appKey
    38. * @param nonce
    39. * @param timestamp
    40. * @param sign
    41. * @param userInfoDto
    42. * @return
    43. */
    44. @PostMapping("/user/saveUserInter")
    45. UserInfoDto saveUserInter(@RequestHeader("x-signature-appkey")String appKey,
    46. @RequestHeader("x-signature-nonce")String nonce,
    47. @RequestHeader("x-signature-timestamp")String timestamp,
    48. @RequestHeader("x-signature-value")String sign,
    49. @RequestHeader("x-signature-sessionid")String sessionId,
    50. @RequestBody UserInfoDto userInfoDto);
    51. /**
    52. * 查询所有用户类型为空的用户信息
    53. * @param appKey
    54. * @param nonce
    55. * @param timestamp
    56. * @param sign
    57. * @param requestParams
    58. * @return
    59. */
    60. @PostMapping("/user/getAllUserTypeIsNull")
    61. Object getAllUserTypeIsNull(@RequestHeader("x-signature-appkey")String appKey,
    62. @RequestHeader("x-signature-nonce")String nonce,
    63. @RequestHeader("x-signature-timestamp")String timestamp,
    64. @RequestHeader("x-signature-value")String sign,
    65. @RequestHeader("x-signature-sessionid")String sessionId,
    66. @RequestBody Map<String, Object> requestParams);
    67. /**
    68. * 为无用户类型账号分配类型
    69. * @param appKey
    70. * @param nonce
    71. * @param timestamp
    72. * @param sign
    73. * @param requestParams
    74. * @return
    75. */
    76. @PostMapping("/user/updateUserTypeByUserIds")
    77. Object updateUserTypeByUserIds(@RequestHeader("x-signature-appkey")String appKey,
    78. @RequestHeader("x-signature-nonce")String nonce,
    79. @RequestHeader("x-signature-timestamp")String timestamp,
    80. @RequestHeader("x-signature-value")String sign,
    81. @RequestHeader("x-signature-sessionid")String sessionId,
    82. @RequestBody Map<String, Object> requestParams);
    83. /**
    84. * 查询用户列表
    85. * @param appKey
    86. * @param nonce
    87. * @param timestamp
    88. * @param sign
    89. * @param sessionId
    90. * @param userListRequest
    91. * @return
    92. */
    93. @GetMapping("/user/listByUserNameOrUserCodeExt")
    94. Object listByUserNameOrUserCodeExt(@RequestHeader("x-signature-appkey")String appKey,
    95. @RequestHeader("x-signature-nonce")String nonce,
    96. @RequestHeader("x-signature-timestamp")String timestamp,
    97. @RequestHeader("x-signature-value")String sign,
    98. @RequestHeader("x-signature-sessionid")String sessionId,
    99. UserListRequest userListRequest);
    100. /**
    101. * 为多个用户添加一个角色
    102. * @param appKey
    103. * @param nonce
    104. * @param timestamp
    105. * @param sign
    106. * @param sessionId
    107. * @param requestParams
    108. * @return
    109. */
    110. @PostMapping("/user/addrel")
    111. ResponseUtil batchAddRoles(@RequestHeader("x-signature-appkey")String appKey,
    112. @RequestHeader("x-signature-nonce")String nonce,
    113. @RequestHeader("x-signature-timestamp")String timestamp,
    114. @RequestHeader("x-signature-value")String sign,
    115. @RequestHeader("x-signature-sessionid")String sessionId,
    116. @RequestBody Map<String, Object> requestParams);
    117. }

    消费者Controller直接调用Feign接口

    1. @Autowire
    2. YunUserService yunUserService;
    3. private ResponseUtil getToken(String userCode, String encryptPwd) {
    4. ResponseUtil tokenResp;
    5. if (Boolean.valueOf(userPassword)) {
    6. tokenResp = yunUserService.getTokenByPassword(userCode, encryptPwd);
    7. }
    8. else {
    9. String yyyyMMddHHmm = DateUtil.formatInputDate(new Date(), "yyyyMMddHHmm");
    10. String artifact = MD5Util.md5Hex(userCode + keyChain + yyyyMMddHHmm);
    11. tokenResp = yunUserService.getTokenByArtifact(userCode, artifact);
    12. }
    13. return tokenResp;
    14. }

    主启动类开启@EnableFeignClients

    1. // 开启远程调用服务
    2. @EnableFeignClients
    3. @SpringBootApplication
    4. public class FeignApplication {
    5. public static void main(String[] args) {
    6. SpringApplication.run(FeignApplication.class, args);
    7. }
    8. }

    :::info Feign的自定义配置 ::: Feign的自定义配置,一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的**@Bean覆盖默认Bean即可。
    Feign的日志级别分为四种:

    • NONE:不记录任何日志信息,默认
    • BASIC:仅记录请求的方法,URL以及响应状态和执行时间
    • HEADERS:在BASIC的基础上,加上请求与响应头信息
    • FULL:记录所有请求和响应的明细,包括头信息、请求体、响应信息,元数据

    基于配置文件修改feign的日志级别

    1. #针对单个服务:
    2. feign:
    3. client:
    4. config:
    5. someservice: # 针对某个微服务的配置
    6. loggerLevel: FULL # 日志级别
    7. #针对针对所有服务
    8. feign:
    9. client:
    10. config:
    11. default: # 这里用default就是全局配置
    12. loggerLevel: FULL # 日志级别

    基于代码方式修改feign的日志级别:
    全局生效放入@EnableFeignClients注解中:@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
    局部生效则放入FeignClients 注解中:@FeignClient(value="userservice", configuration=DefaultFeignConfiguration .class)

    1. import feign.Logger;
    2. import org.springframework.context.annotation.Bean;
    3. public class DefaultFeignConfiguration {
    4. @Bean
    5. public Logger.Level logLevel() {
    6. return Logger.Level.BASIC;
    7. }
    8. }