All Products
Search
Document Center

Function Compute:Gunakan Function Compute untuk mendekompresi file ZIP yang diunggah ke OSS secara otomatis

Last Updated:Apr 02, 2026

Saat file ZIP diunggah ke Object Storage Service (OSS), Function Compute dapat secara otomatis mendekompresinya dan menulis file hasil ekstraksi ke lokasi yang ditentukan dalam bucket yang sama. Hal ini menghilangkan kebutuhan untuk menjalankan infrastruktur dekompresi dan memungkinkan skala sesuai dengan volume unggahan Anda.

Cara kerja

  1. File ZIP yang diunggah ke bucket OSS memicu notifikasi event OSS.

  2. Pemicu OSS memanggil fungsi Function Compute dan meneruskan muatan event yang mencakup nama bucket, kunci objek, dan wilayah.

  3. Fungsi tersebut mengunduh file ZIP langsung dari OSS sebagai objek streaming, mendekompresinya di memori, lalu mengunggah setiap file hasil ekstraksi ke awalan output yang dikonfigurasi dalam bucket yang sama.

Catatan penggunaan

  • Gunakan encoding UTF-8 atau GB2312 untuk nama file dan folder guna menghindari teks rusak selama dekompresi.

  • Pulihkan objek Archive atau Cold Archive sebelum mendekompresinya.

  • Tugas dekompresi yang melebihi 2 jam akan gagal. Pastikan ukuran file individual dalam file ZIP tetap di bawah 1 GB untuk menghindari kegagalan dekompresi.

  • Atur timeout fungsi lebih dari 2 jam, tetapi tidak lebih dari 24 jam.

  • Buat fungsi di wilayah yang sama dengan bucket OSS.

Peringatan

Jika awalan output pemicu OSS tumpang tindih dengan awalan input, setiap unggahan file hasil ekstraksi akan memicu fungsi lagi, menyebabkan loop tak berujung. Gunakan awalan yang berbeda untuk input dan output — misalnya, src/ untuk file ZIP masuk dan processed/ untuk output hasil ekstraksi.

Prasyarat

Sebelum memulai, pastikan Anda telah:

Langkah 1: Buat fungsi

  1. Login ke Konsol Function Compute. Di panel navigasi kiri, klik Functions.

  2. Di bilah navigasi atas, pilih wilayah. Pada halaman Functions, klik Create Function.

  3. Pada halaman Create Function, konfigurasikan item kunci berikut, lalu klik Create. Untuk item lainnya, lihat Buat fungsi.

    • Runtime: Pilih Python 3.10.

    • Function Role: Pilih peran RAM yang sudah ada atau buat yang baru. Sambungkan kebijakan AliyunOSSFullAccess untuk memberikan akses fungsi ke bucket OSS.

  4. Pada halaman detail fungsi, klik tab Code. Di editor kode, buat file berikut dan tempel kode yang sesuai, lalu klik Deploy.

index.py

Fungsi handler adalah titik masuk. Fungsi ini membaca event OSS untuk mendapatkan nama bucket, wilayah, dan kunci objek, kemudian melakukan streaming file ZIP dari OSS dan mengunggah setiap file hasil ekstraksi ke awalan output.

<details> <summary>Klik untuk melihat contoh kode</summary>

# -*- coding: utf-8 -*-
'''
Pernyataan:
Fungsi ini menamai dan mengencode file serta folder sebagai berikut:
1. Untuk MAC/Linux, encoding UTF-8 digunakan secara default.
2. Untuk Windows, encoding GB2312 atau UTF-8 digunakan secara default.

Untuk encoding lainnya, deteksi encoding dilakukan menggunakan library chardet;
namun, akurasi 100% tidak dijamin.
Tulis ulang fungsi ini hanya jika diperlukan, dan pastikan lolos debugging.
'''

import helper
import oss2
import json
import os
import time
import logging
import chardet

"""
Ketika objek dengan awalan source/ ditempatkan di bucket OSS, diharapkan objek tersebut akan didekompresi lalu disimpan di bucket dengan awalan processed/.
Misalnya, source/a.zip akan diproses menjadi processed/a/...
"Source /", "processed/" dapat diubah sesuai kebutuhan.
"""
# Nonaktifkan log info yang dicetak oleh SDK OSS
logging.getLogger("oss2.api").setLevel(logging.ERROR)
logging.getLogger("oss2.auth").setLevel(logging.ERROR)

LOGGER = logging.getLogger()

# Dekorator untuk mencetak waktu eksekusi fungsi


def print_excute_time(func):
    def wrapper(*args, **kwargs):
        local_time = time.time()
        ret = func(*args, **kwargs)
        LOGGER.info('current Function [%s] excute time is %.2f' %
                    (func.__name__, time.time() - local_time))
        return ret
    return wrapper


