рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЕрддреНрдпрдзрд┐рдХ рд▓реЛрдб рдХрд┐рдП рдЧрдП рд╕рд░реНрд╡рд░реЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдШрдЯрдирд╛ рдореЙрдбрд▓ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдореБрдЦреНрдп рдШрдЯрдХ рдПрдкреЛрд▓ рд╣реИ (рдлреНрд░реАрдмреАрдПрд╕рдбреА рдФрд░ рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рдЕрдкрдиреЗ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЪрд▓реЛ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ)ред Epoll_wait рдлрд╝рдВрдХреНрд╢рди, рдПрдХрдорд╛рддреНрд░ рдЕрд╡рд░реБрджреНрдз рдХреЙрд▓ рд╣реЛрдиреЗ рдХреЗ рдирд╛рддреЗ, рдЙрди рд╕рднреА рдиреЗрдЯрд╡рд░реНрдХ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред рдЗрд╕реА рддрд░рд╣, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдкреНрд░рд╕рд┐рджреНрдз NGINX рд╕рд░реНрд╡рд░ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдИрд╡реЗрдВрдЯ-рдЪрд╛рд▓рд┐рдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЙрдбрд▓ рдХреЛрдб рдХреЛ рдмрд╣реБрдд рдЕрдЬреАрдм рдмрдирд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рдЗрд╕реЗ рдЕрдВрджрд░ рдмрд╛рд╣рд░ рдореЛрдбрд╝рдирд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЗрддрдиреА рднрдпрд╛рдирдХ рдирд╣реАрдВ рд╣реИред рдПрдХ рдФрд░ рд╕рдорд╕реНрдпрд╛ рд╣реИ - рдШрдЯрдирд╛-рдЙрдиреНрдореБрдЦ рдХреЛрдб рдореЗрдВ рдореМрдЬреВрджрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рдереЗред рдпрджрд┐ рдРрд╕рд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЕрд╡рд░реБрджреНрдз рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрдиреЗрдХреНрдЯ, рд░рд┐рдХрд╡, рдЖрджрд┐), рддреЛ рдкреВрд░рд╛ рдИрд╡реЗрдВрдЯ рдореЙрдбрд▓ рдЕрдкрдирд╛ рдЕрд░реНрде рдЦреЛ рд╕рдХрддрд╛ рд╣реИред рдЕрдиреНрдп рд╕рднреА рдЧреНрд░рд╛рд╣рдХ рдПрдХ рдРрд╕реА рдХреЙрд▓ рдХреЗ рдЕрдВрдд рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХрд┐ рдпрджрд┐ рдЖрдк рдПрдХ рдЧрдВрднреАрд░ рдЙрддреНрдкрд╛рдж рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЬреЛ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдореВрд▓ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рдерд╛, рд╡рд╣ рд╣реИ libmysqlclient рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реАред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдирдЬреАрдЖрдИрдПрдирдПрдХреНрд╕ рдореЗрдВ рдЕрдХреНрд╕рд░ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдХрдИ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ MySQL рдХреЛ NGINX рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
рдЯрдкрдХрдирд╛ рдФрд░
рд╣реИрдВрдбрд▓рд░ рд╕реЙрдХреЗрдЯ (рдорд╛рдирдХ рдПрдирдЬреАрдЖрдИрдПрдирдПрдХреНрд╕ рдЕрдкрд╕реНрдЯреНрд░реАрдо рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ
рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреБрдЪреНрдЫ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдмрд╣реБрдд
рдЖрд╕рд╛рди рд╣реИ )ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдлрд┐рд░ рднреА, рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдорд╛рдирдХ libmysqlclient рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдФрд░ SQL рднрд╛рд╖рд╛ рдХреА рдкреВрд░реА рд╢рдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред
рдкреНрд░рд╕рдВрдЧ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдФрд░ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯреНрд╕
рдЕрд╡рд░реБрджреНрдз рдХреЙрд▓ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдПрдХ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди рд╣реИред рдЕрд╡рд░реБрджреНрдз рдХреЛрдб рдХреЛ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрд╡рд░реБрджреНрдз рдХреЙрд▓ рдХреЛ рд░реЛрдХрдирд╛ рдФрд░ рдЗрд╕реЗ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдХреЗ рд╕рд╛рде рдмрджрд▓рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдФрд░ рдпрджрд┐ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдореБрдЦреНрдп рд╕рд░реНрд╡рд░ рд▓реВрдк рдкрд░ рдЬрд╛рдПрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд┐ рдЬрдм рдЕрдкреЗрдХреНрд╖рд┐рдд рдШрдЯрдирд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЙрд╕реА рд╕реНрдерд╛рди рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯреЗрдВ рд╡реЗ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИред рдпрд╛рдиреА рдРрд╕рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдереНрд░реЗрдб рдмрдирд╛рдПрдБред рдпрд╣ рд╣рдореЗрдВ рдХрд╛рдлреА рд╕рд╕реНрддреЗ рдореЗрдВ рдЦрд░реНрдЪ рд╣реЛрдЧрд╛ред рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХрд┐рдВрдЧ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рдЙрд╕рдХреЗ рд▓рд┐рдП рдмреЗрдХрд╛рд░ рд╣реИ, рдФрд░ рд╣рдо рд╕рднреА рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рд╕рд╣реА рд╕рдордп рдкрд░ рдЕрдкрдиреЗ рдЖрдк рдмрджрд▓ рджреЗрдВрдЧреЗред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкрддрд╛ рдХрд░реЗрдВ рдХрд┐ рдХреНрдпрд╛ рдХреЙрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдзрд╛рдЧреЗ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣рд╛рдБ рдореБрдЦреНрдп рд╣реИрдВ:
- рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛
- рдХрдиреЗрдХреНрдЯ
- рдкрдврд╝реЗрдВ / рдлрд┐рд░ рд╕реЗ рдкрдврд╝реЗрдВ
- рд▓рд┐рдЦрдирд╛ / рднреЗрдЬрдирд╛
- рдорддрджрд╛рди
рдЗрд╕ рд╕реВрдЪреА рдореЗрдВ рдЕрдВрддрд┐рдо рдХрд╛рд░реНрдп - рдЬрдирдордд - рдХреНрдпреЛрдВрдХрд┐ рдмрд╣реБрдд рдИрдорд╛рдирджрд╛рд░ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рд╕реНрд╡рдпрдВ рдХрднреА-рдХрднреА рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╕рдВрдХреЗрдд рд╣реЛрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, libmysqlclient рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕реЗ рд░реЛрдХрдирд╛ рд╣реЛрдЧрд╛ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, epoll_wait рднреА рдЕрд╡рд░реБрджреНрдз рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЖрд╢рд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЕрд╡рд░реБрджреНрдз рдХреЛрдб рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдЕрднреА рднреА рдПрдХ рдЪреБрдирд┐рдВрджрд╛ рдХреЙрд▓ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ рдФрд░ рдЗрд╕рд▓рд┐рдП (рднрдЧрд╡рд╛рди рдХрд╛ рд╢реБрдХреНрд░ рд╣реИ!) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдо рдФрд░ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛ рднреА рдмрд╛рд╣рд░ рдХрд░ рджрд┐рдпрд╛ред
рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд┐рдмрд╛рд╕ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рд╣рдорд╛рд░рд╛ рдХреЛрдб рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдВрдХ рдХрд░ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдорд╛рдирдХ рдЕрд╡рд░реЛрдзрди рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╣рд░ рдЕрд╡рд╕рд░ рд╣реИред рдореИрдВ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛:
typedef ssize_t (*read_pt)(int fd, void *buf, size_t count); static read_pt orig_read; ssize_t read(int fd, void *buf, size_t count) { ssize_t ret; for(;;) { ret = orig_read(fd, buf, count); if (!mtask_scheduled || ret != -1 || errno != EAGAIN) return ret; if (mtask_yield(fd, NGX_READ_EVENT)) { errno = EIO; return -1; } } } ... orig_read = (read_pt)dlsym(RTLD_NEXT, "read");
рдпрд╣рд╛рдБ
mtask_yield
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рд╕рдВрджрд░реНрдн рдХреЛ рдореБрдЦреНрдп рдИрд╡реЗрдВрдЯ рд▓реВрдк рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИред рдЗрд╕реЗ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЕрд╡рд░реБрджреНрдз рдХреЛрдб рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛;
mtask_scheduled
- рдПрдХ рдореИрдХреНрд░реЛ рдЬреЛ рдЖрдкрдХреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдХреЗ, рдпрд╛ рдорд╛рдирдХ рддрд░реАрдХреЗ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдХреЗ рдЕрд╡рд░реБрджреНрдз рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╣рдорд╛рд░реЗ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдмрд╛рд╣рд░, рд╕рднреА рд╕рдВрджрд░реНрдн рд╕реНрд╡рд┐рдЪ рдХреЗрд╡рд▓ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд░реЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реНрд╡рдпрдВ NG NGX рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдХреЙрд▓ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП) рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░реА рдорджрдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдореВрд▓ рд░реВрдк рд╕реЗ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рдереЗред
рдпрд╣ рднреА рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЬрд┐рд╕ рд╕реЙрдХреЗрдЯ рдкрд░
read
рдСрдкрд░реЗрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЙрд╕реЗ рдиреЙрди-рдмреНрд▓реЙрдХрд┐рдВрдЧ рдореЛрдб рдореЗрдВ рдбрд╛рд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣реБрдХ
connect
рдФрд░
accept
рдореЗрдВ
fcntl
рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдХреЙрд▓ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рд╕рдВрджрд░реНрднреЛрдВ
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рдХреНрдпрд╛ рд╣реИ? рдпрд╣ рдПрдХ рд╕реНрдЯреИрдХ + рд░рдЬрд┐рд╕реНрдЯрд░ рд╣реИ (рд╕рдВрдХреЗрддреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореБрдЦреМрдЯрд╛ рднреА рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рд╕рдВрдХреЗрддреЛрдВ рд╕реЗ рдирд╣реАрдВ рдХреВрджрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЕрдм рд╣рдореЗрдВ рдХреЛрдИ рджрд┐рд▓рдЪрд╕реНрдкреА рдирд╣реАрдВ рд╣реИ)ред рдпрджрд┐ рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рд╕рд░рд▓ рд╣реИ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕рдВрджрд░реНрдн рдХреЛ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рд╣рдо рдЗрд╕реЗ рдорд╣рд╕реВрд╕ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рдЙрдкрдХрд░рдг рд╣реИрдВред
makecontext
- рдПрдХ рд╕рдВрджрд░реНрдн рдмрдирд╛рддрд╛ рд╣реИ, рд╣рдо рд╕реНрдЯреИрдХ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВswapcontext
- рд╕реНрд╡рд┐рдЪ рд╕рдВрджрд░реНрднsetcontext
/ getcontext
- рд╕рдВрджрд░реНрдн рд╕реЗрдЯ / рдкрдврд╝рддрд╛ рд╣реИ
рд╣рдо рдПрдирдЬреАрдЖрдИрдПрдирдПрдХреНрд╕ рдХреЛ рдЙрдкрд╡рд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ
NGINX рдореЗрдВ, рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рд╛рдордЧреНрд░реА рдПрдХ рджреГрд╢реНрдп рд╣реИрдВрдбрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдИ рдЧрдИ рд╣реИ:
static ngx_int_t ngx_http_mtask_handler(ngx_http_request_t *r);
рдпрд╣ рд╣реИрдВрдбрд▓рд░ NGX_HTTP_CONTENT_PHASE рдЪрд░рдг рдХреЗ рд╣реИрдВрдбрд▓рд░ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ:
h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers)
рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдореЗрдВ, рд╣реИрдВрдбрд▓рд░ рдЬрдВрдЬреАрд░реЛрдВ (ngx_chain_t) рдХреЛ рдмрдлрд╝рд░реНрд╕ рдХреЗ рд╕рд╛рде рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рдж рдпрд╣ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ
ngx_http_send_header
- HTTP рд╢реАрд░реНрд╖ рд▓реЗрдЦ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПngx_http_output_filter
- рд╢рд░реАрд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рд╢рд░реАрд░, рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реЙрдХреЗрдЯ рдореЗрдВ "рдлрд┐рдЯ" рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрд╡рд░реБрджреНрдз, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдПрдирдЬреАрдЖрдИрдПрдирдПрдХреНрд╕ рдЦреБрдж рдХреНрд▓рд╛рдЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рднреЗрдЬрдиреЗ рдореЗрдВ рд▓рдЧреЗ рд╣реБрдП рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣реИрдВрдбрд▓рд░ рдЕрд╡рд░реБрджреНрдз рд╕рдВрдЪрд╛рд▓рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд░реЗрдВред
getcontext(&ctx->wctx); ctx->wctx.uc_stack.ss_sp = ngx_palloc(r->pool, mlcf->stack_size); ctx->wctx.uc_stack.ss_size = mlcf->stack_size; ctx->wctx.uc_stack.ss_flags = 0; ctx->wctx.uc_link = NULL; makecontext(&ctx->wctx, &mtask_proc, 0); mtask_wake(r, MTASK_WAKE_NOFINALIZE); r->main->count++;
Mtask_wake рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрди рдмреБрдирд┐рдпрд╛рджреА рдЪреАрдЬрд╝реЗрдВ рдХрд░рддрд╛ рд╣реИ:
mtask_setcurrent( r ); swapcontext(&ctx->rctx, &ctx->wctx); if (!mtask_scheduled) { if (!(flags & MTASK_WAKE_NOFINALIZE)) ngx_http_finalize_request(r, NGX_OK); return 1; } mtask_resetcurrent();
Mtask_yield рдлрд╝рдВрдХреНрд╢рди рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ - рдпрд╣ рдЕрд╡рд░реБрджреНрдз рдХреЙрд▓ рдХреЛ NGINX рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдореБрдЦреНрдп рд╕реАрдорд╛ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
c = ngx_get_connection(fd, mtask_current->connection->log); c->data = mtask_current; if (event == NGX_READ_EVENT) e = c->read; else e = c->write; e->data = c; e->handler = &mtask_event_handler; e->log = mtask_current->connection->log; ngx_add_event(e, event, 0); swapcontext(&ctx->wctx, &ctx->rctx); ngx_del_event(e, event, 0); ngx_free_connection( c );
NGINX рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: I / O рдИрд╡реЗрдВрдЯ рд╣реЛрдиреЗ рдкрд░ рд╕рдВрджрд░реНрдн рдмрджрд▓рддрд╛ рд╣реИ:
static void mtask_event_handler(ngx_event_t *ev) { ... mtask_wake(r, wf); ... }
рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдереНрд░реЗрдб рдореЗрдВ рдЖрдк NGINX рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рдереЗред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ ngx_http_send_header рдФрд░ ngx_http_output_filter рд╕реЗ рдХреЙрд▓ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред рдЗрди рдХреЙрд▓реЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд╡рд░реНрддрдорд╛рди рдХрдиреЗрдХреНрд╢рди рдХреЛ рдмрдлрд░рд┐рдВрдЧ рдореЛрдб рдореЗрдВ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд░рдЦрд╛ рд╣реИ:
c->write->delayed = 1
рдзрд╛рдЧреЗ рдХреЗ рдЕрдВрдд рдореЗрдВ, рдпрд╣ рдзреНрд╡рдЬ рд░реАрд╕реЗрдЯ рд╣реИ рдФрд░ рдбреЗрдЯрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣ рд╕рдорд╛рдзрд╛рди рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдпрд╣ рдХрд╛рд░реНрдп рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИ (рдФрд░ рдЬрдм рдпрд╣ рд╣реЛрддрд╛ рд╣реИ, рддрдм рднреА рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рдХрдо рд╕реБрдВрджрд░ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред
рд╣рдо libmysqlclient рдХреЛ рдлрд╛рд╕реНрдЯ рдХрд░рддреЗ рд╣реИрдВ
рдЕрд╡рд░реБрджреНрдз рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдВрддреНрд░ рдХреЗ рд╕рд╛рде, MySQL рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рдЖрд╕рд╛рди рд╣реИред рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рд╕рдмрд╕реЗ рдЖрдо CONTENT_PHASE рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рд╕реНрдкреЗрд╕ рдереНрд░реЗрдб рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдлрд╝рдВрдХреНрд╢рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рдирд┐рдпрдорд┐рдд рд╣реИрдВрдбрд▓рд░ рдХреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреА рдЕрд╡рд░реБрджреНрдз рдкреНрд░рдХреГрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреВрд▓рдХрд░, рд╣рдо libmysqlclient рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдорд╛рдирдХ рдЯреВрд▓ рдХрд╛ рдорд╛рдирдХ рдорд╛рдирдХ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:
ngx_int_t ngx_http_mysql_handler(ngx_http_request_t *r) { ... mysql_real_connect(...) ... mysql_query(...) ... mysql_store_result(...) ... mysql_fetch_row(...) ... }
рдбреЗрдЯрд╛ рдХреЛ рд╕рд╛рджреЗ рдкрд╛рда рдореЗрдВ, рдлрд╝реАрд▓реНрдб рджреНрд╡рд╛рд░рд╛ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдо ngx_chain_t рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкреНрд░рддрд┐ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдПрдХ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╣рдореЗрдВ NGINX рдХреЗ рдЕрдВрджрд░ рдХреНрд╡реЗрд░реА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЕрд╡рд╕рд░ рджреЗрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, mysql_subrequest рдирд┐рд░реНрджреЗрд╢ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реНрдерд╛рди рдкрд░ рд╡рд░реНрдгрд┐рдд MySQL рдХреНрд╡реЗрд░реА рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕ рдЖрджреЗрд╢ рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдЪрд░ рдХреЗ рдХреНрд░рдо рдореЗрдВ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ (рдиреАрдЪреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ)ред рддрдм рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдмреИрдХрдПрдВрдб (рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкреНрд░рд╛рдкреНрдд) рдХреЛ рдкреНрд░реЙрдХреНрд╕реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛ рдЕрдкрдиреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдХреБрдЫ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИред
рд╣реИрдВрдбрд▓рд░ рд╕реНрд╡рдпрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдирд╣реАрдВ рд╣реИ (CONTENT_PHASE рдЪрд░рдг рдореЗрдВ - рдпрд╣рд╛рдВ рдЖрдкрдХреЛ "рдИрдорд╛рдирджрд╛рд░" рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдХреЛрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ), рд▓реЗрдХрд┐рди mtask рдореЙрдбреНрдпреВрд▓ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВред
ngx_http_mtask_loc_conf_t *mlcf; mlcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_mtask_module); mlcf->handler = &ngx_http_mysql_handler;
рдЙрджрд╛рд╣рд░рдг
рдПрдХ рдЙрджрд╛рд╣рд░рдг nginx.conf config рдЬреЛ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
server { ... # server # unix socket access (default) mysql_host localhost; #mysql_user theuser; #mysql_password thepass; #mysql_port theport; mysql_database test; mysql_connections 32; # # .. NGINX # . mtask_stack 65536; # ! location /select { mysql_query "SELECT name FROM users WHERE id='$arg_id'"; } location /insert { mysql_query "INSERT INTO users(name) VALUES('$arg_name')"; } location /update { mysql_query "UPDATE users SET name='$arg_name' WHERE id=$arg_id"; } location /delete { mysql_query "DELETE FROM users WHERE id=$arg_id"; } # location /pass { # name $name mysql_subrequest /select?id=$arg_id $name; # $name proxy_pass http:
рдЖрдк рдкрддреЗ рдкрд░ рдореЙрдбреНрдпреВрд▓ рджреЗрдЦ рдФрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
github.com/arut/nginx-mtask-modulegithub.com/arut/nginx-mysql-moduleрдЖрдк рд╕рднреА рдХреЛ рдзрдиреНрдпрд╡рд╛рдж!