在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。
每个站点关联的有站点所在目录及所属的域名。
一、站点表设计
多站点CMS系统站点表设计是构建高效、安全、可扩展平台的关键环节。
站点表作为系统的核心配置中心,不仅需要存储基础站点信息,还需承载数据隔离策略、权限控制规则和模板管理机制,直接影响系统的安全性和扩展能力。通过深入分析站群与完全隔离两种多站点架构模式,结合现代数据库设计原则和安全最佳实践,可以制定出兼顾灵活性与安全性的站点表设计方案。
(一)多站点架构模式与站点表设计影响
多站点CMS系统主要采用两种架构模式:站群模式(数据共享)和完全隔离模式(数据独立)。这两种模式对站点表设计有显著影响。
站群模式下,各站点共享部分数据表(如用户表、基础配置表),但通过站点ID进行逻辑隔离;而完全隔离模式下,每个站点拥有独立的数据库或表前缀,数据完全不互通。
1.站群模式
在站群模式下,站点表需重点考虑共享与隔离的平衡。
站点表应包含站点ID、域名、名称、主题路径、权限组ID等基础字段,并通过站点ID在共享表中实现数据隔离。
例如,内容表可通过添加site_id
字段来区分不同站点的数据。这种模式的优势在于资源利用率高,便于统一管理,但需确保权限控制严格,避免数据泄露。
2.完全隔离模式
完全隔离模式则要求站点表具备更全面的数据库配置信息。
站点表需存储数据库连接参数(如主机地址、端口、数据库名称)或表前缀,为每个站点提供独立的数据存储环境。
例如,DedeCMS通过设置不同的表前缀实现多站点隔离。这种模式安全性高,各站点数据完全独立,但管理复杂度和成本也相应增加。
两种模式的选择取决于业务需求和安全性考量。对于需要统一管理但允许部分数据共享的企业集团,站群模式更为合适;而对于对数据隔离要求极高的金融、医疗行业,完全隔离模式则更为安全。
(二)站点表核心字段设计与关系模型
站点表作为多站点CMS系统的核心配置表,其字段设计直接影响系统的功能实现和安全性。根据行业最佳实践,站点表应包含以下核心字段:
1.基础信息字段
基础信息字段是站点表的必备部分,包括站点唯一标识符(site_id
)、站点名称(site_name
)、域名(domain
)、状态(status
)等。
这些字段确保系统能够准确识别和管理各个站点。其中,domain
字段应使用varchar(255)
类型,以满足长域名存储需求;status
字段建议使用tinyint
类型,表示站点启用/禁用状态,便于快速查询和过滤。
2.权限控制字段
权限控制字段是多站点系统安全性的保障。站点表应通过外键关联到权限组表(permission_group_id
),实现不同站点的独立权限体系。
例如,学校网站群案例中,站点等级表(site_level
)定义了不同站点的功能限制,如空间大小、样式数量等。这种设计使得管理员可以根据站点类型和级别分配不同的权限,确保数据安全。
3.模板与主题字段
模板与主题字段负责管理站点外观和用户体验。template_path
字段存储模板路径,theme
字段标识主题样式,这些字段直接影响站点的前端展示。
在站群模式下,可以为不同站点设置共享或独立的模板路径;在完全隔离模式下,则可能需要为每个站点配置完全独立的模板目录。
4.数据隔离字段
数据隔离字段是区分不同多站点架构的关键。
在站群模式下,添加site_id
字段作为逻辑隔离标识;在完全隔离模式下,则需包含db_prefix
(表前缀)或db_config_id
(数据库配置ID)等字段。
db_config_id
字段建议通过外键关联到数据库配置表,避免站点表直接存储敏感信息如数据库密码。这种设计不仅提高安全性,还便于统一管理数据库连接参数。
5.扩展字段
扩展字段用于记录站点创建、更新时间等元数据,以及排序、默认站点标识等业务字段。这些字段虽然不直接影响系统核心功能,但为系统管理和审计提供了重要信息。
例如,created_time
和updated_time
字段可帮助管理员了解站点的变更历史;sort_id
字段则用于控制站点在管理界面中的显示顺序。
6.数据库表设计
下表展示了多站点CMS系统站点表的核心字段设计:
字段名称 | 数据类型 | 长度 | 说明 | 站群模式 | 完全隔离模式 |
---|---|---|---|---|---|
site_id | bigint | 20 | 站点唯一标识符,主键 | 必备 | 必备 |
site_name | varchar | 255 | 站点名称 | 必备 | 必备 |
domain | varchar | 255 | 站点域名 | 必备 | 必备 |
status | tinyint | 4 | 站点状态(0-禁用,1-启用) | 必备 | 必备 |
template_path | varchar | 255 | 模板路径 | 必备 | 必备 |
theme | varchar | 100 | 主题样式 | 必备 | 必备 |
permission_group_id | bigint | 20 | 权限组ID,外键关联 | 必备 | 可选(通过独立数据库实现) |
site_level_id | bigint | 20 | 站点等级ID,外键关联 | 可选 | 可选 |
db_prefix | varchar | 50 | 表前缀,用于完全隔离模式 | 可选 | 必备 |
db_config_id | bigint | 20 | 数据库配置ID,外键关联 | 可选 | 必备 |
created_time | datetime | - | 创建时间 | 必备 | 必备 |
updated_time | datetime | - | 更新时间 | 必备 | 必备 |
在关系模型设计上,站点表通常与以下表建立关联:
- 权限组表(
permission_group
):通过permission_group_id
外键关联,实现站点权限体系的独立性 - 用户表(
user
):通过site_id
字段关联,标识用户所属站点 - 内容表(
content
):通过site_id
字段关联,实现内容数据的站点隔离 - 数据库配置表(
db_config
):通过db_config_id
外键关联,存储站点数据库连接参数
这种关系模型确保了系统各模块能够基于站点表进行数据隔离和共享,支持不同架构模式的灵活实现。
7.站点表创建实例
站点表
create table cms_site
(
site_id bigint not null comment '站点ID'
primary key,
parent_id bigint default 0 not null comment '父级站点ID',
name varchar(150) not null comment '站点名称',
description varchar(500) null comment '简介',
logo varchar(255) null comment '站点LOGO',
path varchar(100) not null comment '站点目录',
resource_url varchar(100) null comment '站点资源访问地址',
catalog_max_code int default 0 null comment '顶级栏目编码最大值',
dept_code varchar(100) null comment '所属机构编码',
index_template varchar(100) null comment '首页模板',
static_suffix varchar(10) null comment '静态文件类型',
sort_flag bigint not null comment '排序标识',
publish_pipe_props text null comment '发布通道属性',
config_props mediumtext null comment '站点扩展属性',
seo_keywords varchar(255) null comment 'SEO关键词',
seo_description varchar(255) null comment 'SEO描述',
seo_title varchar(255) null comment 'SEO标题',
create_by varchar(64) not null comment '创建人',
create_time datetime not null comment '创建时间',
update_by varchar(64) null comment '最近修改人',
update_time datetime null comment '最近修改时间',
remark varchar(400) null comment '备注'
)
charset = utf8mb4
row_format = DYNAMIC;
站点属性表
create table cms_site_property
(
property_id bigint not null comment '属性ID'
primary key,
site_id bigint not null comment '站点ID',
prop_name varchar(100) not null comment '属性名称',
prop_code varchar(50) not null comment '属性编码',
prop_value varchar(255) null comment '属性值',
create_by varchar(50) not null comment '创建人',
create_time datetime not null comment '创建时间',
update_by varchar(50) null comment '最后修改人',
update_time datetime null comment '最后修改时间',
remark varchar(255) null comment '备注'
)
charset = utf8mb4
row_format = DYNAMIC;
(三)数据隔离与共享策略设计
多站点CMS系统的核心挑战在于如何平衡数据共享与隔离。良好的数据隔离与共享策略不仅提高系统性能,还能确保数据安全和操作效率。根据行业实践,可以采用以下策略:
1.站群模式下的数据隔离
在站群模式下,数据隔离主要通过逻辑隔离实现。
共享数据表(如用户表、权限角色表)添加site_id
字段,标识数据所属站点。
例如,SSCMS的内容表包含SiteId
字段,用于区分不同站点的内容。这种设计使得系统可以在同一数据库中管理多个站点的数据,同时保持数据的逻辑隔离。
对于查询操作,应在WHERE条件中添加site_id = ?
,确保只获取当前站点的数据。
2.完全隔离模式下的数据隔离
完全隔离模式则采用物理隔离策略。
每个站点拥有独立的数据库或表前缀,数据表结构相同但存储环境不同。
例如,DedeCMS通过设置不同的db_prefix
实现多站点隔离,如site1 orders
、site2 orders
等。这种设计确保了各站点数据的物理隔离,安全性最高,但管理复杂度也相应增加。
3.混合模式下的数据隔离
混合模式结合了上述两种策略,适用于中大型企业。
基础服务和全局数据采用共享数据库,而业务数据则采用分库分表策略。
例如,可以将用户表、权限表等全局数据存储在共享数据库中,而将内容表、订单表等业务数据按站点分库或分表存储。这种模式既能保证核心数据的安全共享,又能满足业务数据的隔离需求。
在分库分表实现上,可采用以下策略:
- 按业务分库:将不同业务模块的数据存储到独立数据库,如用户库、内容库、订单库等
- 按站点分表:在同一数据库中,为每个站点创建独立的数据表,如
content site1
、content site2
等 - 哈希分表:根据
site_id
字段哈希值将数据均匀分布到多个表中,避免数据热点
无论采用哪种策略,都应确保为site_id
字段添加索引,提高查询效率。同时,分库分表策略应考虑未来扩展性,避免频繁调整架构。
(四)安全与权限控制最佳实践
多站点环境下的安全与权限控制是系统设计的重点。通过合理的安全策略和权限控制机制,可以有效防止跨站点数据泄露和未授权访问。
1.身份验证
在身份验证方面,JWT(JSON Web Token)是多站点环境的理想选择。JWT应在Payload中添加site_id
字段标识当前站点,并结合IP绑定确保令牌安全性。例如,当用户登录时,服务端生成包含site_id
和客户端IP的JWT,并使用AES等加密算法对JWT进行加密。验证时,不仅验证JWT的有效性,还需检查site_id
是否匹配当前站点,以及IP地址是否一致。
对于跨站点请求伪造(CSRF)攻击,可采用以下防护策略:
- 站点专属CSRF Token:为每个站点生成独立的CSRF Token,与站点ID绑定
- 自定义HTTP头:设置如
X-Site-ID
的自定义头,传递站点信息,避免依赖Cookie - Token与站点关联:在JWT中携带站点关联的Token,验证时结合请求域名检查
2.权限控制
权限控制方面,基于角色的访问控制(RBAC)模型是多站点系统的最佳选择。在站群模式下,权限表添加site_id
字段实现站点权限隔离;在完全隔离模式下,则可为每个站点创建独立的权限表。例如,RBAC2模型通过角色互斥表防止跨站点角色冲突,确保用户只能访问其所属站点的资源。
对于数据库安全,建议采用以下措施:
- 敏感数据加密:使用AES、RSA等算法对用户密码、支付信息等敏感数据加密存储
- 最小权限原则:为不同站点设置独立的数据库账户,仅授予必要的操作权限
- 定期安全审计:记录所有站点操作日志,定期审计权限分配和数据访问情况
- HTTPS传输加密:确保所有站点间数据传输使用SSL/TLS加密,防止中间人攻击
(五)性能优化与扩展性考虑
多站点CMS系统的性能优化直接关系到用户体验和系统稳定性。良好的性能优化策略不仅提高查询效率,还能降低服务器负载和响应时间。
1.索引优化
在索引优化方面,应为site_id
字段添加索引,特别是在共享表中。
例如,在用户表、内容表等高频访问表中,site_id
字段应设置为索引,提高查询效率。
同时,对于完全隔离模式下的分表,也应确保主键和常用查询字段有适当索引。
2.缓存策略
缓存策略是提升多站点系统性能的关键。可为每个站点设置独立的缓存区域,避免数据污染。
例如,使用Redis为每个站点创建独立的缓存空间,或在缓存键中添加站点标识符。对于静态内容和模板,可采用CDN加速,根据站点域名自动分发到最近节点,降低网络延迟。
3.分库分表扩容策略
分库分表的扩容策略也需提前规划。对于哈希分表策略,应预留足够的表数量,避免频繁扩容。
例如,可预先创建100张表,根据site_id
哈希值分配站点数据。垂直分库策略则应按业务模块划分,确保数据分布合理,避免跨库查询。同时,应考虑使用分布式数据库中间件(如ShardingSphere)简化分库分表管理。
对于混合模式,性能优化需特别关注跨站点数据访问的性能瓶颈。
例如,当需要获取多个站点的统计信息时,应设计高效的数据聚合机制,避免频繁跨库查询。可考虑使用缓存层或数据中台进行数据聚合,提高查询效率。
(六)实际案例分析与最佳实践总结
通过对多种多站点CMS系统的分析,可以总结出以下最佳实践:
中企动力案例展示了站群模式的成功实现。其站点表包含站点ID、域名、名称、主题路径等字段,并通过site_id
在共享表中实现数据隔离。权限管理采用角色继承机制,支持多层级权限分配,确保不同站点的独立管理。这种设计使得企业在统一后台管理多个站点的同时,保持各站点的个性化配置和内容。
Baklib案例则体现了混合模式的优势。其站点表包含站点基本信息和数据库配置,内容表通过site_id
字段逻辑隔离,而用户表则采用全局共享。系统通过智能缓存机制和分布式节点部署,确保多站点并行访问的稳定性。对于需要快速扩展的场景,提供预设的多语言站点模板与跨站内容同步工具,大大降低了新站点的部署成本。
华为站点隔离方案则代表了完全隔离模式的实现。通过网络配置实现站点隔离,确保非法用户无法接入。站点表存储完整的数据库连接信息,每个站点拥有独立的数据库实例。这种设计虽然管理复杂度高,但安全性最佳,适合对数据隔离要求极高的场景。
综合以上案例,可以总结出多站点CMS系统站点表设计的最佳实践:
- 字段设计规范化:统一命名规则(如
status
而非flag
),选择合适的数据类型(如domain
使用varchar(255)
) - 权限控制精细化:采用RBAC模型,结合站点ID实现细粒度权限管理
- 数据隔离策略化:根据业务需求选择逻辑隔离、物理隔离或混合隔离策略
- 安全防护全面化:实施JWT站点化认证、CSRF防护、数据加密等多层次安全措施
- 性能优化系统化:通过索引优化、缓存策略、分库分表等手段提升系统性能
在实际项目中,应优先考虑业务需求和数据安全要求,选择合适的多站点架构模式。
对于中小型站点,站群模式通常足以满足需求;对于中大型企业,混合模式可能更为适合;而对于对数据隔离要求极高的场景,则完全隔离模式更为稳妥。无论选择哪种模式,站点表设计都应遵循规范化原则,确保系统长期稳定运行。
二、网站静态资源
(一)资源根目录
CMS资源根目录用来保存所有站点各自的相关文件,包括且不限于模板文件、静态资源、用户上传的图片等文件资源等。
资源根目录示例:
wwwroot_rlease # CMS资源根目录
|--swikoon # 站点动态资源目录,一般用来保存用户上传的资源文件
|----resources # 素材库资源目录,保存IResourceType实现相关类型文件,目前默认四种类型:图片、视频、音频、文件
|------image # 图片素材目录
|------video # 视频素材目录
|------audio # 音频素材目录
|------file # 其他文件素材目录
|--swikoon_pc # 发布通道目录,pc为后台发布通道编码,固定格式:站点目录_发布通道编码
|----img # 网站图片
|----js # 网站js
|----css # 网站css
|----template # 网站模板固定目录
|------index.template.html # 模板文件
|--swikoon_h5 # 发布通道目录,h5为后台发布通道编码,固定格式:站点目录_发布通道编码
|----img # 网站图片
|----js # 网站js
|----css # 网站css
|----template # 网站模板固定目录
|------index.template.html # 模板文件
网站静态资源默认路径是当前项目应用同级的wwwroot_release
目录。
例如:项目目录为E:/dev/workspace/my-cms
,那么网站静态资源目录应为:E:/dev/workspace/wwwroot_release
。
网站静态资源目录示例:(以演示站为例,演示站并没有swikoon_h5,此处仅示例目录结构)
# 应用目录
my-cms
|--ruoyi-admin
|--ruoyi-cms
|--ruoyi-common
|--......
一般是可以配置网站根目录的
backend:
cms:
resourceRoot: E:/dev/workspace/wwwroot_release/
(二)站点nginx配置
站点访问配置,nginx参考配置
server {
listen 80;
server_name www.swikoon.com;
# PC站配置www.swikoon.com域名访问swikoon_pc目录
location / {
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;
root /www/docker/ruoyi-admin/wwwroot_release/swikoon_pc;
index index.shtml index.html index.htm;
}
location ~ ^/(images|img|fonts|assets|js|css)/ {
root /www/docker/ruoyi-admin/wwwroot_release/swikoon_pc;
expires 1d;
}
# 搜索动态模板访问代理
location = /_search {
rewrite /_search?(.*) /_search?sid=1630092239507464193&pp=pc&$1 break;
ssi on;
ssi_silent_errors on;
proxy_buffers 32 8k;
add_after_body "";
proxy_cookie_path / /;
proxy_pass http://localhost:8090;
}
# 后台上传的资源文件访问统一代理到swikoon目录,如果使用OSS不需要配置
location ~ ^/(resources)/ {
root /www/docker/ruoyi-admin/wwwroot_release/swikoon;
expires 1d;
}
}