找回密码
 立即注册
首页 业界区 业界 Solon Web 的“分身术”:单应用多端口监听,化身多重服 ...

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

溶绚 2025-11-13 14:00:04
一、概述

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

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

以电商平台开发为例,我们需要在同一应用中集成:
服务类型端口核心功能用户端服务8082商品浏览、购物车管理、订单处理管理端服务8083商品管理、订单管理、数据统计两套服务功能逻辑完全独立,但需要共享应用部署资源。
三、技术实现方案

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

配置主端口(app.yml):
  1. server.port: 8082 #用户端服务
复制代码
动态添加管理端口:
  1. import org.noear.solon.Solon;
  2. import org.noear.solon.annotation.SolonMain;
  3. import org.noear.solon.server.http.HttpServerConfigure;
  4. @SolonMain
  5. public class App {
  6.     public static void main(String[] args) {
  7.         Solon.start(App.class, args, app -> {
  8.             app.onEvent(HttpServerConfigure.class, config -> {
  9.                 config.addHttpPort(8083); // 添加管理端服务端口
  10.             });
  11.         });
  12.     }
  13. }
复制代码
2、端口级访问控制

通过过滤器实现基于端口的访问权限控制:
  1. import org.noear.solon.annotation.Component;
  2. import org.noear.solon.core.handle.Context;
  3. import org.noear.solon.core.handle.Filter;
  4. import org.noear.solon.core.handle.FilterChain;
  5. @Component(index = -1) // 高优先级过滤器
  6. public class PortBasedFilter implements Filter {
  7.    
  8.     private static final int USER_PORT = 8082;
  9.     private static final int ADMIN_PORT = 8083;
  10.    
  11.     @Override
  12.     public void doFilter(Context ctx, FilterChain chain) throws Throwable {
  13.         int currentPort = ctx.localPort();
  14.         
  15.         if (currentPort == ADMIN_PORT) {
  16.             handleAdminRequest(ctx);
  17.         } else if (currentPort == USER_PORT) {
  18.             handleUserRequest(ctx);
  19.         } else {
  20.             ctx.status(403).output("Forbidden: Invalid access port");
  21.             return;
  22.         }
  23.         
  24.         chain.doFilter(ctx);
  25.     }
  26.    
  27.     private void handleUserRequest(Context ctx) {
  28.         // 用户端路径验证
  29.         if (!ctx.pathNew().startsWith("/api/user/")) {
  30.             ctx.status(401).output("Unauthorized: User API required");
  31.             return;
  32.         }
  33.         validateUserRequest(ctx);
  34.     }
  35.    
  36.     private void handleAdminRequest(Context ctx) {
  37.         // 管理端路径验证
  38.         if (!ctx.pathNew().startsWith("/api/admin/")) {
  39.             ctx.status(401).output("Unauthorized: Admin API required");
  40.             return;
  41.         }
  42.         validateAdminRequest(ctx);
  43.     }
  44.    
  45.     private void validateUserRequest(Context ctx) {
  46.         // 用户端请求验证逻辑
  47.         String userAgent = ctx.userAgent();
  48.         if (userAgent == null || userAgent.trim().isEmpty()) {
  49.             throw new SecurityException("Invalid user request: User-Agent required");
  50.         }
  51.     }
  52.    
  53.     private void validateAdminRequest(Context ctx) {
  54.         // 管理端身份验证
  55.         String token = ctx.header("Authorization");
  56.         if (token == null || !token.startsWith("Bearer ")) {
  57.             throw new SecurityException("Admin authentication required");
  58.         }
  59.         
  60.         // Token 验证逻辑
  61.         if (!isValidAdminToken(token.substring(7))) {
  62.             throw new SecurityException("Invalid admin token");
  63.         }
  64.     }
  65.    
  66.     private boolean isValidAdminToken(String token) {
  67.         // 实现具体的 Token 验证逻辑
  68.         return token != null && token.length() > 10;
  69.     }
  70. }
复制代码
3、模块化控制器设计

用户端控制器:
  1. import org.noear.solon.annotation.*;
  2. @Controller
  3. @Mapping("/api/user")
  4. public class UserController {
  5.     @Get
  6.     @Mapping("/products")
  7.     public String getProducts() {
  8.         return "User Products API";
  9.     }
  10.     @Post
  11.     @Mapping("/cart")
  12.     public String addToCart() {
  13.         return "Add to cart";
  14.     }
  15.    
  16.     @Get
  17.     @Mapping("/orders")
  18.     public String getOrders() {
  19.         return "User orders list";
  20.     }
  21. }
复制代码
管理端控制器:
  1. import org.noear.solon.annotation.*;
  2. @Controller
  3. @Mapping("/api/admin")
  4. public class AdminController {
  5.    
  6.     @Get
  7.     @Mapping("/products")
  8.     public String manageProducts() {
  9.         return "Admin Products Management";
  10.     }
  11.     @Get
  12.     @Mapping("/statistics")
  13.     public String getStatistics() {
  14.         return "Admin Statistics Dashboard";
  15.     }
  16. }
复制代码
四、方案优势


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


  • 结合配置中心实现端口动态管理
  • 集成监控组件,分别统计各端口服务指标
  • 基于端口实现差异化的限流和熔断策略
该方案为复杂业务场景下的服务部署提供了灵活而高效的解决方案,既保证了服务间的逻辑隔离,又实现了资源的有效利用。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册