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

news/2025/11/13 13:17:34/文章来源:https://www.cnblogs.com/noear/p/19217781

一、概述

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

典型应用场景:

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

二、场景示例

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

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

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

三、技术实现方案

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

1. 多端口配置

配置主端口(app.yml):

server.port: 8082 #用户端服务

动态添加管理端口:

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、端口级访问控制

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

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;@Overridepublic 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、模块化控制器设计

用户端控制器:

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";}
}

管理端控制器:

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

五、扩展建议

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/964259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025-11-12 PQ v.Next日志记录

2025-11-12 PQ v.Next日志记录 重新pull下来最新的代码做进一步的修改。 https://z.gitee.cn/zgca/projects/777586/repos/zgca/aipq/sources今日进度(3*4):基于课堂收集用户的反馈; 本地仓库与远程仓库代码对齐。…

完整教程:人体心率测量技术

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

如何在WPF中实现ComboBox多选 - 教程

如何在WPF中实现ComboBox多选 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…

内江低噪音西林瓶灌装轧盖机选型,适配洁净车间

在当前制药装备领域,洁净车间对设备运行噪音、无菌保障能力及自动化集成度的要求日益提升,尤其在西林瓶灌装环节,低噪音、高洁净适配性已成为选型核心指标。面对多样化的市场需求,业内企业纷纷优化产品结构,以满足…

week3task

实践报告 1.按照动态规划法的求解步骤分析作业题目“数字三角形”: 1.1 递归方程: dp[i][j]=triangle[i][j]+max(dp[i+1][j], dp[i+1][j+1]) 方程的定义:dp[i][j] 表示从位置 (i, j) 出发到达底部所能得到的最大路径…

trick 选记

拆贡献:数值贡献,所有值之和等于对于所有 i 求出 >=i 的个数求和(数值转 01)。 个体 -> 整体,一般可以考虑的有全局,操作,和操作所影响的更小的个体(或就是单独的个体)(这启示我们要多角度思考问题的本…

Python 元组Tuple 简介

元组Tuple 元组(Tuple)是Python中的一种不可变序列类型,用于存储多个有序的元素。一旦创建,元组的内容就不能被修改。 特点不可变性:元组一旦创建,不能修改其元素 有序性:元组中的元素保持插入顺序 元组可以包含…

网络串流 —— 地址

网络串流 —— 地址音频: BBC News: https://stream.live.vc.bbcmedia.co.uk/bbc_world_service视频:本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份…

抗体人源化技术:治疗性抗体的迭代升级与临床突破

抗体作为能与抗原特异性结合的免疫球蛋白,是免疫系统的核心组成部分,在疾病预防与治疗中占据不可替代的地位。人类对抗体治疗的探索有着深厚的历史积淀,中国唐朝便已有种痘预防天花的记载,这一 “人痘接种术” 被公…

【日记】这个健身器材是真要命了(934 字)

正文今天上午发电机的人来巡检。尝试启动时没反应过来,被柴油燃烧的青烟窜了一脸。眼睛疼到现在。我能不能报工伤啊呜呜。今天又把事情拖到最后一天赶 DDL 呢,明天又有一些事情是 DDL。感觉自己懒得不行(笑。做完了…

Zabbix 配置中文界面、监控告警以及Windows、Linux主/被监控模板

Zabbix 配置中文界面、监控告警以及Windows、Linux主/被监控模板本次优化主要针对 Zabbix 监控配置文章进行结构化梳理与格式规范:一是重构内容框架,将 Linux 与 Windows 监控配置分离呈现,前置主动 / 被动检查核心…

算法-快速排序和归并排序

算法 快速排序 归并排序1. 快排 2. 归并排序最好情况、最坏情况、平均情况,时间复杂度都为\(O(nlogn)\) 空间复杂度为\(O(n)\)。归并排序不是原地排序算法,需要额外的空间来存储tmp数组。public static void mergeSo…

记一次 .NET 某理财管理客户端 OOM溢出分析

一:背景 1. 讲故事 这是训练营里的学员找到我的,让我帮忙看下为什么他的客户程序会偶发的出现 报错弹框,由于dump比较敏感,这里就不截图发出来了,由于是错误弹框,并不会出现程序崩溃,而且朋友在日志中也看到了 …

计算机毕业设计:Python农业数据可视化分析系统 气象数据 农业生产 粮食素材 播种数据 爬虫 Django框架 天气数据 降水量(源码+文档)✅

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P14400 [JOISC 2016] 回转寿司 / Sushi

题意简介 给定一个长度为 \(n\) 的环状数组,每次询问给出 \(l,r,x\),依次遍历 \(i = l , \cdots , r\)(如果 \(l > r\),从 \(l\) 遍历到 \(n\),再从 \(1\) 遍历到 \(r\)),若 \(a_i > x\),则交换二者的值…

思路

思路大模型对宠物语言用拼音写. 然后就是人话跟宠物语言互相翻译任务.

灰度的openkruise rollout - Super

灰度的openkruise rollout一、openkruise的rollout类 例: apiVersion: rollouts.kruise.io/v1beta1 kind: Rollout metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: >{"apiVersion&…

P14367 [JOISC 2018] 帐篷 / Tents

思路 注意到重要性质:每确定一对帐篷,那么这对帐篷所在行和列不能放置其他帐篷,这将解释后来的方案之间为什么不会互相冲突。 考虑设计 \(dp_{ i , j }\) 表示营地大小 \(i\) 行 \(j\) 列时的方案数,逐行计算,对于…

代码加密技术 - 实践

代码加密技术 - 实践2025-11-13 12:03 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-f…

P6532 [COCI 2015/2016 #1] TOPOVI

思路 删掉 \((r_1,c_1)\) 位置上值为 \(val\) 的棋子相当于再在原处放置一个相同的棋子使之异或后为 \(0\),故只需考虑放置新棋子后的影响。 显然一个棋子无法被攻击的充要条件是其所在行的异或和等于所在列的异或和,…