Предыдущие части: Ставим Apache, Порты и сокеты, Введение
Небольшое отступление. Прошу прощения, если информация, которую я рассказываю, тривиальна. Я пишу выпуски, исходя из плана, где каждая следующая часть будет опираться на предыдущие.
А чтобы у вас было понятие, чего всё-таки ждать, я просто перечислю всякие слова (не по порядку): Virtual Host, URL/URI, REST, GET, POST, CRUD, CGI, PHP, php-fpm, cookies, sessions, MySQL, Redis, JavaScript, AJAX, JSON, socket, websocket, Yii2 и другие. Надеюсь, картина приблизительно ясна. Вернёмся теперь к основам.
В предыдущей части мы установили веб-сервер Apache и посмотрели одну страницу сайта.
Для того, чтобы обратиться к собственной машине, мы использовали имя localhost. Чтобы обращаться к другим машинам в сети, мы также используем разнообразные имена: mail.ru, yandex.ru, google.com, zdg.ru и т.д.
Но надо понимать, что запрос – это электрический сигнал. Сначала браузер формирует пакет данных и через сетевой драйвер отдаёт его сетевой карте. Сетевая карта преобразует этот пакет в последовательность электрических импульсов. И отправляет этот уже абсолютно физический сгусток электромагнитной энергии либо в сетевой кабель, либо в воздушное пространство через Wi-Fi.
Возникает вопрос: как этот сигнал достигнет сервера, скажем, zdg.ru, если мы даже не знаем, где он находится? Представим, что наша машина и сервер соединены проводами напрямую. Тогда нет сомнений, что сигнал по проводам дойдёт от одной машины до другой.
Но ведь они не соединены. У вас дома, наверное, стоит Wi-Fi роутер. Сигнал от сетевой карты вашего компьютера через радиоэфир попадает в роутер. Роутер переправляет его по проводам на сервер вашего интернет-провайдера. Интернет-провайдер направляет его ещё куда-то, потом он попадает ещё куда-то и ещё и ещё и наконец достигает сервера zdg.ru.
Путешествие пакета по сети похоже на путешествие почтовой посылки. На посылке написан адрес, допустим, "Россия, г.Новосибирск, ул.Пушкина, д.2, кв.4". Но посылка отправляется из Америки, и соответственно сначала попадает в американскую почтовую службу. Американская почтовая служба, конечно же, без понятия, что это за адрес, и не будет доставлять туда посылку. Но где Россия, она знает. Поэтому просто отправляет посылку в Россию.
В России посылку получает уже Почта России, но в Москве. Она занимается доставкой только по Москве, но знает про Новосибирск. Поэтому она переправит посылку в новосибирское отделение. Когда её примут в Новосибирске, то уже смогут доставить на ул.Пушкина.
Примерно так же устроен интернет. У каждого компьютера есть свой адрес, но не на каждый адрес посылка доставляется напрямую.
Представим, что у нас есть 100 компьютеров и мы хотели бы соединить их в сеть. Тогда одному компьютеру мы дали бы адрес 0, другому адрес 1, и так далее до адреса 99. Все они были бы физически соединены друг с другом, что значит: они в одной сети.
Когда в такую общую сеть попадает электрический сигнал, он растревоживает все машины, которые в ней находятся. Ведь они все соединены, а сигнал распространяется по проводнику во все концы.
И таким образом каждая машина, подключённая к этой сети, получает пакет и смотрит на его заголовок: для какого адреса он предназначен? Для адреса 10. А у меня адрес 5. Тогда я не буду ничего делать. А вот машина с адресом 10, получив этот пакет, как раз и обработает его.
Теперь представим, что где-то ещё образовалась сеть из 100 машин, и им тоже нужны адреса. Мы можем выделить им адреса с 100 по 199 и соединить их в общую сеть.
Но надвигается проблема: если все машины будут соединены, то сигналы от них забьют всю сеть.
Поэтому были добавлены устройства-коммутаторы (свитчи).
В рамках почтовой терминологии это почтовое отделение на вашей улице, которое обслуживает ближайшие дома. Коммутатор получает пакеты от всех машин, но переправляет их только нужным адресатам, так как у него есть отдельная линия связи с каждым.
Далее, чтобы наращивать количество машин в сети, к коммутатору можно подключать другие коммутаторы. Таким образом мы получаем иерархическую структуру типа "дерево".
Наконец, чтобы соединять между собой вообще далёкие сети, были добавлены маршрутизаторы. В каждой сети, если она хочет иметь выход наружу, должен быть известен адрес маршрутизатора (он задаётся в настройках сетевого соединения).
Пакеты начинают сортироваться: если пакет отправлен из сети в эту же сеть, то он доставляется локально. Если же адрес не местный, тогда пакет передаётся на маршрутизатор.
То есть в этом месте происходит то же самое, что и с посылкой из Америки: маршрутизатор "Почта Америки" отправляет пакет на маршрутизатор "Почта России".
Маршрутизатор другой сети, получив пакет, также проверяет его. Если машина находится в его сети, он отправляет пакет ей, а если нет, то пакет может уйти на следующий маршрутизатор, и так по цепочке.
IP-адреса
Первоначально предполагалось, что у каждого устройства в интернете будет свой уникальный адрес. Для этого разработали стандарт IP-адреса (Internet Protocol Address). На данный момент есть две версии: более старая IPv4 и более новая IPv6. Мы рассмотрим старую.
Адрес IPv4 это 32-битное число. Оно состоит из 4-х байт, и для удобства восприятия каждый байт записывается отдельно, например:
77.222.40.81
Когда-то оно казалось большим. Можно было добавить в сеть 4 миллиарда устройств. Но этого оказалось мало (поэтому в IPv6 уже 128 бит).
Стандарт подвергался различным изменениям и доработкам, и всё, что мы должны сейчас из этого усвоить – IP-адрес делится на 2 части. Первая часть это номер сети, а вторая часть собственно адрес машины в сети.
Эти части могут быть разного размера (задаётся в настройках). Мы можем выделить на номер сети 16 бит и на номер машины 16 бит. Тогда у нас будет 65536 сетей и в каждой сети по 65536 машин. Или можем выделить 24 бита на номер сети и 8 бит на номер машины, тогда будет 16777216 сетей и 256 машин в каждой и т.д.
Благодаря тому, что мы знаем номер сети, мы знаем, какие адреса принадлежат одной сети, а какие нет. Это и позволяет маршрутизировать пакеты.
Кроме того, это снижает нагрузку на адресное пространство. Теперь каждой машине необязательно иметь уникальный адрес. Если на неё никто не шлёт запросы из внешних сетей, то и официальный адрес ей не нужен. Внутри локальной сети машины, как правило, имеют адреса вида 10.0.0.*, 172.16.*, 192.168.*. Это специально выделенные диапазоны адресов для локальных сетей.
Все остальные вопросы по переброске пакетов из сети в сеть решают коммутаторы и маршрутизаторы.
Из этого следует, что когда вы запускаете веб-сервер на своей домашней машине, к нему нельзя обратиться извне (если только ваш интернет-провайдер не выдал вам выделенный IP-адрес).
Но ваш Wi-Fi роутер, телефон и компьютер находятся в одной локальной сети, поэтому вы можете посмотреть свой сайт с телефона.
Вы можете узнать адрес своей машины с помощью консольной команды Windows ipconfig:
Так как я работаю через Wi-Fi, то интересует беспроводной адаптер. Здесь видно, что ему назначен IPv4-адрес 192.168.0.103, а маршрутизатором (шлюзом) назначен мой Wi-Fi роутер с адресом 192.168.0.1. Для этой сети назначена маска подсети: 255.255.255.0. Это значит, что адрес сети занимает 3 байта (24 бита), а адреса устройств в сети 1 байт (8 бит). То есть в моей домашней сети могут жить 256 устройств, чего, конечно, более чем достаточно.
Теперь если я на своём телефоне запущу браузер и наберу в нём адрес 192.168.0.103, то зайду на свою машину и увижу сайт, который на ней расположен. Я могу набрать этот адрес даже в браузере прямо на машине и конечно же попаду на свою машину.
DNS
Мы начали с имён сайтов, но перешли на адреса. Каким образом я соединяюсь с сервером по имени, ведь это не IP-адрес? На самом деле мы могли бы ходить на разные сайты, набирая в браузере их IP-адреса. Но очевидно, что для людей это крайне неудобно. Поэтому была придумана DNS - Domain Name System, или система доменных имён.
Например, имя zdg.ru состоит из двух частей: домен первого уровня "ru", говорит о том, что сайт находится в России, а домен второго уровня... собственно уже ни о чём не говорит. Но можно сделать и домен третьего уровня, например: mail.zdg.ru, и четвёртого, и т.д.
Подобная иерархическая схема в некоторой степени соответствует адресам сетей. Скажем, для сайтов в домене "ru" должен быть выделен какой-то диапазон IP-адресов.
Это всё регулируется различными организациями, но вообще говоря, нам это ни к чему. Давайте просто представим, что любому конкретному IP-адресу можно присвоить любое конкретное доменное имя.
И теперь вместо адреса мы можем обращаться к сайту по имени. Но всё-таки, откуда мы узнаем адрес?
Для этого в сети существует DNS-сервер. Его адрес должны заранее знать все устройства в сети (т.е. он должен быть задан в настройках).
Когда я набираю в браузере zdg.ru, браузер первым делом отправляет запрос на DNS-сервер: какой адрес у имени zdg.ru?
В задачи DNS-сервера входит хранить актуальный список доменных имён и их адресов, а также синхронизироваться с другими серверами. Поэтому, если всё работает нормально, DNS-сервер ответит: у zdg.ru IP-адрес 77.222.40.81. После чего браузер пошлёт запрос уже по этому адресу, и произойдёт всё, что было описано выше: пакет попадёт в маршрутизатор, затем в другой маршрутизатор и т.д., пока не достигнет машины с адресом 77.222.40.81.
У имени localhost, которое назначено локальной машине, также есть свой адрес: 127.0.0.1. Он специально зарезервирован и всегда означает локальную машину.
Читайте дальше: Виртуальные хосты Apache