【手写OSS】第1章:项目概述与Express+Ts环境搭建
在当今数字化时代,数据的存储和管理变得至关重要。随着数据量的不断增长,企业和个人用户对高效、安全、可靠的存储解决方案的需求愈发迫切。对象存储系统作为一种新型的存储架构,以其高扩展性、灵活性和易管理性,成为了现代存储解决方案的首选。
瞎编的,就是硬想写~
但是你如果想要借鉴一下到方案中,那还是妥妥的
本章将带领你开始设计并实现一个类似于阿里云OSS的对象存储系统。我们将从零开始,搭建一个完整的项目开发环境,并介绍如何使用Express和TypeScript构建项目的基础结构。通过本章的学习,你将掌握初始化和配置TypeScript项目、安装和配置Express框架、设计项目目录结构以及配置TypeScript编译的基本技能,为后续开发打下坚实的基础。
第1章:项目概述与环境搭建
1.1 项目介绍及目标
1.1.1 详细介绍对象存储系统的用途和优势
对象存储系统是一种用于存储和管理大量非结构化数据的存储架构。其主要用途和优势包括:
- 高扩展性:对象存储系统能够轻松扩展以容纳海量数据,而不会影响系统的性能。它适合存储大规模的非结构化数据,如图片、视频、备份文件等。
- 灵活性:对象存储使用键值对(Key-Value)存储数据,可以灵活地管理和访问文件。每个对象都拥有唯一的标识符(Object Key),便于检索。
- 持久性和可靠性:通过数据冗余和副本机制,对象存储系统确保数据的高可用性和持久性。
- 易管理性:对象存储系统通常提供丰富的API接口,支持多种编程语言和工具,使得数据管理更加便捷。
- 成本效益:相比传统的块存储和文件存储,对象存储在处理大规模数据时更具成本效益。
1.1.2 为什么选择自己构建而不是使用第三方服务
尽管使用第三方存储服务(如AWS S3、阿里云OSS)可以省去很多开发工作,但自行构建对象存储系统也有其独特的优势:
- 灵活性和可控性:自建系统可以根据具体需求进行定制,完全掌控系统的设计、实现和部署。
- 成本控制:在数据量极大的情况下,自建存储系统可能比长期使用第三方服务更具成本效益。
- 学习和成长:构建一个完整的对象存储系统可以极大地提升开发者的技术能力,深入理解存储系统的原理和实现。
- 数据安全和隐私:自建系统可以完全掌握数据的存储和传输,避免数据外泄的风险。
1.1.3 项目短期和长期目标
-
短期目标(MVP):
- 实现基本的文件上传、下载和管理功能。
- 提供用户认证和权限控制。
- 支持元数据管理和基本的安全机制(如HTTPS加密)。
- 搭建基本的监控和日志系统。
-
长期目标:
- 支持大规模数据的分布式存储和多副本机制。
- 提供高级功能,如文件版本控制、临时访问链接、数据备份与恢复等。
- 实现多区域支持,提升数据访问的速度和可靠性。
- 提供跨平台兼容的API接口,支持更多的编程语言和开发工具。
- 持续优化系统性能和用户体验,提升系统的稳定性和可扩展性。
1.2 技术栈选择
1.2.1 对比不同技术的优缺点
-
Node.js:
- 优点:高并发处理能力、非阻塞I/O、丰富的生态系统、适合实时应用。
- 缺点:单线程模型对CPU密集型任务支持不足、需要注意异步编程的复杂性。
-
MongoDB:
- 优点:灵活的文档模型、水平扩展性、强大的查询能力、适合存储非结构化和半结构化数据。
- 缺点:事务支持不如关系型数据库强大、对复杂查询的性能可能不如关系型数据库。
-
Redis:
- 优点:高性能、丰富的数据结构、支持持久化、适合做缓存和会话管理。
- 缺点:内存占用较大、不适合存储大数据量的持久性数据。
1.2.2 选择这些技术的原因
-
Node.js:
- 高并发处理:Node.js采用事件驱动和非阻塞I/O,能够高效处理并发请求,非常适合文件上传、下载等高并发场景。
- 丰富的生态系统:Node.js拥有丰富的模块和库,能够快速构建和扩展功能。
- 全栈开发:使用Node.js可以实现前后端同构开发,提升开发效率。
-
MongoDB:
- 灵活的文档模型:MongoDB的文档模型非常适合存储文件的元数据,如文件名、大小、类型、上传时间等。
- 水平扩展性:MongoDB支持分片和副本集,能够轻松扩展以处理大规模数据。
- 强大的查询能力:MongoDB提供丰富的查询语法,能够快速检索和管理文件元数据。
-
Redis:
- 高性能缓存:Redis能够高效地缓存热门文件的元数据,提升系统的响应速度。
- 丰富的数据结构:Redis支持字符串、哈希、列表、集合等多种数据结构,能够灵活地管理缓存数据。
- 持久化支持:Redis支持RDB和AOF两种持久化方式,能够确保缓存数据的持久性。
1.3 初始化Express + TypeScript项目
1.3.1 安装和配置TypeScript
-
安装Node.js和npm:
- 首先确保已经安装了Node.js和npm。可以通过以下命令检查是否已安装:
node -v npm -v
- 首先确保已经安装了Node.js和npm。可以通过以下命令检查是否已安装:
-
初始化npm项目:
- 在项目目录中运行以下命令初始化npm项目:
npm init -y
- 在项目目录中运行以下命令初始化npm项目:
-
安装TypeScript:
- 全局安装TypeScript编译器:
npm install -g typescript
- 在项目中本地安装TypeScript及其类型定义文件:
npm install typescript @types/node --save-dev
- 全局安装TypeScript编译器:
-
配置TSLint/ESLint:
-
安装ESLint及其TypeScript插件:
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
-
创建
.eslintrc.js
文件并配置ESLint:/* eslint-env node */ // 此文件声明了 ESLint 在 Node.js 环境下运行 module.exports = { // extends 属性用于扩展已有的 ESLint 配置 extends: [ 'eslint:recommended', // 启用 ESLint 内置的推荐规则集 'plugin:@typescript-eslint/strict', // 启用 TypeScript-ESLint 插件的严格规则集 'plugin:@typescript-eslint/stylistic', // 启用 TypeScript-ESLint 插件的风格规则集 ], // parser 属性指定了用于解析代码的解析器 parser: '@typescript-eslint/parser', // 使用 TypeScript-ESLint 的解析器,以支持 TypeScript 语法 // plugins 属性指定了 ESLint 插件 plugins: ['@typescript-eslint'], // 加载 TypeScript-ESLint 插件,以便使用其规则 // root 属性表示这是项目的根配置文件,ESLint 不会向上查找其他配置文件 root: true, };
注意,eslint官方推荐了另外一种方式来使用eslint。有兴趣可以去看看@Getting Started | typescript-eslint
-
-
创建TypeScript配置文件:
- 运行以下命令生成
tsconfig.json
文件:tsc --init
- 配置
tsconfig.json
:{ "compilerOptions": { "target": "ES2020", // 指定 ECMAScript 目标版本为 ES2020,以支持现代 JavaScript 特性 "module": "commonjs", // 将模块解析设置为 CommonJS,以便与 Node.js 兼容 "strict": true, // 启用所有严格类型检查选项,以增强代码的类型安全性 "esModuleInterop": true, // 启用对 ES 模块的互操作性,以便使用 `import` 语句导入 CommonJS 模块 "skipLibCheck": true, // 跳过对声明文件(.d.ts 文件)的类型检查,以加快编译速度 "forceConsistentCasingInFileNames": true, // 强制文件名一致大小写,以避免在不同操作系统上的文件名大小写问题 "outDir": "./dist", // 指定编译输出目录为 `./dist` "rootDir": "./src" // 指定输入文件的根目录为 `./src` }, "include": ["src"] // 指定要包含在编译中的文件或目录 }
- 运行以下命令生成
1.3.2 创建基础项目结构
-
创建目录结构:
- 创建项目的基本目录结构:
mkdir src mkdir src/controllers src/models src/routes src/middlewares src/utils touch src/index.ts
- 创建项目的基本目录结构:
-
安装Express:
- 安装Express及其类型定义文件:
npm install express npm install @types/express --save-dev
- 安装Express及其类型定义文件:
-
创建基本的Express服务器:
- 在
src/index.ts
中创建一个基础的Express服务器:import express, { Request, Response } from 'express'; const app = express(); const port = process.env.PORT || 3000; app.get('/', (req: Request, res: Response) => { res.send('Hello, Object Storage System!'); }); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); });
- 在
-
编译并运行项目:
- 在
package.json
中添加脚本来编译和运行项目:"scripts": { "build": "tsc", "start": "node dist/index.js", "dev": "ts-node-dev src/index.ts" }
- 安装
ts-node-dev
用于开发环境下的自动重启:npm install ts-node-dev --save-dev
- 运行开发服务器:
npm run dev > ore@0.0.1 dev > ts-node-dev src/index.ts [INFO] 10:30:48 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.2, typescript ver. 5.5.3) Server is running on http://localhost:3000
- 在
1.4 配置Express框架
1.4.1 解释每个中间件的作用和配置方法
1.5 项目目录结构设计
1.5.1 详细说明每个目录和文件的用途
src/controllers
:存放控制器文件,处理具体的业务逻辑和请求响应。src/models
:存放数据模型文件,定义数据库模式和数据结构。src/routes
:存放路由文件,定义API路由和请求处理。src/middlewares
:存放中间件文件,处理请求的预处理和后处理逻辑。src/utils
:存放工具函数和通用模块,提供辅助功能。src/index.ts
:项目的入口文件,配置和启动Express服务器。
1.6 配置TypeScript编译
1.6.1 提供一个简单的示例代码
-
配置TypeScript编译:
- 确保
tsconfig.json
配置正确,指定rootDir
为src
,outDir
为dist
。
- 确保
-
编写示例代码:
-
在
src/controllers/helloController.ts
中添加示例控制器代码:import { Request, Response } from 'express'; export const helloController = (req: Request, res: Response) => { res.send('Hello from the controller!'); };
-
在
src/routes/helloRoute.ts
中添加示例路由代码:import { Router } from 'express'; import { helloController } from '../controllers/helloController'; const router = Router(); router.get('/hello', helloController); export default router;
-
在
src/index.ts
中使用示例路由:import express from "express"; import cors from "cors"; import morgan from "morgan"; import helloRoute from "./routes/helloRoute"; const app = express(); const port = process.env.PORT || 3000; // 配置中间件 app.use(express.json()); // 使用 Express 内置的 JSON 解析中间件 app.use(express.urlencoded({ extended: true })); // 使用 Express 内置的 URL 编码解析中间件 app.use(cors()); app.use(morgan("dev")); // 配置路由 app.use("/api", helloRoute); app.get("/", (req, res) => { res.send("Hello, Object Storage System!"); }); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); });
-
-
编译并运行项目:
- 运行以下命令编译TypeScript代码:
npm run build
- 运行以下命令启动编译后的项目:
npm run start
- 访问
http://localhost:3000/api/hello
,应看到控制器返回的Hello from the controller!
消息。
- 运行以下命令编译TypeScript代码:
通过本章的学习,我们已经成功搭建了Express + TypeScript项目的开发环境,并创建了项目的基础结构。我们详细介绍了项目的目标和技术栈选择,完成了TypeScript的安装和配置,创建了基础的项目目录结构,并配置了Express框架和常用中间件。这些准备工作为我们后续的开发打下了坚实的基础。
在接下来的章节中,我们将深入探讨用户管理、文件上传与下载、文件元数据管理、权限控制与安全机制等核心功能的实现。通过逐步构建和完善这些功能,我们将最终实现一个高效、安全、可靠的对象存储系统。让我们继续前行,迎接下一章的挑战吧!
转载自:https://juejin.cn/post/7389800357427609637