22
ההההה הההה ההההDaemon ההההה ההההה הההההה ההההה ההה ההההה ההההה89-211 םםםםם םםםםם2 םםםםם10 םםםםם ם םםםםם םDaemon Daemon ם םJava Java ההההה הההה'ה םםםםם םםםםם םםםםם םםםםם2 2 89-211 89-211 ההההה הההה10 הה"ה2009-2010

דוגמא ל Daemon ב Java

  • Upload
    helia

  • View
    56

  • Download
    3

Embed Size (px)

DESCRIPTION

דוגמא ל Daemon ב Java. תכנות מתקדם 2 89-211 תרגול מספר 10 תש"ע 2009-2010. אליהו חלסצ'י. בשיעור שעבר ראינו כיצד ניתן להריץ תוכנית java כ service תחת windows . השתמשנו ב tomcat כתוכנית native שהריצה JVM ובתוכה התוכנית שלנו. - PowerPoint PPT Presentation

Citation preview

Page 1: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

JavaJava ב ב DaemonDaemonדוגמא ל דוגמא ל

אליהו חלסצ'י

89-21189-211 22תכנות מתקדם תכנות מתקדם 10תרגול מספר

2009-2010תש"ע

Page 2: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

הקדמהבשיעור שעבר ראינו כיצד ניתן להריץ תוכנית •

java כ service תחת windows.

שהריצה native כתוכנית tomcatהשתמשנו ב •JVM.ובתוכה התוכנית שלנו

עבור Daemonבשיעור זה נלמד כיצד לייצר • )לינוקס(Unix שלנו – תחת javaתוכנית ה

ubuntu 9.04התוכניות בתרגול נכתבו תחת •

גם הפעם ברצוננו ליצור תהליך מנותק שרץ •ברקע ללא התערבותנו הישירה.

Page 3: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

Daemonכיצד נוצר )(forkתחילה נעשה שימוש ב •

יוצר העתק )הילד( של התהליך שלנו )ההורה(.forkה – )אב כל Initניתן להורה לסיים, והילד יעבור להיות תחת –

התהליכים(.התוצאה: תהליך הילד מנותק לחלוטין מתהליך האב –

וממשיך לרוץ ברקע כעצמאי.

נאתחל את הרשאות התהליך ע"פ הצורך ע"י •umask)( )user mask(

signalsהתהליך שלנו עדיין יכול לקבל •מההורה המקורי או מהחברים באותה קבוצת

.)(setsidתהליכים, לכן נרצה לנתק אותו ע"י

Page 4: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

Daemonכיצד נוצר כדי)(chdir ע"י directoryנרצה לשנות את ה •

שנפעל מתוך אחת מוכרת )ההפך עלול לגרום לבעיות(–או אחת המתאימה לריצת התהליך שלנו )לדוג' –

chdir)“/servers/”()

שאולי ירשנו ובהםDescriptorsנרצה לסגור •–stdin, stdout, stderrdev/null/ בלתי מזיק כמו I/O deviceנפנה אותם ל –

כעת, לאחר כל הניתוקים, נוכל להריץ כל תוכנית•)(system ע"י קריאת מערכת daemonכ ”java –jar MyDaemon.jar"למשל –

Page 5: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

ה מה זה אומר אםpid 1 שלנו שווה?

זה אומר שאנחנו...daemonכבר

Page 6: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

יוצר העתק חדש של עושה?forkמה ה תהליך ההורה ומחזיר

process idתהליך הילד ימשיך

מאותה השורה בקוד.

Page 7: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

?pid<0מהו pid>0?

מה קורה אם pid==0?

pid<0אומר שתהליך נכשל.forkה

pid>0אומר שאנו נמצאים בתהליך ההורה

ולכן נסיים אותו בהצלחה.pid=0אומר שאנו נמצאים

בתהליך הילד ולכן נמשיךעם הניתוקים שנותרו.

Page 8: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

?umaskמה מגדיר

מגדיר את הרשאות התהליך(chmod )כמו הפקודה

)umask)027למשל chmod 750תקביל ל

(027)המשלים של

Page 9: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

מה אנו רוצים לנתקכעת ?

signalsאת כל ערוצי ה שתהליך זה אולי ירשועשויים להפריע לו.

Page 10: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

chdirמה הפקודה מבצעת?

.cdאת הפקודה directoryכדי להחליף ל

המתאים לשירות שלנו.

Page 11: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>

#define EXIT_SUCCESS 0#define EXIT_FAILURE 1

static void daemonize(void){ pid_t pid, sid; if ( getppid() == 1 ) return;

pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } umask(0);

sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); }

if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/dev/null", "w", stderr);}

שתריץ עבורנו כלCנכתוב תוכנית ב daemon כ javaתוכנית

daemonizeנגדיר את הפונקציה כך שתבצע את הניתוקים ההכרחים

ותשאיר אותנו בתהליך הילד אחריהם.

מה מתבצע כעתוכיצד?

descriptorsסגירה של ה הסטנדרטיים.

ודומיוstdin גם ה unixב מצביעים ל"קובץ".

בפקודות כאן אמרנו להםלהצביע מחדש ל"קובצי"

deviceאחרים – ל null

Page 12: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

