研发提速:nacos+openfeign环境下的本地链接服务

打印 上一主题 下一主题

主题 853|帖子 853|积分 2559

项目研发过程中,经常会遇到与测试人员工作重叠的情况,十分影响效率。
做了一个修改,可以在本地环境启动项目后和测试环境交互,并且不影响测试环境,理论上也可以用于线上环境的异常的快速处理。
准备事项如下:
一:搭建本地的nacos服务。
二:导入测试环境相应项目的nacos配置文件。
三:新增代码:
修改LoadBalancerFactory获取服务host的方式,由于是本地启动的项目,并且连接的还是本地的nacos,所以项目启动后,肯定不会注册到测试环境,相对的也获取不到测试环境的其他服务。
由于本人使用的时候是基于CachingSpringLoadBalancerFactory ,如果直接使用时不生效或者异常,可以DEBUG跟踪一下自己框架调用服务时使用的具体LoadBalancerFactory类。
  1.   3 import cn.hutool.http.HttpUtil;
  2.   4 import com.alibaba.fastjson.JSON;
  3.   5 import com.alibaba.fastjson.JSONArray;
  4.   6 import com.alibaba.fastjson.JSONObject;
  5.   7 import com.netflix.client.config.IClientConfig;
  6.   8 import com.netflix.loadbalancer.ILoadBalancer;
  7.   9 import com.netflix.loadbalancer.Server;
  8. 10 import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
  9. 11 import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
  10. 12 import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
  11. 13 import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
  12. 14 import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;
  13. 15 import org.springframework.cloud.openfeign.ribbon.RetryableFeignLoadBalancer;
  14. 16 import org.springframework.util.ConcurrentReferenceHashMap;
  15. 17 import org.springframework.util.ObjectUtils;
  16. 18
  17. 19 import java.util.ArrayList;
  18. 20 import java.util.List;
  19. 21 import java.util.Map;
  20. 22
  21. 23 public class DevCachingSpringLoadBalancerFactory extends CachingSpringLoadBalancerFactory {
  22. 24
  23. 25     private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();
  24. 26     private volatile Map<String, List<Server>> server = new ConcurrentReferenceHashMap<>();
  25. 27     private volatile String ip;
  26. 28     private volatile String port;
  27. 29     private volatile String namespaceid;
  28. 30
  29. 31     public DevCachingSpringLoadBalancerFactory(SpringClientFactory factory) {
  30. 32         super(factory);
  31. 33     }
  32. 34
  33. 35     public DevCachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) {
  34. 36         super(factory, loadBalancedRetryPolicyFactory);
  35. 37     }
  36. 38
  37. 39     public boolean initialize(String ip,String port,String namespaceid) {
  38. 40         this.ip = ip;
  39. 41         this.port = port;
  40. 42         this.namespaceid = namespaceid;
  41. 43         return null != ip ? null != port ?  null != namespaceid ? true : false :false :false;
  42. 44     }
  43. 45
  44. 46     @Override
  45. 47     public FeignLoadBalancer create(String clientName) {
  46. 48         FeignLoadBalancer client = this.cache.get(clientName);
  47. 49         if (client != null) {
  48. 50             return client;
  49. 51         }
  50. 52         IClientConfig config = this.factory.getClientConfig(clientName);
  51. 53         ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
  52. 54
  53. 55         //修改部分
  54. 56         List<Server> list = lb.getAllServers();
  55. 57         if (null == list || ObjectUtils.isEmpty(list)) list = new ArrayList<>();
  56. 58         list.addAll(Servers(clientName));
  57. 59         lb.addServers(list);
  58. 60
  59. 61         ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,
  60. 62                 ServerIntrospector.class);
  61. 63         client = this.loadBalancedRetryFactory != null
  62. 64                 ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
  63. 65                 this.loadBalancedRetryFactory)
  64. 66                 : new FeignLoadBalancer(lb, config, serverIntrospector);
  65. 67         this.cache.put(clientName, client);
  66. 68         return client;
  67. 69     }
  68. 70
  69. 71     /**
  70. 72      * 获取server
  71. 73      * 返回数组,重试机制交由原框架
  72. 74      * http://ip:port/nacos/v1/ns/instance/list?namespaceId=namespaceid&serviceName=client
  73. 75      */
  74. 76     public List<Server> Servers(String client) {
  75. 77         if(server.containsKey(client)) return server.get(client);
  76. 78         else synchronized (server) {
  77. 79             if(server.containsKey(client)) return server.get(client);
  78. 80             else {
  79. 81                 server.put(client,new ArrayList<Server>());
  80. 82                 String url = new StringBuilder("http://")
  81. 83                         .append(ip)
  82. 84                         .append(":")
  83. 85                         .append(port)
  84. 86                         .append("/nacos/v1/ns/instance/list?")
  85. 87                         .append("namespaceId=")
  86. 88                         .append(namespaceid)
  87. 89                         .append("&serviceName=")
  88. 90                         .append(client).toString();
  89. 91                 JSONObject jsonObject = JSON.parseObject(HttpUtil.get(url));
  90. 92                 JSONArray hosts = jsonObject.getJSONArray("hosts");
  91. 93                 for (int i = 0; i < hosts.size(); i++) {
  92. 94                     server.get(client).add(new Server(hosts.getJSONObject(i).getString("ip"),hosts.getJSONObject(i).getInteger("port")));
  93. 95                 }
  94. 96                 return server.get(client);
  95. 97             }
  96. 98         }
  97. 99     }
  98. 100
  99. 101 }
