צריך לארוז את הקוד המותאם אישית שיוצרים עבור תוספים של Service Extensions ולהעלות אותו ל-Artifact Registry לפני ששירותים אחרים יוכלו לגשת אליו. בדף הזה מוסבר איך ליצור קוד של פלאגין, לארוז את הקוד ולהעלות אותו למאגר של Artifact Registry.
התכונה הזו נמצאת בגרסת טרום-השקה ב-Media CDN.
למידע נוסף על תוספי שירות, קראו את הסקירה הכללית על תוספי שירות.
לפני שמתחילים, מומלץ לעיין בשיטות המומלצות לכתיבת קוד של תוסף.
דוגמאות נוספות מופיעות במאמר דוגמאות קוד לתוספים.
לפני שמתחילים
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Network Services, Network Actions, Artifact Registry, Cloud Build, Cloud Logging, and Cloud Monitoring APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
Configure the gcloud CLI to use your federated identity.
For more information, see Sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
הגדרת שרשרת הכלים
C++
Proxy-Wasm C++ SDK מאפשר למפתחים להשתמש ב-C++ כדי להטמיע תוספים של WebAssembly (Wasm) לתוספי שירות. ה-SDK משתמש בערכת הכלים של C++ WebAssembly Emscripten, וגם בספריות אחרות, כמו protobuf, ובאופן אופציונלי, Abseil.
בגלל שנדרשות גרסאות ספציפיות של הכלים והספריות האלה כדי ליצור פלאגינים שנכתבו ב-C++, אנחנו ממליצים להשתמש בקובץ האימג' של Docker שסופק על ידי Proxy-Wasm C++ SDK. ההוראות ל-C++ בדף הזה משתמשות בשיטת Docker. כדי ליצור תוספים ל-C++ בלי להשתמש ב-Docker, אפשר לעיין במסמכי ה-SDK של Proxy-Wasm C++.
מתקינים את Docker אם הוא עדיין לא מותקן. Docker כלול ב-Cloud Shell, סביבת המעטפת האינטראקטיבית של Google Cloud .
מורידים עותק של Proxy-Wasm C++ SDK. הדרך הכי פשוטה לעשות את זה היא לשכפל את מאגר Git:
git clone https://github.com/proxy-wasm/proxy-wasm-cpp-sdk.gitיוצרים את קובץ האימג' של Docker ל-Proxy-Wasm C++ SDK מקובץ ה-Docker שסופק על ידי ה-SDK:
cd proxy-wasm-cpp-sdk docker build -t wasmsdk:v3 -f Dockerfile-sdk .אחרי שהפקודה מסיימת ליצור את ספריות ה-SDK ואת התלות שלהן, קובץ האימג' של Docker שנוצר משויך לתג שצוין, שהוא
wasmsdk:v3בדוגמה הזו.
המשך
Proxy-Wasm Go SDK מספק ערכת SDK מלאה של Go. היא מספקת ביצועים טובים ותמיכה עשירה בספריות של צד שלישי שנכתבו ב-Go בלבד.
חלודה
יכולת ההתאמה האישית של Service Extensions מתבצעת באמצעות WebAssembly ו-Proxy-Wasm. WebAssembly תומך במספר שפות תכנות. Google ממליצה על Rust כי היא מספקת תמיכה מצוינת ב-WebAssembly, ו-Proxy-Wasm מספקת ערכת SDK מלאה של Rust. בנוסף, Rust מספקת ביצועים טובים ובטיחות חזקה של טיפוסים.
-
בסיום תהליך ההתקנה, פועלים לפי ההוראות שמוצגות במסוף כדי לסיים את תהליך ההגדרה.
הוספת תמיכה ב-Wasm לשרשרת הכלים של Rust:
rustup target add wasm32-wasip1
יצירת חבילת הפלאגין
C++
יוצרים ספרייה חדשה, נפרדת מ-
proxy-wasm-cpp-sdk:mkdir myprojectבספרייה, יוצרים קובץ Makefile עם התוכן הבא:
# Express any dependencies PROTOBUF= # full / lite / none WASM_DEPS= # absl_base re2 ... # Include the SDK Makefile PROXY_WASM_CPP_SDK=/sdk include ${PROXY_WASM_CPP_SDK}/Makefileמוסיפים קובץ מקור C++ לתוסף באותה תיקייה. השמות של קובצי המקור ב-C++ צריכים להיות זהים לקובצי ה-Wasm שה-Makefile מטרגט, עם הסיומת
.ccבמקום.wasm. בדוגמה הזו, שם קובץ המקור צריך להיותmyproject.cc.מוסיפים את קוד הפלאגין לקובץ המקור.
דוגמת קוד המקור הבאה היא פלאגין שכותב מחדש את מארח הבקשה ושולח כותרת תגובה:
השיטה
onRequestHeadersהיא קריאה חוזרת (callback) שמופעלת על ידי Service Extensions.
המשך
יוצרים ספרייה חדשה לתוסף:
mkdir go-pluginבספרייה, יוצרים קובץ
go.modבאמצעות הכלי Go:go mod init go-pluginבאותה ספרייה, יוצרים קובץ מקור בשם
main.goומוסיפים לו את קוד הפלאגין.קוד המקור לדוגמה הבא הוא פלאגין שמשכתב את המארח של הבקשה, ופולט כותרת תגובה:
השיטה
OnHttpRequestHeadersהיא קריאה חוזרת (callback) שמופעלת על ידי Service Extensions.כדי להוריד ולצמיד תלות של הפרויקט בספריות, מריצים את הפקודה
go mod tidy:go mod tidy
חלודה
יוצרים ספריית חבילות של Rust באמצעות הפקודה
cargo newמכלי ניהול החבילות של Rust, Cargo:cargo new --lib my-wasm-pluginהפקודה יוצרת ספרייה שמכילה קובץ
cargo.tomlשאפשר לעדכן כדי לתאר איך ליצור את חבילת Rust, וספרייתsrcשבה מאחסנים את קוד הפלאגין.מעדכנים את הקובץ
cargo.tomlכדי לציין את הפרמטרים שנדרשים ליצירת החבילה:[package] name = "my-wasm-plugin" version = "0.1.0" edition = "2021"כדי לרשום את Proxy-Wasm Rust SDK ואת התמיכה ברישום ביומן כיחסי תלות, מוסיפים את הקטע
dependencies. לדוגמה:[dependencies] proxy-wasm = "0.2" log = "0.4"כדי ליצור ספרייה דינמית כמו שנדרש לפלאגינים, מוסיפים את הקטע
lib. לדוגמה:[lib] crate-type = ["cdylib"]כדי להקטין את הגודל של הפלאגין המקומפל, מוסיפים את הקטע
profile.release. לדוגמה:[profile.release] lto = true opt-level = 3 codegen-units = 1 panic = "abort" strip = "debuginfo"מוסיפים את קוד הפלאגין לקובץ
lib.rsבספרייהsrc.דוגמת קוד המקור הבאה היא פלאגין שכותב מחדש את מארח הבקשה ושולח כותרת תגובה:
ה-method
on_http_request_headersהיא קריאה חוזרת (callback) שמופעלת על ידי Service Extensions.
הידור הפלאגין
C++
כדי לקמפל את הפלאגין, מריצים את הפקודה הבאה מתוך הספרייה שבה נמצאים קובץ ה-Makefile וקבצי המקור של הפלאגין ב-C++:
docker run -v $PWD:/work -w /work wasmsdk:v3 /build_wasm.sh myproject.wasm
הפקודה הזו ממפה את הספרייה הנוכחית לספרייה work בקובץ האימג' של Docker, ואז מריצה את הסקריפט build_wasm.sh שסופק על ידי קובץ האימג' של Docker כדי ליצור את קוד הפלאגין. בסיום פעולת ההידור, אם היא הושלמה בהצלחה, נוצר קובץ myproject.wasm שמכיל את קוד הבייט של Wasm שעבר הידור, בספרייה הנוכחית.
בפעם הראשונה שקוד הפלאגין עובר קומפילציה באמצעות קובץ אימג' של Docker, Emscripten יוצר את הספריות הרגילות. כדי לשמור אותן במטמון בתמונת Docker, כך שלא יהיה צורך ליצור אותן מחדש בכל פעם, צריך לבצע commit לתמונה עם הספריות הרגילות אחרי ההידור הראשון שבוצע בהצלחה:
docker commit `docker ps -l | grep wasmsdk:v3 | awk '{print $1}'` wasmsdk:v3
מידע נוסף על יצירת תוספים ל-C++ זמין במאמרי העזרה בנושא Proxy-Wasm C++ SDK.
המשך
כדי לקמפל את קוד הפלאגין, מריצים את הפקודה go build:
env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm main.go
אם ההידור יצליח, ייווצר קובץ main.wasm בספרייה הנוכחית.
Rust
כדי להדר את קוד הפלאגין, מריצים את הפקודה cargo build:
cargo build --release --target wasm32-wasip1
בסיום ה-build יופיע Finished release [optimized] target(s)
אישור. אם אתם מכירים את Envoy, תוכלו לטעון את הפלאגין ב-Envoy ולאמת את ההתנהגות שלו.
העלאת קוד הפלאגין שעבר קומפילציה אל Artifact Registry
מעלים את קוד הפלאגין המקומפל למאגר Artifact Registry כדי ששירותי Google Cloud יוכלו לגשת אליו.
אם אתם משתמשים בתוספים לשירות עם מאזן עומסים גלובלי, השתמשו במאגר במיקום בכמה אזורים של us.
אם אתם משתמשים במאזן עומסים אזורי, אתם צריכים להשתמש במאגר באותו אזור או במיקום רב-אזורי באותה יבשת.
כשמצרפים פלאגין למאזן עומסים גלובלי, Service Extensions מעתיק את מודול ה-Wasm ממאגר Artifact Registry לאחסון משלו במיקומים ברחבי העולם. לכן, המיקום של המאגר לא משפיע על זמן האחזור של הבקשות שנשלחות למאזן העומסים. במאזני עומסים אזוריים, הפלאגין מועתק למיקומים באותו אזור שבו נמצא מאזן העומסים.
אפשר להעלות תוספים של Service Extensions למאגרי Docker או למאגרים כלליים ב-Artifact Registry.
כדי לנהל קבצים בינאריים עצמאיים בצורה ישירה יותר, מומלץ להשתמש במאגר כללי לאחסון קובצי Wasm. האפשרות הזו נמצאת בגרסת טרום-השקה.
מאגר גנרי
יוצרים ספרייה מקומית בשם
package/ומעתיקים אליה את מודול הפלאגין שאפשר לפרסם. שם הארטיפקט של הפלאגין צריך להיותplugin.wasmהפקודה לדוגמה הבאה מעתיקה את הארטיפקט של הפלאגין שנבנה על ידי Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmיוצרים מאגר Artifact Registry עם
--repository-formatשמוגדר ל-generic.מוודאים שיש לכם את ההרשאות הנדרשות למאגר.
כדי להעלות את מודול ה-Wasm שלכם כארטיפקט גנרי למאגר, משתמשים בפקודה
gcloud artifacts generic upload.gcloud artifacts generic upload \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY \ --source=package/plugin.wasm \ --package=PACKAGE \ --version=VERSIONמחליפים את מה שכתוב בשדות הבאים:
-
PROJECT_ID: Google Cloud מזהה הפרויקט LOCATION: המיקום של המאגר, אזורי או במספר אזורים-
REPOSITORY: השם של המאגר שאליו רוצים להעלות את מודול ה-Wasm -
PACKAGE: שם החבילה של הקובץ -
VERSION: הגרסה של מודול ה-Wasm
בסיום ההעלאה, שימו לב לשם של הפריט הגנרי שמופיע עם התווית
name, לדוגמהadd_header_plugin:v4בדוגמה הבאה. מציינים את השם הזה כשיוצרים פלאגין או גרסת פלאגין.Uploading file: plugin.wasm...done. '@type': type.googleapis.com/google.devtools.artifactregistry.v1.GenericArtifact createTime: '2025-06-16T11:02:25.080248Z' name: projects/my-project/locations/us/repositories/my-generic-repo/genericArtifacts/add_header_plugin:v4 updateTime: '2025-06-16T11:02:25.080248Z' version: v4-
כדי לוודא שהארטיפקט הועלה ל-Artifact Registry, מריצים את הפקודה
gcloud artifacts files listומוודאים שברשימה מופיע קובץ בשםPACKAGE:VERSION:plugin.wasm.gcloud artifacts files list \ --project=PROJECT_ID \ --location=LOCATION \ --repository=REPOSITORY
מאגר Docker
יוצרים מאגר ב-Artifact Registry עם
--repository-formatשמוגדר ל-docker.מוודאים שיש לכם את ההרשאות הנדרשות למאגר.
יוצרים ספרייה מקומית בשם
package/ומעתיקים אליה את ארטיפקט הפלאגין שניתן לפרסום. הדוגמה הבאה מעתיקה את פריט המידע שנוצר בתהליך פיתוח (Artifact) של הפלאגין שנבנה על ידי Rust:mkdir -p package && cp -f target/wasm32-wasip1/release/my_wasm_plugin.wasm package/plugin.wasmיוצרים קובץ
package/Dockerfileעם התוכן הבא:FROM scratch COPY plugin.wasm plugin.wasmאורזים את קוד הפלאגין באמצעות Cloud Build או Docker.
Cloud Build
יוצרים קובץ
package/cloudbuild.yamlbuild config עם התוכן הבא:steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '--no-cache', '--platform', 'wasm', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG', '.' ] images: [ 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG' ]הנתיב שבו מאחסנים את הפלאגין צריך להיות בפורמט הבא:
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
מחליפים את מה שכתוב בשדות הבאים:
-
LOCATION: המיקום האזורי או הרב-אזורי של המאגר -
PROJECT_ID: מזהה הפרויקט במסוף Google Cloud -
REPOSITORY: השם של המאגר שבו אתם רוצים לאחסן את התמונה -
IMAGE: שם קובץ האימג' של הקונטיינר במאגר, לדוגמהus-docker.pkg.dev/my-project/my-repo/my-wasm-plugin -
IMAGE_TAG: תג התמונה שיוקצה לקונטיינר, לדוגמהproduction
-
מפעילים את הפעולה כדי ליצור את מאגר הפלאגין ולהעלות אותו ל-Artifact Registry:
gcloud builds submit --config package/cloudbuild.yaml package/
Docker
מתקינים את Docker אם הוא עדיין לא מותקן. Docker כלול ב-Cloud Shell, סביבת המעטפת האינטראקטיבית של Google Cloud .
הגדרת אימות של Docker ל-Artifact Registry. לדוגמה:
gcloud auth login gcloud auth configure-docker LOCATION-docker.pkg.dev gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://LOCATION-docker.pkg.dev
יוצרים את קובץ האימג' של הקונטיינר:
docker build --no-cache --platform wasm -t my-wasm-plugin package/
כדי לתייג את התמונה המקומית בשם התמונה במאגר, משתמשים בתגי תמונה:
docker tag my-wasm-plugin LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
מחליפים את מה שכתוב בשדות הבאים:
-
LOCATION: המיקום של המאגר, באזור אחד או בכמה אזורים -
PROJECT_ID: מזהה הפרויקט ב Google Cloud מסוף -
REPOSITORY: השם של המאגר שבו אתם רוצים לאחסן את התמונה -
IMAGE: שם קובץ האימג' של הקונטיינר במאגר, לדוגמהus-docker.pkg.dev/my-project/my-repo/my-wasm-plugin. -
IMAGE_TAG: תג האימג' להקצאה לקונטיינר, לדוגמהproduction
-
מעלים את קובץ אימג' של קונטיינר המתויג אל Artifact Registry.
docker push LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:IMAGE_TAG
כדי לוודא שהתמונה הועלתה בהצלחה ל-Artifact Registry, מריצים את הפקודה
gcloud artifacts docker images list.gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \ --include-tags
הכנה והעלאה של קובץ התצורה
תוספים יכולים לקבל נתוני הגדרה, שיכולים להשפיע על ההתנהגות של התוסף בזמן הריצה. נתוני ההגדרה יכולים להיות טקסט או בינאריים, ובכל פורמט שהתוסף מקבל. אם גודל נתוני התצורה גדול, יכול להיות שתצטרכו להעלות את קובץ התצורה ל-Artifact Registry.
כתיבת קוד של תוסף לקריאת נתוני ההגדרה
C++
נתוני ההגדרה מועברים לשיטה onConfigure של אובייקט ההקשר הבסיסי, שנוצר פעם אחת בהפעלת הפלאגין ונשאר פעיל למשך משך החיים של זמן הריצה של Wasm שמארח את הפלאגין. אובייקט ההקשר הבסיסי הוא מופע של המחלקה RootContext או של מחלקת משנה של RootContext.
קוד הפלאגין יכול לקבוע באיזו מחלקה להשתמש בהקשר הבסיסי באמצעות הערך RegisterContextFactory. לדוגמה, קוד הפלאגין הבא רושם את MyRootContext ואת MyHttpContext כסוגי המחלקות שבהן יש להשתמש עבור מופעים של הקשרים root ו-stream. לאחר מכן, התוסף קורא ערך סודי מנתוני ההגדרה של התוסף, שמופעים של הקשר של הזרם יכולים לגשת אליהם דרך אובייקט ההקשר הבסיסי.
המשך
נתוני ההגדרות נקראים במהלך ההפעלה של OnPluginStart, מקבל שיטה שהסביבה בזמן הריצה מפעילה במבנה PluginContext פעם אחת בהפעלת הפלאגין. נתוני ההגדרה לא משתנים במהלך מחזור החיים של זמן הריצה של Wasm שמארח את הפלאגין. הפונקציה PluginContext שימושית להפעלת לוגיקת אתחול ולשמירה על המצב בהרבה בקשות.
קוד התוסף יכול לקבוע באיזה הקשר נעשה שימוש ב-PluginContext על ידי הטמעה של ה-method NewPluginContext ב-VMContext, שמבצעת יצירה של מופע של PluginContext. PluginContext יוצר מופעים של הקשרים HttpContext.
לדוגמה, קוד הפלאגין הבא רושם את VMContext, שיוצר מופע של PluginContext, ההקשר שאחראי לקריאת נתוני ההגדרה וליצירת מופעים של הקשרי HttpContext לפי הצורך.
PluginContext קורא ערך סודי מנתוני התצורה של התוסף, מאחסן אותו בהקשר PluginContext ומעביר אותו אל HttpContext ב-NewHttpContext.
חלודה
נתוני ההגדרה נקראים מRootContext מאפיין, שמוגדר פעם אחת בהפעלת הפלאגין ונשאר פעיל למשך משך החיים של זמן הריצה של Wasm שמארח את הפלאגין. התכונות של RootContext שימושיות לביצוע פעולות או לשמירה על המצב בהרבה בקשות.
קוד הפלאגין יכול לשלוט באיזה סוג משמש להקשר הבסיסי באמצעות השיטה set_root_context, וההקשר הבסיסי יוצר מופעים של הקשרי הזרם.
לדוגמה, קוד הפלאגין הבא רושם את MyRootContext, שיוצר מופע של MyHttpContext לפי הצורך. ההקשר הבסיסי קורא ערך סודי מנתוני ההגדרה של הפלאגין ומעביר אותו להקשרי הזרם.
העלאת קובץ התצורה
אם גודל הנתונים שצריך להעביר לתוסף ב-on_configure
גדול מ-900 KiB, צריך להעלות אותם ל-Artifact Registry בשיטה שמתוארת במאמר העלאת קוד התוסף שעבר קומפילציה ל-Artifact Registry.
במקרה כזה, שומרים את קובץ ההגדרות בשם plugin.config (ולא plugin.wasm).
השלב הבא הוא יצירת פלאגין.
בזמן יצירת הפלאגין, צריך לספק את ה-URI של מודול ה-Wasm או התמונה שהועלו.
יצירת גרסה חדשה של קוד הפלאגין
כדי ליצור גרסה חדשה של קוד הפלאגין, עורכים את קובץ הפלאגין. אחר כך, כמו שמתואר בקטעים הקודמים, מקמפלים את קוד הפלאגין, אורזים אותו מחדש ומעלים אותו ל-Artifact Registry.
התקשרות חזרה
הקוד שאתם קומפלו ל-Wasm יכול להגדיר שיטות או פונקציות שרירותיות, אבל לחלק מהן יש משמעות מיוחדת. אלה השיטות שמוגדרות ב-Proxy-Wasm SDK בשפה שבחרתם, והן ממופות למפרטים של Proxy-Wasm Application Binary Interface (ABI). הפונקציות האלה מופעלות על ידי Service Extensions בתגובה לבקשות של משתמשים או בתגובה לאירועים במחזור החיים של התוסף.
הקריאות החוזרות האלה מפורטות בטבלה הבאה לפי הסדר שבו הן בדרך כלל מופעלות:
| שם ופרטים של פונקציית הקריאה החוזרת | שם השיטה ב-C++ | שם שיטת Go | שם ה-method ב-Rust |
|---|---|---|---|
START_PLUGIN: מופעל כשמפעילים תוסף. |
RootContext::onStart |
VMContext.OnVmStart |
RootContext::on_vm_start |
CONFIGURE_PLUGIN: מופעל אחרי שהפלאגין מתחיל, כדי לספק נתוני הגדרות לפלאגין. |
RootContext::onConfigure |
PluginContext.OnPluginStart |
RootContext::on_configure |
CREATE_CONTEXT: מופעל כשנוצר הקשר של מקור נתונים חדש. כל מקור נתונים מתאים לבקשת HTTP של לקוח. |
Context::onCreate |
PluginContext.NewHttpContext |
RootContext::create_http_context |
HTTP_REQUEST_HEADERS: מופעל כדי לעבד כותרות של בקשות HTTP. |
Context::onRequestHeaders |
HttpContext.OnHttpRequestHeaders |
HttpContext::on_http_request_headers |
HTTP_REQUEST_BODY: מופעל שוב ושוב כדי לעבד נתחים של גוף בקשת HTTP. |
Context::onRequestBody |
HttpContext.OnHttpRequestBody |
HttpContext::on_http_request_body |
HTTP_RESPONSE_HEADERS: מופעל כדי לעבד את הכותרות של תגובת HTTP. |
Context::onResponseHeaders |
HttpContext.OnHttpResponseHeaders |
HttpContext::on_http_response_headers |
HTTP_RESPONSE_BODY: מופעל שוב ושוב כדי לעבד נתחים של גוף התגובה של HTTP. |
Context::onResponseBody |
HttpContext.OnHttpResponseBody |
HttpContext::on_http_response_body |
DONE: מופעל כשעיבוד הפלאגין מסתיים. |
Context::onDone |
HttpContext.OnHttpStreamDone |
Context::on_done |
DELETE: מופעל כשנמחק אובייקט ההקשר של הסטרימינג שתואם לבקשת HTTP של לקוח. |
Context::onDelete |
(אין קריאה חוזרת) | (no callback) |
המאמרים הבאים
- יצירת פלאגין
- אפשר לקרוא מידע נוסף בסקירה הכללית על תוספי שירות.