TuBrief
구독 채널
비디오
커뮤니티

Solusi Masalah Praktis Setelah Deploy di Infrastruktur PaaS Serverless

TuBrief 편집팀
2026년 7월 24일
0
Internet Technology

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Bahasa Indonesia한국어EnglishEspañol中文हिन्दीDeutschFrançaisPortuguêsРусскийالعربية日本語

관련 영상

Cara Menyederhanakan Workflow Anda sebagai Solo Developer?7:18

Cara Menyederhanakan Workflow Anda sebagai Solo Developer?

The Coding Koala

커뮤니티의 다른 글

에이전틱 커머스 프로젝트에 x402 결제를 붙일 때 생기는 일들

2026년 9월 12일

AI 에이전트 결제 트랜잭션이 들어오면 쇼핑몰 코어 DB부터 보호해야 한다

2026년 9월 12일

WP-CLI와 SQL로 워드프레스 은폐 백도어 찾는 법

2026년 7월 30일

Stripe 기반 AI 에이전트에 자금 한도를 거는 백엔드 구현법

2026년 7월 24일

알고리즘 밖에서 나만의 커뮤니티를 지키는 법

2026년 6월 29일

알고리즘보다 내 전문성을 증명하는 법

2026년 4월 18일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Solusi Masalah Praktis Setelah Deploy di Infrastruktur PaaS Serverless

PaaS all-in-one yang memungkinkan Anda melakukan deploy frontend dan backend hanya dengan beberapa klik terlihat sempurna pada awalnya. Masalah baru muncul setelah pengguna yang sebenarnya mulai berdatangan. Kode yang berjalan sangat lancar di lingkungan lokal mendadak menghasilkan error timeout begitu naik ke produksi, dan mencoba mengubah satu schema DB saja bisa membuat seluruh layanan mati total. Ditambah lagi, saat terjebak dalam posisi vendor lock-in yang membuat Anda serba salah, pusing pun makin menjadi-jadi.

Berikut adalah beberapa pola infrastruktur yang dirangkum untuk menyingkirkan hambatan-hambatan tersebut dengan rapi, sambil tetap menikmati kenyamanan dari platform semacam ini.

Memangkas Kesenjang Isolasi antara Lingkungan Lokal dan Runtime Serverless

Proses Node.js di lingkungan lokal terus menyala, tetapi lingkungan serverless hanya muncul sejenak saat ada permintaan masuk dan kemudian menghilang. Jika Anda secara asal-asalan menetapkan variabel global atau koneksi singleton DB pada momen cold start, pool koneksi akan mengering dalam sekejap.

Anda tentu tidak mungkin selalu mengeceknya dengan melakukan deploy ke server staging setiap saat. Mengisolasi layer jaringan itu sendiri di lingkungan lokal dan menjalankan handler jauh lebih cepat.

`typescript
// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
http.get('/api/v1/user/profile', ({ request }) => {
const authHeader = request.headers.get('Authorization');
if (!authHeader) {
return new HttpResponse(null, { status: 401, statusText: 'Unauthorized' });
}
return HttpResponse.json({
id: 'usr_102938',
email: 'dev@example.com',
role: 'ADMIN',
createdAt: new Date().toISOString()
});
})
];

// src/mocks/node.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

`

Proses untuk menerapkan pola ini sangat sederhana.

  • Susun handler yang mencegat permintaan jaringan melalui library MSW (Mock Service Worker).
  • Isolasi komunikasi API eksternal dengan setupServer saat menjalankan emulator.
  • Pisahkan secara ketat alamat koneksi DB pada file .env.local dari endpoint transaction pooler produksi.

Tanpa perlu menekan tombol deploy, Anda dapat memverifikasi perilaku antarmuka backend secara 100% identik di lingkungan lokal. Ini adalah struktur yang mendapatkan umpan balik secara instan setelah kode ditulis, tanpa membuang-buang waktu untuk pengujian jarak jauh yang tidak stabil.

Migrasi Schema Tanpa Downtime Layanan

Saat menggunakan PostgreSQL serverless seperti Supabase atau Neon, mengeksekusi perintah ALTER TABLE secara langsung adalah hal yang berbahaya. Lock ACCESS EXCLUSIVE akan terpasang pada tabel target, membuat query-query berikutnya berada dalam status antrean berturut-turut, yang pada akhirnya menyebabkan gangguan timeout.

Pertama-tama, batasan timeout harus diterapkan pada sesi migrasi.

`sql
SET lock_timeout = '2000ms';
SET statement_timeout = '5000ms';

ALTER TABLE users ADD COLUMN bio VARCHAR(255);

`

Untuk mengubah struktur DB yang sedang beroperasi secara aman, Anda harus menggunakan metode memperluas kode dan DB secara bersamaan, kemudian mengikis hal-hal yang lama secara bertahap.

`typescript
import { db } from './db';

interface UpdateUserProfileInput {
userId: string;
fullName: string;
}

export async function updateUserProfile({ userId, fullName }: UpdateUserProfileInput) {
await db.transaction(async (tx) => {
await tx.user.update({
where: { id: userId },
data: {
full_name: fullName,
name: fullName
}
});
});
}

`

Tiga langkah untuk pekerjaan yang aman.

  1. Ekspansi: Tambahkan kolom baru dengan kondisi Nullable. Buat pengaman dengan mengatur lock_timeout agar pekerjaan segera dihentikan saat terjadi persaingan lock.
  2. Transisi: Deploy kode dual-write yang menulis data ke kolom lama dan kolom baru secara bersamaan. Data lama diisi secara perlahan menggunakan script latar belakang.
  3. Kontraksi: Setelah memastikan seluruh instance server mengarah ke kode baru, jalankan query untuk menghapus kolom lama.

