I still use FCGI. FCGI works a lot like CGI; it loads programs when a request comes in, and the programs deal with the request. But it's much higher performance, because it doesn't have to freshly load the target program each time.
FCGI is an orchestration system. It starts up more worker processes if there are more requests, up to some limit it figures out by itself. If there are few requests, some of the worker processes get an end of file notification and exit. If a worker process crashes, it loads a fresh copy. Little or no human attention required. One of my systems has been up for 1788 days now.
FCGI works fine with Go programs, Python programs, etc. If you use Go, you can get performance reasonably close to what the hardware can do. Until you get to the point that you're renting additional servers as load increases, you don't need more than that for most applications.
You can run FCGI on some cheap shared hosting systems. Why pay more?
I'm really interested in this. How do you handle DB connections? I guess each CGI file becomes stateful because it's not reloaded all the time, and there's a connection handle there.
Each FCGI program has a database connection. That database connection persists as long as the program instance is running. So it's not establishing a new database connection for each transaction.
package main
import (
"database/sql"
"net/http"
"net/http/fcgi"
)
//
// Called by FCGI for each request
//
func (sv FastCGIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
body := make([]byte, 5000) // buffer for body, which should not be too big
if req.Body != nil {
len, _ := req.Body.Read(body) // body of HTTP request
bodycontent := body[0:len] // take correct part of buffer
Handlerequest(sv, w, bodycontent, req) // handle request
}
}
// Run FCGI server
func main() {
sv := new(FastCGIServer)
fcgi.Serve(nil, sv)
}
// Handlerequest -- handle one request from a client
func Handlerequest(sv FastCGIServer, w http.ResponseWriter, bodycontent []byte,
req *http.Request) {
// GENERATE REPLY CONTENT HERE
w.WriteHeader(statuscode) // internal server error
w.Write(content) // report error as text ***TEMP***
}
That will run on low-end hosting at Dreamhost.
So there you are, in a modern language, with hard-compiled code with good performance, and reasonably good fault tolerance. Next step up would be a load balancer and redundant databases.
FCGI is an orchestration system. It starts up more worker processes if there are more requests, up to some limit it figures out by itself. If there are few requests, some of the worker processes get an end of file notification and exit. If a worker process crashes, it loads a fresh copy. Little or no human attention required. One of my systems has been up for 1788 days now.
FCGI works fine with Go programs, Python programs, etc. If you use Go, you can get performance reasonably close to what the hardware can do. Until you get to the point that you're renting additional servers as load increases, you don't need more than that for most applications.
You can run FCGI on some cheap shared hosting systems. Why pay more?