美文网首页我爱编程
spring cloud zuul在使用中遇到的坑

spring cloud zuul在使用中遇到的坑

作者: wangpeng123 | 来源:发表于2018-05-22 14:53 被阅读0次

    在使用zuul的时候遇到的坑总结一下:
    逐渐增加更新以后遇到的
    1、在路由的时候莫名其妙的把serviceId给去掉,导致404。比如请求:/serviceId/search/book,zuul会把serviceId去掉,导致匹配不到服务404
    解决办法:
    zuul:
    strip-prefix: false

    因为我们没有设置zuul.prefix 为所有的匹配增加前缀, 例如 /api,代理前缀默认会从请求路径中移除(通过 zuul.stripPrefix=false 可以关闭这个功能)

    当stripPrefix=true的时候 (http://127.0.0.1:8181/api/user/list -> http://192.168.1.100:8080/user/list

    当stripPrefix=false的时候(http://127.0.0.1:8181/api/user/list -> http://192.168.1.100:8080/api/user/list

    设置这个值以后还是出现了404的问题。最后只能自己实现路由映射。
    自定义路由:https://www.jianshu.com/p/647cf467b47c
    2、在zuul的过滤器中,有一个FormBodyWrapperFilter过滤器,在使用resin做web容器时启动会报 ServletRequestWrapper.request field not found
    通过跟踪源码发现resin的ServletRequestWrapper种的request会多一个下划线,导致

    this.servletRequestField = ReflectionUtils.findField(ServletRequestWrapper.class,
                    "request", ServletRequest.class);
    

    找不到servletRequestField。
    解决办法:
    重写ZuulServerAutoConfiguration这个类并注释掉FormBodyWrapperFilter的bean

    /*
     * Copyright 2013-2017 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.cloud.netflix.zuul;
    
    import com.netflix.zuul.FilterLoader;
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.filters.FilterRegistry;
    import com.netflix.zuul.http.ZuulServlet;
    import com.netflix.zuul.monitoring.CounterFactory;
    import com.netflix.zuul.monitoring.TracerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.actuate.metrics.CounterService;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.autoconfigure.web.ErrorController;
    import org.springframework.boot.autoconfigure.web.ServerProperties;
    import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.cloud.client.actuator.HasFeatures;
    import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
    import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
    import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
    import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
    import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator;
    import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
    import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
    import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
    import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter;
    import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter;
    import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter;
    import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter;
    import org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter;
    import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter;
    import org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactory;
    import org.springframework.cloud.netflix.zuul.metrics.EmptyCounterFactory;
    import org.springframework.cloud.netflix.zuul.metrics.EmptyTracerFactory;
    import org.springframework.cloud.netflix.zuul.web.ZuulController;
    import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.Primary;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.core.annotation.Order;
    
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * @author Spencer Gibb
     * @author Dave Syer
     * @author Biju Kunjummen
     */
    @Configuration
    @EnableConfigurationProperties({ZuulProperties.class})
    @ConditionalOnClass(ZuulServlet.class)
    @ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class)
    // Make sure to get the ServerProperties from the same place as a normal web app would
    @Import(ServerPropertiesAutoConfiguration.class)
    public class ZuulServerAutoConfiguration {
    
        @Autowired
        protected ZuulProperties zuulProperties;
    
        @Autowired
        protected ServerProperties server;
    
        @Autowired(required = false)
        private ErrorController errorController;
    
        @Bean
        public HasFeatures zuulFeature() {
            return HasFeatures.namedFeature("Zuul (Simple)", ZuulServerAutoConfiguration.class);
        }
    
        @Bean
        @Primary
        public CompositeRouteLocator primaryRouteLocator(
                Collection<RouteLocator> routeLocators) {
            return new CompositeRouteLocator(routeLocators);
        }
    
        @Bean
        @ConditionalOnMissingBean(SimpleRouteLocator.class)
        public SimpleRouteLocator simpleRouteLocator() {
            return new SimpleRouteLocator(this.server.getServletPrefix(),
                    this.zuulProperties);
        }
    
        @Bean
        public ZuulController zuulController() {
            return new ZuulController();
        }
    
        @Bean
        public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes) {
            ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController());
            mapping.setErrorController(this.errorController);
            return mapping;
        }
    
        @Bean
        public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
            return new ZuulRefreshListener();
        }
    
        @Bean
        @ConditionalOnMissingBean(name = "zuulServlet")
        public ServletRegistrationBean zuulServlet() {
            ServletRegistrationBean servlet = new ServletRegistrationBean(new ZuulServlet(),
                    this.zuulProperties.getServletPattern());
            // The whole point of exposing this servlet is to provide a route that doesn't
            // buffer requests.
            servlet.addInitParameter("buffer-requests", "false");
            return servlet;
        }
    
        // pre filters
    
        @Bean
        public ServletDetectionFilter servletDetectionFilter() {
            return new ServletDetectionFilter();
        }
    
    //    @Bean
    //    public FormBodyWrapperFilter formBodyWrapperFilter() {
    //        return new FormBodyWrapperFilter();
    //    }
    
        @Bean
        public DebugFilter debugFilter() {
            return new DebugFilter();
        }
    
        @Bean
        public Servlet30WrapperFilter servlet30WrapperFilter() {
            return new Servlet30WrapperFilter();
        }
    
        // post filters
    
        @Bean
        public SendResponseFilter sendResponseFilter() {
            return new SendResponseFilter();
        }
    
        @Bean
        public SendErrorFilter sendErrorFilter() {
            return new SendErrorFilter();
        }
    
        @Bean
        public SendForwardFilter sendForwardFilter() {
            return new SendForwardFilter();
        }
    
        @Bean
        @ConditionalOnProperty(value = "zuul.ribbon.eager-load.enabled", matchIfMissing = false)
        public ZuulRouteApplicationContextInitializer zuulRoutesApplicationContextInitiazer(
                SpringClientFactory springClientFactory) {
            return new ZuulRouteApplicationContextInitializer(springClientFactory,
                    zuulProperties);
        }
    
        @Configuration
        protected static class ZuulFilterConfiguration {
    
            @Autowired
            private Map<String, ZuulFilter> filters;
    
            @Bean
            public ZuulFilterInitializer zuulFilterInitializer(
                    CounterFactory counterFactory, TracerFactory tracerFactory) {
                FilterLoader filterLoader = FilterLoader.getInstance();
                FilterRegistry filterRegistry = FilterRegistry.instance();
                return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory, filterLoader, filterRegistry);
            }
    
        }
    
        @Configuration
        @ConditionalOnClass(CounterService.class)
        protected static class ZuulCounterFactoryConfiguration {
    
            @Bean
            @ConditionalOnBean(CounterService.class)
            public CounterFactory counterFactory(CounterService counterService) {
                return new DefaultCounterFactory(counterService);
            }
        }
    
        @Configuration
        protected static class ZuulMetricsConfiguration {
    
            @Bean
            @ConditionalOnMissingBean(CounterFactory.class)
            public CounterFactory counterFactory() {
                return new EmptyCounterFactory();
            }
    
            @ConditionalOnMissingBean(TracerFactory.class)
            @Bean
            public TracerFactory tracerFactory() {
                return new EmptyTracerFactory();
            }
    
        }
    
        private static class ZuulRefreshListener
                implements ApplicationListener<ApplicationEvent> {
    
            @Autowired
            private ZuulHandlerMapping zuulHandlerMapping;
    
            private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();
    
            @Override
            public void onApplicationEvent(ApplicationEvent event) {
                if (event instanceof ContextRefreshedEvent
                        || event instanceof RefreshScopeRefreshedEvent
                        || event instanceof RoutesRefreshedEvent) {
                    this.zuulHandlerMapping.setDirty(true);
                } else if (event instanceof HeartbeatEvent) {
                    if (this.heartbeatMonitor.update(((HeartbeatEvent) event).getValue())) {
                        this.zuulHandlerMapping.setDirty(true);
                    }
                }
            }
    
        }
    
    }
    

    相关文章

      网友评论

        本文标题:spring cloud zuul在使用中遇到的坑

        本文链接:https://www.haomeiwen.com/subject/exghjftx.html