audit your reactive applications
DESCRIPTION
You use Play, AKKA, VertX, RxJava, AsyncHTTPClient ? Audit your code to detect all blocking methods.TRANSCRIPT
Audit your reactive applications
+PhilippePrados @pprados+François-Xavier Bonnet @fxbonnet
What is reactive?
● Responsive● Resilient● Elastic● Message driven
“Non-blocking communication allows recipients to only consume resources while active,
leading to less system overhead.”
http://www.reactivemanifesto.org/
The problem: blocking APIs
● Blocking APIs consume the thread pool because of too much waiting time
● We should have no more threads than cores
on the machine
How do I track blocking API calls?
● Modifying the JVM?● Generating warnings during compilation?● Instrumenting the code at runtime using a
JVM agent?
Code Compiler JRE
Modifying the JDK
● This strategy has been used by Google in Android SDK in order to avoid the use of blocking API in a UI thread
● Not too hard for pure java methods but what about native methods (OS specific)?
Generating warnings during compilation?
● Annotate JDK methods inside an IDE? Used by IntelliJ for @Nullable and @NotNull annotations but not standard
● JSR 269 allows to do things at compile time https://jcp.org/en/jsr/detail?id=269
● Compilation occurs in several phases, we can access the syntax tree only after the first phase
o The pure syntax, not the called method name
Generating warnings during compilation?
● JSR308 allows to do things after the second phase http://types.cs.washington.edu/jsr308/
o The augmented syntax tree
● But not included in JDK 8
Generating warnings during compilation?
● Many things can be seen only at runtime
● Ex: java.io.Reader.read() is blocking for a file or network connection but not for memory
Instrumenting the code at runtime using a JVM agent?
● Patch the code at application startup● Solution:
Auditing using Aspect programing
● Load time weaving● Java agent at JVM startup● List all blocking methods
● But, can not be weaving the SDK itself
Some tweaks:● Some methods might be blocking depending
on the arguments or internal use!
Aspect programming: example
Checking an application - Play
Log output with Play
DEMO
Log output with PlayHIGH : Call method void java.io.PrintWriter.print(String) with /tmp/sbt1269029892078438540.logcom.octo.reactive.audit.lib.FileReactiveAuditException: Call method void java.io.PrintWriter.print(String) with /tmp/sbt1269029892078438540.logat thread "play-internal-execution-context-1"at sbt.ConsoleOut$$anon$3.print(ConsoleOut.scala:52)at sbt.ConsoleLogger.setColor(ConsoleLogger.scala:158)at sbt.ConsoleLogger.reset(ConsoleLogger.scala:153)at sbt.ConsoleLogger.sbt$ConsoleLogger$$printLabeledLine(ConsoleLogger.scala:168)at sbt.ConsoleLogger$$anonfun$log$1.apply(ConsoleLogger.scala:164)at sbt.ConsoleLogger$$anonfun$log$1.apply(ConsoleLogger.scala:163)at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)at sbt.ConsoleLogger.log(ConsoleLogger.scala:163)at sbt.ConsoleLogger.log(ConsoleLogger.scala:151)at sbt.AbstractLogger.log(Logger.scala:31)...
Use it with in testing scope
● Because the analysis is performed on effective method calls at runtime
● The audit should be used while runningo Integration testso Functional tests
● Not relevant in unit tests
Configuration
● Alert for all calls to blocking methods?
● We need some filterso Startup shifto Thread name (pattern matching)o Kind and level of blocking call (CPU, File, Network)o Annotations
Configuration at runtime
Log output with Play
DEMO
Checked SDK APIs +500
java.iojava.langjava.netjava.nio.channeljava.nio.filejava.rmi.registryjava.rmi.serverjava.sqljava.utiljava.util.concurrentjava.util.concurrent.locksjava.util.loggerjava.util.zip
javax.activationjavax.imageiojavax.netjavax.net.ssljavax.rmijavax.rmi.ssljavax.sql.rowset.spijavax.sql.rowsetjavax.sqljavax.toolsjavax.transaction.xajavax.xml.bindjavax.xml.parsersjavax.xml.soapjavax.xml.ws.spijavax.xml.wsorg.xml.sax
Supported frameworks/languages/servers
Framework Windows Mac/linux
unknown > reactive-audit> java %AUDIT_OPTS% ...
$ source reactive-audit$ java %AUDIT_OPTS% ...
jetty > reactive-audit jetty> java %AUDIT_OPTS% -jar start.jar
$ source reactive-audit jetty$ java %AUDIT_OPTS% -jar start.jar
catalina > reactive-audit catalina -run catalina run $ reactive-audit catalina -run catalina run
play > reactive-audit play -run activator run $ reactive-audit play -run activator run
vert.x > reactive-audit vertx -run vertx run ... $ reactive-audit vertx -run vertx run ...
maven > reactive-audit maven -run mvn ... $ reactive-audit maven -run mvn ...
gradle > reactive-audit gradle -run gradle ... $ reactive-audit gradle -run gradle ...
sbt > reactive-audit sbt -run sbt ... $ reactive-audit sbt -run sbt ...
Build integration and continuous testing
● Sample script foro Maveno Gradleo Sbt
● You’re welcome to propose others
Use it with your reactive project
● Play● Akka● VertX● AsyncHttpClient● RxJava● …
We need you !
● Check it with your project● Improve the rules● Submit some extensions● Submit plugins for others tools● Submit XSTL to format XML log file
https://github.com/octo-online/reactive-audit
Questions?
https://github.com/octo-online/reactive-audit
Questions?
LES CONTACTS
Philippe PRADOS
Manager Tribu Reactive
+33 (0)6 20 66 71 00
François-Xavier Bonnet
Consultant
+33 (0)6 13 26 82 99