一、整體架構方案
(一)架構方案選擇(根據項目規模)
1. 中小型項目推薦方案(團隊<10人)
- 技術要點:
- 使用 模塊化單體架構(非微服務)
- 通過 package劃分 隔離管理/門戶API
- 利用 Profile 實現環境隔離
- 無需Spring Cloud,保持簡單
2. 大型項目方案(團隊>20人)
- 技術要點:
- 采用 Spring Cloud Alibaba
- 通過 Nacos 實現服務發現
- 使用 Sentinel 做流量控制
- 需要獨立 DBA團隊 支持
3.部署方案對比
方案 | 優點 | 缺點 | 適用階段 |
---|---|---|---|
單體部署 | 運維簡單,成本低 | 擴展性受限 | 初期(<5萬UV) |
模塊分離部署 | 部分服務可獨立伸縮 | 需要基礎監控能力 | 中期(5-50萬UV) |
全微服務 | 彈性擴展,故障隔離 | 運維復雜,成本高 | 后期(>50萬UV) |
(二)演進路線實施建議
# 初期:單體模塊化
src/
└── main└── java└── com└── company└── cms├── content├── comment└── statistics# 中期:子模塊拆分
cms-system/
├── cms-content
├── cms-comment
└── cms-statistics# 后期:微服務化
cms-admin-service/
cms-portal-service/
cms-comment-service/
-
初期采用模塊化單體:
- 使用 Maven多模塊 而非微服務
- 通過 @Profile(“admin”) 隔離配置
- 使用 Flyway 管理多環境數據庫
-
漸進式演進路徑:
-
監控準備:
- 即使單體架構也要配置 Prometheus+Granfana
- 日志系統使用 ELK Stack
- 關鍵業務指標埋點
可根據實際用戶量增長逐步升級架構,避免早期過度設計。
二、模塊化分層架構設計
(一)總體劃分架構
1.后端目錄劃分
采用 「業務垂直切分 + 客戶端橫向隔離 + 技術縱向分層」 的三維結構,具體實現如下:
src/main/java/com/company/cms
├── content # 內容業務模塊
│ ├── admin # 管理端實現
│ │ ├── controller
│ │ ├── service
│ │ └── mapper
│ ├── portal # 門戶端實現
│ │ ├── controller
│ │ ├── service
│ │ └── mapper
│ └── domain # 公共領域對象
│ ├── entity
│ ├── dto
│ └── vo
├── comment # 評論業務模塊
│ ├── admin
│ ├── portal
│ └── domain
├── statistics # 統計業務模塊
│ ├── admin
│ ├── portal
│ └── domain
└── common # CMS公共模塊├── config # 專有配置├── interceptor # 攔截器└── utils # 工具類
2. 業務垂直切分
-
隔離性:各業務模塊可獨立開發部署
-
可維護性:修改影響范圍明確
-
復用性:公共domain對象跨客戶端復用
3. 客戶端橫向隔離
// 內容模塊下的權限差異示例
// 管理端Controller
@PreAuthorize("hasRole('CONTENT_ADMIN')")
@PostMapping("/admin/content")
public AjaxResult createContent(...) {// 需要審核流程
}// 門戶端Controller
@RateLimit(100) // 限流注解
@GetMapping("/portal/content")
public ContentVO getContent(...) {// 緩存優化實現
}
4. 技術縱向分層
# 典型業務模塊內部結構
content/
├── admin
│ ├── controller # API入口
│ ├── service # 業務邏輯
│ └── mapper # 數據持久
├── portal
│ ├── controller
│ ├── service
│ └── mapper
└── domain # 核心領域模型├── entity # JPA實體├── dto # 傳輸對象└── vo # 視圖對象
(二)前后端代碼統籌
1.代碼倉庫管理策略
若是屬于少量人開發項目,則推薦單一代碼倉庫 + 多模塊結構的方案進行開發。
my-cms-project/
├── backend/ # Spring Boot后端
│ ├── src/
│ └── pom.xml
├── admin-frontend/ # 管理端Vue3
│ ├── src/
│ └── package.json
└── portal-frontend/ # 門戶端Nuxt3├── pages/└── package.json
若是多人開發項目,應該分為3個代碼倉庫,由不同的技術人員開發提交對應的代碼。
2.配置示例(.gitignore):
# 通用忽略
*.log
*.iml
.idea/# 后端忽略
backend/target/# 前端忽略
admin-frontend/node_modules/
admin-frontend/dist/
portal-frontend/node_modules/
portal-frontend/.nuxt/
三、后端實施建議
(一)領域對象
1.領域對象復用
// 公共實體定義
@Entity
@Table(name = "cms_content")
public class Content {@Id@GeneratedValueprivate Long id;// 公共字段private String title;private String content;// 管理端特有字段(審計用)@Column(name = "audit_status")@AdminOnly // 自定義注解private AuditStatus auditStatus;// 門戶端特有字段(展示用)@Column(name = "view_count")@PortalOnlyprivate Integer viewCount;
}
(二)API控制器
1.API路徑設計規范
管理端和門戶端的api接口需要隔離,用/api/admin和/api/portal區分好,還是用/admin/api和/portal/api區分好?
推薦:/api/admin
和 /api/portal
雙前綴模式
管理端: /api/admin/v1/content
門戶端: /api/portal/v1/content
優勢分析:
- 路由清晰:/api 明確標識API入口,/admin|portal區分客戶端
- 網關友好:Nginx可統一配置/api路由規則
- 安全隔離:方便在網關層設置不同安全策略
- 版本控制:v1支持平滑升級到v2
2.控制器隔離
// 管理端文章控制器
@RestController
@RequestMapping("/api/admin/v1/articles")
public class AdminArticleController {@PreAuthorize("hasRole('ADMIN')")@PostMappingpublic AjaxResult createArticle(@Valid @RequestBody ArticleCreateDTO dto) {// 管理端專用創建邏輯}
}// 門戶端文章控制器
@RestController
@RequestMapping("/api/portal/v1/articles")
public class PortalArticleController {@GetMapping("/{id}")public ArticleVO getArticle(@PathVariable Long id) {// 門戶端專用查詢邏輯}
}
3.API文檔管理
// 使用Swagger分組
@Bean
public Docket adminApi() {return new Docket(DocumentationType.OAS_30).groupName("管理端API").select().apis(RequestHandlerSelectors.basePackage("com.cms.controller.admin"))
}
(三)服務層
1.服務層復用策略
// 通用服務接口
public interface ArticleBaseService {Article getById(Long id);
}// 管理端服務實現
@Service
public class AdminArticleService implements ArticleBaseService {@Overridepublic Article getById(Long id) {// 管理端專用邏輯(包含審計字段)}public void auditArticle(Long id) {// 管理端特有方法}
}// 門戶端服務實現
@Service
public class PortalArticleService implements ArticleBaseService {@Overridepublic Article getById(Long id) {// 門戶端專用邏輯(緩存優化)}
}
2. 服務層差異處理
// 管理端服務實現
@Service
public class AdminContentService {@AdminAuditRequired // 自定義審核注解public void publishContent(Long id) {// 包含審核流程}
}// 門戶端服務實現
@Service
public class PortalContentService {@Cacheable("content") // 緩存優化public ContentVO getContent(Long id) {// 訪問統計邏輯}
}
(四)安全配置
1.安全配置分離
// 管理端安全配置類
@Configuration
@EnableWebSecurity
@Order(1) // 高優先級
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasRole("ADMIN").and().formLogin().disable();}
}// 門戶端安全配置類
@Configuration
@Order(2) // 低優先級
public class PortalSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/portal/**").authorizeRequests().antMatchers(HttpMethod.GET).permitAll().anyRequest().authenticated().and().oauth2ResourceServer().jwt();}
}
# application-admin.yml(管理端配置)
security:oauth2:resource:id: admin-apiuser-info-uri: http://auth-server/oauth2/user# application-portal.yml(門戶端配置)
security:oauth2:resource:id: portal-apiuser-info-uri: http://auth-server/oauth2/openid
# 權限配置示例(admin/portal分離)
security:admin:roles: [CONTENT_ADMIN, COMMENT_ADMIN]access: DENY_AFTER_17:00-08:00 # 管理端時間限制portal:rate-limit: 1000/分鐘open-apis: [/api/portal/content/*]
(五)異常處理
1.異常處理方案
@RestControllerAdvice(basePackages = {"com.company.cms.content.admin","com.company.cms.content.portal"})
public class ContentExceptionHandler {@ExceptionHandler(ContentNotFoundException.class)public ResponseEntity<ErrorResult> handleNotFound(ContentNotFoundException ex) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResult("CONTENT_NOT_FOUND", ex.getMessage()));}
}
2. 錯誤碼規范示例
模塊 | 錯誤范圍 | 示例 |
---|---|---|
內容模塊 | 1000-1999 | 1001=內容不存在 |
評論模塊 | 2000-2999 | 2003=評論包含敏感詞 |
統計模塊 | 3000-3999 | 3005=數據導出失敗 |
(六)配置管理
1.配置管理策略
多環境配置示例
config/
├── application.yml # 公共配置
├── application-dev.yml # 開發環境
├── application-prod.yml # 生產環境
├── content-admin.yml # 內容管理端特有配置
└── content-portal.yml # 內容門戶端特有配置
# application.yml(公共配置)
spring:datasource:url: jdbc:mysql://localhost:3306/cmsusername: rootpassword: 123456---
# application-admin.yml(管理端特有配置)
management:endpoints:web:exposure:include: health,info,metricsendpoint:health:show-details: always---
# application-portal.yml(門戶端特有配置)
spring:redis:host: portal-redisport: 6379
動態配置示例
@Configuration
@ConfigurationProperties(prefix = "cms.content")
public class ContentConfig {// 管理端特有配置private AdminConfig admin;// 門戶端特有配置private PortalConfig portal;@Datapublic static class AdminConfig {private int auditTimeout = 24; // 審核超時時間(小時)}@Datapublic static class PortalConfig {private int cacheTTL = 3600; // 緩存時間(秒)}
}
3. 數據庫隔離策略
-- 管理表(admin_開頭)
CREATE TABLE admin_operation_log (id BIGINT PRIMARY KEY,user_id BIGINT NOT NULL,action VARCHAR(50) NOT NULL
);-- 門戶表(portal_開頭)
CREATE TABLE portal_comment (id BIGINT PRIMARY KEY,article_id BIGINT NOT NULL,content TEXT
);
四、前端技術確認
端類型 | 技術棧 | 適用場景 | 示例代碼 |
---|---|---|---|
管理后臺 | Vue3 + Ruoyi-UI | 需要快速開發CRUD界面 | 使用若依的src/views/system 結構 |
門戶網站 | Nuxt3 + SSR | 需要SEO優化和首屏性能 | pages/article/[id].vue 動態路由 |
(一)前端API調用對比
管理端調用示例(Vue3):
// admin-frontend/src/api/content.js
import request from '@/utils/request'export function getContentList(params) {return request({url: '/api/admin/v1/content',method: 'get',params})
}
門戶端調用示例(Nuxt3):
// portal-frontend/composables/useContent.js
export default () => {const getContent = async (id) => {return $fetch(`/api/portal/v1/content/${id}`, {method: 'GET'})}return { getContent }
}
(二)開發環境代理配置
管理端Vite配置(admin-frontend/vite.config.js):
export default defineConfig({server: {proxy: {'/api/admin': {target: 'http://localhost:8080', // Spring Boot地址changeOrigin: true,rewrite: path => path.replace(/^\/api\/admin/, '')}}}
})
門戶端Nuxt配置(portal-frontend/nuxt.config.js):
export default defineNuxtConfig({devServer: {proxy: {'/api/portal': 'http://localhost:8080'}}
})
前端環境變量:
# admin-frontend/.env.development
VITE_API_BASE=/api/admin# portal-frontend/.env.production
NUXT_PUBLIC_API_BASE=/api/portal
五、其它
1.Nginx統一配置:
server {listen 80;# 管理前端location /admin {alias /var/www/admin-frontend/dist;try_files $uri $uri/ /admin/index.html;}# 門戶前端location / {alias /var/www/portal-frontend/dist;try_files $uri $uri/ /index.html;}# API路由location /api {proxy_pass http://backend-server:8080;proxy_set_header Host $host;# 管理API超時設置location ~ ^/api/admin {proxy_read_timeout 300s;}# 門戶API緩存配置location ~ ^/api/portal.*\.(js|css|png)$ {expires 30d;}}
}