Skip to content

simonneutert/Joda

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Joda ๐Ÿ–– == JRuby + Roda

And here it is ๐ŸŽ‰ My template for Ruby's notorious web router Roda - running on the JVM (JRuby)! ๐ŸŒ‹

Start the server with $ rackup, then benchmark (see below) as unscientifically as possible (but easy as pie), using HTTPie:

๐Ÿคซ or for production sth like: $ jruby --server -S bundle exec rackup -o 0 -E production

$ time http :9292/jsondata >/dev/null
sucks 25mb from your server ๐Ÿง›โ€โ™€๏ธ

Add rodauth to have a proper user account management ๐Ÿคฏ

Why though?

I cannot really say why JRuby intriqued me, since I fell in love with Ruby. But, JRuby never felt especially beginner friendly. ๐Ÿ˜ฌ
Something didn't work. Very tough to google. JDBC what?
Java docs?! Java ecosystem?! They do what? How on earth? Cheesus ... ๐Ÿคข

This repository is aimed at

  • curious Rubyists, struggling to find a use case of getting something up with JRuby
  • those who want get hold of JRuby, without the suspicious feeling that Rails takes care of everything behind the curtains (it's why we love you, Rails, you know that! ๐Ÿ˜˜)
  • People curious of Roda
  • PORO lovers
  • Rack fanboys
  • Sinatra / Fastify / FastAPI / Gin
  • Java people / JVM users โ˜•๏ธ
  • those on a journey, they don't know, they are on: Ruby โžก JRuby โžก Clojure โ˜ฎ๏ธ

Run

Your Java version should be pinned to 11.x as this is what the CI is running on. MacOS checks for JRuby run on Java v8.

if one of you gets this going on another OS, please submit a PR with some handy notes โœŒ๏ธ

Docker

  • $ docker build . -t joda
  • $ docker run --rm -it -p9292:9292 joda

with jemalloc

For aarch64 (e.g. Mac M1):

  • $ docker run -ti --env LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292

For x86_64:

  • $ docker run -ti --env LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292

Production

๐Ÿš€

  • $ docker run -ti --env LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2 --rm -p9292:9292 rackup -o 0 -E production

MacOS and asdf

please, see the docs of your asdf-vm java plugin (docs of the default java plugin ๐Ÿ“–). It's about JRuby having Java in it's PATH.

Then fire the following commands:

  • $ asdf install java microsoft-17.35.1
  • $ asdf reshim
  • $ asdf install ruby jruby-9.4.1.0
  • $ bundle install -j4
  • $ jruby -S rackup

Profiling JRuby

$ jruby --profile.graph -S rackup

JVM Options

This is how you could use it for production: $ jruby -J-Xmx512m --server -S rackup -E production

  • minimum and maximum Java heap size to 512 MB
  • optimization for server ON
  • runs Rack in production mode

or:

$ jruby -J-Xms2g -J-Xmx2g --server -J-Djruby.thread.pool.enabled=true -S rackup -E production

Benchmarks ๐Ÿฅผ๐Ÿงช๐Ÿ’ป

FIRST OF ALL the JVM had some requests before the benchs to warm up a little
BUT let's be honest the server wasn't fresh and had already other stuff to do
AND had just 2 cores (but 8 gigs of RAM ๐Ÿ˜…)
AND for sure I missed an opportunity for tweaking something
BECAUSE the JVM still is completely new to me at this point
SO this is worthless, but some just need to see some numbers

well, enough whining...

  • ab (comes pre-installed on MacOS)
  • wrk (i.e. $ brew install wrk)

Benchmarking with ab:

$ ab -n 1000 -c 10 -k -H "Accept-Encoding: gzip, deflate" "https://joda.test.test/hello/world"

This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking joda.test.test (be patient)
[...shortened...]

Server Software:
Server Hostname:        joda.test.test
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,4096,256
Server Temp Key:        ECDH X25519 253 bits
TLS Server Name:        joda.test.test

Document Path:          /hello/world
Document Length:        38 bytes

Concurrency Level:      10
Time taken for tests:   11.268 seconds
Complete requests:      1000
Failed requests:        0
Keep-Alive requests:    0
Total transferred:      166000 bytes
HTML transferred:       38000 bytes
Requests per second:    88.74 [#/sec] (mean)
Time per request:       112.685 [ms] (mean)
Time per request:       11.268 [ms] (mean, across all concurrent requests)
Transfer rate:          14.39 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       49   78  14.4     77     137
Processing:    12   33  22.0     22     113
Waiting:       11   23  12.1     17      77
Total:         64  111  26.2    105     244

Percentage of the requests served within a certain time (ms)
  50%    105
  66%    117
  75%    126
  80%    131
  90%    151
  95%    164
  98%    176
  99%    186
 100%    244 (longest request)

Benchmarking with wrk:

$ wrk -t10 -c10 -d30s "https://joda.test.test/hello/world"

Running 30s test @ https://joda.test.test/hello/world
  10 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    23.21ms   15.14ms  81.68ms   84.52%
    Req/Sec    46.87     15.47    80.00     62.34%
  14065 requests in 30.10s, 2.07MB read
Requests/sec:    467.21
Transfer/sec:     70.28KB

Device

Model Name MacBook Pro
Model Identifier MacBookPro18,1
Chip Apple M1 Pro
Total Number of Cores 10 (8 performance and 2 efficiency)
Memory 16 GB

Thought Section

Entering this fancy new rabbit hole, here's what didn't work, or may well be served with butter in the future

Database

when load testing /jsondata/items route:

Roda

there's so much beauty in Roda, so it would be nice to showcase more of it.

I suggest you stumble through the following websites:


Credits

SEO Stuff ๐Ÿคญ

Tags/Keywords: Ruby, JRuby, Java, Roda, Sequel, JDBC, Puma, REST, API, JSON