美文网首页我爱编程
spring-cloud-gateway使用其他容器遇到的问题

spring-cloud-gateway使用其他容器遇到的问题

作者: wangpeng123 | 来源:发表于2018-06-09 14:30 被阅读0次

    在使用spring-cloud-gateway的时候,想使用其他的web容器,但是会遇到一个报错

    java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
    

    笔者折腾了半天、百度谷歌都没有解决方案,无奈只能去找源头Spencer Gibb 大神问了问。

    image.png

    他说现在只支持默认的NettyWebServer。不支持其他容器。
    但是他也写了一个解决方案,


    image.png

    于是我翻阅了一下他的源码发现这两个bean是注释掉的。
    如果想启用的话只能修改源码,于是我改了一下他的源码GatewayAutoConfiguration这个配置类:

    /*
     * Copyright 2013-2018 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.gateway.config;
    
    import com.netflix.hystrix.HystrixObservableCommand;
    import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.AutoConfigureBefore;
    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.reactive.HttpHandlerAutoConfiguration;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.boot.context.properties.PropertyMapper;
    import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint;
    import org.springframework.cloud.gateway.filter.*;
    import org.springframework.cloud.gateway.filter.factory.*;
    import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
    import org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter;
    import org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter;
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver;
    import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
    import org.springframework.cloud.gateway.handler.FilteringWebHandler;
    import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
    import org.springframework.cloud.gateway.handler.predicate.*;
    import org.springframework.cloud.gateway.route.*;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.cloud.stream.reactive.shaded.rx.RxReactiveStreams;
    import org.springframework.context.ApplicationEventPublisher;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.context.annotation.Primary;
    import org.springframework.http.codec.ServerCodecConfigurer;
    import org.springframework.util.StringUtils;
    import org.springframework.validation.Validator;
    import org.springframework.web.reactive.DispatcherHandler;
    import org.springframework.web.reactive.function.client.WebClient;
    import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
    import org.springframework.web.reactive.socket.client.WebSocketClient;
    import org.springframework.web.reactive.socket.server.WebSocketService;
    import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
    import reactor.core.publisher.Flux;
    import reactor.ipc.netty.http.client.HttpClient;
    import reactor.ipc.netty.http.client.HttpClientOptions;
    import reactor.ipc.netty.options.ClientProxyOptions;
    import reactor.ipc.netty.resources.PoolResources;
    
    import java.util.List;
    import java.util.function.Consumer;
    
    import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.DISABLED;
    import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.FIXED;
    
    /**
     * @author Spencer Gibb
     */
    @Configuration
    @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
    @EnableConfigurationProperties
    @AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
    @AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
    @ConditionalOnClass(DispatcherHandler.class)
    public class GatewayAutoConfiguration {
    
        @Configuration
        @ConditionalOnClass(HttpClient.class)
        protected static class NettyConfiguration {
            @Bean
            @ConditionalOnMissingBean
            public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
                return HttpClient.create(options);
            }
    
            @Bean
            public Consumer<? super HttpClientOptions.Builder> nettyClientOptions(HttpClientProperties properties) {
                return opts -> {
    
                    // configure ssl
                    HttpClientProperties.Ssl ssl = properties.getSsl();
    
                    if (ssl.isUseInsecureTrustManager()) {
                        opts.sslSupport(sslContextBuilder -> {
                            sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
                        });
                    }
    
                    // configure pool resources
                    HttpClientProperties.Pool pool = properties.getPool();
    
                    if (pool.getType() == DISABLED) {
                        opts.disablePool();
                    } else if (pool.getType() == FIXED) {
                        PoolResources poolResources = PoolResources.fixed(pool.getName(),
                                pool.getMaxConnections(), pool.getAcquireTimeout());
                        opts.poolResources(poolResources);
                    } else {
                        PoolResources poolResources = PoolResources.elastic(pool.getName());
                        opts.poolResources(poolResources);
                    }
    
    
                    // configure proxy if proxy host is set.
                    HttpClientProperties.Proxy proxy = properties.getProxy();
                    if (StringUtils.hasText(proxy.getHost())) {
                        opts.proxy(typeSpec -> {
                            ClientProxyOptions.Builder builder = typeSpec
                                    .type(ClientProxyOptions.Proxy.HTTP)
                                    .host(proxy.getHost());
    
                            PropertyMapper map = PropertyMapper.get();
    
                            map.from(proxy::getPort)
                                    .whenNonNull()
                                    .to(builder::port);
                            map.from(proxy::getUsername)
                                    .whenHasText()
                                    .to(builder::username);
                            map.from(proxy::getPassword)
                                    .whenHasText()
                                    .to(password -> builder.password(s -> password));
                            map.from(proxy::getNonProxyHostsPattern)
                                    .whenHasText()
                                    .to(builder::nonProxyHosts);
    
                            return builder;
                        });
                    }
                };
            }
    
            @Bean
            public HttpClientProperties httpClientProperties() {
                return new HttpClientProperties();
            }
    
            //        @Bean
            public NettyRoutingFilter routingFilter(HttpClient httpClient,
                                                    ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
                return new NettyRoutingFilter(httpClient, headersFilters);
            }
    
            //        @Bean
            public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
                return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
            }
    
            @Bean
            public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
                return new ReactorNettyWebSocketClient(options);
            }
        }
    
        @Bean
        public RouteLocatorBuilder routeLocatorBuilder(ConfigurableApplicationContext context) {
            return new RouteLocatorBuilder(context);
        }
    
        @Bean
        @ConditionalOnMissingBean
        public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
            return new PropertiesRouteDefinitionLocator(properties);
        }
    
        @Bean
        @ConditionalOnMissingBean(RouteDefinitionRepository.class)
        public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
            return new InMemoryRouteDefinitionRepository();
        }
    
        @Bean
        @Primary
        public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
            return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
        }
    
        @Bean
        public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
                                                        List<GatewayFilterFactory> GatewayFilters,
                                                        List<RoutePredicateFactory> predicates,
                                                        RouteDefinitionLocator routeDefinitionLocator) {
            return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
        }
    
        @Bean
        @Primary
        //TODO: property to disable composite?
        public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
            return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
        }
    
        @Bean
        public RouteRefreshListener routeRefreshListener(ApplicationEventPublisher publisher) {
            return new RouteRefreshListener(publisher);
        }
    
        @Bean
        public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
            return new FilteringWebHandler(globalFilters);
        }
    
        @Bean
        public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
                                                                         RouteLocator routeLocator) {
            return new RoutePredicateHandlerMapping(webHandler, routeLocator);
        }
    
        // ConfigurationProperty beans
    
        @Bean
        public GatewayProperties gatewayProperties() {
            return new GatewayProperties();
        }
    
        @Bean
        public SecureHeadersProperties secureHeadersProperties() {
            return new SecureHeadersProperties();
        }
    
        // HttpHeaderFilter beans
    
        @Bean
        @ConditionalOnProperty(name = "spring.cloud.gateway.forwarded.enabled", matchIfMissing = true)
        public ForwardedHeadersFilter forwardedHeadersFilter() {
            return new ForwardedHeadersFilter();
        }
    
        @Bean
        public RemoveHopByHopHeadersFilter removeHopByHopHeadersFilter() {
            return new RemoveHopByHopHeadersFilter();
        }
    
        @Bean
        @ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled", matchIfMissing = true)
        public XForwardedHeadersFilter xForwardedHeadersFilter() {
            return new XForwardedHeadersFilter();
        }
    
    
        // GlobalFilter beans
    
        @Bean
        public AdaptCachedBodyGlobalFilter adaptCachedBodyGlobalFilter() {
            return new AdaptCachedBodyGlobalFilter();
        }
    
        @Bean
        public RouteToRequestUrlFilter routeToRequestUrlFilter() {
            return new RouteToRequestUrlFilter();
        }
    
        @Bean
        @ConditionalOnBean(DispatcherHandler.class)
        public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
            return new ForwardRoutingFilter(dispatcherHandler);
        }
    
        @Bean
        public ForwardPathFilter forwardPathFilter() {
            return new ForwardPathFilter();
        }
    
        @Bean
        public WebSocketService webSocketService() {
            return new HandshakeWebSocketService();
        }
    
        @Bean
        public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient,
                                                             WebSocketService webSocketService,
                                                             ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
            return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
        }
    
        @Bean
        public WeightCalculatorWebFilter weightCalculatorWebFilter(@Qualifier("webFluxValidator") Validator validator) {
            return new WeightCalculatorWebFilter(validator);
        }
    
        @Bean
        //TODO: default over netty? configurable
        public WebClientHttpRoutingFilter webClientHttpRoutingFilter() {
            //TODO: WebClient bean
            return new WebClientHttpRoutingFilter(WebClient.builder().build());
        }
    
        @Bean
        public WebClientWriteResponseFilter webClientWriteResponseFilter() {
            return new WebClientWriteResponseFilter();
        }
    
        // Predicate Factory beans
    
        @Bean
        public AfterRoutePredicateFactory afterRoutePredicateFactory() {
            return new AfterRoutePredicateFactory();
        }
    
        @Bean
        public BeforeRoutePredicateFactory beforeRoutePredicateFactory() {
            return new BeforeRoutePredicateFactory();
        }
    
        @Bean
        public BetweenRoutePredicateFactory betweenRoutePredicateFactory() {
            return new BetweenRoutePredicateFactory();
        }
    
        @Bean
        public CookieRoutePredicateFactory cookieRoutePredicateFactory() {
            return new CookieRoutePredicateFactory();
        }
    
        @Bean
        public HeaderRoutePredicateFactory headerRoutePredicateFactory() {
            return new HeaderRoutePredicateFactory();
        }
    
        @Bean
        public HostRoutePredicateFactory hostRoutePredicateFactory() {
            return new HostRoutePredicateFactory();
        }
    
        @Bean
        public MethodRoutePredicateFactory methodRoutePredicateFactory() {
            return new MethodRoutePredicateFactory();
        }
    
        @Bean
        public PathRoutePredicateFactory pathRoutePredicateFactory() {
            return new PathRoutePredicateFactory();
        }
    
        @Bean
        public QueryRoutePredicateFactory queryRoutePredicateFactory() {
            return new QueryRoutePredicateFactory();
        }
    
        @Bean
        public ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {
            return new ReadBodyPredicateFactory(codecConfigurer);
        }
    
        @Bean
        public RemoteAddrRoutePredicateFactory remoteAddrRoutePredicateFactory() {
            return new RemoteAddrRoutePredicateFactory();
        }
    
        @Bean
        @DependsOn("weightCalculatorWebFilter")
        public WeightRoutePredicateFactory weightRoutePredicateFactory() {
            return new WeightRoutePredicateFactory();
        }
    
        // GatewayFilter Factory beans
    
        @Bean
        public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() {
            return new AddRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() {
            return new AddRequestParameterGatewayFilterFactory();
        }
    
        @Bean
        public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() {
            return new AddResponseHeaderGatewayFilterFactory();
        }
    
        @Configuration
        @ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class})
        protected static class HystrixConfiguration {
            @Bean
            public HystrixGatewayFilterFactory hystrixGatewayFilterFactory(DispatcherHandler dispatcherHandler) {
                return new HystrixGatewayFilterFactory(dispatcherHandler);
            }
        }
    
        @Bean
        public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
            return new ModifyRequestBodyGatewayFilterFactory(codecConfigurer);
        }
    
        @Bean
        public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
            return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer);
        }
    
        @Bean
        public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() {
            return new PrefixPathGatewayFilterFactory();
        }
    
        @Bean
        public PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() {
            return new PreserveHostHeaderGatewayFilterFactory();
        }
    
        @Bean
        public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() {
            return new RedirectToGatewayFilterFactory();
        }
    
        @Bean
        public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() {
            return new RemoveRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() {
            return new RemoveResponseHeaderGatewayFilterFactory();
        }
    
        @Bean(name = PrincipalNameKeyResolver.BEAN_NAME)
        @ConditionalOnBean(RateLimiter.class)
        public PrincipalNameKeyResolver principalNameKeyResolver() {
            return new PrincipalNameKeyResolver();
        }
    
        @Bean
        @ConditionalOnBean({RateLimiter.class, KeyResolver.class})
        public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter, PrincipalNameKeyResolver resolver) {
            return new RequestRateLimiterGatewayFilterFactory(rateLimiter, resolver);
        }
    
        @Bean
        public RewritePathGatewayFilterFactory rewritePathGatewayFilterFactory() {
            return new RewritePathGatewayFilterFactory();
        }
    
        @Bean
        public RetryGatewayFilterFactory retryGatewayFilterFactory() {
            return new RetryGatewayFilterFactory();
        }
    
        @Bean
        public SetPathGatewayFilterFactory setPathGatewayFilterFactory() {
            return new SetPathGatewayFilterFactory();
        }
    
        @Bean
        public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
            return new SecureHeadersGatewayFilterFactory(properties);
        }
    
        @Bean
        public SetRequestHeaderGatewayFilterFactory setRequestHeaderGatewayFilterFactory() {
            return new SetRequestHeaderGatewayFilterFactory();
        }
    
        @Bean
        public SetResponseHeaderGatewayFilterFactory setResponseHeaderGatewayFilterFactory() {
            return new SetResponseHeaderGatewayFilterFactory();
        }
    
        @Bean
        public SetStatusGatewayFilterFactory setStatusGatewayFilterFactory() {
            return new SetStatusGatewayFilterFactory();
        }
    
        @Bean
        public SaveSessionGatewayFilterFactory saveSessionGatewayFilterFactory() {
            return new SaveSessionGatewayFilterFactory();
        }
    
        @Bean
        public StripPrefixGatewayFilterFactory stripPrefixGatewayFilterFactory() {
            return new StripPrefixGatewayFilterFactory();
        }
    
        @Bean
        public RequestHeaderToRequestUriGatewayFilterFactory requestHeaderToRequestUriGatewayFilterFactory() {
            return new RequestHeaderToRequestUriGatewayFilterFactory();
        }
    
        @Configuration
        @ConditionalOnClass(Health.class)
        protected static class GatewayActuatorConfiguration {
    
            @Bean
            @ConditionalOnEnabledEndpoint
            public GatewayControllerEndpoint gatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
                                                                       List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
                                                                       RouteLocator routeLocator) {
                return new GatewayControllerEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
            }
        }
    
    }
    

    将NettyRoutingFilter和NettyWriteResponseFilter这两个bean注释掉把GB大神说的WebClientHttpRoutingFilter和WebClientWriteResponseFilter注释放开。启动成功,访问正常。看似解决了,但是偶尔还会报一下错,还是netty的东西,

    o.netty.util.ReferenceCountUtil         : Failed to release a message: DefaultHttpContent(data: PooledUnsafeHeapByteBuf(freed), decoderResult: success)
    
    io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1
      at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:100) ~[netty-buffer-4.1.23.Final.jar!/:4.1.23.Final]
      at 
    

    最后决定暂时不折腾了,只能老老实实用他的NettyWebServer

    相关文章

      网友评论

        本文标题:spring-cloud-gateway使用其他容器遇到的问题

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