0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Di Chuyển CMS: Từ Nuxeo Sang Strapi

Đăng vào 1 tuần trước

• 8 phút đọc

Di Chuyển CMS: Từ Nuxeo Sang Strapi

Giới thiệu

Trong bối cảnh các công ty đang ngày càng phụ thuộc vào Hệ thống Quản lý Nội dung (CMS) để đáp ứng nhu cầu nội dung ngày càng tăng, việc chuyển đổi CMS khi nó trở thành gánh nặng thay vì lợi ích là điều cần thiết. Một trong những khách hàng của chúng tôi, một nhà phát hành game toàn cầu, đã xây dựng CMS trên Nuxeo, nhưng nền tảng này đã chứng minh là tốn kém, phức tạp và không được sử dụng hiệu quả. Họ cần một giải pháp nhẹ hơn, linh hoạt và có thể mở rộng hơn.

Chúng tôi đã chuyển sang Strapi, một CMS headless, linh hoạt, đáp ứng tất cả các mục tiêu đó.

Động Lực Chuyển Đổi Từ Nuxeo

Mặc dù Nuxeo cung cấp nhiều khả năng, khách hàng của chúng tôi đã gặp phải một số thách thức:

  • Khóa nhà cung cấp: Cấu trúc dữ liệu độc quyền hạn chế khả năng di chuyển, trong khi quy trình làm việc cứng nhắc và tùy chỉnh sơ đồ bị hạn chế, tạo ra sự phụ thuộc lâu dài vào Nuxeo.
  • Chi phí cao so với mức sử dụng thấp: Đội ngũ đã có một frontend ReactJS riêng, vì vậy giao diện quản trị và tự động hóa quy trình của Nuxeo chủ yếu không liên quan. Thiết kế và triển khai sơ đồ cũng phụ thuộc vào Nuxeo Studio, điều này tỏ ra không trực quan và không hiệu quả.
  • Phức tạp về quyền truy cập: Hệ thống phân quyền của Nuxeo quá chi tiết khiến cho việc quản lý trở nên khó khăn với các quản trị viên và nhóm người dùng.
  • Vấn đề về khả năng mở rộng: Chúng tôi chỉ có thể chạy một phiên bản Nuxeo một cách đáng tin cậy. Các nỗ lực để thiết lập clustering cho quy mô không thành công.

Trong quá trình phát triển, những vấn đề này trở nên rõ ràng hơn khi chúng tôi phải tìm các giải pháp thay thế cho các chức năng cốt lõi của Nuxeo. Chúng tôi đã khám phá các tùy chọn như Directus, Contentful, và Strapi, nhưng nhanh chóng loại bỏ hai tùy chọn đầu tiên:

  • Directus: Đòi hỏi nhiều công việc tùy chỉnh.
  • Contentful: Gặp phải những thách thức tương tự như Nuxeo, bao gồm chi phí cao và ít quyền kiểm soát hơn đối với sơ đồ dữ liệu và tùy chỉnh phân quyền.

Cuối cùng, Strapi là sự lựa chọn tốt nhất, với tư cách là một CMS mã nguồn mở, headless, cung cấp nhiều tính năng sẵn có và giúp khách hàng lấy lại quyền quản lý với quyền sở hữu dữ liệu hoàn toàncách tiếp cận API-first để tối đa hóa tính linh hoạt.

Tổng Quan về Kiến Trúc Mới

Máy Chủ Strapi CMS

Máy chủ Strapi đã được cấu hình như một kho lưu trữ nội dung, tích hợp với AWS S3 cho lưu trữ có thể mở rộng:

  • Cổng quản trị: Chúng tôi đã tận dụng giao diện người dùng sẵn có của Strapi để quản lý các mô hình nội dung, vai trò và quyền truy cập mà không cần lập trình.
  • Định nghĩa mô hình nội dung: Chúng tôi đã định nghĩa các mô hình nội dung rõ ràng, hiệu quả và thích ứng trong Strapi.
  • Tích hợp AWS S3: Đảm bảo khả năng mở rộng và hiệu suất cho việc lưu trữ tài sản.
  • Lớp API: Chúng tôi sử dụng REST APIs của Strapi làm xương sống nội dung cho Lớp Middleware.

