تخزين البيانات في ذاكرة التخزين المؤقت من تطبيق Spring Boot باستخدام Memorystore

1. نظرة عامة

Memorystore for Redis هي خدمة Redis مُدارة بالكامل على Google Cloud. يمكن للتطبيقات التي تعمل على Google Cloud تحقيق أداء فائق من خلال الاستفادة من خدمة Redis الآمنة والمتاحة والقابلة للتوسّع بشكل كبير بدون عبء إدارة عمليات نشر Redis المعقّدة. يمكن استخدامها كخادم خلفي لتخزين البيانات مؤقتًا من أجل تحسين أداء تطبيقات Spring Boot. يوضّح هذا الدرس التطبيقي حول الترميز كيفية إعدادها.

ما ستتعلمه

  • كيفية استخدام Memorystore كخادم خلفي للتخزين المؤقت لتطبيق Spring Boot

المتطلبات

  • مشروع على السحابة الإلكترونية من Google
  • متصفّح، مثل Google Chrome
  • الإلمام بأدوات تحرير النصوص العادية في Linux، مثل Vim وEmacs وGNU Nano

كيف ستستخدم هذا الدرس العملي؟

إذن بالقراءة فقط قراءة التمارين وإكمالها

كيف تقيّم تجربتك مع خدمات Google Cloud؟

مبتدئ متوسط متقدّم

2. الإعداد والمتطلبات

إعداد البيئة بالسرعة التي تناسبك

  1. سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. (إذا لم يكن لديك حساب على Gmail أو G Suite، عليك إنشاء حساب).

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

تذكَّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (الاسم أعلاه مستخدَم حاليًا ولن يكون متاحًا لك، نأسف لذلك). سيتم الإشارة إليه لاحقًا في هذا الدرس العملي باسم PROJECT_ID.

  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console من أجل استخدام موارد Google Cloud.

لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير من المال، إن لم تكلفك شيئًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "التنظيف" الذي ينصحك بكيفية إيقاف الموارد حتى لا تتحمّل رسومًا تتجاوز هذا البرنامج التعليمي. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

إذا لم يسبق لك بدء Cloud Shell، ستظهر لك شاشة وسيطة (الجزء السفلي غير المرئي من الصفحة) توضّح ماهيته. في هذه الحالة، انقر على متابعة (ولن تظهر لك مرة أخرى). في ما يلي الشكل الذي ستظهر به هذه الشاشة لمرة واحدة:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

يستغرق توفير Cloud Shell والاتصال به بضع لحظات فقط.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. توفّر هذه الخدمة دليلًا رئيسيًا دائمًا بسعة 5 غيغابايت وتعمل في Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إنجاز معظم العمل في هذا الدرس التطبيقي حول الترميز، إن لم يكن كله، باستخدام متصفّح أو جهاز Chromebook فقط.

بعد الاتصال بـ Cloud Shell، من المفترض أن يظهر لك أنّه تم إثبات هويتك وأنّه تم ضبط المشروع على رقم تعريف مشروعك.

  1. نفِّذ الأمر التالي في Cloud Shell للتأكّد من إكمال عملية المصادقة:
gcloud auth list

ناتج الأمر

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

ناتج الأمر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

ناتج الأمر

Updated property [core/project].

3- إعداد مثيل Memorystore for Redis

إنشاء Cloud Shell

بعد تشغيل Cloud Shell، استخدِم سطر الأوامر لتفعيل واجهة برمجة التطبيقات Memorystore API وإنشاء مثيل Memorystore جديد.

$ gcloud services enable redis.googleapis.com
$ gcloud redis instances create myinstance --size=1 --region=us-central1

بعد اكتمال العملية، سيصبح الجهاز الظاهري جاهزًا للاستخدام.

احصل على عنوان IP لمضيف Redis الخاص بالمثيل من خلال تنفيذ الأمر التالي. ستستخدمها مرة أخرى لاحقًا عند ضبط تطبيق Spring Boot.

$ gcloud redis instances describe myinstance --region=us-central1 \
  | grep host
host: 10.0.0.4

في Google Cloud Console، انتقِل إلى قواعد البيانات > Memorystore > Redis. يجب أن تكون الآلة الافتراضية في الحالة "جاهزة":

ee90b43f15a6dc1f.png

4. إعداد آلة افتراضية على Compute Engine

أنشئ آلة افتراضية في Compute Engine في المنطقة نفسها.

$ gcloud compute instances create instance-1 --zone us-central1-c

بعد اكتمال العملية، سيصبح الجهاز الظاهري جاهزًا للاستخدام.

اتّصِل بالمثيل عبر بروتوكول SSH باستخدام الأمر التالي:

$ gcloud compute ssh instance-1 --zone us-central1-c

بدلاً من ذلك، انتقِل إلى Compute > Compute Engine > الأجهزة الافتراضية، ثم انقر على SSH في عمود الاتصال:

a87bd437a0c8c7b4.png

في واجهة سطر الأوامر الخاصة بمثيل الجهاز الافتراضي (VM) (وليس Cloud Shell)، ثبِّت أدوات OpenJDK وMaven وRedis:

$ sudo apt-get install openjdk-17-jdk-headless maven redis-tools

انتظِر إلى أن يكتمل التثبيت، ثم انتقِل إلى الخطوة التالية.

