In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the relevant knowledge of "how to solve the problem of SpringCloud Gateway configuration custom routing 404". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Catalogue
Problem background
Problem phenomenon
Solution process
1 check the gateway configuration
2 follow the source code to find the possible cause
3Analysis of abnormal causes.
Solution method
Problem background
Migrate the websocket module in the original project to the SpringCloud Alibaba-based micro-service system, in which the gateway part uses gateway.
Problem phenomenon
After the migration, we made an error in using the client to connect to websocket Times:
Io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Invalid subprotocol. Actual: null. Expected one of: protocol
...
At the same time, we also have a program written in py to simulate the client connection, but the websocket connection of the program is normal.
Resolution process 1 check the gateway configuration
At first, we thought there was something wrong with the configuration of gateway.
However, after checking the route configuration of gateway, it was found that there was no problem. It's a common kind.
... Gateway: routes: # indicates the forwarding of websocket-id: user-service-websocket uri: lb:ws://user-service predicates:-Path=/user-service/mq/** filters:-StripPrefix=1
Where lb refers to load balancer, and ws specifies websocket protocol.
Ps, if there is a request for the same path for other protocols, it can also be written directly as:
... gateway: routes: # indicates the forwarding of websocket-id: user-service-websocket uri: lb://user-service predicates:-Path=/user-service/mq/** filters:-StripPrefix=1
In this way, requests for other protocols can also be forwarded through this rule.
2 follow the source code to find the possible cause
Since there is nothing wrong with the configuration of gate, let's try to see how gateway handles ws protocol requests from a source point of view.
First of all, we need to get a general idea of how gateway works:
It can be seen that after receiving the request, you have to go through multiple Filter before you can reach the Proxied Service. Among them, there must be a custom Filter and a global Filter, and the global filter can be viewed through the GET request / actuator/gateway/globalfilters
{"org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5": 10100, "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000, "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650":-1, "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647, "org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147 483647, "org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0 "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637, "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646}
As you can see, the WebSocketRoutingFilter seems to have something to do with us.
Public Mono filter (ServerWebExchange exchange, GatewayFilterChain chain) {this.changeSchemeIfIsWebSocketUpgrade (exchange); URI requestUrl = (URI) exchange.getRequiredAttribute (ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); String scheme = requestUrl.getScheme (); if (! ServerWebExchangeUtils.isAlreadyRouted (exchange) & & ("ws" .equals (scheme) | | "wss" .equals (scheme)) {ServerWebExchangeUtils.setAlreadyRouted (exchange); HttpHeaders headers = exchange.getRequest (). GetHeaders () HttpHeaders filtered = HttpHeadersFilter.filterRequest (this.getHeadersFilters (), exchange); List protocols = headers.get ("Sec-WebSocket-Protocol"); if (protocols! = null) {protocols = (List) headers.get ("Sec-WebSocket-Protocol"). Stream (). FlatMap ((header)-> {return Arrays.stream (StringUtils.commaDelimitedListToStringArray (header)) }) .map (String::trim) .pictures (Collectors.toList ());} return this.webSocketService.handleRequest (exchange, new WebsocketRoutingFilter.ProxyWebSocketHandler (requestUrl, this.webSocketClient, filtered, protocols));} else {return chain.filter (exchange);}}
After tracking here in debug mode, you can see that the subprotocol is specified as "protocol" in the client request.
Netty related:
WebSocketClientHandshaker
WebSocketClientHandshakerFactory
This is a bad end.
Let's just look at the conclusion.
Finally, it was found that the cause of the error was in the WebSocketClientHandshanker.finishHandshake of netty.
Public final void finishHandshake (Channel channel, FullHttpResponse response) {this.verify (response); String receivedProtocol = response.headers () .get (HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL); receivedProtocol = receivedProtocol! = null? ReceivedProtocol.trim (): null; String expectedProtocol = this.expectedSubprotocol! = null? This.expectedSubprotocol: "; boolean protocolValid = false; if (expectedProtocol.isEmpty () & & receivedProtocol = = null) {protocolValid = true; this.setActualSubprotocol (this.expectedSubprotocol);} else if (! expectedProtocol.isEmpty () & & receivedProtocol! = null & &! receivedProtocol.isEmpty ()) {String [] var6 = expectedProtocol.split (", "); int var7 = var6.length For (int var8 = 0; var8 < var7; + + var8) {String protocol = var6 [var8]; if (protocol.trim (). Equals (receivedProtocol)) {protocolValid = true; this.setActualSubprotocol (receivedProtocol); break } if (! protocolValid) {throw new WebSocketHandshakeException (String.format ("Invalid subprotocol.) Actual:% s. Expected one of:% s ", receivedProtocol, this.expectedSubprotocol);} else {. }}
Here, an exception is thrown when the expected subprotocol type is not empty and the actual subprotocol does not belong to the desired subprotocol. That is, the one originally mentioned in the article.
3Analysis of abnormal causes.
When the client requests, the subprotocol is required to be "protocol", but our background websocket component does not specify which subprotocol to use, so it is impossible to select which subprotocol to use. Therefore, when you get to finishHandShaker, netty throws an exception WebSocketHandshakeException when checking whether the subprotocols match. In py's simulator, no subprotocol is specified, so there is no error.
In the version of springboot, since we are directly connected (forwarded through nginx) to the websocket server by the client, there is no error (guess is that the client does not check whether the subprotocol is legal).
Solution method
In the annotation @ ServerEndpoint of the WebSocketServer class, add subprotocols= {"protocol"}
@ ServerEndpoint (value = "/ ws/asset", subprotocols = {"protocol"})
The websocket request is then initiated by the client. The connection is successful and no exception is thrown.
After communicating with the developers on the client, they pointed out that their code did specify the sub-protocol as "protocol", which was casually written at that time.
This is the end of the content of "how to solve the problem of SpringCloud Gateway configuration Custom Route 404". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.