Lớp Middleware

Đối với lớp middleware, chúng tôi đã triển khai các dịch vụ Node.js containerized trên ECS và các chức năng AWS Lambda:

  • Dịch vụ Node.js: Đóng vai trò là gateway API giữa frontend React và backend Strapi để quản lý logic kinh doanh phức tạp và xử lý hình ảnh/video.
  • Chức năng AWS Lambda: Quản lý các tác vụ xử lý tài sản kỹ thuật số không đồng bộ.

Lớp Front-End

Các ứng dụng ReactJS cung cấp giao diện trực quan và giao tiếp liền mạch với các API middleware.

Triển Khai Chi Tiết Xử Lý Ảnh/Video

Trong lớp middleware, chúng tôi đã triển khai một hệ thống mạnh mẽ để xử lý hình ảnh, tài liệu và video. Một trong những thách thức đầu tiên khi chuyển từ Nuxeo sang Strapi là hỗ trợ tải lên nhiều tài sản và tổ chức chúng một cách hợp lý. Để đạt được tính linh hoạt, chúng tôi đã áp dụng mô hình chiến lược, mà trong đó tạo ra các lệnh ImageMagick dựa trên các tham số thời gian chạy.

Triển Khai Mô Hình Chiến Lược trong Middleware

javascript Copy
const { exec } = require('child_process')
const { promisify } = require('util')

const execAsync = promisify(exec)

const makeThumbnail = (inputPath) => `convert ${inputPath} -strip -thumbnail 150x150^ -gravity center -extent 150x150 -quality 85 thumbnail.jpg`

const makeResize = size => (inputPath, outputPath) =>
  `convert ${inputPath} -resize ${size} -strip ${outputPath}.jpg`

// Định nghĩa các lệnh dưới dạng hàm thuần túy
const commandStrategies = {
  thumbnail: makeThumbnail(),
  small:     makeResize('640x480'),
  large:     makeResize('1920x1080'),
}

// processImage hiện trả về một Promise; không có lớp, không có biến đổi
const processImage = (commandName, inputPath, outputPath) => {
  const command = commandStrategies[commandName]
  if (!command) {
    return Promise.reject(new Error(`Unknown command: ${commandName}`))
  }
  const cmd = command(inputPath, outputPath)
  return execAsync(cmd)
}

// Ví dụ sử dụng:
processImage('thumbnail', 'in.jpg', 'out-rendition.jpg')
  .then(({ stdout, stderr }) => {
    console.log('Hoàn thành!', stdout)
  })
  .catch(err => {
    console.error('Xử lý thất bại:', err)
  })

Cấu Hình Rendition

Các rendition được ánh xạ trong một cấu hình có cấu trúc, dễ dàng quản lý và gọi.

json Copy
[
  {
    "id": "thumbnail",
    "label": "Thumbnail (150x150)",
    "command": "thumbnail"
  },
  {
    "id": "small",
    "label": "Small (640x480)",
    "command": "small"
  },
  {
    "id": "large",
    "label": "Large (1920x1080)",
    "command": "large"
  }
]

Điều này có thể được nâng cao bằng cách bao gồm các điều kiện cho mỗi rendition. Ví dụ, chỉ tạo một rendition “large” khi kích thước hình ảnh đầu vào lớn hơn kích thước đầu ra của rendition “large”.

Quy Trình Xử Lý Tự Động

Middleware của chúng tôi tự động kích hoạt các sự kiện xử lý ngay sau khi tải lên tài sản lên AWS S3:

