AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

Async Server And Fiber

发布者 airjd   简介 Ruby技术大会相关演讲
发布于 1427244030531  浏览 6648 关键词 Ruby 
分享到

第1页

Async Server And Fiber

c_zlui@groupon.com



第2页

Me

github/luikore ruby-china/luikore



第3页

Motivation



第4页

Challenges To Ruby



第5页

Ruby Advantages

Unicode done right

"".length

Builtin continuation - Fiber And...



第6页

Fast



第7页

How To Build A High Performance Server



第8页

How To Build An Async Server



第9页

How To Build An Async Server Yet Providing Good API



第10页

Study The Background



第12页

The Bottle Neck

Client Side Of View

IO bound - network is slow CPU bound - complex page rendering Server load - wait for other requests to finish



第13页

The Bottle Neck

Server Side Of View

IO bound - visiting database / oauth is slow CPU bound - context switch



第14页

Scaling

Increase App Throughput

Reduce server side IO-waiting is the most effective way Create less threads, to avoid context switching



第15页

Learn From Existing Solutions



第16页

Chances To Ruby



第17页

Limited Server Objects



第18页

Many Crazy Clients



第19页

Multiplexing



第20页

Single Threaded

One Client, One Process, Prefork

unicorn -- multiplex with accept thin -- multiplex with load balancer



第21页

Multithreaded

One Client, One Thread, No Prefork

puma, recommended for rails4 A simple way to implement is to use POSIX functions with callbacks: aio_read(), aio_write()



第22页

Single Threaded And Event Loop

One Client, One Event Context, Prefork

nginx, redis, nodejs, twisted, eventmachine



第23页

Thread Pool On Event Loop

One Client, One Event Context, No Prefork

erlang, golang, scala actors



第24页

Hello World



第25页

TCPSocket In 5 Minutes



client



TCPSocket.new host, port



server



TCPServer.new host, port



receive



socket.read socket.read_nonblock



send



socket.write socket.write_nonblock



第26页

Hello World HTTP Server

server = TCPServer.new 'localhost', 4000 loop do

c = server.accept c << "HTTP/1.1 200 OK Content-Length: 12

Hello world!" c.close

end



第27页

Make It Fast



第28页

Non­Blocking Our Loop

loop do client = server.accept Thread.new do ... end

end



第29页

Threads Are Outdated

Lets Use System Events



第30页

Multiplexing Functions



select



IO.select r, w, err, timeout



poll IO.poll fds, timeout



第31页

System Events

Linux For Example

poll - iterate check all fds epoll - is more effective and provides more options



第32页

Epoll In 5 Minutes

sudo apt-get install manpages-dev man epoll



第33页

Epoll In 5 Minutes

register event: epoll_ctl()

retrieve event: epoll()



第34页

Cons

Ruby does not ship with epoll API. You need to wrap it with C-ext.



第35页

Loop With Epoll

loop do event = epoll(timeout) if from_server?(event) connection = server.accept else connection = find_conn_by(event) end ... # resume processing

end



第36页

How To Make It Resumable?



第37页

Eventmachine

async web server



第38页

clients are multiplexed to EM::Connection

you define callbacks for readable events: def receive_data(data)



第39页

"Resume Processing"

connection.receive_data read_nonblock



第40页

Make It Good



第41页

How EM Send_data Works

write to socket, if the socket can’t take any more, append the rest to a buffer chain when the socket becomes writable again (IO event), try consume the buffer chain



第42页

Pitfalls

Callbacks Are Not Sufficient

avoid loss of chained buffers

close_connection_after_writing avoid infinite recursion when registering events in callback:

EM.next_tick{ ... }



第43页

Resume Processing With Fiber

Fiber was the “Thread” in 1.8 Like thread, but lighter, pausable, and no need to lock



第44页

Example

fiber = Fiber.new do i=0 loop do Fiber.yield i += 1 end

end fiber.resume #=> 1 fiber.resume #=> 2



第45页

Read With Fiber

def read_with_fiber result = '' while buffer = read_nonblock result << buffer if nothing to read Fiber.yield :reading! end end result

end



第46页

Write With Fiber

def write_with_fiber content loop do write_nonblock content content = unwritten part of content break if content.empty? Fiber.yield :writing! end

end



第47页

Recall Our Loop

loop do event = epoll(timeout) if from_server?(event) connection = server.accept else connection = find_conn_by(event) end ... # resume processing

end



第48页

loop do event = epoll(timeout) if from_server?(event) connection = server.accept fiber = Fiber.new { ... read_with_fiber ... write_with_fiber } else fiber = find_fiber_by(event) end fiber.resume

end



第49页

Summary



第50页

Network latency and C10k leads to async solutions. With Fiber it can be callback-free.



第51页

In concept it is simple. In practice it is complex: protocols, IO exceptions, ...



第52页

Product

github.com/luikore/nyara faster than sinatra/expressjs in hello world benchmarks



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。