You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:05:40