javascript Copy
exports.handler = async (event) => {
  const s3 = new AWS.S3();
  const record = event.Records[0];
  const bucket = record.s3.bucket.name;
  const key = decodeURIComponent(record.s3.object.key.replace(/\\+/g, ' '));

  const inputPath = `/tmp/${key}`;
  await downloadFromS3(bucket, key, inputPath);

  const renditionTypes = ['thumbnail', 'small', 'large'];
  for (const type of renditionTypes) {
    const outputKey = `renditions/${type}/${key}`;
    const outputPath = `/tmp/${type}-${key}`;
    processImage(type, inputPath, outputPath);
    await uploadToS3(bucket, outputKey, outputPath);
  }
};

Tối Ưu Hiệu Suất

Việc chuyển đổi xử lý thumbnail từ Nuxeo sang middleware tùy chỉnh của chúng tôi mang lại những cải tiến đáng kể về tốc độ và hiệu quả:

  • Giảm 90% thời gian xử lý: Thumbnails trước đây mất vài giây để tạo giờ đây gần như được tạo ngay lập tức.
  • Giảm 95% kích thước thumbnail: Xử lý hình ảnh tối ưu tạo ra các tệp nhỏ hơn mà không làm giảm chất lượng.

Triển Khai Di Chuyển Dữ Liệu Elasticsearch

Như bất kỳ quá trình chuyển đổi nào, di chuyển dữ liệu là một trong những phần quan trọng nhất. Chúng tôi đã sử dụng Elasticsearch làm điểm xuất, kéo các bản ghi theo lô, đơn giản hóa các mối quan hệ và sau đó nhập chúng vào Strapi.

Bước 1: Trích xuất Dữ liệu từ Nuxeo sử dụng Elasticsearch

json Copy
GET nuxeo-assets/_search
{
  "query": { "match_all": {} },
  "size": 1000
}

Bước 2: Biến đổi Dữ liệu & Đơn giản hóa Mối Quan Hệ

javascript Copy
function transformRecord(nuxeoRecord) {
  return {
    title: nuxeoRecord.title,
    description: nuxeoRecord.description,
    metadata: nuxeoRecord.metadata,
    fileUrl: nuxeoRecord.file.url
  };
}

Bước 3: Nhập Tự Động vào Strapi

javascript Copy
async function migrateData(records) {
  for (const record of records) {
    await axios.post(`${STRAPI_ENDPOINT}/assets`, transformRecord(record));
  }
}

Những Thách Thức Kỹ Thuật Chính & Giải Pháp

  • Xử lý Tài sản không đồng bộ: Cần xử lý hình ảnh, tài liệu và video quy mô lớn.
  • Di chuyển Dữ liệu: Di chuyển khối lượng lớn nội dung từ Nuxeo sang Strapi yêu cầu một quy trình đáng tin cậy.
  • Quản lý Cập nhật một phần: Một số nội dung yêu cầu cập nhật một phần thay vì toàn bộ.
  • Bảo mật và Quyền truy cập: Đảm bảo bảo vệ tài sản và quyền truy cập nội dung là mối quan tâm lớn.

Lộ Trình Tương Lai

  • Phân tích và Báo cáo Nâng cao: Cải thiện khả năng cung cấp thông tin sâu hơn về việc sử dụng và hiệu suất nội dung.
  • Tự động hóa Quản lý Vòng đời Nội dung: Tối ưu hóa quy trình tạo, cập nhật và lưu trữ tài sản.
  • Mở rộng Tích hợp AWS: Mở rộng kiến trúc với các dịch vụ AWS bổ sung để cải thiện khả năng mở rộng và tính linh hoạt.

Kết luận

Việc di chuyển từ Nuxeo sang Strapi đã tạo ra sự khác biệt lớn cho khách hàng. Nó đơn giản hóa hạ tầng công nghệ của họ, giảm 90% thời gian xử lý và 95% kích thước thumbnail, đồng thời mang lại cho họ một CMS linh hoạt và có thể mở rộng mà không gặp phải các vấn đề về khóa nhà cung cấp. Quan trọng nhất, họ giờ đây có quyền kiểm soát hoàn toàn dữ liệu của mình và tự do phát triển quản lý tài sản kỹ thuật số theo cách của riêng họ.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào