506
2

הכירו את Nginx – שרת Web עם ביצועים גבוהים במעט משאבים

506
זמן קריאה: 6 דקות

תוכן עניינים

מבוא

בשנת 2002 איגור סיסוב, מפתח תוכנה צעיר מרוסיה היה מתוסכל מכמות המגבלות שהיו לאתרי אינטרנט וחוסר היכולת שלהם לטפל ביותר מ10K בקשות במקביל (זוהי בעיה המכונה Ck problem )

כפתרון לכך הוא החל לעבוד כבר ב2002 על שרת אינטרנט חדש כאשר באותם שנים שלט בשוק Apache המפורסם ובשנת 2004 הוא הושק באופן רשמי ומופץ כקוד פתוח ונכון ליוני 2021 מדובר בשרת אינטרנט הכי נפוץ בעולם עם שימוש של כ34% בכל אתרי האינטרנט ו44.6% בשימוש ע”י 10K האתרים המובילים בעולם (ע”פ נתונים סטטיסטים של w3Techs

ההצלחה הגדולה של Nginx קרתה בזכות היכולת שלו לטפל בכמות ענקית של בקשות (כיום יש הרבה יותר מ10K לאתרים רבים) תוך שימוש מועט במשאבים,
Nginx מציעה ארכיטקטורה מונעת אירועים ואסינכרונית וזו אחת הסיבות מדוע NGINX נחשב לשרת האמין והנפוץ ביותר.
בין האתרים / החברות שמתשמות בNginx תוכלו למצוא כמה שמות מוכרים כמו: Autodesk, Atlassian, Intuit, T-Mobile, GitLab, DuckDuckGo, Microsoft, IBM, Google, Adobe, Salesforce, VMWare, Xerox, LinkedIn, Cisco, Facebook, Target, Citrix Systems, Twitter, Apple, Intel, WordPress וכמובן עוד רבות אחרות.

 

מה זה Nginx?

NGINX תחילה התחיל להיות מוכר כשרת אינטרנט עם קוד פתוח, אך כעת הוא משמש גם כRevese Proxy, HTTP cache, Load Balancer.
כשרת אינטרנט הוא תוכנן לעמוד בעומסים רבים והוא נותן ביצועים טובים ויציבים תוך שהוא מנצל מעט משאבים יחסית.

שרת אינטרנט

בכל אתר שאנחנו צופים בו נשלחות בכל עת מלא בקשות אל השרת, והשרת תפקידו להחזיר אל הדפדפן / הפלאפון שלנו את הטקסט / התמונות / דפי HTML, JS, CSS וחבריו
הוא יוצר תור של תהליכים שניתן למקבל בקלות בין מספר חיבורים ברשת,  בכל פעם שתוגש בקשה, יוקצה משאב לתהליך וכתוצאה מכך יש ניצול משאבים טוב יותר שיכול להתמודד בקלות עם כמות גדולה של חיבורים.

Reverse Proxy

זהו למעשה השימוש הנפוץ ביותר שקיים עם Nginx, תפקידו לחצוץ בין המחשב המקומי לבין מחשב היעד, כל בקשה שלכם תעבור דרכו והוא ינתב אותה לשרת ולהפך על פי מה שהגדרתם.

במקרה הזה המשתמש לא יכול לזהות את השרת עצמו ולמעשה לא יידע אם הוא מתחבר לשרת אחד או כמה שרתים.

ארבעה יכולות / יתרונות שנקבל משימוש בNginx + Proxy: 

      1. שיפור מהירות – אחסון בCache ודחיסת תוכן בפרוקסי בשילוב עם אופטימיזציות כגון HTTP/2 מספקים חווית משתמש טובה ומהירה הרבה יותר
      2. שכבת SSL / TLS – לא צריך להתעסק בלאבטח את החיבור בין השרת ללקוח, הפניית כל הפניות לNginx בשילוב עם SSL תפתור את הבעיה הזו שאגב כיום מדובר בתנאי חובה אם אתם רוצים שיצליחו לראות את האתר שלכם בדפדפנים המוכרים.
      3. Load Balancing – איזון עומסים על סמך קריטריונים רבים כמו  זמינות של שרת כזה או אחר, סוג הבקשה ואפילו מיקום גיאוגרפי.
      4. Web application firewall – שכבת אבטחה / חומת אש ליישומי אינטרנט (WAF) הפרוסה בפרוקסי הפוך יכולה להגן על יישומים מפני איומים שונים.

NGINX vs Apache

Apache ו- Nginx הם שני שרתי האינטרנט הנפוצים ביותר בקוד פתוח בעולם. נכון להיום (אוגוסט 2021 יחד הם אחראים לשרת מעל 70% מסך התנועה באינטרנט. שני הפתרונות מסוגלים להתמודד עם עומסי עבודה שונים ועובדים עם תוכנות אחרות. 
Apache היא אחת היריבות העיקריות של NGINX. היא קיימת כבר מאז שנות ה -90 ויש לה גם קהילת משתמשים גדולה. 

תמיכה במערכת ההפעלה

תאימות היא אחד הפרטים הקטנים שכדאי לקחת בחשבון בבחירת תוכנה. גם NGINX וגם Apache פועלות מצויין במערכות הפעלה מבוססות Unix.
אך מנגד, הביצועים של NGINX ב- Windows לא מספיק טובים בנוסף לצורך בהתקנה ידנית
לעומת זאת, Apache מציעה תמיכה מלאה עבור Windows, Linux ועוד מספר מערכות הפעלה. אם מסיבה כזו או אחרת תרצו להפעיל שרת בסביבת Windows (למה לעזאזל?!)  Apache תהיה האפשרות הטובה ביותר.

תמיכת משתמש

מדובר בשתי פלטפורמות ותיקות  ומתועדות מאוד. כך שלא סביר שתיתקלו בבעיה או שאלה שתשובתה לא נמצאת בתוך התיעוד של Apache או NGINX
שלא נדבר על Stack Overflow וחבריו.

לשני השרתים יש גם פורומים תמיכה בקהילה גדולים ופעילים ושירותי רשימות שבהם מנהלי מערכת יכולים לבקש עזרה במידת הצורך.

בנוסף ניתן לקבל תמיכה מסחרית בתשלום הן עבור Apache והן עבור NGINX רק שבמקרה של Apache התמיכה מגיעה מספקי צד שלישי. עבור NGINX, תמיכה זמינה מ- NGINX, Inc., אותו ארגון שעוזר לתת חסות לפיתוח NGINX.

ביצועים

 אפאצ’י מתפקדת טוב יותר בעת אחסון אתרים עם רמות תנועה נמוכות יחסית – סביבות ה1000 בקשות או פחות לשעה.
NGINX מביאה ביצועים טובים יותר לאתרים שחווים הרבה בקשות במקביל. הבדל זה אינו מפתיע; כפי שציינתי במבוא זו הייתה מטרתו הראשית של איגור סיסוב, מתן פתרון המתפקד היטב בקנה מידה גדול.

חלק מהסיבה להבדלי הביצועים בין Apache ל- NGINX היא שאפצ’י מאחסן חלק מפרטי התצורה שלה לאתרים בודדים בקבצי .htaccess. בכל פעם שמשתמש מבקר באתר, על Apache לקרוא את קובץ .htaccess לפני שהוא יכול לקבוע כיצד להגיש את תוכן האינטרנט הרלוונטי. במקרים בהם Apache צריכה לשרת קבצי אתר רבים בבת אחת, הדבר מסתכם בהרבה קריאות קבצים. לפיכך, כאשר משתמשים רבים מבקשים תוכן אינטרנט בו זמנית, קיבולת הקלט/פלט של שרת המארח של Apache תהיה מרבית, מה שמעכב את הביצועים. לעומת זאת,

ל- NGINX אין קבצי htaccess; הוא שומר את התצורה שלו באופן שניתן לגשת אליו מבלי לדרוש קריאת קבצים מוגזמת.

NGINX גם בדרך כלל מציעה ביצועים טובים יותר בקנה מידה מכיוון שהיא שומרת בCache תוכן אינטרנט כברירת מחדל.  ניתן להגדיר את אפאצ’י לנתוני מטמון באמצעות מודול mod_cache, אך הוא אינו עושה זאת כברירת מחדל.

נוסף על כך, מכיוון שצריכת הזיכרון של NGINX נמוכה יותר, היא נוטה להתמודד עם יותר חיבורים בו זמנית מבלי להעמיס על השרת המארח. אם אפאצ’י מתמודד עם כמויות גדולות של בקשות, הוא עלול בסופו של דבר לצרוך את כל זיכרון המערכת ולדרוש אחסון נתונים במחיצות החלפה או קבצי דפים, דבר המאט את הביצועים באופן משמעותי.

 

הגיע הזמן להתקין

הפקודות יתאימו למערכות Ubuntu / Debian

				
					sudo apt update
sudo apt install nginx

				
			

פקודות בסיסיות

על מנת להפעיל את Nginx:

				
					sudo nginx
				
			
כאשר nginx פועל, תוכל לנהל אותו על ידי אחת מהפקודות הבאות:
  • stop  fast shutdown
  • quit  graceful shutdown (wait for workers to finish their processes)
  • reload  reload the configuration file
  • reopen  reopen the log files

 

				
					sudo nginx -s ________

				
			

קובץ הקונפיגורציה ממוקם כאן: etc/nginx/nginx.conf

דוגמה לקינפוג קצר ופשוט של Reverse Proxy

				
					http {
	server {
		listen 443 ssl http2;
		server_name localhost;
		ssl_certificate /etc/nginx/certs/Cert.crt;
		ssl_certificate_key /Cert/nginx/certs/Cert.rsa;
        ssl_protocols TLSv1.2;
	 

		location / {	
			proxy_set_header Host $host;
			proxy_pass http://127.0.0.1:8081;
	   }
	   
	   location /check/nginx {
			return 200 'Nginx is up!';
		}
	   
	   location /api/ {
			proxy_pass http://127.0.0.1:9090;
		}
}

				
			

זו דוגמא קלאסית וקצרה לקונפיגורציה של Nginx + Reverse Proxy

במקרה הזה כל האזנה ל443 (הפורט המקובל לHttps) תפנה את הבקשות לפורט 8081 או 9090 שהם עצמם לא מאובטחים על ידי SSL וכך הוספנו שכבת Ssl לאתר / שרת שלנו בקלות ובלי יותר מידי מאמץ.

בנוסף אם תיכנסו ל localhost:443/check/nginx תוכלו לראות את השורה שכתובה שם “Nginx is up!”

כעת אפרט על הקובץ שנלקח מNginx – דוגמא מלאה לקונפיגורציה והפירוט עליה ע”פ מספרים יוצג בהמשך.

				
					user       nginx;  ##1
worker_processes  1;  ##2
error_log  logs/error.log; ##3
pid        logs/nginx.pid; ##4
worker_rlimit_nofile 8192; ##5

events {
  worker_connections  1024;  ##6
}

http {
  include    conf/mime.types; ##7
  access_log   logs/access.log  main; ##8


  ##9
  server { # php/fastcgi
    listen       80;
    server_name  domain1.com www.domain1.com;
    access_log   logs/domain1.access.log  main;
    root         html;

    location ~ \.php$ {
      fastcgi_pass   127.0.0.1:1025;
    }
  }

  ##10
  server { # simple reverse-proxy
    listen       80;
    server_name  domain2.com www.domain2.com;
    access_log   logs/domain2.access.log  main;

    # serve static files
    location ~ ^/(images|javascript|js|css|flash|media|static)/  {
      root    /var/www/virtual/big.server.com/htdocs;
      expires 30d;
    }

    # pass requests for dynamic content to rails/turbogears/zope, et al
    location / {
      proxy_pass      http://127.0.0.1:8080;
    }
  }

}
				
			
  1. user מגדיר באיזה מערכת התהליכים (OS processes) של nginx ירוצו. לא ניגע בזה בד”כ.
  2. כמה Worker Processes להפעיל.
    הערך האופטימלי תלוי בגורמים רבים, כולל (אך לא רק) מספר ליבות המעבד, מספר כונני הדיסק הקשיח המאחסנים נתונים ודפוס הטעינה. כאשר יש ספק, הגדרת מספר ליבות המעבד הזמינות תהיה התחלה טובה (הערך “auto” ינסה לזהות אותו אוטומטית).
  3.  מה הרמה המינימלית של Log level, שאותה נרצה לשמור לתוך לוג ייעודי לפלט של בעיות? 
    ניתן גם להגדיר כמה כאלה ובמידה ולא נגדיר בכלל הלוג יישמר בכל זאת לפי הגדרת ברירת המחדל error.log
  4. מגדיר קובץ שיאחסן את מזהה התהליך של התהליך הראשי.
  5. משנה את המגבלה על המספר המרבי של קבצים פתוחים (RLIMIT_NOFILE) עבור כל Worker. משמש להגדלת המגבלה מבלי להפעיל מחדש את התהליך העיקרי.
  6. קובע את המספר המרבי של חיבורים בו זמנית שניתן לפתוח על ידי תהליך הWorker.
  7. ה include מצרף קובץ אחר / מרחיב את הקונפיגורציה על ידי קובץ קונפיגורציה נוסף.
  8. כאן אנחנו מגדירים פורמט מסוים ל access log ושומרים את הפורמט בשם “main”.
    ה Access log של nginx ישמור לכם כל בקשה שעברה דרך שרת ה nginx – מה שיכול לסייע לניתוח ה traffic שאנו מקבלים.
  9. כאן כבר מתחילים לקנפג את השרת עצמו, כמו בדוגמה למעלה – יש כאן הפנייה מפורט 80 ל1025 שם יושבת / רצה האפליקציה שלנו
  10. עוד דוגמא לReverse Proxy

לסיכום


דיברנו על כך שNginx זה אחד הכלים הנפוצים היום בשוק, הבנו איזה פתרונות הוא יכול לספק ולמה הוא משפר לנו את החיים והביצועים
ראינו דוגמאות לקונפיגורציות שיכולים לעזור לכם בהמשך.
אין ספק שפוסט אחד לא יכול לתת לכם את הידע הנדרש אך כמו בכל כלי של תוכנה – צריך פשוט לנסות, תתקינו, תנסו ואין סיבה שלא תצליחו.

לינקים שימושיים

אמיר שטיימן
WRITEN BY

אמיר שטיימן

Backend Engineer @Cynet
ביום יום מפתח Backend בסביבת SaaS, מיקרו סרביסים בשילוב של מערכות מבוזרות. בזמני הפנוי - לומד ומשתדרג בעולם התוכנה, אוהד מכבי חיפה, פלייסטיישן ובירה עם חברים :)
Linkedin | Twitter

2 thoughts on “הכירו את Nginx – שרת Web עם ביצועים גבוהים במעט משאבים

  1. מעניין מאוד, תודה!
    פרט אחד חשוב שלדעתי פספסת –
    אולי ה-הבדל בין אפאצ’י לאנג’ניקס הוא האסינכרוניות –
    אפרצ’י מקצה מראש כמות Threads כדי לטפל בבקשות,
    והקוד שלו כתוב בצורה סינכרונית, כך שכל בקשה מטופלת בthread נפרד מהתחלתה עד סופה. זהו מודל תכנותי פשוט ולכן היה הגיוני להשתמש בו בשנות התשעים כשתכנתו את אפאצ’י והמושג של עומסים על אתרים היה נשמע כמו בעיה שהלוואי והיינו צריכים להתמודד איתה..
    הבעיה היא שברגע שיש הרבה בקשות, השרת צריך לייצר הרבה threadים – יותר מכמות המעבדים שיש בשרת, ככה שכדי לא לתקוע בקשות המערכת הפעלה קופצת בין threadים שונים בפרקי זמן מסוימים. הבעיה פה היא שהתקורה של מעבר בין threadים היא גבוהה מאוד )באופן יחסי( ולכן הדבר הזה עובד טוב במספר קטן של בקשות אבל לא scales well. אנג’ניקס מבצע את הפעולות בצורה אסינכרונית, ככה שברגע שישנה פעולת I/O כגון קריאה מהדיסק או שליחה/קבלה של מידע מהרשת, הפעולה בעצם מתבצעת אסינכרונית והשרת יכול להתשמש באותו thread

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *