使用Node.js分片上傳大文件到阿里云OSS

阿里云OSS的分片上傳(Multipart Upload)是一種針對大文件優化的上傳方式,其核心流程和關鍵特性如下:

1. ?核心流程?
分片上傳分為三個步驟:

  • 初始化任務?:調用InitiateMultipartUpload接口創建上傳任務,獲取唯一標識(Upload ID)。
  • 上傳分片?:通過UploadPart接口并發上傳切分后的文件塊(Part),每個Part需指定序號(partNumber),但上傳順序不影響最終合并。
  • 合并文件?:調用CompleteMultipartUpload接口將所有Part按序號合并為完整文件。若中途放棄上傳,需調用AbortMultipartUpload清理未完成的Part。

2. 適用場景?

  • 大文件加速上傳?:文件超過5GB時,分片上傳通過并行傳輸顯著提升速度。
  • 網絡環境波動?:單個Part失敗僅需重傳該部分,避免全文件重傳。
  • 暫停與恢復?:任務無過期時間,可隨時中斷后繼續上傳。
  • 未知文件大小?:如視頻監控等場景,可在文件生成過程中開始上傳。

3. 技術細節與建議?

  • ?分片大小?:官方建議文件大于100MB時采用分片上傳,過小分片可能導致進度顯示異常。
  • 并發控制?:并非并發數越多越快,需權衡網絡帶寬和設備負載。
  • ?安全實踐?:瀏覽器端使用時應通過臨時訪問憑證(STS)授權,避免暴露主賬號密鑰。
  • ?跨域配置?:瀏覽器直接上傳需預先設置OSS的CORS規則。

4. 操作方式?

  • 工具支持?:OSS控制臺不支持分片上傳,需使用ossbrowser(圖形化工具)、ossutil(命令行)或SDK(如Browser.js、阿里云SDK)。
  • 代碼示例?:Vue項目中可通過ali-oss SDK實現分片上傳,結合進度條組件(如Element UI)提升用戶體驗。

5. 注意事項?

  • ?碎片清理?:未完成的分片會占用存儲空間,需手動調用AbortMultipartUpload或配置生命周期規則自動清理。
  • 費用影響:未清理的分片會產生存儲費用,每月費用 = 分片大小 × 分片數量 × 存儲單價 × 存儲天數。始終對放棄的上傳調用
    abortMultipartUpload
  • 自動清理機制:OSS 默認 7 天后清理未完成的分片。可通過生命周期規則縮短:
xml:
<LifecycleConfiguration><Rule><AbortIncompleteMultipartUpload><DaysAfterInitiation>1</DaysAfterInitiation> <!-- 1天后清理 --></AbortIncompleteMultipartUpload></Rule>
</LifecycleConfiguration>
  • API靈活性?:若需高度定制化,可直接調用REST API(需自行計算簽名)。
    在這里插入圖片描述

一:阿里官方文檔:Node.js用一個步驟實現分片上傳
二:阿里官方文檔:Node.js分三個步驟實現分片上傳,可擴展暫停/繼續上傳和取消上傳操作
在這里插入圖片描述

一個步驟實現:

以上分片上傳完整示例調用的方法multipartUpload中封裝了初始化分片上傳、上傳分片以及完成分片上傳三個API接口。如果您希望分步驟實現分片上傳,請依次調用.initMultipartUpload、.uploadPart以及.completeMultipartUpload方法。
在這里插入圖片描述
在這里插入圖片描述

