Hacker News new | ask | show | jobs
by twic 3090 days ago
Here's a quick attempt at the same thing in Java (although note that the command line format is different):

https://gist.github.com/tomwhoiscontrary/b4888b86057c74a636c...

The main takeaway is that the JDK's built-in web server is poor:

* There is no way to configure timeouts

* Filters have to be added to each handler separately, by mucking with its filter list

* Filters have to extend an abstract class with two methods (one totally pointless), so you can't use lambdas for them

* Handlers use a simple string prefix match, so a request for "/healthzone" will hit the health handler

* The stop method always blocks for the specified timeout, and never returns early as the docs promise (IME)

Other minor irritations:

* There is no method to parse an InetSocketAddress from a string

* Java's support for handling clean process shutdown is not great; i think there's some sort of race between the shutdown hook and the logging system getting shut down, so you never see the "Server stopped" message

7 comments

If you're using java, just use finagle's http server and be done with it. It is really good and runs most all of twitter.com's production web services. The very definition of "web scale":

https://twitter.github.io/finagle/guide/Quickstart.html

"zero dependencies" was an essential feature of this. Finagle would be a dependency. And, according to a quick 'gradle distZip', it drags in a further 49 transitive dependencies.
That seems sensible. Really cool project (and I didn't mean to piss on it), just wanted to point out that generally speaking, finagle is serious business and can be used already.
Not sure if I would use Twitter as a success story for handling scale. Not exactly the poster boy of reliable software.
You're kidding, right? After they ditched ruby and wrote finagle, they've been super reliable. They've got one of the biggest Apache Mesos clusters in the world (second only to Apple's Siri backend per Apple employees who presented at MesosCon) and run it all with Apache Aurora, a really nice mesos framework for long running jobs.

Twitter, Soundcloud, Salesforce, Pinterest, FitBit, Tumblr, Box, Foursquare... What do they all have in common? They all run finagle in production. For java, it is about as battletested and as good as you'll get unless you want to write your own. Personally, I'm more of a golang and python developer, but respect where it is due. Twitter is massively more scalable than the overwhelmingly majority of the sites on the internet and they've gotten their act together since abandoning Ruby and the fail whale.

Is it Java or Scala? I only see Scala on this page: https://twitter.github.io/finagle/guide/Quickstart.html#a-mi...
Finagle proper is written in Scala, but you can use java as well for building services with it:

https://github.com/jghoman/finagle-java-example

Really good; web scale; reliable.

Pick two.

Yea, the built-in JDK HTTP server is pretty poor, but I don't think I've ever run across it in the wild thankfully.

> There is no way to configure timeouts

They're configured by properties if I recall.

> Filters have to be added to each handler separately, by mucking with its filter list

I personally prefer the explicitness of this.

As for the rest... I think a lot of these issues stem from the fact it's an old, not particularly well-known API in the JDK.

Hi twic, thanks for sharing this! I love to see implementation in other languages. I'm particularly interested in Rust, it would be awesome if anyone can make a attempt! :)
That would be awesome, but note that Rust, due to it being a low-level language, doesn't really have a net/http equivalent in its standard library and therefore any implementation would be more of a representation of the 3rd party libraries used.
Jetty does everything, else Spring with tomcat. I don't see any reason to rely on JDK web server (which I've never seen anyone seriouosly use.
I've been developing in Java for around 20 years and I never knew the JDK included a web server. This must be the thing I learned today ;)
Nice. Does anyone have a server like this but with the addition of

* serving of files and directories

* LetsEncrypt certificates and SSL

static file server in go:

    package main

    import (
        "fmt"
        "net/http"
        "path/filepath"
    )

    var (
        host = "0.0.0.0"
        path = "/var/www/public"
        port = 8080
    )

    func main() {
        path, err := filepath.Abs(path)
        if err != nil {
            panic(err)
        }
        listenAt := fmt.Sprintf("%s:%v", host, port)
        fmt.Println("static-serve-dir serving", path, "over http at", listenAt)
        err = http.ListenAndServe(listenAt, http.FileServer(http.Dir(path)))
        if err != nil {
            panic(err)
        }
    }
The builtin golang.org/x/crypto/acme/autocert [0] package manages SSL for you easily through Lets Encrypt.

[0]: https://godoc.org/golang.org/x/crypto/acme/autocert

golang.org/x/ packages are not builtin. You still must download them and use them just as you do any other dependencies, they just share some contribution process and developers with golang's stdlib.
Just wrap the handlers with middleware rather than using that filter abstraction.

Same thing!

By 'middleware', do you mean another handler? That would work, but i'd still have to wrap each handler separately.