This document discusses socket programming and network programming concepts like TCP and UDP. It provides examples of using Netcat and Python for sockets. It also summarizes the architecture of Nginx and Openresty, a framework that embeds Lua in Nginx allowing full web applications to run within the Nginx process for high performance and scalability. Openresty allows accessing and modifying requests and responses with Lua scripts.
2. ● 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
Resources:
3. 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
4. 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
7. 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)
8. 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
9. Nginx
● Created to address C10k problem/challenge
○ High concurrency
○ low/predictable memory usage
○ event-driven architecture
10. 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
11. 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")
12. 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
13. 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
14. 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
15. 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)
}
}
Example of access control with lua
● If /auth location does not return ‘200’, access denied
16. 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.
17. 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
18. Other lua-resty-* modules
● lua-resty-redis
● lua-resty-mysql
● lua-resty-memcached
● lua-resty-string
● lua-resty-websocket etc.
20. 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...")
}