34
Проектирование ПО для высоконагруженных систем Лекция №1 Александр Быков

Highload осень 2012 лекция 1

Embed Size (px)

Citation preview

Page 1: Highload осень 2012 лекция 1

Проектирование ПО для высоконагруженных систем

Лекция №1

Александр Быков

Page 2: Highload осень 2012 лекция 1

Лекция 1

Единицы в которых измеряется нагрузка

1. Количество запросов в единицу времениRequests per second (RPS)Requests per minute (RPM)

2. Количество данных в единицу времениPackets per second (PPS)Мегабит в секунду (MB/s)

3. Количество одновременно обслуживаемых соединенийSimultaneous connectionsConcurrency

Page 3: Highload осень 2012 лекция 1

Лекция 1

http://www.liveinternet.ru/stat/mail.ru/mins.html

Page 4: Highload осень 2012 лекция 1

Лекция 1

http://www.liveinternet.ru/stat/vkontakte.ru/mins.html

Page 5: Highload осень 2012 лекция 1

Лекция 1

Page 6: Highload осень 2012 лекция 1

Лекция 1

Статистических пакетов в секунду (RPS,PPS)

Page 7: Highload осень 2012 лекция 1

Лекция 1

Nginx frontend active connections

Page 8: Highload осень 2012 лекция 1

Лекция 1

Высокая нагрузка

• Такая нагрузка которую «обычный» сайт не выдержит

• Как правило речь идет о сотнях/тысячах запросов в минуту

Page 9: Highload осень 2012 лекция 1

Лекция 1

Slashdot-эффект

Кто-то разместил ссылку на популярном сайте

Page 10: Highload осень 2012 лекция 1

Лекция 1

Что видит пользователь ?

Page 11: Highload осень 2012 лекция 1

Лекция 1

503 Service Unavailable

Page 12: Highload осень 2012 лекция 1

Лекция 1

503 Service Unavailable

Page 13: Highload осень 2012 лекция 1

Лекция 1

502 Bad Gateway

Page 14: Highload осень 2012 лекция 1

Лекция 1

DDOS-аттака

Page 15: Highload осень 2012 лекция 1

Лекция 1

Высокая доступность

Отношение времени когда сайт работал к общему времени

Доступность % Время простоя в год Время простоя в месяц99% ("две девятки") 3.65 дней 7.20 часов99.5% 1.83 дней 3.60 часов99.9% ("три девятки") 8.76 часов 43.2 минут99.95% 4.38 часов 21.56 минут99.99% ("четыре девятки") 52.56 минут 4.32 минут99.999% ("пять девяток") 5.26 минут 25.9 секунд99.9999% ("шесть девяток") 31.5 секунд 2.59 секунд

Page 16: Highload осень 2012 лекция 1

Лекция 1

Page 17: Highload осень 2012 лекция 1

Лекция 1

Типичный сайт

( Perl / Python )

Page 18: Highload осень 2012 лекция 1

Лекция 1

Типичный сайт

Page 19: Highload осень 2012 лекция 1

Лекция 1

helloworld.pl:#!/usr/bin/perlprint "Content-type: text/html\n\n";print "<H1>Hello World</H1>\n";

%ENV:DOCUMENT_ROOT = /usr/local/wwwGATEWAY_INTERFACE = CGI/1.1HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8HTTP_ACCEPT_CHARSET = ISO-8859-1,utf-8;q=0.7,*;q=0.3HTTP_ACCEPT_ENCODING = gzip,deflate,sdchHTTP_ACCEPT_LANGUAGE = en-US,en;q=0.8HTTP_CACHE_CONTROL = max-age=0HTTP_CONNECTION = closeHTTP_COOKIE = p=uc0bAMnfrgAA; t=obLD1AAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAdAA4FxQcA; VID=1Y6UOS0sMI11HTTP_HOST = bykov.corp.mail.ruHTTP_USER_AGENT = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 MRSpy/1.0.0QUERY_STRING = REMOTE_ADDR = 194.186.63.231REMOTE_PORT = 51638REQUEST_METHOD = GETREQUEST_URI = /cgi-bin/hellowworld.plSERVER_ADDR = 127.0.0.1SERVER_ADMIN = [email protected]_NAME = bykov.corp.mail.ruSERVER_PORT = 80SERVER_PROTOCOL = HTTP/1.0

Динамическое содержимое: CGI

Page 20: Highload осень 2012 лекция 1

Лекция 1

Динамическое содержимое:  CGI

• Fork и запуск интерпретатора на каждом обращении

• Не очень эффективный протокол• Можно писать скрипты на любом языке