Dengan mematuhi prosedur ini, Anda dapat mengganti schema tanpa melewatkan satu pun permintaan dari pengguna.

Prapemrosesan Log Terdistribusi dan Pengendalian Biaya Pemantauan Error

Dalam lingkungan serverless, jika Anda hanya menyisakan console.log, log dari berbagai instance akan bercampur aduk dan menjadi kacau. Request ID yang unik dan format JSON yang terstruktur sangat esensial untuk melacak alur mulai dari saat satu permintaan masuk hingga keluar.

`typescript
import { Hono } from 'hono';
import { requestId } from 'hono/request-id';
import pino from 'pino';

const logger = pino({
level: process.env.LOG_LEVEL || 'info',
formatters: {
level: (label) => ({ level: label.toUpperCase() })
},
base: { env: process.env.NODE_ENV }
});

const app = new Hono();

app.use('', requestId());
app.use('
', async (c, next) => {
const reqId = c.var.requestId;
const startTime = performance.now();

c.set('logger', logger.child({ reqId }));

await next();

const durationMs = Math.round(performance.now() - startTime);
logger.info({
reqId,
method: c.req.method,
path: c.req.path,
status: c.res.status,
durationMs
}, 'Request processing finished');
});

`

Berikut adalah pengaturan untuk menghindari lonjakan biaya akibat melampaui batas saat menggunakan tool pemantauan eksternal.

  • Suntikkan Server-Timing ke dalam response header untuk mengirimkan titik bottleneck ke sistem pemantauan.
  • Filter kehilangan traffic sederhana atau error jaringan sementara dari engine pengumpul error.

`typescript
import * as Sentry from '@sentry/node';

Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.1,
beforeSend(event, hint) {
const error = hint.originalException;
if (error && error instanceof Error && error.message.includes('ECONNRESET')) {
return null;
}
return event;
}
});

`

Dengan memilah log 200 OK yang tidak berarti dan situasi pengecualian yang bersifat noise saja, Anda sudah dapat mengontrol sistem secara cukup baik di dalam batas tier gratis platform pemantauan.

Adapter Pattern dan Pipeline Backup untuk Mencegah Lock-in Platform

Mengkoneksikan SDK khusus PaaS tertentu secara langsung ke logika bisnis akan membuat Anda harus membongkar dan mengganti seluruh kode saat akan pindah ke platform lain di kemudian hari. Itulah alasan mengapa kita menggunakan Adapter Pattern yang dirangkum oleh Martin Fowler untuk memisahkan titik temu antara logika inti aplikasi dan SDK cloud eksternal.

`typescript
export interface IStorageService {
uploadFile(path: string, fileBuffer: Buffer, mimeType: string): Promise<{ url: string }>;
deleteFile(path: string): Promise;
}

import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';

export class S3StorageAdapter implements IStorageService {
private s3: S3Client;
private bucket: string;

constructor(region: string, bucket: string) {
this.s3 = new S3Client({ region });
this.bucket = bucket;
}

async uploadFile(path: string, fileBuffer: Buffer, mimeType: string): Promise<{ url: string }> {
await this.s3.send(new PutObjectCommand({
Bucket: this.bucket,
Key: path,
Body: fileBuffer,
ContentType: mimeType
}));
return { url: https://${this.bucket}.s3.amazonaws.com/${path} };
}

async deleteFile(path: string): Promise {
await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: path }));
}
}

`

Otomatiskan juga backup data agar Anda dapat berpindah kapan saja.

`bash
#!/usr/bin/env bash
set -euo pipefail

TIMESTAMP=(date +%Y%m%d_%H%M%S) BACKUP_DIR="/tmp/db_backup_{TIMESTAMP}"
S3_BUCKET="s3://my-app-exit-backups/pg_dumps"
export PGPASSWORD="${DB_PASSWORD}"

mkdir -p "${BACKUP_DIR}"

pg_dump -h "DBHOST"−p"{DB_HOST}" -p "DBH​OST"−p"{DB_PORT}" -U "DBUSER"−d"{DB_USER}" -d "DBU​SER"−d"{DB_NAME}"
-Fc --exclude-table-data='logs_*' > "${BACKUP_DIR}/full_schema_data.dump"

tar -czvf "BACKUPDIR.tar.gz"−C"{BACKUP_DIR}.tar.gz" -C "BACKUPD​IR.tar.gz"−C"{BACKUP_DIR}" .
aws s3 cp "BACKUPDIR.tar.gz""{BACKUP_DIR}.tar.gz" "BACKUPD​IR.tar.gz""{S3_BUCKET}/TIMESTAMP.tar.gz"−−endpoint−url"{TIMESTAMP}.tar.gz" --endpoint-url "TIMESTAMP.tar.gz"−−endpoint−url"{R2_ENDPOINT_URL}"
rm -rf "BACKUPDIR""{BACKUP_DIR}" "BACKUPD​IR""{BACKUP_DIR}.tar.gz"

`

  1. Tulis shell script yang memanfaatkan pg_dump untuk mengekstrak schema dan data.
  2. Daftarkan ke crontab agar file backup dikirimkan ke Cloudflare R2 atau bucket S3 eksternal.
  3. Saat perlu melakukan migrasi keluar, kurangi TTL DNS CNAME menjadi 300 detik terlebih dahulu dan cukup lakukan switching.

Dengan mengurangi risiko terikat pada platform tertentu, Anda akan jauh lebih mudah untuk mengatasi masalah kenaikan biaya unit infrastruktur maupun saat terjadi gangguan pada platform.