Журнал LinuxFormat - перейти на главную

LXF168:Руб­ри­ка си­сад­ми­на

Материал из Linuxformat
Перейти к: навигация, поиск
(thumbnail)
Д-р Крис Браун. Доктор обучает, пишет и консультирует по Linux. Ученая степень по физике элементарных частиц ему в этом совсем не помогает.

Содержание

По рецептам доктора Брауна

Эзо­те­ри­че­ское сис­тем­ное ад­ми­ни­ст­ри­ро­ва­ние из при­чуд­ли­вых за­во­ро­тов ки­шок сер­вер­ной

OpenNebula

Ни­ко­гда не стес­няв­ший­ся сме­шан­ных ме­та­фор док­тор соз­да­ет об­ла­ко в пе­соч­ни­це.

Rightscale, scalr, cloudkick, enstratus – ути­лит управ­ления об­ла­ком боль­ше, чем мож­но со­счи­тать. Мно­гие из них сто­ят денег, но OpenNebula – нет. OpenNebula – от­кры­тый про­ект, ко­то­рый раз­ра­ба­ты­ва­ет – ци­ти­рую его сайт – «ре­шение уров­ня пред­при­ятия для по­строения вир­туа­ли­зи­ро­ван­ных да­та-цен­тров и об­ла­ков IaaS и управ­ления ими». Не­дав­но они вы­пусти­ли несколь­ко вир­ту­аль­ных об­ра­зов, с ко­то­ры­ми все это очень лег­ко по­про­бо­вать. В них ис­поль­зу­ет­ся CentOS 6.3 с на­стро­ен­ным кли­ен­том OpenNebula 3.8.1 и хостом вир­туа­ли­за­ции на ба­зе QEMU. Эти об­ра­зы мож­но за­пускать в VirtualBox, VMWare или KVM, есть да­же об­раз Amazon EC2.

Я за­гру­зил об­раз для VirtualBox, вы­полнил ин­ст­рук­ции по уста­нов­ке, и все за­ра­бо­та­ло. Про­ясним, что про­ис­хо­дит: на род­ной ОС мое­го но­ут­бу­ка за­пу­ще­на вир­ту­аль­ная ма­ши­на (ВМ) с уста­нов­лен­ной про­грам­мой OpenNebula, ко­то­рая мо­жет соз­да­вать «внут­ренние» ВМ и управ­лять ими. От са­мой мыс­ли о ВМ, ра­бо­таю­щей внут­ри дру­гой ВМ, у ме­ня бо­лит го­ло­ва, но свою за­да­чу эта схе­ма вы­пол­ня­ет – в ней мож­но бы­ст­ро на­чать поль­зо­вать­ся OpenNebula и по­чув­ст­во­вать, что это та­кое.

Во-пер­вых, в ней есть ути­ли­ты команд­ной стро­ки для соз­дания ВМ и управ­ления ими. На­при­мер, но­вый эк­зем­п­ляр мож­но соз­дать так:

onevm create --name “tty3” --memory 128 --cpu 0.5 --disk ttylinux --network cloud

Мож­но соз­да­вать шаб­ло­ны и но­вые эк­зем­п­ля­ры на их осно­ве.

В вир­ту­аль­ном об­ра­зе есть один (ма­лень­кий) об­раз Linux; его мож­но за­гру­зить. Ни­кто не ждет, что в этих сис­те­мах бу­дут реально ра­бо­тать, а ес­ли вы хо­ти­те за­пустить и по­ра­бо­тать с несколь­ки­ми об­раз­ами, вы­де­ляй­те па­мять эко­номнее. Есть еще web-ин­тер­фейс SunStone, он при­ятнее на вид.

Стек LAMP

Вто­рая ста­тья се­рии, в ко­то­рой мы уви­дим, как HTML и PHP иг­ра­ют друг дру­гу на ру­ку, что­бы соз­дать web-при­ло­же­ние.

Быть web-раз­ра­бот­чи­ком непро­сто, по­то­му что нуж­но уметь мно­гое. Нуж­но изу­чить как минимум че­ты­ре язы­ка (для сте­ка LAMP это PHP, HTML, CSS и SQL) и, по­жа­луй, немно­го JavaScript. Нуж­но понимать струк­ту­ру ре­ля­ци­он­ной ба­зы дан­ных и немно­го пред­став­лять че­ло­ве­че­­ские фак­то­ры, ок­ру­жаю­щие раз­ра­бот­ку web-при­ло­жений. Ес­ли все это у вас есть, ры­нок тру­да для вас от­крыт. А есть или нет – это боль­шой во­прос.

Но с че­го-то на­чи­нать все же на­до, и в этом ме­ся­це мы рас­смот­рим HTML и PHP и уви­дим, как они ра­бо­та­ют вме­сте при соз­дании про­сто­го web-при­ло­жения. В про­шлом ме­ся­це мы на­ча­ли уста­нав­ли­вать стек LAMP, и ес­ли вы хо­ти­те сле­до­вать за моим повест­во­ва­нием (а я на­де­юсь, что да), у вас долж­ны быть уста­нов­ле­ны по крайней ме­ре Apache и PHP.

Начнем со ста­ро­го доб­ро­го “Hello World” на HTML. Есть ли смысл это де­лать? Конеч­но, есть! Для со­от­вет­ст­вия стан­дар­там HTML-до­ку­мент дол­жен иметь до­воль­но спе­ци­фи­че­­ское об­рам­ление, по­это­му наш файл дол­жен вы­гля­деть так:

<!DOCTYPE html>

<html>

<head>

<title> Hello from HTML </title>

</head>

Hello World!

</body>

</html>

Стро­го го­во­ря, мы долж­ны го­во­рить об XHTML, а не об HTML. XHTML стро­же HTML и поя­вил­ся в основ­ном по­то­му, что раз­ные брау­зе­ры ото­бра­жа­ют HTML по-раз­но­му. На­при­мер, в XHTML от­кры­ваю­щие тэ­ги должны иметь за­кры­ваю­щие, и все тэ­ги и ат­ри­бу­ты долж­ны быть в нижнем ре­ги­ст­ре. На прак­ти­ке же брау­зе­ры очень то­ле­рант­ны и сде­ла­ют все воз­мож­ное, что­бы пра­виль­но об­ра­бо­тать непра­виль­ный код; но это не является оп­рав­данием для неряш­ли­во­го ко­да.

