openresty: превращаем nginx в полноценный сервер приложений /...

41
Разработчик облачных сервисов в || Владимир Протасов OpenResty Превращаем NGINX в полноценный сервер приложений

Upload: ontico

Post on 16-Apr-2017

660 views

Category:

Engineering


1 download

TRANSCRIPT

Page 1: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

Разработчик облачных сервисов в ||

Владимир Протасов

OpenRestyПревращаем NGINX в полноценный сервер приложений

Page 2: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

2

О себе

• ¾ жизни пишу код• ¼ жизни – промышленная разработка• 2+ ТБ базы• 20+ языков

Page 3: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

3

О компании

• 13 офисов по всему миру• 300+ сотрудников• Разработка в Москве, Таллине и на Мальте

Page 4: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

4

На чем мы пишем?

• Python 2• Django• MySQL• Redis• NGINX

Page 5: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

5

Коротко о главном

• Зачем изобретать велосипед?• Что это и с чем едят?

• Примеры из жизни

Page 6: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

6

OpenResty

Page 7: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

7

NGINX

• Полноценный веб-сервер• Скорость• Асинхронный I/O• Кеширование, статический контент, …• Удобство деплоя• Структурированная обработка запросов

Page 8: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

8

OpenResty

+

Page 9: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

9

Lua

• Размер• Скорость• Простота в освоении

Page 10: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

10

OpenResty

Page 11: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

11

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 12: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

12

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 13: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

13

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 14: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

14

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 15: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

15

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 16: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

16

Hello world

location /hello { content_by_lua_block { local hello = string.format('Hello, %s!', ngx.var.remote_addr) ngx.say(hello); }

}

Page 17: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

17

Hello world

$ curl http://127.0.0.1/helloHello, 127.0.0.1!

Page 18: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

18

Возвращаемся в реальный мир

Page 19: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

19

Реальное приложение

• Поиск картинок• Расширенный список ключевых слов для поиска

Page 20: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

20

Получаем данные

https://awesome.example.com/search?query=котята

location /search { content_by_lua_block { local args = ngx.req.get_uri_args() local search = args.search -- … }}

Page 21: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

21

Расширение набора ключевых слов

• База данных• Слово -> набор схожих

котята -> котики, коты, пушистики

Page 22: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

22

Расширение набора ключевых слов

local mysql = require "resty.mysql”

local db, err = mysql:new()local ok, err, errcode, sqlstate = db:connect{ path = "/path/to/mysql.sock", database = ”keywords",}

Page 23: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

23

Расширение набора ключевых слов

local sql = string.format([[ SELECT kwd FROM keywords WHERE search = %s]], ngx.quote_sql_str(search))

local res, err, errcode, sqlstate = db:query(sql, 10)

-- res = [ { kwd = ‘котики’}, {kwd = ‘пушистики’} ]

Page 24: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

24

Находим картинки по всем запросам

local reqs = {}

for , keyword in ipairs( keywords_list ) do table.insert (reqs, { '/fetch', { args = { search_q = keyword } } })end

resps = { ngx.location.capture_multi( reqs ) }

Page 25: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

25

Находим картинки по всем запросам

location /fetch { internal; proxy_pass http://example.com/search?$request_args; -- кеширование и т.п.}

Page 26: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

26

Выводим данные пользователю

local links = parse_responses(resps)

ngx.headers['Content-Type'] = 'application/json’ngx.say(cjson.encode(links))

Page 27: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

27

Выводим данные пользователю

• Пользователь не хочет читать JSON• SEO-специалисты негодуют• Что делать?• Отдаем пользователю HTML

Page 28: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

28

Выводим данные пользователю

$ opm install lua-resty-template

local links = parse_responses(resps)

local template = require "resty.template"template.render("view.html", { links = links })

Page 29: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

29

Выводим данные пользователю

Page 30: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

30

Фазы обработки запроса

• access• rewrite• content• headers filter• body filter• log

Page 31: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

31

Авторизация

access_by_lua_block { -- …}

Page 32: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

32

Авторизация

local ck = require "resty.cookie”local cookie, err = ck:new() local token = cookie:get('token')

if not token then return ngx.redirect("/auth") end

Page 33: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

33

Авторизация

local redis = require "resty.redis”

local r = redis:new()local ok, err = r:connect("127.0.0.1", 6379)

local res, err = r:get(string.format('token:%s', token))if not res then return ngx.redirect("/auth")end

Page 34: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

34

Авторизация

location /auth { content_by_lua_file "/path/to/auth.lua";}

Page 35: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

35

Авторизация

ngx.req.read_body()local args, err = ngx.req.get_post_args()

if args.login ~= "admin" and args.password ~= "secret" then return ngx.redirect("/auth")end

Page 36: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

36

Авторизация

local redis = require "resty.redis”

local r = redis:new()local ok, err = red:connect("127.0.0.1", 6379)

local token = "admintoken”red:set(string:format('token:%s', token), '1')

Page 37: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

37

Авторизация

local ck = require "resty.cookie”

local cookie, err = ck:new()local token = cookie:set{ key='token', value=token,}

return ngx.redirect("/")

Page 38: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

38

Что ещё можно сделать?

• Минималистичный бекенд• Препроцессинг данных• Фасад для микросервиса• Статистика и аналитика• Многопользовательские системы• Фильтрация запросов (WAF)

Page 39: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

39

Сообщество

• NGINX-коммьюнити• Lua-разработчики

• Рассылка на китайском

• Github• Список рассылки (google groups)

Page 40: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

40

Итого

• Удобный фреймворк, заточенный под веб• Низкий порог вхождения• Асинхронный I/O без коллбеков

• Большое отзывчивое сообщество• Легкий деплой

Page 41: OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Протасов (Parallels)

41

Спасибо за внимание