5- إعداد تطبيق Spring Boot

أنشئ مشروع Spring Boot جديدًا مع تبعيات web وredis وcache:

$ curl https://start.spring.io/starter.tgz \
  -d dependencies=web,redis,cache -d language=java -d baseDir=cache-app \
  -d type=maven-project \
  | tar -xzvf - && cd cache-app

عدِّل الملف application.properties لضبط التطبيق على استخدام عنوان IP الخاص بمثيل Memorystore لمضيف Redis.

$ nano src/main/resources/application.properties

أضِف السطر التالي مع عنوان IP الخاص بخدمة Memorystore for Redis (من الخطوات السابقة):

spring.data.redis.host=<memorystore-host-ip-address> 

أضِف سطرًا جديدًا بعد ذلك وأنشئ فئة Java لوحدة تحكّم REST:

$ nano src/main/java/com/example/demo/HelloWorldController.java

أدرِج المحتوى التالي في الملف:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
@Autowired
private StringRedisTemplate template;

@RequestMapping("/hello/{name}")
@Cacheable("hello")
public String hello(@PathVariable String name) throws InterruptedException {
  Thread.sleep(5000);
  return "Hello " + name;
 }
}

تعرض التعليق التوضيحي @RequestMapping الطريقة كنقطة نهاية HTTP وتربط جزءًا من المسار بمعلَمة الطريقة (كما هو موضّح في التعليق التوضيحي @PathVariable).

تشير التعليق التوضيحي @Cacheable("hello") إلى أنّه يجب تخزين تنفيذ الطريقة مؤقتًا وأنّ اسم ذاكرة التخزين المؤقت هو "hello". ويتم استخدامه مع قيمة المَعلمة كمفتاح لذاكرة التخزين المؤقت. ستظهر لك أمثلة لاحقًا في مختبر البرمجة.

بعد ذلك، سنفعّل التخزين المؤقت في فئة تطبيق Spring Boot. تعديل DemoApplication.java:

$ nano src/main/java/com/example/demo/DemoApplication.java

استورِد org.springframework.cache.annotation.EnableCaching وأضِف هذه التعليقات التوضيحية إلى الصف. يجب أن تبدو النتيجة على النحو التالي:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class DemoApplication {

public static void main(String[] args) {
  SpringApplication.run(DemoApplication.class, args);
 }
}

6. تشغيل التطبيق والوصول إلى نقطة النهاية

تأكَّد من ضبط JAVA_HOME على الإصدار الصحيح:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

أنت الآن جاهز لتشغيل التطبيق.

$ mvn spring-boot:run

افتح اتصال SSH آخر بمثيلك بالطريقة نفسها التي اتّبعتها سابقًا. في نافذة SSH الجديدة، يمكنك الوصول إلى نقطة نهاية /hello/ عدة مرات، مع تمرير "bob" كاسم.

$ time curl http://localhost:8080/hello/bob
Hello bob!

real        0m5.408s
user        0m0.036s
sys        0m0.009s

$ time curl http://localhost:8080/hello/bob
Hello bob!

real        0m0.092s
user        0m0.021s
sys        0m0.027s

لاحظ أنّ الطلب استغرق خمس ثوانٍ في المرة الأولى، ولكن كان الطلب التالي أسرع بكثير على الرغم من أنّ لديك Thread.sleep(5000)استدعاء في الطريقة. ويرجع ذلك إلى أنّ الطريقة الفعلية تم تنفيذها مرة واحدة فقط وتم وضع النتيجة في ذاكرة التخزين المؤقت. تعرض كل مكالمة لاحقة النتيجة مباشرةً من ذاكرة التخزين المؤقت.

7. مراجعة العناصر المخزّنة مؤقتًا

يمكنك الاطّلاع على المحتوى الذي خزّنه التطبيق مؤقتًا. من الوحدة الطرفية نفسها التي استخدمتها في الخطوة السابقة، اتّصِل بمضيف Memorystore for Redis باستخدام redis-cli:

$ redis-cli -h <memorystore-host-ip-address>

للاطّلاع على قائمة بمفاتيح ذاكرة التخزين المؤقت، استخدِم الأمر التالي:

:6379> KEYS *
1) "hello::bob"

كما ترى، يتم استخدام اسم ذاكرة التخزين المؤقت كبادئة للمفتاح، ويتم استخدام قيمة المَعلمة كالجزء الثاني.

لاسترداد القيمة، استخدِم الأمر GET:

:6379> GET hello::bob
   Hello bob!

استخدِم الأمر exit للخروج.

8. تَنظيم

لإجراء عملية تنظيف، احذف مثيلات Compute Engine وMemorystore من Cloud Shell.

احذف الجهاز الظاهري:

$ gcloud compute instances delete instance-1 --zone us-central1-c

احذف مثيل Memorystore for Redis:

$ gcloud redis instances delete myinstance --region=us-central1

9- تهانينا!

لقد أنشأت خدمة Memorystore for Redis ومثيل Compute Engine. لقد أعددت أيضًا تطبيق Spring Boot لاستخدام Memorystore مع التخزين المؤقت في Spring Boot.

مزيد من المعلومات

الترخيص

يخضع هذا العمل لترخيص المشاع الإبداعي مع نسب العمل إلى مؤلفه 2.0 Generic License.