Page 21: Highload осень 2012 лекция 1

Лекция 1

Динамическое содержимое: mod_php

• Интерпретатор загружается при старте сервера • Скрипты компилируются при каждом обращении

Page 22: Highload осень 2012 лекция 1

Лекция 1

Динамическое содержимое: mod_perl

• Интерпретатор загружается при старте сервера • При старте сервера загружаются модули из

startup.pl• Скомпилированные скрипты кешируются в веб-

сервере• При изменении скриптов – автоматическое

обновление

Page 23: Highload осень 2012 лекция 1

Лекция 1

#include <httpd.h>#include <http_protocol.h>#include <http_config.h>static int helloworld_handler(request_rec *r) { if (!r->handler || strcmp(r->handler, "helloworld")) { return DECLINED; } if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } ap_set_content_type(r, "text/html;charset=ascii"); ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n", r); ap_rputs("<html><head><title>Apache HelloWorld " "Module</title></head>", r); ap_rputs("<body><h1>Hello World!</h1>", r); ap_rputs("<p>This is the Apache HelloWorld module!</p>", r); ap_rputs("</body></html>", r); return OK;}static void helloworld_hooks(apr_pool_t *pool) { ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);}module AP_MODULE_DECLARE_DATA helloworld_module = { STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, helloworld_hooks};

Apache: mod_helloworld

Page 24: Highload осень 2012 лекция 1

Лекция 1

Apache: mod_helloworld

# apxs -c mod_helloworld.c# apxs -i mod_helloworld.la

httpd.conf:LoadModule helloworld_module modules/mod_helloworld.so<Location /helloworld> SetHandler helloworld</Location>

Page 25: Highload осень 2012 лекция 1

Лекция 1

Nginx: ngx_http_hello_modulestatic ngx_int_tngx_http_hello_handler(ngx_http_request_t *r){ ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out;

/* we response to 'GET' and 'HEAD' requests only */ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; }

/* discard request body, since we don't need it here */ rc = ngx_http_discard_request_body(r);

if (rc != NGX_OK) { return rc; }

/* set the 'Content-type' header */ r->headers_out.content_type_len = sizeof("text/html") - 1; r->headers_out.content_type.len = sizeof("text/html") - 1; r->headers_out.content_type.data = (u_char *) "text/html";

/* send the header only, if the request type is http 'HEAD' */ if (r->method == NGX_HTTP_HEAD) { r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = sizeof(ngx_hello_string) - 1;

return ngx_http_send_header(r); }

/* allocate a buffer for your response body */ b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; }

/* attach this buffer to the buffer chain */ out.buf = b; out.next = NULL; /* adjust the pointers of the buffer */ b->pos = ngx_hello_string; b->last = ngx_hello_string + sizeof(ngx_hello_string) - 1; b->memory = 1; /* this buffer is in memory */ b->last_buf = 1; /* this is the last buffer in the buffer chain */

/* set the status line */ r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = sizeof(ngx_hello_string) - 1;

/* send the headers of your response */ rc = ngx_http_send_header(r);

if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; }

/* send the buffer chain of your response */ return ngx_http_output_filter(r, &out);}

Page 26: Highload осень 2012 лекция 1

Лекция 1

Nginx: ngx_http_hello_module

config:ngx_addon_name=ngx_http_hello_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_hello_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_module.c"

./configure –add-module=./hello/ & make && make install

nginx.conf:location / { hello;}

Page 27: Highload осень 2012 лекция 1

Лекция 1

Nginx: content_by_lua

nginx.conf:location /lua_content { content_by_lua "ngx.say('Hello,world!')";}

Page 28: Highload осень 2012 лекция 1

Лекция 1

FastCGI

Page 29: Highload осень 2012 лекция 1

Лекция 1

Page 30: Highload осень 2012 лекция 1

Лекция 1

Page 31: Highload осень 2012 лекция 1

Лекция 1

TCP/IP: блокирующийся сервер

Page 32: Highload осень 2012 лекция 1

Лекция 1

TCP/IP: неблокирующая обработка

Системные вызовы:• select • kqueue (FreeBSD 4.1+)• epoll (Linux 2.6+)

Прикладные библиотеки:• libevent• libev

Веб-серверы:• Nginx• Lighttpd• Thttpd• 0W-httpd• Tornado• Node.js

Page 33: Highload осень 2012 лекция 1

Лекция 1

Домашнее задание

• Написание простого веб-сервера

Page 34: Highload осень 2012 лекция 1

Спасибо за вниманиеАлександр Быков

[email protected]