Web Server Architecture

Download Report

Transcript Web Server Architecture

Web Server Architecture
Web Server Architecture
• Complex
– Helpful to consider best design practices
• Items to consider
– Response Time
• Use concurrency
– Features
• HTTP/1.1
• CGI
Web Server Architecture
use dup2 to redirect
stdin and stdout back
to the web server
Client
Web
Server
stdin
stdout
CGI
program
Web Server Architecture
Main Thread
for(j=0;j<nthread;
pthread_create()
while(1)
newsock = accept()
enQ(newsock)
Client
Connection
Queue
Thread Pool
while(1)
while(1)
sock = deQ()
while(1)
sock = deQ()
recv()
while(1)
sock = deQ()
recv()
process
while(1)
sock = deQ()
recv()
process
send()
while(1)
sock = deQ()
recv()
process
send()
close(sock)
while(1)
sock = deQ()
recv()
process
send()
close(sock)
sock = deQ()
recv()
process
send()
close(sock)
read()
process
send()
close(sock)
process
send()
close(sock)
write()
close(sock)
close(sock)
Web Server Architecture
• Minimize Overhead
– Launch threads that stay around
– Use semaphores to eliminate busy wait
• Be Careful with shared data structures
– Connection Queue
• Producer - main thread
• Consumers - connection handling threads
Web Server Architecture
#include …
Queue connectionQ;
main()
{
// Use signal handlers to shut down nicely
SetUpSignalHandlers()
void *HandleConn(void *args)
{
while(we are still running)
{
// This call should block until I have a connection
// You will need producer-consumer code
sock = connectionQ.deQ();
SetUpSocket()
recv(sock, message…)
for(j = 0; j < nthreads; j++)
pthread_create(thread[j], HandleConn,args)
processURL()
if (cgi)
DoCGI()
else
{
read file
send(sock, response…)
close(sock)
}
pthread_create(logthread, LogWriter, args)
for(;;)
{
sock = accept(…)
connectionQ.enQ(sock)
}
}
}
}
Shared Data Structures
• Queue of socket connections
• Strategy
– Write a template queue that inherits from the STL queue class
– Override the enqueue and dequeue methods
init(EmptySem, QSIZE);
init(PresentSem, 0);
init(mutex, 1);
template <class Elem>
void MyQueue<Elem>::enqueue(const Elem &Item)
{
template <class Elem>
wait(EmptySem)
Elem MyQueue<Elem>::dequeue(void)
wait(mutex)
{
super.enqueue(Item)
wait(PresentSem)
post(mutex)
wait(mutex)
post(PresentSem)
super.dequeue(Item)
}
signal(mutex)
signal(EmptySem)
}
Sample Exchange
GET /path/file.html HTTP/1.1
Host: www.host1.com:80
[blank line here]
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354
<html>
<body>
<h1>Happy New Year!</h1>
(more fiile contents) . . .
</body>
</html>
Web Request Processing
• Receive the request
GET /CS360 HTTP/1.1
Host: star.cs.byu.edu
• Process the URL
– Append URL to DocumentRoot
– Use stat to determine if file exists or if it is a
directory
• Send Response
HTTP/1.1 200 OK
Content-type: text/html, image/jpg or other mime type
Content-length: #bytes as reported by stat
Binary Data (Write a loop that reads a buffer
full of data and writes it to the socket until EOF)