def get_zipfile_name(origin_name):  # Mengatasi masalah teks Cina yang rusak
    name = origin_name
    try:
        name_bytes = origin_name.encode(encoding="cp437")
    except:
        name_bytes = origin_name.encode(encoding="utf-8")

    # Jika string yang akan dideteksi cukup panjang, akurasi hasil deteksi lebih tinggi
    detect = chardet.detect(name_bytes)
    confidence = detect["confidence"]
    detect_encoding = detect["encoding"]
    if confidence > 0.75 and (detect_encoding.lower() in ["gb2312", "gbk", "gb18030", "ascii", "utf-8"]):
        try:
            if detect_encoding.lower() in ["gb2312", "gbk", "gb18030"]:
                detect_encoding = "gb18030"
            name = name_bytes.decode(detect_encoding)
        except:
            name = name_bytes.decode(encoding="gb18030")
    else:
        try:
            name = name_bytes.decode(encoding="gb18030")
        except:
            name = name_bytes.decode(encoding="utf-8")
    # Perbaiki \\ windows sebagai segmen direktori
    name = name.replace("\\", "/")
    return name


@print_excute_time
def handler(event, context):
    """
    Objek dari OSS akan didekompresi secara otomatis.
    param: event:   String JSON event OSS, termasuk URI objek OSS dan informasi lainnya.

    param: context: Konteks fungsi, termasuk kredensial dan informasi waktu proses.

    """
    evt_lst = json.loads(event)
    creds = context.credentials
    auth = oss2.StsAuth(
        creds.access_key_id,
        creds.access_key_secret,
        creds.security_token)

    evt = evt_lst['events'][0]
    bucket_name = evt['oss']['bucket']['name']
    endpoint = 'oss-' + evt['region'] + '-internal.aliyuncs.com'
    bucket = oss2.Bucket(auth, endpoint, bucket_name)
    object_name = evt['oss']['object']['key']

    if "ObjectCreated:PutSymlink" == evt['eventName']:
        object_name = bucket.get_symlink(object_name).target_key
        if object_name == "":
            raise RuntimeError('{} adalah file symlink yang tidak valid'.format(
                evt['oss']['object']['key']))

    file_type = os.path.splitext(object_name)[1]

    if file_type != ".zip":
        raise RuntimeError('{} bukan file zip'.format(object_name))

    LOGGER.info("mulai mendekompresi file zip = {}".format(object_name))

    lst = object_name.split("/")
    zip_name = lst[-1]
    PROCESSED_DIR = os.environ.get("PROCESSED_DIR", "")
    RETAIN_FILE_NAME = os.environ.get("RETAIN_FILE_NAME", "")
    if PROCESSED_DIR and PROCESSED_DIR[-1] != "/":
        PROCESSED_DIR += "/"
    if RETAIN_FILE_NAME == "false":
        newKey = PROCESSED_DIR
    else:
        newKey = PROCESSED_DIR + zip_name

    zip_fp = helper.OssStreamFileLikeObject(bucket, object_name)
    newKey = newKey.replace(".zip", "/")

    with helper.zipfile_support_oss.ZipFile(zip_fp) as zip_file:
        for name in zip_file.namelist():
            with zip_file.open(name) as file_obj:
                name = get_zipfile_name(name)
                bucket.put_object(newKey + name, file_obj)

</details>

helper.py

File helper.py membungkus bucket OSS sebagai objek mirip file sehingga library ZIP dapat membaca langsung dari OSS tanpa mengunduh seluruh file terlebih dahulu.

<details> <summary>Klik untuk melihat contoh kode</summary>

# -*- coding: utf-8 -*-
import oss2
from oss2 import utils, models
import ossZipfile as zipfile

zipfile_support_oss = zipfile

# Mendukung unggah ke OSS sebagai objek mirip file


def make_crc_adapter(data, init_crc=0):
    data = utils.to_bytes(data)
    # Objek mirip file
    if hasattr(data, 'read'):
        return utils._FileLikeAdapter(data, crc_callback=utils.Crc64(init_crc))


utils.make_crc_adapter = make_crc_adapter


class OssStreamFileLikeObject(object):
    def __init__(self, bucket, key):
        super(OssStreamFileLikeObject, self).__init__()
        self._bucket = bucket
        self._key = key
        self._meta_data = self._bucket.get_object_meta(self._key)

    @property
    def bucket(self):
        return self._bucket

    @property
    def key(self):
        return self._key

    @property
    def filesize(self):
        return self._meta_data.content_length

    def get_reader(self, begin, end):
        begin = begin if begin >= 0 else 0
        end = end if end > 0 else self.filesize - 1
        end = end if end < self.filesize else self.filesize - 1
        begin = begin if begin < end else end
        return self._bucket.get_object(self._key, byte_range=(begin, end))

    def get_content_bytes(self, begin, end):
        reader = self.get_reader(begin, end)
        return reader.read()

    def get_last_content_bytes(self, offset):
        return self.get_content_bytes(self.filesize-offset, self.filesize-1)

</details>

ossZipfile.py

File ossZipfile.py adalah versi modifikasi dari modul zipfile standar Python yang mendukung pembacaan entri ZIP sebagai rentang byte dari OSS, bukan dari file lokal. Salin seluruh isi ossZipfile.py dari dokumen sumber dan tempelkan ke file ini di editor kode.