<template><div class="upload-container"><el-upload ref="upload" drag action="" :auto-upload="false" :on-change="handleFileChange" :limit="1" :on-exceed="handleExceed"><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div></el-upload><el-button style="margin-top: 20px;" type="primary" @click="uploadFile" :disabled="!isupload">開始上傳</el-button><el-progress v-if="uploading" :text-inside="true" :stroke-width="26" :percentage="uploadPercentage"></el-progress></div>
</template><script>
import OSS from 'ali-oss'; // npm install ali-oss
import md5 from 'js-md5'; // npm install js-md5
export default {data() {return {file: null,uploading: false,isupload: false,uploadPercentage: 0,};},methods: {handleFileChange(file) {this.file = file.raw;this.isupload = true;},handleExceed() {this.$message.warning('只能上傳一個文件');},async uploadFile() {if (!this.file) {this.$message.error('請先選擇文件');return;}this.uploading = true;try {let content = this.setConfig(this.$ossConfig);//這里涉及身份識別,我這里是取接口返回在解密獲得(如上圖),下同,不再解釋console.log(content)const client = new OSS({region: content.region,bucket: content.bucket,accessKeyId: content.accessKeyId,accessKeySecret: content.accessKeySecret,stsToken: content.securityToken,});const fileName = `uploads/${this.file.name}`;const options = {partSize: 1024 * 1024 * 5, // 分片大小為 5MBparallel: 3, // 并發上傳的分片數量progress: (p, cpt, res) => {this.uploadPercentage = Math.round(p * 100);},};const result = await client.multipartUpload(fileName, this.file, options);this.$message.success('文件上傳成功');console.log('Upload result:', result);} catch (error) {this.$message.error('文件上傳失敗');console.error('Upload error:', error);} finally {this.uploading = false;this.uploadPercentage = 0;}},setConfig(content) {let Base64 = require('js-base64').Base64let str1 = Base64.decode(content.substr(1, 3) + content.substr(5, 3) + content.substr(9, content.length - 9));let contentN = Base64.decode(str1.substr(1, 3) + str1.substr(5, 3) + str1.substr(9, str1.length - 9));return JSON.parse(contentN);},},
};
</script><style scoped>
.upload-container {max-width: 600px;margin: 20px auto;padding: 20px;border: 1px solid #ebeef5;border-radius: 4px;
}
</style>

效果:
在這里插入圖片描述
在這里插入圖片描述

擴展:一個步驟擴展暫停/繼續上傳、取消上傳

<template><div class="upload-container"><!-- <el-upload ref="uploadRef" class="upload-demo" drag :action="''" :auto-upload="false" :show-file-list="false" accept="*" :limit="2" :on-change="handleChange" :on-exceed="handleExceed"> --><el-upload ref="uploadRef" class="upload-demo" drag :action="''" :auto-upload="true" :show-file-list="false" accept="*" :limit="1" :before-upload="handleChange"><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳3</em></div></el-upload><div v-if="file" class="file-info"><div>文件名稱: {{ file.name }}</div><div>文件大小: {{ formatFileSize(file.size) }}</div><div>分片大小: {{ (chunkSize / 1024 / 1024).toFixed(2) }} MB</div><div>分片數量: {{ chunks }}</div></div><el-progress v-if="showProgress && !isUploaded" :percentage="percentage" :status="uploadStatus" :stroke-width="16" style="margin: 20px 0"></el-progress><el-button v-if="isUploaded" type="text">上傳成功</el-button><div v-if="showButtons"><!-- <el-button type="primary" @click="submitForm" v-if="!isUploading && !isUploaded && !tempCheckpoint">開始上傳</el-button> --><el-button type="primary" icon="el-icon-refresh-left" @click="submitForm" v-if="!isUploading && !isUploaded && !tempCheckpoint">重試</el-button><el-button type="text" @click="shareclearn" v-if="isUploaded">分享 | 清除記錄</el-button><el-button type="primary" icon="el-icon-video-pause" @click="pauseUpload()" v-if="paused && isUploading && !isUploaded">暫停上傳</el-button><el-button type="primary" icon="el-icon-video-play" @click="resumeUpload()" v-if="!paused && !isUploaded">繼續上傳</el-button><el-button type="danger" icon="el-icon-circle-close" @click="cancelUpload" v-if="!isUploaded && tempCheckpoint">取消上傳</el-button></div></div>
</template><script>
import OSS from 'ali-oss'
import md5 from 'js-md5'export default {data() {return {client: null,parallel: 3, // 并發上傳的分片數量chunkSize: 2 * 1024 * 1024, // 分片大小 2MBchunks: 0,// 總分片數量file: null,ossKey: '',uploadStatus: null, // 進度條上傳狀態percentage: 0, // 進度條百分比showProgress: false,// 是否顯示進度條showButtons: false,// 是否顯示按鈕tempCheckpoint: null, // 用于緩存當前切片內容uploadId: '',isUploading: false,// 是否上傳中isUploaded: false,//是否上傳完畢paused: true,//是否暫停};},created() {this.initOSSClient();},methods: {async initOSSClient() {try {let content = this.setConfig(this.$ossConfig);console.log(content)this.client = new OSS({region: content.region,bucket: content.bucket,accessKeyId: content.accessKeyId,accessKeySecret: content.accessKeySecret,stsToken: content.securityToken,});} catch (error) {console.error('OSS初始化失敗:', error);this.$message.error('上傳服務初始化失敗');}},setConfig(content) {let Base64 = require('js-base64').Base64let str1 = Base64.decode(content.substr(1, 3) + content.substr(5, 3) + content.substr(9, content.length - 9));let contentN = Base64.decode(str1.substr(1, 3) + str1.substr(5, 3) + str1.substr(9, str1.length - 9));return JSON.parse(contentN);},// 選擇文件async handleChange(file) {// console.log(file)this.resetState();this.file = file//.raw;this.ossKey = `uploads/${Date.now()}_${this.file.name}`;this.chunks = Math.ceil(this.file.size / this.chunkSize);this.showButtons = true;this.submitForm();},// 開始上傳submitForm() {this.initMultipartUpload();this.multipartUpload();},// 初始化分片上傳async initMultipartUpload() {const result = await this.client.initMultipartUpload(this.ossKey);this.uploadId = result.uploadId;console.log(`初始化分片上傳成功, uploadId: ${this.uploadId}`);},// 開始分片上傳async multipartUpload() {if (!this.file) {this.$message.error('請選擇文件');return;}this.uploadStatus = null;this.percentage = 0;this.showProgress = true;this.isUploading = true;try {const result = await this.client.multipartUpload(this.file.name, this.file, {progress: (p, checkpoint) => {this.tempCheckpoint = checkpoint;// this.uploadId = checkpoint.uploadId;this.percentage = Math.floor(p * 100);},parallel: this.parallel,partSize: this.chunkSize,});this.uploadStatus = 'success';this.isUploading = false;this.isUploaded = true;this.$message.success('上傳成功');console.log(result, '切片上傳完畢');} catch (e) {if (e.code === 'ConnectionTimeoutError') {this.uploadStatus = 'exception';window.addEventListener('online', this.resumeUpload);}this.isUploading = false;console.error(e);}},// 取消上傳cancelUpload() {this.pauseUpload();this.paused = true;this.showProgress = false;this.percentage = 0;this.uploadStatus = null;this.tempCheckpoint = null;this.uploadId = '';},// 暫停上傳pauseUpload() {this.isUploading = false;this.paused = false;this.client.cancel();},// 繼續上傳async resumeUpload() {if (!this.tempCheckpoint) {this.$message.error('請先上傳');return;}this.uploadStatus = null;this.isUploading = true;this.paused = true;try {const result = await this.client.multipartUpload(this.file.name, this.file, {progress: (p) => {this.percentage = Math.floor(p * 100);},checkpoint: this.tempCheckpoint,});this.uploadStatus = 'success';this.isUploading = false;this.isUploaded = true;this.$message.success('續傳成功');console.log(result, '恢復上傳完畢');} catch (e) {this.isUploading = false;console.error(e);}},// 重置resetState() {this.file = null;this.ossKey = '';this.uploadStatus = null;this.percentage = 0;this.showProgress = false;this.showButtons = false;this.tempCheckpoint = null;this.uploadId = '';this.isUploading = false;this.isUploaded = false;this.paused = true;},// 限制上傳一個文件,重新選擇文件替換原來的文件handleExceed(files) {// console.log(this.$refs.uploadRef)if (this.$refs.uploadRef.uploadFiles.length > 1) {this.$refs.uploadRef.uploadFiles.shift();}},// 格式化文件大小formatFileSize(size) {const units = ['B', 'KB', 'MB', 'GB'];let unitIndex = 0;while (size >= 1024 && unitIndex < units.length - 1) {size /= 1024;unitIndex++;}return `${size.toFixed(2)} ${units[unitIndex]}`;},shareclearn() {console.log('分享 | 清除記錄')},},
};
</script><style scoped>
.upload-container {width: 100%;max-width: 600px;margin: 0 auto;
}.el-button {margin-right: 10px;
}.file-info {margin: 20px 0;padding: 15px;background-color: #f8f9fa;border-radius: 4px;
}.file-info div {margin-bottom: 10px;color: #606266;
}
</style>

效果:

一個步驟分片上傳(擴展暫停繼續取消)

三個步驟實現:

<template><div class="upload-container"><!-- multiple drag on-change --><el-upload class="upload-demo" action="" :show-file-list="false" :auto-upload="true" :before-upload="handleFileChange" :accept="'*'"><!-- <i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div> --><el-button size="small" type="primary">選擇文件</el-button></el-upload><div class="file-info" v-if="file"><div>文件名: {{ file.name }}</div><div>文件大小: {{ formatFileSize(file.size) }}</div><div>分片大小: {{ (chunkSize / 1024 / 1024).toFixed(2) }} MB</div><div>分片數量: {{ chunks }}</div><el-progress v-if="isUploading" :percentage="progressPercent" :status="uploadStatus" :stroke-width="14"></el-progress><div><el-button type="primary" :icon="isPaused?'el-icon-video-play':'el-icon-video-pause'" @click="togglePause" v-if="isUploading">{{ isPaused ? '繼續' : '暫停' }}</el-button><el-button type="danger" icon="el-icon-circle-close" @click="cancelUpload" v-if="isUploading">取消</el-button><el-button type="primary" icon="el-icon-refresh-left" @click="startUpload" v-if="!isUploading && !uploaded">重試</el-button><el-button type="text" v-if="!isUploading && uploaded">分享 | 清除記錄</el-button></div></div></div>
</template><script>
import OSS from 'ali-oss'
import md5 from 'js-md5'export default {data() {return {file: null,chunkSize: 2 * 1024 * 1024, // 5MB 分片chunks: 0,                  // 分片數量uploadedChunks: [],  // 已上傳的分片索引uploadId: '',        // OSS 分片上傳 IDclient: null,        // OSS 客戶端isPaused: false,     // 是否暫停isUploading: false,  // 上傳中uploaded: false,     // 上傳完成progressPercent: 0,  // 進度條-百分比uploadStatus: null,  // 進度條-狀態concurrency: 3,      // 并發數activeChunks: 0,     // 當前活躍的分片數cancelTokens: {},    // 取消令牌parts: [],           // 分片列表};},created() {this.initOSSClient();},methods: {async initOSSClient() {// 這里應該從后端獲取臨時憑證(安全考慮)// 以下是模擬數據,實際使用需替換為真實接口const credentials = await this.getSTSToken();this.client = new OSS({region: credentials.region,accessKeyId: credentials.accessKeyId,accessKeySecret: credentials.accessKeySecret,stsToken: credentials.securityToken,bucket: credentials.bucket,refreshSTSToken: async () => {const newCredentials = await this.getSTSToken();return {accessKeyId: newCredentials.accessKeyId,accessKeySecret: newCredentials.accessKeySecret,stsToken: newCredentials.securityToken};}});},async getSTSToken() {// 實際項目中從這里獲取STS token// 示例返回結構:var content = this.setConfig(this.$ossConfig);console.log(content)return {region: content.region,bucket: content.bucket,accessKeyId: content.accessKeyId,accessKeySecret: content.accessKeySecret,securityToken: content.securityToken,};},setConfig(content) {let Base64 = require('js-base64').Base64let str1 = Base64.decode(content.substr(1, 3) + content.substr(5, 3) + content.substr(9, content.length - 9));let contentN = Base64.decode(str1.substr(1, 3) + str1.substr(5, 3) + str1.substr(9, str1.length - 9));return JSON.parse(contentN);},// 格式化文件大小formatFileSize(size) {const units = ['B', 'KB', 'MB', 'GB'];let unitIndex = 0;while (size >= 1024 && unitIndex < units.length - 1) {size /= 1024;unitIndex++;}return `${size.toFixed(2)} ${units[unitIndex]}`;},// 標準化ETag格式normalizeETag(etag) {let cleanETag = String(etag).replace(/^"+/, '').replace(/"+$/, '').replace(/\\/g, '');if (!/^[0-9A-F]{32}$/i.test(cleanETag)) {throw new Error(`無效的ETag格式: ${etag}`);}return `"${cleanETag}"`;},// 重置上傳resetState() {this.uploadedChunks = [];this.uploadId = '';this.isPaused = false;this.isUploading = false;this.uploaded = false;this.progressPercent = 0;this.uploadStatus = null;this.activeChunks = 0;this.cancelTokens = {};// // 取消所有進行中的請求// Object.values(this.cancelTokens).forEach(ctrl => ctrl.abort());// this.cancelTokens = {};// // 強制更新視圖// this.$nextTick();},handleFileChange(file) {// console.log(file)this.resetState();this.file = file;//file.raw;this.chunks = Math.ceil(this.file.size / this.chunkSize);this.startUpload();},// 1、初始化分片上傳async startUpload() {if (!this.file) return;try {this.isUploading = true;this.isPaused = false;if (!this.uploadId) {const result = await this.client.initMultipartUpload(this.file.name,{ timeout: 60000 });this.uploadId = result.uploadId;console.log(`初始化分片上傳成功, uploadId: ${this.uploadId}`);}// 獲取未上傳的分片const unuploaded = Array.from({ length: this.chunks }, (_, i) => i).filter(i => !this.uploadedChunks.includes(i));// 并發控制const uploadNext = async () => {if (this.isPaused || !this.isUploading) return;// 上傳完,合并分片if (unuploaded.length === 0 && this.activeChunks === 0) {await this.completeUpload();return;}if (this.activeChunks < this.concurrency && unuploaded.length > 0) {const chunkIndex = unuploaded.shift();this.activeChunks++;// 取消步驟一:創建取消令牌,取消正在進行的 HTTP 請求(分片上傳請求)const controller = new AbortController();this.cancelTokens[chunkIndex] = controller;// 2、調用上傳分片-sthis.uploadChunk(chunkIndex, controller.signal).then((res) => {// console.log(res)// console.log(chunkIndex)// this.parts.push({ partNumber: chunkIndex + 1, etag: res.etag });this.uploadedChunks.push(chunkIndex);this.updateProgress();}).catch(err => {if (err.name !== 'AbortError') {console.error(`分片 ${chunkIndex} 上傳失敗:`, err);}}).finally(() => {this.activeChunks--;delete this.cancelTokens[chunkIndex];uploadNext();});// 調用上傳分片-euploadNext();}};// 啟動并發上傳for (let i = 0; i < this.concurrency; i++) {uploadNext();}} catch (err) {console.error('上傳初始化失敗:', err);this.$message.error('上傳初始化失敗');this.resetState();}},// 2、分片上傳async uploadChunk(index, signal) {const start = index * this.chunkSize;const end = Math.min(start + this.chunkSize, this.file.size);const chunk = this.file.slice(start, end);return this.client.uploadPart(this.file.name,this.uploadId,index + 1,chunk,signal,);},// 3、完成上傳async completeUpload() {try {// 獲取已上傳分片列表const listParts = await this.client.listParts(this.file.name,this.uploadId,);// console.log(listParts)// 按分片號排序const sortedParts = listParts.parts.sort((a, b) => a.partNumber - b.partNumber);// console.log(sortedParts)this.parts = await sortedParts.map(p => ({number: Number(p.PartNumber),//!!!注意!!!鍵名只能用numberetag: this.normalizeETag(p.ETag),//!!!注意!!!鍵名只能用etag}))// console.log(this.parts)// 完成上傳const completeResult = await this.client.completeMultipartUpload(this.file.name,this.uploadId,this.parts,);console.log(completeResult)this.$message.success('完成上傳-成功');this.uploadStatus = 'success';this.uploaded = true;this.isUploading = false;} catch (err) {this.uploadStatus = 'exception';console.error('完成上傳-失敗:', err);this.$message.error('完成上傳-失敗');}},// 暫停/繼續 上傳togglePause() {this.isPaused = !this.isPaused;if (!this.isPaused) {this.startUpload();}},// 取消上傳 cancelUpload() {this.isUploading = false;// 取消所有正在上傳的分片Object.values(this.cancelTokens).forEach(controller => {controller.abort();});// 取消步驟二:清理OSS上傳記錄,清理掉OSS上存儲的所有已經上傳的分片,終止本次分片上傳過程,并刪除所有已上傳的分片數據。// 這樣確保不會在 OSS 上留下無效的分片數據,避免產生不必要的存儲費用。if (this.uploadId && this.file) {try {this.client.abortMultipartUpload(this.file.name, this.uploadId).finally(() => {this.resetState();}).catch((err) => {console.error('取消上傳失敗:', err)});} catch (err) {console.error('OSS清理異常:', err);}}this.$message.info('上傳已取消');// 使用Vue的強制更新視圖(針對Element UI進度條)this.$nextTick(() => {this.$forceUpdate();});},// 更新進度條updateProgress() {// 如果不在上傳狀態,不更新進度if (!this.isUploading) return;const percent = Math.round((this.uploadedChunks.length / this.chunks) * 100);this.progressPercent = Math.min(percent, 100);},}
};
</script><style scoped>
.upload-container {max-width: 600px;margin: 20px auto;padding: 20px;border: 1px solid #ebeef5;border-radius: 4px;
}
.upload-demo {width: 300px;margin: 0 auto;
}
.file-info {margin-top: 20px;padding: 15px;background-color: #f8f9fa;border-radius: 4px;
}
.file-info div {margin-bottom: 10px;color: #606266;
}
.el-progress {margin-top: 20px;
}
</style>

效果:

三個步驟分片上傳

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82712.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82712.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82712.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ if語句完全指南:從基礎到工程實踐

一、選擇結構在程序設計中的核心地位 程序流程控制如同城市交通網絡&#xff0c;if語句則是這個網絡中的決策樞紐。根據ISO C標準&#xff0c;選擇結構占典型項目代碼量的32%-47%&#xff0c;其正確使用直接影響程序的&#xff1a; 邏輯正確性 執行效率 可維護性 安全邊界 …

【大模型LLM學習】Flash-Attention的學習記錄

【大模型LLM學習】Flash-Attention的學習記錄 0. 前言1. flash-attention原理簡述2. 從softmax到online softmax2.1 safe-softmax2.2 3-pass safe softmax2.3 Online softmax2.4 Flash-attention2.5 Flash-attention tiling 0. 前言 Flash Attention可以節約模型訓練和推理時間…

python打卡day46@浙大疏錦行

知識點回顧&#xff1a; 不同CNN層的特征圖&#xff1a;不同通道的特征圖什么是注意力&#xff1a;注意力家族&#xff0c;類似于動物園&#xff0c;都是不同的模塊&#xff0c;好不好試了才知道。通道注意力&#xff1a;模型的定義和插入的位置通道注意力后的特征圖和熱力圖 內…

JavaSec-SPEL - 表達式注入

簡介 SPEL(Spring Expression Language)&#xff1a;SPEL是Spring表達式語言&#xff0c;允許在運行時動態查詢和操作對象屬性、調用方法等&#xff0c;類似于Struts2中的OGNL表達式。當參數未經過濾時&#xff0c;攻擊者可以注入惡意的SPEL表達式&#xff0c;從而執行任意代碼…

SpringCloud——OpenFeign

概述&#xff1a; OpenFeign是基于Spring的聲明式調用的HTTP客戶端&#xff0c;大大簡化了編寫Web服務客戶端的過程&#xff0c;用于快速構建http請求調用其他服務模塊。同時也是spring cloud默認選擇的服務通信工具。 使用方法&#xff1a; RestTemplate手動構建: // 帶查詢…

【深入學習Linux】System V共享內存

目錄 前言 一、共享內存是什么&#xff1f; 共享內存實現原理 共享內存細節理解 二、接口認識 1.shmget函數——申請共享內存 2.ftok函數——生成key值 再次理解ftok和shmget 1&#xff09;key與shmid的區別與聯系 2&#xff09;再理解key 3&#xff09;通過指令查看/釋放系統中…

探索 Java 垃圾收集:對象存活判定、回收流程與內存策略

個人主頁-愛因斯晨 文章專欄-JAVA學習筆記 熱門文章-賽博算命 一、引言 在 Java 技術體系里&#xff0c;垃圾收集器&#xff08;Garbage Collection&#xff0c;GC&#xff09;與內存分配策略是自動內存管理的核心支撐。深入探究其原理與機制&#xff0c;對優化程序內存性能…

hbase資源和數據權限控制

hbase適合大數據量下點查 https://zhuanlan.zhihu.com/p/471133280 HBase支持對User、NameSpace和Table進行請求數和流量配額限制&#xff0c;限制頻率可以按sec、min、hour、day 對于請求大小限制示例&#xff08;5K/sec,10M/min等&#xff09;&#xff0c;請求大小限制單位如…

大數據-275 Spark MLib - 基礎介紹 機器學習算法 集成學習 隨機森林 Bagging Boosting

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; 大模型篇章已經開始&#xff01; 目前已經更新到了第 22 篇&#xff1a;大語言模型 22 - MCP 自動操作 FigmaCursor 自動設計原型 Java篇開…

Delphi 實現遠程連接 Access 數據庫的指南

方法一&#xff1a;通過局域網共享 Access 文件&#xff08;簡單但有限&#xff09; 步驟 1&#xff1a;共享 Access 數據庫 將 .mdb 或 .accdb 文件放在局域網內某臺電腦的共享文件夾中。 右鍵文件夾 → 屬性 → 共享 → 啟用共享并設置權限&#xff08;需允許網絡用戶讀寫&a…

VR視頻制作有哪些流程?

VR視頻制作流程知識 VR視頻制作&#xff0c;作為融合了創意與技術的復雜制作過程&#xff0c;涵蓋從初步策劃到最終呈現的多個環節。在這個過程中&#xff0c;我們可以結合眾趣科技的產品&#xff0c;解析每一環節的實現與優化&#xff0c;揭示背后的奧秘。 VR視頻制作有哪些…

文件上傳/下載接口開發

接口特性 文件傳輸接口與傳統接口的核心差異體現在數據傳輸格式&#xff1a; 上傳接口采用 multipart/form-data 格式支持二進制文件傳輸下載接口接收二進制流并實現本地文件存儲 文件上傳接口開發 接口規范 請求地址&#xff1a;/createbyfile 請求方式&#xff1a;POST…

深入學習RabbitMQ隊列的知識

目錄 1、AMQP協議 1.1、介紹 1.2、AMQP的特點 1.3、工作流程 1.4、消息模型 1.5、消息結構 1.6、AMQP 的交換器類型 2、RabbitMQ結構介紹 2.1、核心組件 2.2、最大特點 2.3、工作原理 3、消息可靠性保障 3.1、生產端可靠性 1、生產者確認機制 2、持久化消息 3.…

【計算機網絡】NAT、代理服務器、內網穿透、內網打洞、局域網中交換機

&#x1f525;個人主頁&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收錄專欄&#x1f308;&#xff1a;計算機網絡 &#x1f339;往期回顧&#x1f339;&#xff1a;【計算機網絡】數據鏈路層——ARP協議 &#x1f516;流水不爭&#xff0c;爭的是滔滔不息 一、網絡地址轉…

[論文閱讀] 人工智能 | 大語言模型計劃生成的新范式:基于過程挖掘的技能學習

#論文閱讀# 大語言模型計劃生成的新范式&#xff1a;基于過程挖掘的技能學習 論文信息 Skill Learning Using Process Mining for Large Language Model Plan Generation Andrei Cosmin Redis, Mohammadreza Fani Sani, Bahram Zarrin, Andrea Burattin Cite as: arXiv:2410.…

C文件操作2

五、文件的隨機讀寫 這些函數都需要包含頭文件 #include<stdio.h> 5.1 fseek 根據文件指針的位置和偏移量來定位文件指針&#xff08;文件內容的光標&#xff09; &#xff08;重新定位流位置指示器&#xff09; int fseek ( FILE * stream, long int offset, int or…

react私有樣式處理

react私有樣式處理 Nav.jsx Menu.jsx vue中通過scoped來實現樣式私有化。加上scoped&#xff0c;就屬于當前組件的私有樣式。 給視圖中的元素都加了一個屬性data-v-xxx&#xff0c;然后給這些樣式都加上屬性選擇器。&#xff08;deep就是不加屬性也不加屬性選擇器&#xff09; …

【信創-k8s】海光/兆芯+銀河麒麟V10離線部署k8s1.31.8+kubesphere4.1.3

? KubeSphere V4已經開源半年多&#xff0c;而且v4.1.3也已經出來了&#xff0c;修復了眾多bug。介于V4優秀的LuBan架構&#xff0c;核心組件非常少&#xff0c;資源占用也顯著降低&#xff0c;同時帶來眾多功能和便利性。我們決定與時俱進&#xff0c;使用1.30版本的Kubernet…

單片機內部結構基礎知識 FLASH相關解讀

一、總線簡單說明 地址總線、控制總線、數據總線 什么是8位8051框架結構的微控制器&#xff1f; 數據總線寬度為8位&#xff0c;即CPU一次處理或傳輸的數據量為8位&#xff08;1字節&#xff09; 同時還有一個16位的地址總線&#xff0c;這個地方也剛好對應了為什么能看到內存…

HTTPS加密的介紹

HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff0c;超文本傳輸安全協議&#xff09;是HTTP協議的安全版本。它在HTTP的基礎上加入了SSL/TLS協議&#xff0c;用于對數據進行加密&#xff0c;并確保數據傳輸過程中的機密性、完整性和身份驗證。 在HTTPS出現之前&a…