Spring Boot双IP配置:双网卡分别处理Web与流式请求
Spring Boot 双IP网卡请求隔离方案
Great question! Spring Boot的默认application.yml配置只能绑定单个IP/端口,但我们可以通过自定义嵌入式Tomcat服务器,创建多个分别绑定不同网卡IP的连接器,从而实现文本Web请求与WebSocket流式请求的隔离处理。以下是分步解决方案:
1. 自定义Tomcat绑定多IP
创建一个配置类,添加两个独立的Tomcat连接器,分别映射到你的目标网卡IP和端口,让Tomcat同时监听两个地址:
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; import java.net.UnknownHostException; @Configuration public class MultiIpTomcatConfig { @Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() { return factory -> { try { // 文本Web请求连接器(绑定第一块网卡IP) org.apache.catalina.connector.Connector textWebConnector = new org.apache.catalina.connector.Connector( TomcatServletWebServerFactory.DEFAULT_PROTOCOL); textWebConnector.setPort(8080); // 替换为你想用的文本请求端口 textWebConnector.setAddress(InetAddress.getByName("192.168.1.100")); // 替换为你的文本网卡IP textWebConnector.setScheme("http"); textWebConnector.setSecure(false); // WebSocket流式请求连接器(绑定第二块网卡IP) org.apache.catalina.connector.Connector wsConnector = new org.apache.catalina.connector.Connector( TomcatServletWebServerFactory.DEFAULT_PROTOCOL); wsConnector.setPort(8081); // 替换为你想用的WebSocket端口 wsConnector.setAddress(InetAddress.getByName("192.168.2.100")); // 替换为你的WebSocket网卡IP wsConnector.setScheme("http"); wsConnector.setSecure(false); // 将两个连接器添加到Tomcat factory.addAdditionalTomcatConnectors(textWebConnector, wsConnector); } catch (UnknownHostException e) { throw new RuntimeException("解析目标IP地址失败", e); } }; } }
2. 通过IP/路径隔离流量
Tomcat监听双IP后,添加过滤器确保文本请求仅通过第一块网卡处理,WebSocket流量仅通过第二块网卡处理,避免跨IP访问错误服务:
import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import java.io.IOException; @Component public class IpTrafficFilter implements Filter { // 与Tomcat配置中的IP保持一致 private static final String TEXT_WEB_ALLOWED_IP = "192.168.1.100"; private static final String WS_ALLOWED_IP = "192.168.2.100"; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest) request; String serverIp = httpReq.getLocalAddr(); // 获取接收请求的网卡IP // 限制文本Web端点(如/api/**)仅允许第一块网卡访问 if (httpReq.getRequestURI().startsWith("/api/")) { if (!TEXT_WEB_ALLOWED_IP.equals(serverIp)) { ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, "文本Web请求仅允许指定网卡访问"); return; } } // 限制WebSocket端点(如/ws/**)仅允许第二块网卡访问 if (httpReq.getRequestURI().startsWith("/ws/")) { if (!WS_ALLOWED_IP.equals(serverIp)) { ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, "WebSocket流量仅允许指定网卡访问"); return; } } chain.doFilter(request, response); } }
3. WebSocket配置(按需添加)
如果你还没配置WebSocket支持,添加以下代码将自定义处理器映射到/ws/**路径(与过滤器中的路径保持一致):
import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final YourWebSocketHandler yourWebSocketHandler; // 注入你的自定义WebSocket处理器 public WebSocketConfig(YourWebSocketHandler yourWebSocketHandler) { this.yourWebSocketHandler = yourWebSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(yourWebSocketHandler, "/ws/stream") .setAllowedOrigins("*"); // 根据实际需求调整CORS设置 } }
关键注意事项
- 替换代码中的占位IP(
192.168.1.100、192.168.2.100)和端口(8080、8081)为你的实际网卡地址和偏好端口。 - 如果需要HTTPS支持,修改连接器使用
org.apache.coyote.http11.Http11NioProtocol,配置SSL密钥库,并设置scheme="https"和secure=true。 - 测试验证:向
http://192.168.1.100:8080/api/...发送文本请求,向ws://192.168.2.100:8081/ws/stream建立WebSocket连接,确认流量隔离生效。
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

