当前位置:   article > 正文

feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务_feignclient url 配置文件

feignclient url 配置文件

最近接手一个项目,各子工程之间通过feign调用;各服务部署在K8S上,通过nacos管理配置;由于服务部署的机器无法开放端口等原因,导致本机服务与测试环境网络端口无法互通,故需要重写feign的调用地址;个人总结的方法有以下几种:

目录

 第一种:feignclient配置URL

第二种:实现RequestInterceptor接口;

第三种:重写feign的client的execute方法;


 第一种:feignclient配置URL

        在feignclient里写一个固定地址或者写一个可配置的地址,这样可以在配置文件里指定,这种方式在创建feign客户端的时候就需要规划好。

        1.1 固定地址

  1. @FeignClient(name = "feignCustomerService", url = "http://localhost:8080")
  2. public interface FeignCustomerService {
  3. /**
  4. * 请求客户的接口
  5. */
  6. @RequestMapping(value = "order/update", method = RequestMethod.POST)
  7. @Headers(value = "Content-Type: application/json")
  8. OrderHttpResponse updateOrder(@RequestBody OrderUpdateDTO orderUpdateDTO);
  9. }

1.2 可配置的地址

  1. @FeignClient(name = "feignCustomerService", url = "${customer.url}")
  2. public interface FeignCustomerService {
  3. @RequestMapping(value = "test/list", method = RequestMethod.POST)
  4. @Headers(value = "Content-Type: application/json")
  5. OrderHttpResponse updateTest(@RequestBody OrderUpdateDTO orderUpdateDTO);
  6. }

配置文件配置地址

customer.url=http://localhost:8080

第二种:实现RequestInterceptor接口;

        这种方式具有局限性,在nacos上注册的服务IP与本机IP不一致的时候(连接VPN)可能依旧调不通服务,但是实现RequestInterceptor接口可以处理全局请求(header,身份认证等)

  1. @Component
  2. public class Oauth2TokenRequestInterceptor implements RequestInterceptor {
  3. @Override
  4. public void apply(RequestTemplate requestTemplate) {
  5. // 获取请求中的消息头
  6. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  7. HttpServletRequest request = attributes.getRequest();
  8. String requestHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
  9. if (StringUtils.isNotBlank(requestHeader) && requestHeader.startsWith("Bearer ")) {
  10. // 将消息头塞入到请求模板中
  11. requestTemplate.header(HttpHeaders.AUTHORIZATION, requestHeader);
  12. }
  13. //重写URL,访问指定服务
  14. String url = target.url();
  15. String newUrl = "http://localhost:8080";
  16. template.target(newUrl );
  17. }
  18. }

第三种:重写feign的client的execute方法;

        这种方式可以自定义负载均衡的策略,也可以自定义访问指定服务IP,这里以FeignBlockingLoadBalancerClient为例

配置类

  1. package com.***.redirect;
  2. import lombok.Getter;
  3. import lombok.Setter;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.cloud.context.config.annotation.RefreshScope;
  6. import org.springframework.stereotype.Component;
  7. import java.util.Map;
  8. @Getter
  9. @Setter
  10. @RefreshScope
  11. @ConfigurationProperties("localbalance")
  12. @Component
  13. public class LocalFeignPerpreties {
  14. private Boolean enable;
  15. private Map<String,String> rule;
  16. }

配置文件配置内容:

  1. localbalance:
  2. enable: true
  3. rule:
  4. aiflow-sys: http://IP:8888/SERVICE
  5. aiflow-auth: http://IP:8888/SERVICE

