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. 灵活性:不同端口可采用独立的运维策略和安全配置

五、扩展建议

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

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

相关推荐
niucloud-admin16 分钟前
NIUCLOUD PHP SAAS上门家政使用文档:服务保障
java·开发语言·php
IT枫斗者枫哥30 分钟前
CompletableFuture失败后返回空列表:异常没了,业务含义也变了
java·后端
知识搬运临时工41 分钟前
一个模板把 AEM 拖进 Full GC 死亡螺旋:300% CPU、7 GB 堆、310 万行堆栈
java·aws
用户432935928051 小时前
CoAP还是MQTT:1万只Cat.1水表三个月带宽续航实测
java
知守观1 小时前
多模块架构演进:横向分层 vs 纵向领域,13 个真实项目的切分对照
java·后端·微服务
Java成神之路-1 小时前
Java String 为什么不可变?和 HashMap 到底有什么关系?
java
paopaokaka_luck1 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
文丑颜不良啊1 小时前
LeetCode1401~1420题目解析
java·leetcode
Nuanyt1 小时前
LeetCode Hot 100 链表专题2 3 题 (Java)
java·笔记·算法·leetcode·链表
文丑颜不良啊2 小时前
LeetCode1341~1360题目解析
java·leetcode