diff options
Diffstat (limited to '_build/content')
-rw-r--r-- | _build/content/articles/cowboy2-performance.asciidoc | 80 | ||||
-rw-r--r-- | _build/content/articles/gun-2.0.0-pre.2.asciidoc | 59 |
2 files changed, 139 insertions, 0 deletions
diff --git a/_build/content/articles/cowboy2-performance.asciidoc b/_build/content/articles/cowboy2-performance.asciidoc new file mode 100644 index 00000000..269be791 --- /dev/null +++ b/_build/content/articles/cowboy2-performance.asciidoc @@ -0,0 +1,80 @@ ++++ +date = "2020-12-07T07:00:00+01:00" +title = "Cowboy 2 performance" + ++++ + +https://github.com/sponsors/essen[You can now reward my work via GitHub Sponsors]. + +Recently an article was published by Stressgrid entitled +https://stressgrid.com/blog/cowboy_performance/[Survey of Cowboy Webserver Performance] +that compares Cowboy performance across the different versions +as well as Erlang/OTP versions. The results are not very surprising +to me personally (although the drop is bigger than I expected), +but they might be to others. + +This prompted an experiment that I will now describe in two parts. +The first part is about modifying Cowboy to use `active,N` instead +of `active,once` to reduce the amount of time spent in the TCP +driver. The second part is about writing a stream handler in order +to squeeze the most performance out of Cowboy 2. + +In order to support both HTTP/1.1 and HTTP/2 with a common interface +(as well as HTTP/3 in the future), Cowboy 2 switched from the model +of "one process per connection" to "one process per connection + +one process per request". This is required because from HTTP/2 +onward requests are processed concurrently rather than sequentially, +not to mention the protocols include a number of control messages +that must be handled at the same time. + +But this necessarily has some impact on the performance of HTTP/1.1 +connections, and this is what the Stressgrid benchmarks show. Note +that while I will demonstrate in this article that it is indeed the +use of multiple processes that causes this reduction in performance, +I do not really know why this happens, though. + +After reading the blog post I started experimenting. I took Cowboy's +`hello_world` example and added https://github.com/rabbitmq/looking_glass[Looking Glass] +to the release. I then ran a quick benchmark against the example with +Looking Glass enabled: + +``` erlang +$ make run +... +(hello_world_example@host)1> lg:trace([ + {app, ranch}, {app, cowlib}, {app, cowboy}, {app, stdlib} +], lg_file_tracer, "traces.lz4", #{mode => profile, running => true}). +ok +... Run the benchmark here for a few seconds. +(hello_world_example@host)2> lg:stop(). +ok +(hello_world_example@host)3> lg_callgrind:profile_many("traces.lz4.*", "callgrind.out", #{running => true}). +ok +(hello_world_example@host)4> q(). +... +$ qcachegrind _rel/hello_world_example/callgrind.out +``` + +The benchmark can be done with `wrk` for example: + +``` bash +$ wrk -c100 -d10s http://localhost:8080 +``` + +The benchmark results don't matter, what we want is to see what +`qcachegrind` tells us about what happened in the system while +the benchmark was running. + +// @todo Need to run the above again in order to extract a picture to put here. + +What we can see in the above picture is that around 8% of the +active time (the time when processes are not waiting for messages) +is spent in `ranch_tcp:setopts/2`. This is when Cowboy sets +`active,once`. Turns out this is really expensive, at least +with synthetic benchmarks, if not more. + +A few years ago Steve Vinoski added `active,N` to Erlang/OTP +to reduce the amount of time spent in the TCP driver. Instead +of having to call `setops/2` for every packet we want to get +from the socket, we can tell the driver how many packets we +want and reduce the number of `setopts/2` calls. diff --git a/_build/content/articles/gun-2.0.0-pre.2.asciidoc b/_build/content/articles/gun-2.0.0-pre.2.asciidoc new file mode 100644 index 00000000..441e27aa --- /dev/null +++ b/_build/content/articles/gun-2.0.0-pre.2.asciidoc @@ -0,0 +1,59 @@ ++++ +date = "2019-09-27T07:00:00+01:00" +title = "Gun 2.0 pre-release 2" + ++++ + +Gun `2.0.0-pre.2` has been released! + +The second pre-release version of Gun 2.0 has been released! +Gun 2.0 adds a ton of features along with a small number of +breaking changes. + +The main highlight of this pre-release is the support for +a pluggable cookie store mechanism. Gun 2.0 comes with a +cookie store engine that can automatically process cookies +and store them to and retrieve them from a pluggable backend. + +Gun 2.0 comes with the `gun_cookies_list` backend which can +be enabled via the new `cookie_store` option. This backend +will keep cookies in-memory on a per-connection basis and +without any persistence built-in. It should however be easy +to create a backend on top of this one to add persistence +or share the cookie store backend between multiple connections +should that be necessary. + +The cookie store engine implements the RFC6265bis draft that +will become a proper RFC in the nearby future and includes +all the most recent improvements to cookies that modern +browsers have implemented. Gun is not a browser however so +some features were skipped (at least for now): there is no +support for setting cookies from the Erlang side; and there +is no SameSite checks because Gun does not have a concept of +a "browsing context". + +Please consult the link:/articles/gun-2.0.0-pre.1/[announcement for the first pre-release] +for information about other Gun 2.0 features. + +Gun 2.0 currently requires Erlang/OTP 22 or above and is tested +and supported on Linux, FreeBSD, macOS and Windows. + +A complete +list of changes can be found in the migration guide: +https://ninenines.eu/docs/en/gun/2.0/guide/migrating_from_1.3/[Migrating from Gun 1.3 to 2.0]. + +I will have more free time available for consulting or for +paid open source development starting from next week. If you +are interested, drop me an email at mailto:[email protected][[email protected]]. +A feature that may be useful for some of you could be for +example an implementation for the "Happy Eyeballs" mechanism +(RFC 8305) as this would allow faster connections to servers +on dual IPv4 and IPv6 environments. + +You can donate to this project via +https://github.com/sponsors/essen[GitHub Sponsors]. +These funds are used to pay for additional servers for +testing. + +As usual, feedback is appreciated, and issues or +questions should be sent via Github tickets. Thanks! |