重写FeignBlockingLoadBalancerClient 的execute方法

  1. package com.***.redirect;
  2. import feign.Client;
  3. import feign.Request;
  4. import feign.RequestTemplate;
  5. import feign.Response;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.apache.commons.lang3.StringUtils;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
  10. import org.springframework.cloud.client.ServiceInstance;
  11. import org.springframework.cloud.client.discovery.DiscoveryClient;
  12. import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
  13. import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
  14. import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
  15. import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
  16. import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
  17. import org.springframework.context.annotation.Primary;
  18. import org.springframework.util.Assert;
  19. import org.springframework.web.context.request.RequestContextHolder;
  20. import org.springframework.web.context.request.ServletRequestAttributes;
  21. import org.springframework.web.util.UriComponentsBuilder;
  22. import javax.servlet.http.HttpServletRequest;
  23. import java.io.IOException;
  24. import java.net.URI;
  25. import java.net.URLEncoder;
  26. import java.nio.charset.Charset;
  27. import java.util.*;
  28. //@ConditionalOnBean
  29. //@Primary
  30. @Slf4j
  31. public class LocalBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient {
  32. private Client delegate;
  33. private BlockingLoadBalancerClient loadBalancerClient;
  34. @Autowired
  35. private LocalFeignPerpreties localFeignPerpreties;
  36. public LocalBlockingLoadBalancerClient(Client delegate,
  37. BlockingLoadBalancerClient loadBalancerClient) {
  38. super(delegate, loadBalancerClient);
  39. this.delegate = delegate;
  40. this.loadBalancerClient = loadBalancerClient;
  41. }
  42. @Override
  43. public Response execute(Request request, Request.Options options) throws IOException {
  44. try {
  45. log.info("feign -> 配置化客户端");
  46. Boolean enable = localFeignPerpreties.getEnable();
  47. if (enable) {
  48. String url = request.url();
  49. RequestTemplate requestTemplate = request.requestTemplate();
  50. String name = requestTemplate.feignTarget().name();
  51. Map<String, String> urlMap = localFeignPerpreties.getRule();
  52. if (urlMap != null && urlMap.containsKey(name)) {
  53. URI uri = URI.create(url);
  54. StringBuffer strbuf = new StringBuffer();
  55. strbuf.append(urlMap.get(name)).append(uri.getPath());
  56. if (StringUtils.isNotBlank(uri.getQuery())) {
  57. strbuf.append("?").append(uri.getQuery());
  58. }
  59. requestTemplate.target(urlMap.get(name));
  60. Map<String, Collection<String>> headers = request.headers();
  61. Map<String, Collection<String>> newheaders = new HashMap<>();
  62. //处理请求头
  63. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  64. HttpServletRequest attributesRequest = attributes.getRequest();
  65. Enumeration<String> headerNames = attributesRequest.getHeaderNames();
  66. if (headerNames != null) {
  67. while (headerNames.hasMoreElements()) {
  68. String element = headerNames.nextElement();
  69. String elementVal = attributesRequest.getHeader(element);
  70. newheaders.put(element, new ArrayList<String>() {{
  71. add(elementVal);
  72. }});
  73. }
  74. }
  75. //构建新的request
  76. Request newRequest = buildRequest(request, strbuf.toString(), newheaders);
  77. return super.getDelegate().execute(newRequest, options);
  78. }
  79. }
  80. } catch (Exception e) {
  81. e.printStackTrace();
  82. }
  83. log.info("feign -> 默认客户端");
  84. return super.execute(request, options);
  85. }
  86. protected Request buildRequest(Request request,
  87. String reconstructedUrl,
  88. Map<String, Collection<String>> headers) {
  89. return Request.create(request.httpMethod(), reconstructedUrl, headers,
  90. request.body(), Charset.forName("UTF-8"), request.requestTemplate());
  91. }
  92. }

使配置类和重写的client生效

  1. package com.***.redirect;
  2. import feign.Client;
  3. import org.springframework.boot.context.properties.EnableConfigurationProperties;
  4. import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. //@ConditionalOnProperty(prefix = ReBalancerProperties.prefix,name = "enable",havingValue = "true")
  8. @Configuration
  9. @EnableConfigurationProperties(value = {LocalFeignPerpreties.class})
  10. public class ReBalancerConfiguration {
  11. @Bean
  12. public Client feignReBalancer(BlockingLoadBalancerClient discoveryClient) {
  13. return new LocalBlockingLoadBalancerClient(new Client.Default(null, null),
  14. discoveryClient);
  15. }
  16. }

        到这里基本上可以满足重写feign URL的需求了,这个前提条件是代码在application启动类的下一级,如果不在启动类的同级或者下一级,是无法扫描到相关类的,这时我们可以注解完成扫描,需要在启动类上加上相关注解

  1. package com.***.annotation;
  2. import com.***.ReBalancerConfiguration;
  3. import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
  4. import org.springframework.context.annotation.Import;
  5. import java.lang.annotation.ElementType;
  6. import java.lang.annotation.Retention;
  7. import java.lang.annotation.RetentionPolicy;
  8. import java.lang.annotation.Target;
  9. @Target({ElementType.TYPE})
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Import(ReBalancerConfiguration.class)
  12. @AutoConfigurationPackage
  13. public @interface EnableLocalFeignClient {
  14. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/96586
推荐阅读
相关标签
  

闽ICP备14008679号