我想使用 spring cloud 编写一个简单的网关,以便对第三方的请求似乎来自我的服务(就像我过去对 Zuul 所做的那样)。
github 页面上的示例以及官方文档中的示例似乎正是我想要的。即一个简单的控制器路由将所有请求代理到给定路由:
@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
Run Code Online (Sandbox Code Playgroud)
但我遇到的问题是,人工制品spring-cloud-starter-gateway不包括org.springframework.cloud.gateway.mvc.ProxyExchange.
为了获得ProxyExchange,我需要包含spring-cloud-gateway-mvc与spring-cloud-starter-gateway. 将这两个东西放在一起会导致以下错误:
***************************************************
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway
at this time. Please remove spring-boot-starter-web dependency.
***************************************************
Run Code Online (Sandbox Code Playgroud)
因此,我不得不使用以下两个依赖项来使基本网关正常工作:
spring-cloud-gatewayspring-cloud-gateway-mvc哪个工作正常,直到我需要org.springframework.cloud.gateway.filter.*在项目中的其他地方使用这些包,这意味着我需要包括:
spring-cloud-gateway-core, 或者spring-cloud-starter-gateway这意味着我又回到了不兼容横幅。
无论如何,是否可以仅使用spring-cloud-starter-gateway依赖项来使用简单的 …
如何将http呼叫重定向到httpsin spring-cloud-gateway. 我已按照此链接中的说明在我的网关项目中配置了 https 。
现在 HTTPS 网址工作正常,但此外我需要将所有http调用重定向到https. 我试过这个
但这对我不起作用,因为我没有使用默认http端口 8080,而且我的应用程序正在 Spring Security 上运行。
以下代码显示了如何重定向http到https,但我需要相同的Netty服务器配置,因为spring-cloud-gateway仅支持 netty ..
@Configuration
public class RedirectToHttpsConfig {
@Value("${server.port}")
private Integer httpsPort;
@Value("${server.http.port}")
private Integer httpPort;
/* ################ THIS WILL WORK FINE ################
################ IF YOU HAVE TOMCAT ################
################ AS EMBEDDED SERVER ################
*/
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new …Run Code Online (Sandbox Code Playgroud) Host我需要 Spring Cloud Gateway 根据标头或路径前缀将请求路由到微服务。在任何情况下,都必须从路径中删除路径前缀,但前提是已设置路径前缀。
我想出了以下代码,我认为只有“sip”是前缀:
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.host("sip")
.or()
.path("/sip/**")
.filters(f -> f.stripPrefix(1))
.uri("http://sip:8080")
)
.build();
}
Run Code Online (Sandbox Code Playgroud)
问题是 Spring 会删除路径的第一段,即使它不是前缀。
例如,具有路径的请求/sip/calls会成功,但/calls设置了 Host 标头则不会成功,因为 Spring 会考虑/calls前缀并将其删除,从而导致路径为空。/calls/calls带有标头的路径Host会成功,因为 Spring 仅删除第一个calls路径段。
如何一起使用主机和路径,仅在与定义的值匹配时才删除前缀?
ps 我正在考虑每个服务有两条路线,但它看起来不太好,尽管它实现了目标:
.route(r -> r.header("Host", "form").uri("http://form:8080"))
.route(r -> r.path("/form/**")
.filters(f -> f.stripPrefix(1))
.uri("http://form:8080"))
Run Code Online (Sandbox Code Playgroud) 我在使用consul作为服务发现的微服务设置中将spring cloud网关用作API网关。
在某些情况下,某些微服务的API需要2分钟以上的时间,网关会抛出以下错误:
java.io.IOException: Connection closed prematurely
at reactor.ipc.netty.http.client.HttpClientOperations.onInboundClose(HttpClientOperations.java:269)
at reactor.ipc.netty.channel.ChannelOperationsHandler.channelInactive(ChannelOperationsHandler.java:113)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:420)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:377)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:342)
at io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:282)
at io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:223)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1429)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:947)
at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:313)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
我多次尝试了相同的API,恰好在2分钟后收到此错误。
是否有任何属性设置。版本和依赖项详细信息:
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile('org.springframework.cloud:spring-cloud-starter-gateway')
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
springBootVersion=2.0.3.RELEASE
springDMPVersion=1.0.4.RELEASE
springPlatformBomVersion=Cairo-SR2
Run Code Online (Sandbox Code Playgroud)
功能区设置:
ribbon:
ConnectTimeout: 3000
ReadTimeout: 3000
Run Code Online (Sandbox Code Playgroud) java spring-boot spring-cloud netflix-ribbon spring-cloud-gateway
我一直在从下面提到的三个 API 网关中选择一个 API 网关:
我的要求是:
所有这三个,从功能列表和性能方面看起来都不错。我正在考虑放宽第二个要求,因为我不确定这是否是一个好的做法。
我在 spring 云网关中遇到了一个非常奇特的问题。每个备用请求都会返回 404。这发生在我在 api-gateway 中配置的所有服务中,无一例外。我什至不知道从哪里开始调试这个问题。
这是我用于通用配置的 application.yml 文件。
server:
port: 8080
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: pkcs12
key-alias: tomcat
security:
require-ssl=true:
logging:
level:
org:
springframework:
cloud.gateway: DEBUG
http.server.reactive: DEBUG
web.reactive: DEBUG
spring:
application:
name: api-gateway
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
Run Code Online (Sandbox Code Playgroud)
这是我的java配置文件
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
ReactiveClientRegistrationRepository clientRegistrationRepository) {
// Authenticate through configured OpenID Provider
http.oauth2Login();
// Also logout at the OpenID Connect provider
http.logout(logout -> logout.logoutSuccessHandler(new OidcClientInitiatedServerLogoutSuccessHandler(
clientRegistrationRepository)));
// …Run Code Online (Sandbox Code Playgroud) 这是我第一次使用 Spring Cloud Gateway 实现。
我需要过滤每个请求并在某些路径上应用过滤器验证。按照 Baeldung 自定义过滤器教程,我制作了一个简单的应用程序来过滤请求。
应用程序必须释放路径,/actuator/health并验证后端服务的特定路径。到目前为止,我已经实现了 aGlobalFilter和 a GatewayFilterFactory。每个请求都会调用全局过滤器,但在应用程序启动时只调用一次 GatewayFilter,这样我就无法对每个请求进行身份验证。身份验证逻辑是关于特定的头字段。所以,我的颗粒化问题是:
全局过滤器
@Component
public class LoggingGlobalPreFilter implements GlobalFilter {
final Logger LOGGER = LoggerFactory.getLogger(LoggingGlobalPreFilter.class);
@Override
public Mono<Void> filter(
ServerWebExchange exchange,
GatewayFilterChain chain) {
LOGGER.info("Global Pre Filter executed");
return chain.filter(exchange);
}
}
Run Code Online (Sandbox Code Playgroud)
网关过滤器
@Component
public class LoggingGatewayFilterFactory extends
AbstractGatewayFilterFactory<LoggingGatewayFilterFactory.Config> {
final Logger LOGGER =
LoggerFactory.getLogger(LoggingGatewayFilterFactory.class);
public LoggingGatewayFilterFactory() {
super(Config.class);
}
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
ServerHttpResponse response …Run Code Online (Sandbox Code Playgroud) java spring spring-cloud spring-cloud-security spring-cloud-gateway
我想了解 Netflix Zuul2 和 Spring Cloud Gateway 之间的技术差异。
每次我从 spring.io 创建项目时,都会在项目中创建一个 ServletInitializer 文件。我只有 spring 云网关依赖项。这是该文件存在的原因,如果是,有人可以解释原因吗?
这些是它的内容:
package com.springcloudgatewayexample;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringCloudGatewayExampleApplication.class);
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试调试我的应用程序,但调试器没有命中此代码块。这是我的自定义网关过滤器。
@RefreshScope
@Component
public class AuthorizationHeaderFilter extends
AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config> {
@Autowired
Environment environment;
public AuthorizationHeaderFilter () {
super(Config.class);
}
public static class Config {
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
return onError(exchange, "No authorization header", HttpStatus.UNAUTHORIZED);
}
String token = Objects.requireNonNull(request.getHeaders().get(HttpHeaders.AUTHORIZATION))
.get(0).replace("Bearer","");
if(isJwtValid(token))
return onError(exchange, "JWT Token is not valid", HttpStatus.UNAUTHORIZED);
return chain.filter(exchange);
});
}
private Mono<Void> onError(ServerWebExchange exchange, String error, HttpStatus status) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(status); …Run Code Online (Sandbox Code Playgroud) spring-cloud ×6
java ×4
spring-boot ×4
spring ×3
api-gateway ×2
kong ×1
kotlin ×1
krakend ×1
netflix-zuul ×1