Merge pull request #711 from kasmanavt/newchapters

add ru translation for chapter 03.2, 03.3
This commit is contained in:
astaxie
2016-09-16 10:46:55 +08:00
committed by GitHub
2 changed files with 154 additions and 0 deletions

67
ru/03.2.md Normal file
View File

@@ -0,0 +1,67 @@
# 3.2 Создание простого веб-сервера
Ранее мы говорили о том, что Go предоставляет широкие возможности для работы с протоколом HTTP и создания веб-приложений, базирующихся на данном протоколе. Все эти возможности реализуются в пакете `net/http`.
## Использование пакета net/http для создания веб-сервера
package main
import (
"fmt"
"log"
"net/http"
"strings"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // разбор аргументов, необходимо вызвать самостоятельно
fmt.Println(r.Form) // печать данных формы на стороне сервера
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
fmt.Println(r.Form["url_long"])
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello astaxie!") // отправка данных на клиент
}
func main() {
http.HandleFunc("/", sayhelloName) // устанавливаем обработчик
err := http.ListenAndServe(":9090", nil) // устанавливаем порт, который будем слушать
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Когда мы исполним данный код, он запустит прослушивание порта 9090 на вашем компьютере.
Откройте браузер и введите URL `http://localhost:9090`. Вы увидите сообщение `Hello astaxie` на экране.
Давайте попробуем передать серверу несколько аргументов `http://localhost:9090/?url_long=111&url_long=222`
Посмотрите, что произошло на стороне сервера и клиента.
Вы должны увидеть следующие сообщения на стороне сервера
![](images/3.2.goweb.png?raw=true)
Рисунок 3.8 вывод информации на стороне сервера
Как вы видите, нам потребовалось вызвать всего две функции для того чтобы создать простой веб-сервер.
Если вы работаете с PHP, вы, вероятно, хотите спросить, нужно ли нам что-то вроде Nginx или Apache? Ответ - нет! Go реализует прослушку TCP порта самостоятельно, а функция `sayhelloName`, в нашем примере, очень похожа на контроллер из PHP.
Если вы работаете с Python, вы должны знать Tornado, и он очень похож на приведенный выше пример.
Если вы работаете с Ruby, вы наверняка заметили, что это как сценарий/сервер в RoR.
В данном разделе мы использовали две простые функции для создания простого веб-сервера который уже готов к параллельным вычислениям. В следующих двух разделах мы будем говорить о том, как использовать эту особенность.
## Ссылки
- [Содержание](preface.md)
- Предыдущий раздел: [Принципы работы Веб](03.1.md)
- Следующий раздел: [Как Go работает с веб](03.3.md)

87
ru/03.3.md Normal file
View File

@@ -0,0 +1,87 @@
# 3.3 Как Go работает с веб
В предыдущем разделе мы научились использовать пакет `net/http` для создания простого веб-сервера. В этом разделе мы вернемся к принципам работы Веб, которые рассматривали ранее, но уже в контексте языка Go.
## Некоторые понятия, необходимые для понимания принципов работы веб-сервера.
Request: запрос данных от пользователей, включая методы POST, GET, Cookie и URL
Response: данные ответа от сервера.
Conn: соединения между клиентами и серверами.
Handler: логика обработки запроса и получение ответа.
## механизм работы пакета http
На следующей картинке показано как работает веб-сервер Go/
![](images/3.3.http.png?raw=true)
Рисунок 3.9 работа http сервера
1. Сервер создает прослушивающий сокет на определенном порту и ожидает подключения клиентов.
2. Сервер принимает запросы от клиентов.
3. Обрабатывает запросы посредством чтения HTTP заголовков (если используется метод POST, читаются данные из тела запроса) и отправляет их обработчикам. Наконец, сокет возвращает данные клиентам.
Для того чтобы точно узнать как Go работает с Веб - необходимо получить ответ на три вопроса:
- Как прослушивается порт?
- Как принимаются клиентские соединения?
- Как распределяются обработчики?
В предыдущем разделе мы видели, что Go использует функцию `ListenAndServe` для инициализации объекта сервера и вызова метода `net.Listen("tcp", addr)`, устанавливающего TCP прослушку на заданный адрес и порт.
Давайте посмотрим на исходный код пакета `http`.
//используется код Go версии 1.1.2
func (srv *Server) Serve(l net.Listener) error {
defer l.Close()
var tempDelay time.Duration // время сна в случае сбоя
for {
rw, e := l.Accept()
if e != nil {
if ne, ok := e.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)
time.Sleep(tempDelay)
continue
}
return e
}
tempDelay = 0
c, err := srv.newConn(rw)
if err != nil {
continue
}
go c.serve()
}
}
Как происходит прием клиентских запросов? В исходном коде мы видим, что происходит вызов метода `srv.Serve(net.Listener)` для управления клиентскими запросами. В теле функции бесконечный цикл `for{}` принимает запросы, создает новое соединение, запускает новую горутину `go c.serve()` и передает в нее данные запроса. Так Go поддерживает высокий параллелизм, за счет того, что все горутины являются независимыми.
Теперь ответим на вопрос как используются конкретные функции для управления запросами? Сначала метод `conn` парсит запрос возвращаемый `c.ReadRequest()`, а затем получет соответсвующий обработчик: `handler := c.server.Handler`, который, в совою очередь, передается в качестве второго аргумента при вызове метода `ListenAndServe`. В нашем сервере мы использовали `nil`, поэтому Go использует обработчик по умолчанию: `handler = DefaultServeMux`. Возникает вопрос - что здесь делает `DefaultServeMux`? DefaultServeMux - это переменная, содержащая указатель на текущий маршрутизатор, который вызывает обработчики для заданных URL-адресов. Разве мы его устанавливали? Ответ - да. Помните в первой строке нашего веб-сервера мы использовали `http.HandleFunc("/", sayhelloName)`. Эта функция регистрирует правила маршрутизации для пути "/". Когда URL-адрес запроса соответствует «/», маршрутизатор вызывает функцию «sayhelloName». DefaultServeMux вызывает ServerHTTP для получения функции обработчика соответсвующего заданному пути.В нашем случае он вызывает «sayhelloName». Наконец, сервер отвечает клиенту.
Подробное оприсание процесса:
![](images/3.3.illustrator_Ru.png?raw=true)
Рисунок 3.10 воркфлоу обработки HTTP-запроса
Теперь, я думаю, вы разобрались с тем, как работают веб-сервера Go.
## Ссылки
- [Содержание](preface.md)
- Предыдущий раздел: [Создание простого веб-сервера](03.2.md)
- Следующий раздел: [Внутренний мир пакет http](03.4.md)