Solon Web 的“分身术”:单应用多端口监听,化身多重服务

一、概述

常规 Solon Web 应用通常采用单一端口提供服务。然而在实际业务场景中,我们往往需要单个应用具备"多面服务"能力:在不同端口上提供功能完全独立的服务模块。

典型应用场景:

  • 外部 API 服务 + 内部监控端口:对外提供业务接口,对内提供运维监控
  • 用户前台系统 + 管理后台系统:同一应用同时服务终端用户和运营管理
  • 多租户隔离服务:不同端口服务不同客户群体,实现逻辑隔离

二、场景示例

以电商平台开发为例,我们需要在同一应用中集成:

服务类型 端口 核心功能
用户端服务 8082 商品浏览、购物车管理、订单处理
管理端服务 8083 商品管理、订单管理、数据统计

两套服务功能逻辑完全独立,但需要共享应用部署资源。

三、技术实现方案

采用多端口方式。多端口有个好处,不同端口可以采用不同的运维策略。

1. 多端口配置

配置主端口(app.yml):

yaml 复制代码
server.port: 8082 #用户端服务

动态添加管理端口:

java 复制代码
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
import org.noear.solon.server.http.HttpServerConfigure;

@SolonMain
public class App {
    public static void main(String[] args) {
        Solon.start(App.class, args, app -> {
            app.onEvent(HttpServerConfigure.class, config -> {
                config.addHttpPort(8083); // 添加管理端服务端口
            });
        });
    }
}

2、端口级访问控制

通过过滤器实现基于端口的访问权限控制:

java 复制代码
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;

@Component(index = -1) // 高优先级过滤器
public class PortBasedFilter implements Filter {
    
    private static final int USER_PORT = 8082;
    private static final int ADMIN_PORT = 8083;
    
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        int currentPort = ctx.localPort();
        
        if (currentPort == ADMIN_PORT) {
            handleAdminRequest(ctx);
        } else if (currentPort == USER_PORT) {
            handleUserRequest(ctx);
        } else {
            ctx.status(403).output("Forbidden: Invalid access port");
            return;
        }
        
        chain.doFilter(ctx);
    }
    
    private void handleUserRequest(Context ctx) {
        // 用户端路径验证
        if (!ctx.pathNew().startsWith("/api/user/")) {
            ctx.status(401).output("Unauthorized: User API required");
            return;
        }
        validateUserRequest(ctx);
    }
    
    private void handleAdminRequest(Context ctx) {
        // 管理端路径验证
        if (!ctx.pathNew().startsWith("/api/admin/")) {
            ctx.status(401).output("Unauthorized: Admin API required");
            return;
        }
        validateAdminRequest(ctx);
    }
    
    private void validateUserRequest(Context ctx) {
        // 用户端请求验证逻辑
        String userAgent = ctx.userAgent();
        if (userAgent == null || userAgent.trim().isEmpty()) {
            throw new SecurityException("Invalid user request: User-Agent required");
        }
    }
    
    private void validateAdminRequest(Context ctx) {
        // 管理端身份验证
        String token = ctx.header("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            throw new SecurityException("Admin authentication required");
        }
        
        // Token 验证逻辑
        if (!isValidAdminToken(token.substring(7))) {
            throw new SecurityException("Invalid admin token");
        }
    }
    
    private boolean isValidAdminToken(String token) {
        // 实现具体的 Token 验证逻辑
        return token != null && token.length() > 10;
    }
}

3、模块化控制器设计

用户端控制器:

java 复制代码
import org.noear.solon.annotation.*;

@Controller
@Mapping("/api/user")
public class UserController {

    @Get
    @Mapping("/products")
    public String getProducts() {
        return "User Products API";
    }

    @Post
    @Mapping("/cart")
    public String addToCart() {
        return "Add to cart";
    }
    
    @Get
    @Mapping("/orders")
    public String getOrders() {
        return "User orders list";
    }
}

管理端控制器:

java 复制代码
import org.noear.solon.annotation.*;

@Controller
@Mapping("/api/admin")
public class AdminController {
    
    @Get
    @Mapping("/products")
    public String manageProducts() {
        return "Admin Products Management";
    }

    @Get
    @Mapping("/statistics")
    public String getStatistics() {
        return "Admin Statistics Dashboard";
    }
}

四、方案优势

  1. 资源复用:共享应用上下文,减少系统资源占用
  2. 部署简化:单一应用包包含多套服务功能
  3. 隔离性:端口级别的访问控制和业务逻辑隔离
  4. 灵活性:不同端口可采用独立的运维策略和安全配置

五、扩展建议

  • 结合配置中心实现端口动态管理
  • 集成监控组件,分别统计各端口服务指标
  • 基于端口实现差异化的限流和熔断策略

该方案为复杂业务场景下的服务部署提供了灵活而高效的解决方案,既保证了服务间的逻辑隔离,又实现了资源的有效利用。

相关推荐
装不满的克莱因瓶2 小时前
【项目亮点】基于EasyExcel + 线程池解决POI文件导出时的内存溢出及超时问题
java·jvm·excel·线程池·async·虚拟机·easyexcel
Lisonseekpan2 小时前
IntelliJ IDEA 快捷键全解析与高效使用指南
java·ide·后端·intellij-idea
Fantasydg2 小时前
外卖项目 day01
java
SeaTunnel2 小时前
结项报告完整版:Apache SeaTunnel 支持 Flink 引擎 Schema Evolution 功能
java·大数据·flink·开源·seatunnel
q***71852 小时前
常见的 Spring 项目目录结构
java·后端·spring
元亓亓亓2 小时前
考研408--操作系统--day4--进程同步&互斥&信息量机制
java·数据库·考研·操作系统·408
武子康2 小时前
Java-169 Neo4j CQL 实战速查:字符串/聚合/关系与多跳查询
java·开发语言·数据库·python·sql·nosql·neo4j
q***23572 小时前
记录 idea 启动 tomcat 控制台输出乱码问题解决
java·tomcat·intellij-idea
一只小灿灿2 小时前
深入解析 Maven 与 Gradle:Java 项目构建工具的安装、使用
java·开发语言·maven