Ес­ли вы уста­но­ви­ли Apache с корневым ка­та­ло­гом до­ку­мен­та /var/www/html, как мы сде­ла­ли в про­шлом ме­ся­це, по­мес­ти­те этот код в файл /var/www/html/greet.html, за­тем от­крой­те его в брау­зере (т. е. от­крой­те ад­рес http://localhost/greet.html). Тэг

за­да­ет за­го­ло­вок пер­во­го уров­ня, по­это­му вы долж­ны уви­деть при­ят­ное боль­шое “Hello World”. Фор­мы – это кон­тейнеры, ко­то­рые со­дер­жат эле­мен­ты управ­ления, с ко­то­ры­ми взаи­мо­дей­ст­ву­ют поль­зо­ва­те­ли: тек­сто­вые по­ля, га­лоч­ки, кноп­ки и т. д. Это клю­че­вые ком­понен­ты лю­бо­го web-при­ло­жения. Наш пер­вый при­мер – про­стой каль­ку­ля­тор с че­тырь­мя опе­ра­ция­ми. Смот­реть в нем осо­бен­но не на что, но с его по­мо­щью мы уви­дим, как поль­зо­ва­те­ли вво­дят дан­ные в web-при­ло­жение и как эти дан­ные мож­но по­лу­чить и об­ра­бо­тать на сто­роне сер­ве­ра с по­мо­щью PHP. Для на­ча­ла соз­да­дим ко­пию на­шей страницы “hello world”: $ cd /var/www/html $ cp greet.html calculator.html Те­перь от­крой­те файл и за­мените “hello world” раз­мет­кой фор­мы, как по­ка­за­но ниже. Но­ме­ра строк до­бав­ле­ны для удоб­ст­ва ссы­лок, они не яв­ля­ют­ся ча­стью фай­ла: 1. <form action = “calculator.php” method = get> 2. Округлить до целого 3. <input type=”checkbox” name=”round”>
4. <input type=”text” size=”10” name=”op1”> 5. <select size=”1” name=”operator”> 6. <option selected> + 7. <option> - 8. <option> * 9. <option> / 10. </select> 11. <input type=text size=10 name=”op2”> 12. <input type=submit value=”Calculate”> 13. </form> От­крыв http://localhost/calculator.html в брау­зе­ре, вы долж­ны уви­деть фор­му. Не­мно­го раз­бе­рем раз­мет­ку: фор­ма на­чи­на­ет­ся в стро­ке 1 и за­кан­чи­ва­ет­ся в стро­ке 13. От­кры­ваю­щий тэг в стро­ке 1 оп­ре­де­ля­ет два важ­ных ат­ри­бу­та: ат­ри­бут action за­да­ет web-страницу, ко­то­рой пе­ре­да­ет дан­ные фор­ма, т. е. когда поль­зо­ва­тель на­жи­ма­ет кноп­ку Submit [От­пра­вить], брау­зер за­про­сит эту страницу и вклю­чит в за­прос ин­фор­ма­цию, вве­ден­ную поль­зо­ва­те­лем в фор­му. Ат­ри­бут method оп­ре­де­ля­ет, как эта ин­фор­ма­ция вклю­ча­ет­ся в за­прос. На фор­ме пять эле­мен­тов управ­ления: га­лоч­ка (стро­ка 3), два тек­сто­вых по­ля для опе­ран­дов (стро­ки 4 и 11), вы­па­даю­щий спи­сок для вы­бо­ра ариф­ме­ти­че­­ско­­го опе­ра­то­ра (стро­ки 5 – 10). В стро­ке 12 соз­да­ет­ся кноп­ка, ко­то­рая от­прав­ля­ет дан­ные фор­мы. Об­ра­ти­те внимание, что у всех эле­мен­тов управ­ления есть име­на – на­при­мер, тек­сто­вые по­ля на­зы­ва­ют­ся op1 и op2. Мы ис­поль­зу­ем эти име­на для по­лу­чения со­дер­жи­мо­го эле­мен­тов управ­ления в на­шем скрип­те на PHP.
LXF168.sysadmin.calcul opt.jpeg

Те­перь рас­смот­рим страницу, где об­ра­ба­ты­ва­ют­ся дан­ные фор­мы. Соз­дай­те файл /var/www/html/calculator.php со сле­дую­щим со­дер­жи­мым (но без но­ме­ров строк):

1. <!DOCTYPE html>

2. <html>

3. <head>

4. <title> Calculator Results </title>

5. </head>

6. <body>

7. <?php

8. $op1 = $_REQUEST[‘op1’];

9. $op2 = $_REQUEST[‘op2’];

10. $op = $_REQUEST[‘operator’];

11. if ($op == ‘+’) $res = $op1 + $op2;

12. if ($op == ‘-’) $res = $op1 - $op2;

13. if ($op == ‘*’) $res = $op1 * $op2;

14. if ($op == ‘/’) $res = $op1 / $op2;

15. if (isset($_REQUEST[‘round’]))

16. $res = round($res);

17. echo “result is $res”;

18. ?>

19.
<a href=”calculator.html”>

20. Return to calculator </a>

21. </body>

22. </html>

Раз­бе­рем его под­роб­но. В стро­ках 1 – 6, 21 и 22 за­да­ет­ся стан­дарт­ный кар­кас HTML. Наш код PHP ог­раничи­ва­ет­ся тэ­га­ми в стро­ках 7 и 18. Пер­вое, что мы де­ла­ем – доста­ем зна­чения эле­мен­тов фор­мы. На­при­мер, в стро­ке 8 мы по­лу­ча­ем стро­ку, ко­то­рую поль­зо­ва­тель ввел в тек­сто­вое по­ле op1.

Как ви­ди­те, пе­ре­мен­ные в PHP на­чи­на­ют­ся с $. $_REQUEST – при­мер ас­со­циа­тив­но­го мас­си­ва; он по­хож на обыч­ный мас­сив, толь­ко в ка­че­­ст­ве ин­дек­са ис­поль­зу­ет­ся стро­ка, а не чис­ло. PHP ав­то­ма­ти­че­­ски за­пол­ня­ет этот мас­сив всей ин­фор­ма­ци­ей, при­ня­той как часть за­про­са ме­то­да­ми GET или POST или че­рез ку­ки [cookie]. В стро­ках 11 – 14 вы­пол­ня­ет­ся со­от­вет­ст­вую­щее вы­чис­ление в со­от­вет­ст­вии с опе­ра­то­ром, вы­бран­ным в вы­па­даю­щем спи­ске. В стро­ке 15 про­ве­ря­ет­ся, сто­ит ли га­лоч­ка “Round to integer [Ок­руг­лить до це­ло­го]”; ес­ли да, в стро­ке 16 мы вы­пол­няем ок­руг­ление встро­ен­ной функ­ци­ей round(). В стро­ке 17 мы воз­вра­ща­ем ре­зуль­тат брау­зе­ру. В стро­ках 19 и 20 (об­ра­ти­те внимание, что мы вы­шли за тэ­ги PHP) соз­да­ет­ся ссыл­ка (с техниче­­ской точ­ки зрения на­зы­вае­мая яко­рем), ко­то­рая воз­вра­ща­ет нас об­рат­но на глав­ную фор­му.

Для про­вер­ки от­крой­те ад­рес http://localhost/calculator.html, за­полните фор­му, на­жми­те кноп­ку Calculate [Вы­чис­лить] и на­сла­ди­тесь ре­зуль­та­том. Ес­ли вы понимае­те, как эти два фай­ла ра­бо­та­ют вме­сте, вы поч­ти пол­но­стью понимае­те, как ра­бо­та­ют web-при­ло­жения. Важ­ная идея, ко­то­рую вам нуж­но по­нять, со­сто­ит в том, что управ­ление по­сто­ян­но пе­ре­да­ет­ся от кли­ен­та (брау­зе­ра) к сер­ве­ру и об­рат­но. Брау­зер за­пра­ши­ва­ет ис­ход­ную страницу, сер­вер от­прав­ля­ет ее, поль­зо­ва­тель взаи­мо­дей­ст­ву­ет со страницей и от­прав­ля­ет вве­ден­ные дан­ные, по­па­дая на ту же са­мую страницу или на дру­гую и т. д.

Ве­лик ли про­цент?

Вот еще один при­мер, в ко­то­ром мы вы­чис­ля­ем еже­год­ный слож­ный про­цент бан­ков­ско­го сче­та за за­дан­ное ко­ли­че­­ст­во лет. Про­сто­ты ра­ди, на наш счет бу­дет нель­зя класть и снимать день­ги: там бу­дет толь­ко пер­во­на­чаль­ный ба­ланс. Как и в пре­ды­ду­щем при­ме­ре, у нас бу­дут про­стая фор­ма для вво­да дан­ных на чис­том HTML и вто­рая страница для об­ра­бот­ки дан­ных. Сна­ча­ла рас­смот­рим фор­му вво­да дан­ных. Для крат­ко­сти я при­вел толь­ко те­ло страницы, уб­рав внешний кар­кас.

Рас­чет бан­ков­ско­го про­цен­та

<form action=”calc_interest.php” method=”POST”>

Ис­ход­ный ба­ланс: <input type=”text” name=”startbal”>

Про­цент до­хо­да (%): <input type=”text” name=”intrate”>

Начальный год: <input type=”text” name=”startyear”>

Ко­неч­ный год: <input type=”text” name=”endyear”>

<input type=”submit” value=”Calculate”>

</form>

Здесь нет осо­бых нов­шеств: про­сто че­ты­ре тек­сто­вых по­ля и кноп­ка Calculate. Те­перь пе­рей­дем к PHP. Опять же, я при­во­жу толь­ко те­ло фор­мы:

<?php

// По­лу­чить па­ра­мет­ры вво­да из фор­мы

$balance = $_REQUEST[‘startbal’];

$intrate = $_REQUEST[‘intrate’] / 100.0;

$startyear = $_REQUEST[‘startyear’];

$endyear = $_REQUEST[‘endyear’];

// По­стро­ить таб­ли­цу с за­го­лов­ка­ми

echo ‘’;

// Цикл по го­дам

for ($year = $startyear; $year <= $endyear; $year++)

{

$interest = $balance * $intrate;

$interest = round($interest, 2);

$balance += $interest;

echo “”; } echo ‘
YearInterestBalance
$year$interest$balance</ td>
’;

?>

Об­щая схе­ма та же – вы­дер­ги­ва­ем по­ля вво­да из фор­мы, вы­пол­ня­ем вы­чис­ления и воз­вра­ща­ем ре­зуль­та­ты. В этом при­ме­ре мы ви­дим про­стой цикл for, ко­то­рый вы уз­нае­те, ес­ли зна­ко­мы с лю­бым из язы­ков се­мей­ст­ва C. Об­ра­ти­те внимание на неук­лю­жую смесь HTML-тэ­гов и пе­ре­мен­ных PHP в опе­ра­то­рах echo. Это ти­пич­ная си­туа­ция. Тэ­ги в основ­ном от­но­сят­ся к таб­ли­це для ото­бра­жения ре­зуль­та­тов.

Со­хранение со­стояния

Од­на из слож­но­стей при на­пи­сании web-при­ло­жений со­сто­ит в со­хранении «со­стояния» в те­чение сро­ка жизни при­ло­жения. Клас­си­че­­ский при­мер – кор­зи­на в элек­трон­ном ма­га­зине: Ше­рон от­кры­ва­ет ка­та­лог, вы­би­ра­ет то­ва­ры для по­куп­ки. Ка­ким-то об­ра­зом где-то нуж­но за­помнить, что она вы­бра­ла, и Apache, ра­зу­ме­ет­ся, не бу­дет это­го де­лать. Он и не по­доз­ре­ва­ет, что по­сле­до­ва­тель­ность об­ра­бо­тан­ных им HTTP-за­про­сов пред­став­ля­ла вы­бор и по­куп­ку то­ва­ров Ше­рон.

Вот про­стей­ший при­мер, ко­то­рый я смог пред­ло­жить для ил­лю­ст­ра­ции про­бле­мы: у при­ло­жения есть страница с един­ст­вен­ной кноп­кой. При ка­ж­дом на­жа­тии кноп­ки поль­зо­ва­те­лем счет­чик уве­ли­чи­ва­ет­ся, и его зна­чение ото­бра­жа­ет­ся на странице. Зву­чит до­воль­но про­сто, и ес­ли бы вы пи­са­ли обыч­ную про­грам­му, это и в са­мом де­ле бы­ло бы три­ви­аль­но. Вы про­сто бы взя­ли ста­ти­че­скую пе­ре­мен­ную и про­дол­жа­ли ин­кре­мен­ти­ро­вать ее. Пе­ре­мен­ная на­хо­дит­ся там, ин­кре­мен­ти­ру­ет­ся, и ее зна­чение за­по­ми­на­ет­ся. Это мож­но по­про­бо­вать на­пи­сать в ви­де web-при­ло­жения та­ким образом:

<body>

<form action=”counter.php” method=”get”>

<input type=”submit” value=”Count”>

</form>

<?php

$count = $count + 1;

echo “
count is $count “;

?>

</body>

Об­ра­ти­те внимание, что эта страница от­кры­ва­ет са­мое се­бя – очень рас­про­странен­ный под­ход в web-при­ло­жениях. Бе­да толь­ко в том, что ра­бо­тать она не бу­дет. При ка­ж­дом за­про­се страницы сер­вер­ный код инициа­ли­зи­ру­ет­ся за­но­во, и счет­чик никогда не вы­рас­тет боль­ше единицы. Есть и дру­гая про­бле­ма: пред­по­ло­жим, что мы как-то смо­жем соз­дать ста­ти­че­­ское хранили­ще на сто­роне сер­ве­ра. Пом­ня о том, что од­но­вре­мен­но с про­грам­мой мо­гут ра­бо­тать несколь­ко поль­зо­ва­те­лей, хо­тим ли мы под­счи­тать об­щее ко­ли­че­­ст­во их щелч­ков? На­вер­ное, нет. Ско­рее мы за­хо­тим вес­ти от­дель­ные счет­чи­ки для ка­ж­до­го.

«Со­хранение со­стояния», т. е. хранение ин­фор­ма­ции о дей­ст­ви­ях ка­ж­до­го поль­зо­ва­те­ля на­пря­мую, не свой­ст­вен­но web-при­ло­жениям, так как web-сер­ве­ры по су­ти не име­ют со­стояния – они об­ра­ба­ты­ва­ют ка­ж­дый за­прос от­дель­но и сра­зу за­бы­ва­ют о нем. Од­на­ко на по­мощь при­хо­дит PHP с ас­со­циа­тив­ным мас­си­вов $_SESSION. По­мес­тив дан­ные в этот мас­сив, при­ло­жение мо­жет со­хранить их в те­чение по­сле­до­ва­тель­но­сти взаи­мо­дей­ст­вий, из­вест­ной как сес­сия. Пе­ре­пи­шем на­ше при­ло­жение со счет­чи­ком:

1. <body>

2. <form action=”counter2.php” method=”get”>

3. <input type=”submit” value=”Count”>

4. </form>

5. <?php

6. session_start();

7. if (! isset($_SESSION[‘counter’]))

8. $count = 0;

9. else

10. $count = $_SESSION[‘counter’];

11. $count = $count + 1;

12. $_SESSION[‘counter’] = $count;

13. echo “
count is $count “;

14. ?>

Вот как это ра­бо­та­ет. При пер­вом вы­зо­ве session_start() в стро­ке 6 соз­да­ет­ся но­вая сес­сия. Все дан­ные, ко­то­рые со­хра­ня­ют­ся в этой сес­сии, хра­нят­ся во вре­мен­ном фай­ле на сер­ве­ре. PHP фор­ми­ру­ет слу­чай­ный иден­ти­фи­ка­тор сес­сии, и он вклю­ча­ет­ся в имя фай­ла. Что­бы по­лу­чить кор­рект­ную ин­фор­ма­цию о сес­сии при сле­дую­щем под­клю­чении кли­ен­та, PHP воз­вра­ща­ет брау­зе­ру ку­ки. Имя ку­ки – PHPSESSID, а зна­чение – иден­ти­фи­ка­тор сес­сии. Брау­зер воз­вра­ща­ет ку­ки об­рат­но со сле­дую­щим за­про­сом, что­бы сер­вер мог по­лу­чить иден­ти­фи­ка­тор сес­сии и, сле­до­ва­тель­но, ин­фор­ма­цию сес­сии. В стро­ке 7 мы про­ве­ря­ем, есть ли в сес­сии наш счет­чик. Ес­ли нет, в стро­ке 8 мы об­ну­ля­ем счет­чик – это про­ис­хо­дит толь­ко при пер­вом за­хо­де на страницу. В про­тив­ном слу­чае мы по­лу­ча­ем дан­ные сес­сии (стро­ка 10). По­сле об­нов­ления дан­ных сес­сии (стро­ка 11) мы по­ме­ща­ем их об­рат­но в сес­сию (стро­ка 12). Конеч­но, наш про­стень­кий счет­чик – лишь сим­во­ли­че­­ское изо­бра­жение со­стояния, ко­то­рое мы пы­та­ем­ся хранить; в ре­аль­ном ми­ре это бы­ло бы нечто бо­лее мас­штаб­ное.

Как вы, на­вер­ное, знае­те, сей­час су­ще­ст­ву­ет ев­ро­пей­ский за­кон о ку­ки, и ес­ли вы поль­зуе­тесь дан­ной тех­но­ло­ги­ей на пуб­лич­ном сай­те, то пе­ред от­прав­кой ку­ки вы обя­за­ны по­лу­чать на это ин­фор­ми­ро­ван­ное со­гла­сие по­се­ти­те­лей сай­та. |

Персональные инструменты
купить
подписаться
Яндекс.Метрика