Slide 1

Slide 1 text

A Whole New World! Rails on the JVM with JRuby!

Slide 2

Slide 2 text

Who Am I • Charles Oliver Nutter • @headius(@mastodon.social) • [email protected] • JRuby developer since 2004 • Full-time JRuby and JVM language advocate since 2006

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

What is JRuby? • An implementation of Ruby atop the Java Virtual Machine • Ruby implementation fi rst, JVM language second • Many bene fi ts from JVM ecosystem • Ruby code should "just work" • Different extension API, no forking, parallel threads • www.jruby.org

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Ruby Compatibility • JRuby 9.4 is out now! • Ruby 3.1 compatible, 98% of language specs passing • Nearly complete core + stdlib features from 2.7, 3.0 and 3.1 • JRuby 9.3 (Ruby 2.6 compat) • Maintenance through 2023 as needed • Compatibility before performance! • Now we can refocus on optimization again

Slide 8

Slide 8 text

Ruby 3.2 Coming Soon! • Checklist issue: jruby/jruby#7517 • You can help us add missing features! • Hopefully release 3.2 compatibility in the next 6 months

Slide 9

Slide 9 text

Why JRuby? • JVM GC, JIT, concurrency scales Rails extremely well • Rich tools for monitoring, pro fi ling, debugging • Wide platform support: desktop, server, mobile • Zero-compile cross-platform GUI support • Java ecosystem moving fast, with thousands of excellent libraries

Slide 10

Slide 10 text

Getting Started

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

JRuby Install • Install a JDK • Java 11+ recommended, there's many distributions out there • Java 8 supported for 9.4 and lower • Install JRuby • Recommended: system package, Ruby installer, Docker image • Download tarball/zip or Windows installer

Slide 13

Slide 13 text

Test it out! [] ~ $ rvm use jruby Using /Users/headius/.rvm/gems/jruby-9.4.2.0 [] ~ $ irb >> runtime = java.lang.Runtime.runtime => # >> runtime.available_processors => 8 >> runtime.free_memory => 91420584 >>

Slide 14

Slide 14 text

JRuby on Rails

Slide 15

Slide 15 text

JRuby Runs Rails! • Since 2007! • "Are there JRuby users running Rails applications?" • Oh yes! And at large scale! • Bene fi t from the JVM, libraries, languages • Great way to scale large Rails apps today!

Slide 16

Slide 16 text

Rails 7 • Rails 7 works on JRuby 9.4! • activerecord-jdbc for JRuby: SQLite, MySQL, PostgreSQL • Version 60.0 for Rails 6, 70.0 for Rails 7, etc • Oracle, SQL Server, DB2, are available, may need updates • Performance and compatibility looking good!

Slide 17

Slide 17 text

Rails 7 actioncable: 203 runs, 921 assertions, 0 failures, 10 errors actionmailbox: 92 runs, 238 assertions, 0 failures, 0 errors actionmailer: 230 runs, 516 assertions, 0 failures, 1 errors actionpack: 3550 runs, 16802 assertions, 1 failures, 1 errors actiontext: 80 runs, 145 assertions, 7 failures, 2 errors actionview: 2424 runs, 5395 assertions, 2 failures, 4 errors activejob: 368 runs, 837 assertions, 0 failures, 0 errors activemodel: 966 runs, 2853 assertions, 5 failures, 0 errors activestorage: 392 runs, 1121 assertions, 0 failures, 0 errors activesupport: 5188 runs, 12926 assertions, 43 failures, 28 errors 99% passing!

Slide 18

Slide 18 text

Minimal Con fi g Changes • Generate a new app, Rails will use JRuby defaults • Use threads in Puma instead of workers • 2n+1 is a good rule of thumb • Make sure to increase DB connections as well • Existing app: try bundling, replace unsupported libs • Let us know! We can prioritize adding JRuby support!

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Scaling Rails with JRuby

Slide 21

Slide 21 text

Scaling Rails • Classic problem on CRuby/MRI • No concurrent threads, so we need worker processes • Processes duplicate runtime state and waste resources • JRuby is the answer! • Multi-threaded single process runs your entire site • Single process with leading-edge GC uses resources better

Slide 22

Slide 22 text

Baseline Rails App • Scaffolded "blog" application on PostgreSQL, Puma • IBM VPC instance: 8 vCPU, 32GB • CRuby 3.2, 16 workers • JRuby 9.4: 16 threads • Database, siege benchmark driver on same instance

