Spring Cloud feign的底层代码分析,以及feign本地调用方法。

        最近几天研究了下springCloud feign的底层源码~feign的核心就是注解@EnableFeignClients

点进去可以看到是一个组合注解,如下图:

        可以看到这里注入了一个类,@Import({FeignClientsRegistrar.class})。接下来点进这个类,底层核心逻辑也都在这个类里面。

类中我看来比较重要的两个方法是:registerFeignClients和registerFeignClient,这两个方法名有点神似,从英文的解释来看都是注册feign客户端,但是一个是单数,一个是复数。registerFeignClients方法会扫描@EnableFeignClients注解的basePackages(默认是当前目录和子包,和spring自动装配一样,也可以自定义即配置basePackages),注册所有的FeignClient。registerFeignClient()是对单个FeignClient注册的方法。

下面是registerFeignClients方法,我直接cv了代码然后在代码上做了一些注释。

public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    LinkedHashSet<BeanDefinition> candidateComponents = new LinkedHashSet<>();
    Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());
    // 获取clients属性
    final Class<?>[] clients = attrs == null ? null : (Class<?>[]) attrs.get("clients");
    if (clients == null || clients.length == 0) {
        // 如果clients属性为null,则获取basePackages属性,扫描其中的所有client
        ClassPathScanningCandidateComponentProvider scanner = getScanner();
        scanner.setResourceLoader(this.resourceLoader);
        scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
        Set<String> basePackages = getBasePackages(metadata);
        for (String basePackage : basePackages) {
            candidateComponents.addAll(scanner.findCandidateComponents(basePackage));
        }
    } else {
        // 如果clients属性不为null,则直接注入
        for (Class<?> clazz : clients) {
            candidateComponents.add(new AnnotatedGenericBeanDefinition(clazz));
        }
    }
    // 遍历所有的clients,将其封装为BeanDefinition注册进Spring容器中
    for (BeanDefinition candidateComponent : candidateComponents) {
        if (candidateComponent instanceof AnnotatedBeanDefinition) {
            AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
            AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
            Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
    
            Map<String, Object> attributes = annotationMetadata
                .getAnnotationAttributes(FeignClient.class.getCanonicalName());
    
            String name = getClientName(attributes);
            registerClientConfiguration(registry, name, attributes.get("configuration"));
    
            registerFeignClient(registry, annotationMetadata, attributes);
        }
    }
}

    }

简单来说就是下面的几步:

1、获得EnableFeignClients注解上面的属性,然后判断里面的clients属性,如果为null则开始扫描,如果不为null则直接注入

2、遍历所有的client,进行验证是否是使用在接口上,然后进行注册,也就是调用registerFeignClient方法

下面是对应的registerFeignClient方法:

private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
        String className = annotationMetadata.getClassName();
        Class clazz = ClassUtils.resolveClassName(className, (ClassLoader)null);
        ConfigurableBeanFactory beanFactory = registry instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory)registry : null;
        String contextId = this.getContextId(beanFactory, attributes);
        String name = this.getName(attributes);
        FeignClientFactoryBean factoryBean = new FeignClientFactoryBean();
        factoryBean.setBeanFactory(beanFactory);
        factoryBean.setName(name);
        factoryBean.setContextId(contextId);
        factoryBean.setType(clazz);
        factoryBean.setRefreshableClient(this.isClientRefreshEnabled());
        BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> {
            factoryBean.setUrl(this.getUrl(beanFactory, attributes));
            factoryBean.setPath(this.getPath(beanFactory, attributes));
            factoryBean.setDecode404(Boolean.parseBoolean(String.valueOf(attributes.get("decode404"))));
            Object fallback = attributes.get("fallback");
            if (fallback != null) {
                factoryBean.setFallback(fallback instanceof Class ? (Class)fallback : ClassUtils.resolveClassName(fallback.toString(), (ClassLoader)null));
            }

            Object fallbackFactory = attributes.get("fallbackFactory");
            if (fallbackFactory != null) {
                factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class)fallbackFactory : ClassUtils.resolveClassName(fallbackFactory.toString(), (ClassLoader)null));
            }

            return factoryBean.getObject();
        });
        definition.setAutowireMode(2);
        definition.setLazyInit(true);
        this.validate(attributes);
        AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
        beanDefinition.setAttribute("factoryBeanObjectType", className);
        beanDefinition.setAttribute("feignClientsRegistrarFactoryBean", factoryBean);
        boolean primary = (Boolean)attributes.get("primary");
        beanDefinition.setPrimary(primary);
        String[] qualifiers = this.getQualifiers(attributes);
        if (ObjectUtils.isEmpty(qualifiers)) {
            qualifiers = new String[]{contextId + "FeignClient"};
        }

        BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, qualifiers);
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
        this.registerOptionsBeanDefinition(registry, contextId);
    }