int main( int argc, char *argv[] ) { daemonize(); char command[80]="java"; int i; for(i=1;i<argc;i++){ strcat(command," "); strcat(command,argv[i]); } system(command); return 0;}

)(daemonize נוכל לקרוא ל mainכעת ב שאחריו נהיה למעשה בתהליך הילד שכעת

.daemonמנותק מהכל ומהווה למעשה

בדוגמא לקחנו את כל הארגומנטים וצירפנו .command תחת המחרוזת javaלפקודה

(java)יותר כללי היה לו לא היינו מקבעים את

.)(system ע"י shell נריץ ב commandאת

.Daemonלתוכנית המקומפלת נקרא ריצה למשל ע"י:

/. #Daemon –jar /home/eli/MyDaemon.jar

Daemonמה יקרה כשנריץ?ההורה

Init

Daemonהילד

java

Page 13: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

int main( int argc, char *argv[] ) { daemonize(); char command[80]="java"; int i; for(i=1;i<argc;i++){ strcat(command," "); strcat(command,argv[i]); } system(command); return 0;}

)(daemonize נוכל לקרוא ל mainכעת ב שאחריו נהיה למעשה בתהליך הילד שכעת

.daemonמנותק מהכל ומהווה למעשה

בדוגמא לקחנו את כל הארגומנטים וצירפנו .command תחת המחרוזת javaלפקודה

(java)יותר כללי היה לו לא היינו מקבעים את

.)(system ע"י shell נריץ ב commandאת

.Daemonלתוכנית המקומפלת נקרא ריצה למשל ע"י:

/. #Daemon –jar /home/eli/MyDaemon.jar

?java ל killמה יקרה כשנעשה

Init

Daemonהילד

java

Page 14: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

שימוש בכלים קיימיםכמו שראינו יכולנו להפוך את התוכנית שלנו •

לכלי גנרי להרצת כל תוכנית שאינה יכולה .daemonizeלעשות

כלי אחד כבר קיים תחת השם•start-stop-daemon

דוגמא לשימוש:•pidחשוב לייצר •

חדש ולשמור את תוכנו בקובץ כדי שהמע' לא , וכדי שמאוחר javaתטעה עם תהליך אחר של

השמור.pid ל stop--יותר נוכל לבצע

# sudo start-stop-daemon --start --quiet --background--make-pidfile --pidfile /var/run/eli.txt--startas java -- -jar /home/eli/MyDaemon.jar

Page 15: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

בעיההריגת התהליך בצורה "ברוטאלית" שכזו, כפי שראינו •

בדוגמאות עד כה, לא מאפשרת לנו לבצע סגירות שלנו.javaאחרונות מתוך תוכנית ה

התהליך עצמו נסגר, ואין קריאה לאיזושהי מתודת •stop שמימשנו בתוך ה java.

אז מה ניתן לעשות כדי לסגור תוכנית כמו שצריך?•

כלשהו ולהאזין.port על socket ניתן למשל לפתוח • למשל, נבצע סגירה.”stop me“ כשתינתן הפקודה •”stop me“ הזה port נבנה תוכנית נוספת השולחת ל •

ופשוט נריץ אותה רגע לפני שנהרוג את התהליך בברוטאליות.

Page 16: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

שימוש בכלים קיימיםאפשרות נוספת תהיה להשתמש בכלים •

. )הכלי המקובל ל apache של jsvcאחרים כגון java)

עם מתודות לאתחול, Daemonמספק ממשק •הפעלה, עצירה והריסה.

תפעיל את אותן המתודות ע"פ jsvcהפקודה •הפרמטרים שתקבל כשתופעל.

jsvc -cp /usr/share/java/commons-daemon.jar:/home/eli/MyService.jar Main #לדוגמא:•

Page 17: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

שימוש בכלים קיימים

התקנה:http://commons.apache.org מתוך: sourceהורידו את ה •

/downloads/download_daemon.cgi

קמפלו את הקוד:•

packageכעת ניתן להעתיק את תיקיות ה • רגיל ואז java אל כל פרויקט javaשתחת

.Daemonלממש את הממשק

JAVA_HOME=/usr/bin/javaexport JAVA_HOMEcd daemon-1.0.1/src/native/unix./configuremake

Page 18: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

שימוש בכלים קיימיםimport org.apache.commons.daemon.*;

public class Main implements Daemon{

@Overridepublic void destroy() {// TODO Auto-generated method stub}

@Overridepublic void init(DaemonContext context) throws Exception {// TODO Auto-generated method stub}

@Overridepublic void start() throws Exception {// TODO Auto-generated method stub

}

@Overridepublic void stop() throws Exception {// TODO Auto-generated method stub}

}

Page 19: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

שימוש בכלים קיימים

עובד?jsvcאיך

יוצר

יוצרsignalsמפעיל ע"י

אתcontrolled processה

Page 20: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

הפעלה בעת אתחול שבנינו יופעל עם daemonבד"כ נרצה שה •

אתחול המערכת. מכילה סקריפטים שטוענים etc/init.d/התיקייה •

daemons.בעת אתחול המערכת שלנו עם האתחול, daemonכדי להפעיל את ה •

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

מוכנים.

Page 21: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

הפעלה בעת אתחול•/etc/init.d/skeleton

.daemonsסקריפט שלדי עבור הרצת – שלנו.daemonניתן להעתיק ולהתאים ל –start-stop-daemonמשתמש ב –

•/etc/init.d/tomcat6.daemon כ tomcatסקריפט להרצת שרת ה –.jsvcמשתמש ב –

Page 22: דוגמא ל  Daemon  ב  Java

הקדמהDaemonכיצד נוצר

שימוש בכלים קיימיםהפעלה בעת אתחול

הטמעה

10 – תרגול 2 תכנות מתקדם 89-211

הטמעה ולא להריץ ישר forkמדוע היינו צריכים לעשות •

באותו התהליך?

מה הבעיה בשיטות שראינו בתחילת השיעור •וכיצד ניתן לפתור אותן?

?etc/init.d/למה משמשת התיקייה •

חישבו אילו התאמות תצטרכו לעשות בפרויקט • וגם Windowsהקורס כדי להריצו כשירות גם ב

.Linuxב