Slide 23

Slide 23 text

Workers vs Threads • Workers duplicate a lot of work • N * GC overhead, single large heap is better • N * JIT overhead and memory usage • Unavoidable to have some duplicated memory • JVM and JRuby support real parallel threads • One process, one GC, one JIT scales all the way up

Slide 24

Slide 24 text

Caveats • PostgreSQL local via Docker (<5% overhead) • Siege benchmark driver also local (<5% overhead) • Very minimal blog app, full end-to-end requests • JRuby tuning and warmup time are important

Slide 25

Slide 25 text

Requests per second 0 450 900 1350 1800 60s siege iteration 1 2 3 4 5 6 7 JRuby 9.4 CRuby 3.2

Slide 26

Slide 26 text

requests per second (higher is better) 0rps 450rps 900rps 1350rps 1800rps 1,280rps 1,705rps JRuby 9.4 CRuby 3.2

Slide 27

Slide 27 text

Memory • Baseline • JRuby: 3.4GB RSS • CRuby: 16x 103MB = 1.6GB • With tuning options • JRuby with 300MB heap: 955MB • CRuby YJIT: 16x 125MB = 2GB

Slide 28

Slide 28 text

Requests per second 0 450 900 1350 1800 60s siege iteration 1 2 3 4 5 6 7 JRuby CRuby 3.2 JRuby 300MB heap CRuby 3.2 + YJIT

Slide 29

Slide 29 text

requests per second (higher is better) 0rps 450rps 900rps 1350rps 1800rps 1,550rps 1,643rps 1,280rps 1,705rps JRuby 9.4 CRuby 3.2 JRuby 300MB heap CRuby + YJIT

Slide 30

Slide 30 text

JRuby on Rails Scales! • More requests per second with lower latency • Lower memory usage beyond 8-10 concurrent users • Deploy anywhere that has a JVM (which is basically everywhere) • Leverage JVM tools to monitor and optimize

Slide 31

Slide 31 text

True Story • Large Rails application using 40 xlarge on EC2 • 40 worker processes per server • 100k-150k req/min, 50-75ms response times • Migrated app to JRuby, made more use of threading • Down to 10 xlarge, 75% cost reduction • Consistently over 150k req/min, 30ms response times $

Slide 32

Slide 32 text

Deploying JRuby the Ruby Way • Typical servers, devops tools in Ruby work fi ne • Usually no compilation required; install and go • Scales great with Puma • Rails using Puma by default • Small frameworks (e.g. Sinatra, Roda) scale even better

Slide 33

Slide 33 text

Deploying with Warbler • gem install warbler ; warble • Bundle your app + libs + JRuby into a single fi le • Hand off to ops to deploy or run as executable (w/ built-in server) • One click deploy to Java clouds: • Elastic Beanstalk, Google AppEngine, etc • github.com/jruby/warbler

Slide 34

Slide 34 text

But wait, there's more!

Slide 35

Slide 35 text

So much more! • JVM and JRuby have much more to offer • We'll cover a few areas that make JRuby stand out • Some of these are early or experimental, but very exciting!

Slide 36

Slide 36 text

JVM Tools

Slide 37

Slide 37 text

JDK Flight Recorder • Low-overhead monitoring and pro fi ling for JVM • Always-on monitoring <1% overhead • Active pro fi ling around 5% overhead • Track memory, heap usage, GC, hot methods, JIT activity • Think New Relic, AppSignal, Sentry.io... but built-in and FREE

Slide 38

Slide 38 text

JDK Mission Control • GUI control center and visualizer for Flight Recorder data • Start and manage recordings • Save, load, and browse recorded data • https://adoptium.net/jmc/

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

Visual VM

Slide 46

Slide 46 text

GUI and Graphics

Slide 47

Slide 47 text

GUI Libraries • Swing, built into JDK • Clean, cross-platform, easy to build simple UIs • Scalable Windowing Toolkit (Eclipse SWT) • Native widgets, WebKit browser component, rich ecosystem • JavaFX (via JRubyFX, github/jruby/jrubyfx) • Scene-based, vector drawing, event-driven modern UI library

Slide 48

Slide 48 text

Shoes 4

Slide 49

Slide 49 text

Glimmer • Glimmer GUI DSL • Multiple backends (SWT, GTK, ...) • JRuby + SWT is the most mature • JRuby makes cross-platform GUI much easier! • Works same everywhere • GUI libraries shipped with gem

Slide 50

Slide 50 text

