Sunteți pe pagina 1din 20

Some socket

programming
Openresty later

@ntavish
Resources:

● http://beej.us/guide/bgnet/ Beej’s guide to network programming


● man 7 socket, man 7 ip, man 2 socket
● kernel(linux/*bsd/windows etc.) provides socket interface for IPC
○ same computer, or on different one
● Kernel handles networking stack
● We’ll only see a bit of TCP and UDP as seen by application
TCP / UDP

● SOCK_STREAM & SOCK_DGRAM are two types of internet sockets


(AF_INET/AF_INET6)
● UDP is connectionless, you specify length and set destination address
○ No guarantee of delivery
○ No guarantee of being in order of sending
○ Used when speed is most important
● TCP is called ‘connection-oriented’, client connects to server
○ Is reliable
○ Has byte stream
Example
● Netcat
○ Like ‘cat’ but can connect/listen to TCP/UDP
● nc -l 7000 # listen to TCP port 7000 on machine


● nc localhost 7000 # connects to tcp port 7000 on 127.0.0.1
Sample python code
HTTP with nc
sent
TCP server socket handling
● A lot of info on http://www.kegel.com/c10k.html
● Server opens, bind()s, and listen()s to socket
● Server can now do
○ blocking accept(), which gives an fd for accepted socket
■ Not very useful for a single process server
○ Non-blocking accept()
■ On accepting it will get an fd for accepted socket, which it can add to queue
■ gathers multiple fd’s, it can use select/poll/epoll on queue of fd’s
● Architectures in some real web servers
○ Multiple processes(or single), each handling one req. at a time (Apache)
○ Multiple processes(or single), each has multiple threads, threads handle a req. (Apache)
○ Multiple processes(or single), all requests handled in a single ‘event loop’ without blocking
socket system calls (nginx)
Further reading

● C10K challenge http://www.kegel.com/c10k.html


● Architecture of open source applications, nginx
http://aosabook.org/en/nginx.html
● Digitalocean blog: Apache vs nginx, practical considerations
https://www.digitalocean.com/community/tutorials/apache-vs-nginx-practi
cal-considerations
● http://pl.atyp.us/content/tech/servers.html
Nginx

● Created to address C10k problem/challenge


○ High concurrency
○ low/predictable memory usage
○ event-driven architecture
Nginx architecture

● See infographic
https://www.nginx.com/resources/library/infographic-inside-nginx/

● Master process
○ reads configuration, binds sockets, forks worker processes
● Worker process
○ Event-driven state-machine/scheduler
○ As any socket event occurs, the state machine progresses for that particular socket/context
Lua

Lua is a powerful, efficient, lightweight, embeddable scripting language.

Where?

● Lots of video games, mediawiki, redis, netbsd kernel

Luajit

● a very high performance JIT compiler for Lua (compared to lua.org one)

io.write("Hello world, from ",_VERSION,"!\n")


Openresty

Openresty is standard nginx core + luajit bundled with (non-blocking) lua libraries
and 3rd party nginx modules

● Created at taobao.com, and also supported by cloudflare


● lua-nginx-module embeds lua VM in event loop
● Aim is to run web application, gateway, etc. completely in nginx process
● Nginx asynchronous event handling plus lua allows
○ Synchronous code, but non-blocking, readable code
○ Non-blocking for the nginx process, but without callback hell unlike Node.js
Openresty cont.

● All nginx qualities (high concurrency low memory etc.) with powerful
scripting
● Api can:
○ Access HTTP request
○ Generate response (maybe by mixing/matching content from various external storage,
sub-requests etc.)
○ Use external services like databases, upstream servers, http requests without blocking
Nginx request phases

Hooks for various phases of request are exposed:

● rewrite_by_lua
● access_by_lua - ex. Usage: authentication via cookies/headers
● content_by_lua - http response
● log_by_lua

Details at https://github.com/openresty/lua-nginx-module
Example of access control with lua
location / {
access_by_lua_block {
local res = ngx.location.capture("/auth")

if res.status == ngx.HTTP_OK then


return
end

if res.status == ngx.HTTP_FORBIDDEN then


ngx.exit(res.status)
end

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
}
}

● If /auth location does not return ‘200’, access denied


Modifying requests / response
local headers = ngx.req.get_headers()
local body = ngx.req.read_body()
local method = ngx.req.get_method
local querystring_params = ngx.req.get_uri_args()
local post_params = ngx.req.get_post_args()

All the above can be modified with set_* equivalents,


before passing the request to ngx.location.capture(), which can be proxy location

res = ngx.location.capture(‘/proxy’)

Returns a Lua table with- res.status, res.header, res.body, and res.truncated. ngx.say(res.body) to forward this response.
Non-blocking redis connection (example)
local redis = require "resty.redis"
-- connect to redis
local red = redis:new()
red:set_timeout(10)

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


if not ok then
ngx.log(ngx.STDERR, "failed to connect to redis: " .. tostring(err))
return
end

local res, err = red:publish("all", "HI!")


if not res then
ngx.log(ngx.STDERR, "failed to publish: " .. tostring(err))
return
End
Other lua-resty-* modules

● lua-resty-redis
● lua-resty-mysql
● lua-resty-memcached
● lua-resty-string
● lua-resty-websocket etc.
Nginx stream module

stream-lua-nginx-module embeds lua into nginx stream module.

● Implement arbitrary TCP/UDP server/clients/protocols with lua and nginx


core
example

content_by_lua_block {
local sock = assert(ngx.req.socket(true)) -- get request’s socket
local data = sock:receive() -- read a line from downstream
if data == "thunder!" then
ngx.say("flash!") -- output data
else
ngx.say("boom!")
end
ngx.say("the end...")
}

S-ar putea să vă placă și