可以看到cv的我没写什么注释,主要是这段代码逻辑很清晰,主要就是将扫描到的BeanDefinition中的元信息提取出来,然后构造成一个FeignClientFactoryBean,后面我们每次获取容器中的FeignClient时,就会通过该FactoryBean的getObject()方法中获取。

        以上就是我的大致理解,仅代表个人看法。下面讲一下我看完后整的花活思路(没整成功)。

        使用feign的时候我们大多时候需要在本地调试,一般的话都是这样@FeignClient(name="***",url="***")但是不够优雅,因为部署的时候容易忘记去掉然后导致问题的发生。优雅点的会使用占位符这样@FeignClient(name = "****", url = "${my.feign.client.url}")需要在本地测试环境的配置文件加属性,生产也要加(但是需要没有值否则会报错)。

        但是我个人觉得还是不够优雅,我想不需要动配置文件也可以实现。然后开始了花活,其实没啥必要,最后还失败了。。。。

        我的思路,在看源码的时候发现有没有配置url和方法factoryBean.getObject()相关,然后这个里面有套娃了下面方法:

<T> T getTarget() {
        FeignContext context = this.beanFactory != null ? (FeignContext)this.beanFactory.getBean(FeignContext.class) : (FeignContext)this.applicationContext.getBean(FeignContext.class);
        Feign.Builder builder = this.feign(context);
        if (!StringUtils.hasText(this.url)) {
            if (LOG.isInfoEnabled()) {
                LOG.info("For '" + this.name + "' URL not provided. Will try picking an instance via load-balancing.");
            }

            if (!this.name.startsWith("http")) {
                this.url = "http://" + this.name;
            } else {
                this.url = this.name;
            }

            this.url = this.url + this.cleanPath();
            return this.loadBalance(builder, context, new Target.HardCodedTarget(this.type, this.name, this.url));
        } else {
            if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
                this.url = "http://" + this.url;
            }

            String url = this.url + this.cleanPath();
            Client client = (Client)this.getOptional(context, Client.class);
            if (client != null) {
                if (client instanceof FeignBlockingLoadBalancerClient) {
                    client = ((FeignBlockingLoadBalancerClient)client).getDelegate();
                }

                if (client instanceof RetryableFeignBlockingLoadBalancerClient) {
                    client = ((RetryableFeignBlockingLoadBalancerClient)client).getDelegate();
                }

                builder.client(client);
            }

            this.applyBuildCustomizers(context, builder);
            Targeter targeter = (Targeter)this.get(context, Targeter.class);
            return targeter.target(this, builder, context, new Target.HardCodedTarget(this.type, this.name, url));
        }
    }

仔细看过这个方法就会发现最后都会在容器中拿一个Targeter的bean然后调用方法targeter返回。于是我就想我能不能改变容器中的bean,让他固定返回本地的url。于是就写了下面的代码:

package com.ruoyi.job.config;

import feign.Feign;
import feign.Target;
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.Targeter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeighConfig {

    @Bean
    public Targeter getTargeter() {
        return new Targeter() {
            @Override
            public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) {
                /*
                 * 为了实现本地调试绕过nacos配置,增加了一个对本地环境变量的解析
                 * 使用方法:-Droute.fuxi-basic=http://127.0.0.1:9201
                 */
                String systemRouter = System.getProperty("route." + target.name());
                if (systemRouter != null) {
//                    logger.info("use systemRouter for:" + target.name());
                    System.out.println("------------------use systemRouter for:" + target.name());
                    systemRouter += target.url().substring(target.url().indexOf(target.name()) + target.name().length());
                    return feign.target(new Target.HardCodedTarget<T>(target.type(), target.name(), systemRouter));
                }
                return feign.target(target);
            }
        };
    }
}

        通过虚拟机启动配置拿的值,我认为比较优雅。就在我认为ok的时候报错了

