Pelajari cara menggunakan antrean tugas dan App Engine Image API untuk mengubah ukuran image.
Antrean tugas menjalankan kode di luar interaksi pengguna langsung, sehingga tugas terjadi di latar belakang. Panduan ini menggunakan Antrean Tugas untuk melakukan tugas setelah menambahkan image ke Cloud Storage. Tugas yang akan dilakukan di Antrean Tugas adalah:
- Mengambil file image yang baru saja diupload ke Cloud Storage.
- Mengubah ukuran menjadi image thumbnail menggunakan Image API.
- Menyimpan thumbnail yang dihasilkan di Cloud Storage.
Runtime App Engine Java 8 juga mendukung class manipulasi gambar image Java seperti AWT dan Java2D.
Sebelum memulai
Mengonfigurasi lingkungan pengembangan dan membuat project App Engine.
Panduan ini menggunakan library Apache Commons IOUtils. Untuk menyertakan library IOUtils ke project App Engine Anda:
Tambahkan ke
pom.xml
:<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>
Mengimpor library
Kode contoh yang diberikan pada panduan ini menggunakan impor berikut:
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import org.apache.commons.io.IOUtils;
Membuat antrean tugas
Meskipun App Engine menyediakan antrean tugas default
, Anda dapat membuat
antrean tugas yang berbeda untuk jenis pekerjaan yang berbeda. Misalnya, Anda dapat membuat satu antrean tugas untuk mengubah ukuran gambar dan satu lagi untuk memperbarui database aplikasi Anda.
Untuk menambahkan antrean, buat file queue.xml
di direktori WEB-INF
project App Engine Anda. Antrean Tugas harus menentukan nama dan rasio eksekusi:
<?xml version="1.0" encoding="UTF-8"?>
<queue-entries>
<queue>
<name>resize-image</name>
<rate>60/h</rate>
</queue>
</queue-entries>
Contoh antrean ini, yang bernama resize-image
, menentukan laju eksekusi 60 kali per jam, atau satu menit sekali. Untuk melihat opsi antrean daftar lengkap, lihat referensi queue.xml
.
Antrean Tugas memiliki dua komponen, pemohon tugas dan pengendali tugas. Pemohon menambahkan tugas ke antrean dan mengirimkannya ke pengendali tugas.
Menambahkan tugas ke antrean
Untuk menambahkan tugas ke antrean:
Buat objek antrean tugas menggunakan
QueueFactory.getQueue()
, pastikan Anda menentukan nama antrean yang ditentukan diqueue.xml
:Queue imageResizeQueue; // Taskqueue queue @Override public void init() throws ServletException { // Setup Cloud Storage service gcsService = GcsServiceFactory.createGcsService( new RetryParams.Builder() .initialRetryDelayMillis(10) .retryMaxAttempts(10) .totalRetryPeriodMillis(15000) .build()); // Initialize the queue object with the specific queue imageResizeQueue = QueueFactory.getQueue([QUEUE-NAME]); // Cloud SQL connection setup try { final String url = System.getProperty("cloudsql"); // Cloud SQL server URI try { conn = DriverManager.getConnection(url); // Connect to the database Statement createTable; // SQL statement // Batch SQL table creation commands createTable.addBatch(createContentTableSql); createTable.addBatch(createUserTableSql); createTable.addBatch(createImageTableSql); createTable.addBatch(createBlogPostImageTableSql); conn.createTable.executeBatch(); // Execute batch } catch (SQLException e) { throw new ServletException("Unable to connect to Cloud SQL", e); } } finally { // Nothing really to do here. } }
Tambahkan tugas ke objek
Queue
. Seperti yang ditunjukkan dalam contoh kode,imageResizeQueue.add()
menambahkan tugas ke objekimageResizeQueue
:try { // Add a queued task to create a thumbnail of the uploaded image imageResizeQueue.add( TaskOptions.Builder.withUrl("/tasks/imageresize").param("filename", filename)); }
Tentukan URI pengendali tugas menggunakan
TaskOptions.Builder.withUrl()
, beserta dan parameter apa pun yang dikirim ke pengendali.Dalam contoh ini, URI-nya adalah
/tasks/imageresize
dan parameternya adalah variabel bernamafilename
, yang berisi nama file image yang akan diproses.
Membuat pengendali tugas
Setelah Anda menambahkan tugas ke antrean, pengendali tugas yang dipetakan ke URI
/tasks/imageresize
akan berjalan. Pengendali tugas adalah Java Servlet yang mencoba
melakukan tugas sampai berhasil.
Dalam contoh ini, pengendali tugas melakukan tiga tugas:
Mengambil image yang ditentukan oleh pemanggil dari Cloud Storage.
Mengubah image menggunakan App Engine Image API, dalam contoh ini, menjadi image thumbnail.
Menyimpan image yang ditransformasi (thumbnail) di Cloud Storage.
Untuk membuat pengendali tugas:
Tambahkan anotasi yang memetakan pengendali ke URI
/tasks/imageresize
:@WebServlet(name = "imageResize", description = "Task queue handler", urlPatterns = "/tasks/imageresize") public class imageResize extends HttpServlet { // Task handler functionality }
Siapkan koneksi ke Cloud Storage seperti yang didokumentasikan dalam panduan Menggunakan Cloud Storage dan ambil image dari Cloud Storage:
public void init() throws ServletException { // initiate GcsService GcsService gcsService = GcsServiceFactory.createGcsService( new RetryParams.Builder() .initialRetryDelayMillis(10) .retryMaxAttempts(10) .totalRetryPeriodMillis(15000) .build()); }
Tangani permintaan Antrean Tugas yang masuk, menggunakan nama file yang disediakan untuk mengambil image dari Cloud Storage:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String filename = req.getParameter("filename"); // Get the filename passed from the task requestor GcsFilename gcsFile = new GcsFilename(bucket, filename); // Create a valid Cloud Storage filename GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(gcsFile, 0, BUFFER_SIZE); // Read the file from Cloud Storage
Gunakan objek
ImagesService
untuk melakukan pengubahan ukuran gambar:// Get an instance of the ImagesService we can use to transform images. ImagesService imagesService = ImagesServiceFactory.getImagesService(); // Make an image directly from a byte array, and transform it. Image image = ImagesServiceFactory.makeImage(IOUtils.toByteArray(Channels.newInputStream(readChannel))); Transform resize = ImagesServiceFactory.makeResize(100, 50); // resize image to 100x50 Image resizedImage = imagesService.applyTransform(resize, image); // Write the transformed image back to a Cloud Storage object. gcsService.createOrReplace( new GcsFilename(bucket, "thumbnail_" + filename), new GcsFileOptions.Builder().acl("public-read").build(), ByteBuffer.wrap(resizedImage.getImageData()));
Cuplikan di atas menggunakan metode
makeResize()
Image API untuk mengubah ukuran image menjadi thumbnail. Untuk melakukannya, aplikasi membaca image dari Cloud Storage menjadiInputChannel
dan mengonversinya menjadi ByteArray menggunakanIOUtils.toByteArray()
.Setelah menerapkan transformasi, image baru memiliki string
thumbnail_
yang ditambahkan ke nama filenya, izin ditetapkan agar dapat dibaca secara publik dan ditulis ke Cloud Storage.
Mengamankan URL pengendali tugas
Anda harus mengamankan tugas-tugas yang melakukan operasi sensitif seperti mengubah data sehingga pengguna eksternal tidak dapat memanggilnya secara langsung. Anda dapat melakukannya dengan membatasi akses tugas ke administrator App Engine, yang mencegah pengguna mengakses URL tugas. Perhatikan bahwa pembatasan ini tidak berlaku untuk permintaan tugas yang berasal dari aplikasi App Engine Anda.
Dalam contoh saat ini, pengendali tugas memiliki URL di folder /tasks/
.
Untuk membatasi akses ke folder /tasks/
bagi administrator App Engine, tambahkan hal berikut ke web.xml
project.
<security-constraint>
<web-resource-collection>
<web-resource-name>tasks</web-resource-name>
<url-pattern>/tasks/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
Menghapus satu tugas dari antrean
Untuk menghapus satu tugas dari antrean, gunakan deleteTask()
:
private void removeTask(Queue queue, String taskName) {
queue.deleteTask(taskName); // remove a task from a queue
}
Menghapus semua tugas dari antrean
Untuk menghapus semua tugas dari antrean, gunakan purge()
. Pembersihan permanen bisa memakan waktu hingga satu menit untuk menghapus semua tugas dalam antrean.
private void purgeQueue(Queue queue) {
queue.purge(); // remove all tasks from a queue
}
Diperlukan waktu satu menit untuk menghapus semua tugas dari antrean, jadi Anda harus menunggu beberapa detik sebelum menambahkan tugas baru ke antrean.
Menghapus antrean tugas
Untuk menghapus antrean tugas, hapus entri dari file queue.xml
project dan deploy ulang.
Men-deploy ke App Engine
Anda dapat men-deploy aplikasi ke App Engine menggunakan Maven.
Buka direktori root project Anda dan ketik:
mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID
Ganti PROJECT_ID dengan ID project Google Cloud Anda. Jika file pom.xml
sudah menentukan ID project, Anda tidak perlu menyertakan properti -Dapp.deploy.projectId
dalam perintah yang dijalankan.
Setelah Maven men-deploy aplikasi Anda, buka tab browser web secara otomatis di aplikasi baru dengan mengetik:
gcloud app browse
Langkah berikutnya
Panduan ini menunjukkan cara menggunakan antrean tugas untuk membuat thumbnail gambar dan menyimpannya di Cloud Storage. Data ini dapat digunakan dengan layanan penyimpanan lain seperti Cloud Datastore atau Cloud SQL.