Langkah 2: Buat pemicu OSS

  1. Pada halaman detail fungsi, klik tab Configurations, lalu klik Triggers di panel navigasi kiri.

  2. Klik Create Trigger. Di panel yang terbuka, pilih jenis pemicu OSS dan konfigurasikan item kunci berikut, lalu klik OK. Untuk item lainnya, lihat Konfigurasi pemicu OSS native.

    ItemNilai contoh
    Bucket NamePilih bucket yang telah Anda buat
    Object Prefixsrc
    Object Suffixzip
    Trigger Eventoss:ObjectCreated:PutObject, oss:ObjectCreated:PostObject, oss:ObjectCreated:CompleteMultipartUpload, oss:ObjectCreated:PutSymlink
    Role NamePilih peran RAM dengan kebijakan AliyunFCFullAccess

Setelah pemicu dibuat, pemicu tersebut akan muncul di halaman Triggers.

Langkah 3: Uji dan verifikasi

Gunakan salah satu metode berikut untuk memastikan pipeline berfungsi dari ujung ke ujung.

Metode 1: Unggah file melalui Konsol OSS

  1. Login ke Konsol Object Storage Service.

  2. Unggah file ZIP (misalnya, code.zip) ke awalan src/ bucket yang Anda pilih di Langkah 2.

  3. Setelah unggahan selesai, buka daftar file bucket dan pastikan file hasil ekstraksi muncul di direktori root (atau di awalan output yang Anda konfigurasi).

Metode 2: Picu fungsi dengan event uji

Gunakan metode ini untuk menguji logika fungsi tanpa mengunggah file nyata — berguna saat melakukan iterasi pada kode fungsi.

  1. Pada halaman detail fungsi, klik tab Code. Klik ikon dropdown icon di samping Test Function dan pilih Configure Test Parameters.

  2. Di panel Configure Test Parameters, pilih Event Template, masukkan Event Name, tempel muatan event berikut, lalu klik OK.

    Penting

    File ZIP yang ditentukan oleh object.key harus sudah ada di bucket. Jika tidak, pemanggilan fungsi akan gagal.

    ParameterFormatTempat menemukannya
    bucket.arnacs:oss:<region>:<account_id>:<bucket_name>ID Akun terdapat di halaman Overview Konsol Function Compute
    bucket.nameNama bucket AndaKonsol OSS
    bucket.ownerIdentityID akun Alibaba Cloud AndaPusat akun
    object.keyJalur ke file ZIP yang ada di bucket, misalnya src/test.zipKonsol OSS
    regionWilayah tempat Anda membuat fungsi, misalnya cn-hangzhouKonsol Function Compute
    userIdentity.principalIdID akun Alibaba Cloud AndaPusat akun
    {
        "events": [
            {
                "eventName": "ObjectCreated:PutObject",
                "eventSource": "acs:oss",
                "eventTime": "2023-08-13T06:45:43.000Z",
                "eventVersion": "1.0",
                "oss": {
                    "bucket": {
                        "arn": "acs:oss:cn-hangzhou:10343546824****:bucket****",
                        "name": "bucket****",
                        "ownerIdentity": "10343546824****"
                    },
                    "object": {
                        "deltaSize": 122539,
                        "eTag": "688A7BF4F233DC9C88A80BF985AB****",
                        "key": "src/test.zip",
                        "size": 122539
                    },
                    "ossSchemaVersion": "1.0",
                    "ruleId": "9adac8e253828f4f7c0466d941fa3db81161****"
                },
                "region": "cn-hangzhou",
                "requestParameters": {
                    "sourceIPAddress": "140.205.XX.XX"
                },
                "responseElements": {
                    "requestId": "58F9FF2D3DF792092E12044C"
                },
                "userIdentity": {
                    "principalId": "10343546824****"
                }
            }
        ]
    }

    Ganti placeholder berikut dengan nilai aktual Anda: Untuk daftar lengkap parameter event, lihat Langkah 2: (Opsional) Konfigurasi parameter input.

  3. Klik Test Function di tab Code.

  4. Setelah fungsi selesai dijalankan, login ke Konsol Object Storage Service dan verifikasi bahwa file ZIP target (misalnya, src/test.zip) telah didekompresi ke dalam bucket. Lihat Gunakan Konsol OSS untuk mengkueri objek.

Pembersihan

Jika Anda tidak lagi memerlukan pengaturan ini, hapus sumber daya berikut untuk menghindari biaya berkelanjutan:

  • Fungsi Function Compute

  • Pemicu OSS yang dilampirkan ke fungsi

  • Peran RAM yang dibuat untuk fungsi (jika dibuat khusus untuk tutorial ini)

Langkah selanjutnya

  • Untuk mempelajari lebih lanjut tentang pemicu OSS, lihat Ikhtisar.

  • Untuk menggunakan Function Compute guna mengemas dan mengunduh file dari OSS, lihat Unduh beberapa objek sebagai paket.

  • Untuk informasi lebih lanjut tentang bucket dan objek OSS, lihat Bucket dan Objek.

Referensi