15:49:13.367 [http-nio-9203-exec-1] WARN  o.s.c.l.c.ServiceInstanceListSupplierBuilder - [lambda$withCaching$11,248] - LoadBalancerCacheManager not available, returning delegate without caching.
15:49:13.702 [http-nio-9203-exec-1] ERROR o.s.c.l.c.DiscoveryClientServiceInstanceListSupplier - [logException,113] - Exception occurred while retrieving instances for service 127.0.0.1
java.lang.RuntimeException: Can not get hosts from nacos server. serviceId: 127.0.0.1
	at com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient.getInstances(NacosDiscoveryClient.java:72)
	at org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient.getInstances(CompositeDiscoveryClient.java:54)
	at org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.lambda$new$0(DiscoveryClientServiceInstanceListSupplier.java:64)
	at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:57)
	at reactor.core.publisher.FluxFromMonoOperator.subscribe(FluxFromMonoOperator.java:83)
	at reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4490)
	at reactor.core.publisher.Mono.block(Mono.java:1741)
	at org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.choose(BlockingLoadBalancerClient.java:178)
	at org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient.execute(FeignBlockingLoadBalancerClient.java:97)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:121)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:91)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
	at com.sun.proxy.$Proxy110.aaa(Unknown Source)
	at com.ruoyi.job.controller.SysJobController.sss(SysJobController.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:750)
Caused by: com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING
	at com.alibaba.nacos.common.remote.client.RpcClient.request(RpcClient.java:639)
	at com.alibaba.nacos.common.remote.client.RpcClient.request(RpcClient.java:619)
	at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.requestToServer(NamingGrpcClientProxy.java:356)
	at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.doSubscribe(NamingGrpcClientProxy.java:310)
	at com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy.subscribe(NamingGrpcClientProxy.java:295)
	at com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate.subscribe(NamingClientProxyDelegate.java:173)
	at com.alibaba.nacos.client.naming.NacosNamingService.selectInstances(NacosNamingService.java:311)
	at com.alibaba.nacos.client.naming.NacosNamingService.selectInstances(NacosNamingService.java:281)
	at com.alibaba.nacos.client.naming.NacosNamingService.selectInstances(NacosNamingService.java:269)
	at com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery.getInstances(NacosServiceDiscovery.java:58)
	at com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient.getInstances(NacosDiscoveryClient.java:62)
	... 68 common frames omitted
15:49:13.708 [http-nio-9203-exec-1] WARN  o.s.c.l.c.RoundRobinLoadBalancer - [getInstanceResponse,98] - No servers available for service: 127.0.0.1
15:49:13.710 [http-nio-9203-exec-1] WARN  o.s.c.o.l.FeignBlockingLoadBalancerClient - [execute,103] - Load balancer does not contain an instance for the service 127.0.0.1
15:49:13.734 [http-nio-9203-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - [log,175] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException$ServiceUnavailable: [503] during [GET] to [http://127.0.0.1:8000/gen/aa] [RuoYiGenClient#aaa()]: [Load balancer does not contain an instance for the service 127.0.0.1]] with root cause
feign.FeignException$ServiceUnavailable: [503] during [GET] to [http://127.0.0.1:8000/gen/aa] [RuoYiGenClient#aaa()]: [Load balancer does not contain an instance for the service 127.0.0.1]
	at feign.FeignException.serverErrorStatus(FeignException.java:256)
	at feign.FeignException.errorStatus(FeignException.java:197)
	at feign.FeignException.errorStatus(FeignException.java:185)
	at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92)
	at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:98)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:141)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:91)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
	at com.sun.proxy.$Proxy110.aaa(Unknown Source)
	at com.ruoyi.job.controller.SysJobController.sss(SysJobController.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:750)

大致意思就是没在nacos找到对应实例,但是被调用服务是正常的。打断点看对应的target路径确实被改动成了127.0.0.1但是不知道为啥会报这个错误。有大神还知道可以似下我。谢谢。后来试了下初始化bean的时候直接就去修改注解中的url值,替换成功了但是不知道为什么还是走的轮询,很奇怪

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值