Purugin for Minecraft event(:player_egg_throw) do |e| e.hatching = true e.num_hatches = 120 e.player.mesg "hatched" end

Slide 51

Slide 51 text

GUIs... like Android?

Slide 52

Slide 52 text

Ruboto: JRuby on Android • ruboto.org • Actively used for commercial projects today • Build interface with GUI builder, wire it up with Ruby code • Neglected a bit but being updated for JRuby 9.4 now!

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Trying Ruboto IRB • Original was pulled from store because it asked for ALL privileges! • Duh, it was a tech demo and REPL • We will republish soon, but search for two packages to download: • Ruboto Core: JRuby and Ruboto framework as a shared package • Ruboto IRB: REPL, editor, example scripts

Slide 55

Slide 55 text

More JVM Features for Ruby

Slide 56

Slide 56 text

InvokeDynamic

Slide 57

Slide 57 text

InvokeDynamic • User-de fi ned binding of methods and values • Language decides target based on dynamic lookup logic • JVM optimizes that target like static code • Introduced in Java 1.7 (2011) with input from JRuby • Key to JRuby performance!

Slide 58

Slide 58 text

InvokeDynamic Performance Times faster than JRuby Java 8 no indy 0 1.25 2.5 3.75 5 Mandelbrot Red/Black 4.05x 3.92x 3.74x 3.68x 3.72x 1.97x Java 8 indy Java 11 indy Java 17 indy 3.28x CRuby JIT 1.86x CRuby JIT

Slide 59

Slide 59 text

Indy + Graal JIT? Times faster than JRuby Java 8 no indy 0 4 8 12 16 Mandelbrot Red/Black 3.13x 15.7x 4.05x 3.92x 3.74x 3.68x 3.72x 1.97x Java 8 indy Java 11 indy Java 17 indy Graal CE indy Escape analysis But not always better

Slide 60

Slide 60 text

Project Loom

Slide 61

Slide 61 text

Project Loom • JRuby's fi bers are based on threads • Too many, JVM blows up! • Scheduling, resource-intensive • Loom brings fi bers to JVM • Easily handles thousands of fi bers • Faster context-switching

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

5.times do t = Time.now # create 100k fibers ary = 100_000.times.map { Fiber.new { } } # resume and complete 100k fibers ary.each(&:resume) p Time.now - t end

Slide 65

Slide 65 text

$ jruby fiber_test.rb [7.603s][warning][os,thread] Attempt to protect stack guard pages failed (0x00007fc240a00000-0x00007fc240a04000). # # A fatal error has been detected by the Java Runtime Environment: # Native memory allocation (mprotect) failed to protect 16384 bytes for # memory to guard stack pages # # An error report file with more information is saved as: # /home/headius/work/jruby93/hs_err_pid75149.log # # If you would like to submit a bug report, please visit: # https://bugreport.java.com/bugreport/crash.jsp # Aborted (core dumped) 😩

Slide 66

Slide 66 text

--enable-preview

Slide 67

Slide 67 text

$ jruby -J--enable-preview fiber_test.rb 2.324123 0.880373 0.6916289999999999 0.73703 0.655856 🤩

Slide 68

Slide 68 text

Project Panama • Foreign function interface (FFI) • With JVM help to make direct calls • Foreign memory API • JVM-assisted access, lifecycle • API extraction from C/++ headers • Save time setting up bindings

Slide 69

Slide 69 text

jextract code generator • Writing bindings using FFI or Fiddle is still challenging • Parameter sizes, struct layout, in and out values, pointers • Differences across platforms • jextract: produce Panama/FFI stub code from a C header fi le • Call that stub code from JRuby... easy FFI for all!

Slide 70

Slide 70 text

Wrapping Up

Slide 71

Slide 71 text

JRuby Future • JRuby 9.4 continues to stablize • Many production users already! • Big optimization work coming the rest of this year • JRuby 9.5: Java 17 minimum, Ruby 3.2 support, many optimizations • Lots of new JVM features to leverage • Looking into native compilation, snapshotting for fast startup!

Slide 72

Slide 72 text

JRuby on Rails Future • Rails 7 support is looking great! • We are caught up again, will keep tracking updates • As your app grows, JRuby can help you scale • Reduce resources, save money 🤑 • Let's talk about running your app on JRuby!

Slide 73

Slide 73 text

Thank You! • Charles Oliver Nutter • [email protected] • @headius • https://github.com/jruby/jruby • https://www.jruby.org