复制代码
这个文件可以不用添加,主要是用来做一些其他的扩展。
  1. 3 import feign.Client;
  2. 4 import feign.Request;
  3. 5 import feign.Response;
  4. 6 import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
  5. 7 import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
  6. 8 import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
  7. 9
  8. 10 import java.io.IOException;
  9. 11
  10. 12 public class DevFeignClient extends LoadBalancerFeignClient{
  11. 13
  12. 14     public DevFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory, SpringClientFactory clientFactory) {
  13. 15         super(delegate, lbClientFactory, clientFactory);
  14. 16     }
  15. 17
  16. 18     @Override
  17. 19     public Response execute(Request request, Request.Options options) throws IOException {
  18. 20         return super.execute(request, options);
  19. 21     }
  20. 22 }
复制代码
配置文件用来替换原来IOC中的BEAN,另外用于获取后面yml文件中的自定义配置。
  1. <em id="__mceDel"> 3 import feign.Client;
  2. 4 import org.springframework.beans.factory.annotation.Value;
  3. 5 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  4. 6 import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
  5. 7 import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
  6. 8 import org.springframework.context.annotation.Bean;
  7. 9 import org.springframework.context.annotation.Configuration;
  8. 10
  9. 11 @Configuration
  10. 12 public class DevFeignConfig {
  11. 13
  12. 14     @ConditionalOnProperty("feign.dev.enabled")
  13. 15     @Configuration(proxyBeanMethods = false)
  14. 16     class DefaultFeignLoadBalancedConfiguration {
  15. 17         @Value("${feign.dev.ip}")
  16. 18         String ip;
  17. 19         @Value("${feign.dev.port}")
  18. 20         String port;
  19. 21         @Value("${feign.dev.namespaceid}")
  20. 22         String namespaceid;
  21. 23
  22. 24
  23. 25         @Bean
  24. 26         public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, DevCachingSpringLoadBalancerFactory devFactory,
  25. 27                                   SpringClientFactory clientFactory) {
  26. 28             System.out.println("#####################################进入本地调试模式#####################################");
  27. 29             return new DevFeignClient(new Client.Default(null, null),null == devFactory?cachingFactory:devFactory,
  28. 30                     clientFactory);
  29. 31         }
  30. 32
  31. 33         @Bean
  32. 34         public DevCachingSpringLoadBalancerFactory devFactory(SpringClientFactory factory) {
  33. 35             DevCachingSpringLoadBalancerFactory devFactory = new DevCachingSpringLoadBalancerFactory(factory);
  34. 36             if(devFactory.initialize(ip,port,namespaceid)) return devFactory;
  35. 37             System.out.println("#####################################本地调试模式异常#####################################");
  36. 38             System.out.println("feign.dev.ip " + ip);
  37. 39             System.out.println("feign.dev.port " + port);
  38. 40             System.out.println("feign.dev.namespaceid " + namespaceid);
  39. 41             System.out.println("#####################################本地调试模式异常#####################################");
  40. 42             return null;
  41. 43         }
  42. 44     }
  43. 45
  44. 46
  45. 47 }</em>
复制代码
修改yml文件,主要是用来配置新增的自定义属性和小插件的开启和关闭。
建议手动在本地项目的yml文件添加属性,yml文件的配置,直接复制容易出现问题。
新增属性如下:
  1. feign.dev.enabled
复制代码
  1. feign.dev.ip
复制代码
  1. feign.dev.port
复制代码
  1. feign.dev.namespaceid
复制代码
  1. server:
  2.   port: 服务端口号
  3. spring:
  4.   application:
  5.     name: 服务名称
  6.   profiles:
  7.     active: dev
  8.   cloud:
  9.     nacos:
  10.       config:
  11.         file-extension: yml
  12.         namespace: 本地Nacos的命名空间
  13.       username: 本地Nacos的账号
  14.       password: 本地Nacos的密码
  15.       server-addr: 本地Nacos的IP:本地Nacos的端口号
  16.       discovery:
  17.         namespace: 本地Nacos的命名空间
  18.         group: DEFAULT_GROUP
  19.         enabled: true
  20.         register-enabled: true
  21. feign:
  22.   dev:
  23.     #true为开启本地调式,false为关闭
  24.     enabled: false
  25.     ip: 测试环境Nacos的IP
  26.     port: 测试环境Nacos的端口号
  27.     namespaceid:  测试环境Nacos的命名空间
  28.   client:
  29.     config:
  30.       default:
  31.         #不设置connectTimeout会导致readTimeout设置不生效
  32.         connectTimeout: 5000
  33.         readTimeout: 5000
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦见你的名字

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表