Giter Club home page Giter Club logo

java-perf-workshop's People

Contributors

anemortalkid avatar cchesser avatar deining avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

java-perf-workshop's Issues

Enable gatling from parent project

  • When load testing, gatling needs to be executed from the java-perf-workshop-tester module. However everything else in the instructions is from the java-perf-workshop module (relative to it). The gatling tests should also run from that directory so there's no confusion on what needs to be ran from where.

Random test failures in SearcherTest#testSearch from text.png file access

The SearcherTest#testSearch suffers from intermittent failures, I've been able to reproduce it a bunch and have some symptoms:

When the test takes less than a second, things fail. When it doesn't, things pass. I'm guessing there's some synchronization / concurrency state involved in the failure.

I've been able to get a consistent exception in the console when this fails:

On thread:wkshp-conf-loader-1
Process finished with exit code -1
java.io.FileNotFoundException: text.png (Access is denied)
	at java.io.RandomAccessFile.open0(Native Method)
	at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
	at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243)
	at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:69)
	at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:55)
	at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
	at javax.imageio.ImageIO.write(ImageIO.java:1530)
	at cchesser.javaperf.workshop.data.AsciiArtConverter.convert(AsciiArtConverter.java:32)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:128)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:105)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.NullPointerException

	at cchesser.javaperf.workshop.data.ConferenceSessionLoader.load(ConferenceSessionLoader.java:98)
	at cchesser.javaperf.workshop.data.Searcher.search(Searcher.java:44)
	at cchesser.javaperf.workshop.data.SearcherTest.testSearch(SearcherTest.java:19)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:72)
	at org.junit.rules.RunRules.evaluate(RunRules.java:18)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.NullPointerException
	at com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:299)
	at com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:286)
	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
	at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:137)
	at com.google.common.cache.LocalCache$Segment.getAndRecordStats(LocalCache.java:2348)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2320)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader.load(ConferenceSessionLoader.java:96)
	... 26 more
Caused by: java.util.concurrent.ExecutionException: java.lang.NullPointerException
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$1.load(ConferenceSessionLoader.java:58)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$1.load(ConferenceSessionLoader.java:49)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
	... 32 more
Caused by: java.lang.NullPointerException
	at javax.imageio.ImageIO.write(ImageIO.java:1538)
	at cchesser.javaperf.workshop.data.AsciiArtConverter.convert(AsciiArtConverter.java:32)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:128)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:105)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

I thought it had to do with where the threads are launched from (and somehow not having access to write, so I added some naive prints for the thread name:

On thread:wkshp-conf-loader-0
java.io.FileNotFoundException: text.png (Access is denied)
	at java.io.RandomAccessFile.open0(Native Method)
	at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
	at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243)
	at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:69)
	at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:55)
	at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
	at javax.imageio.ImageIO.write(ImageIO.java:1530)
	at cchesser.javaperf.workshop.data.AsciiArtConverter.convert(AsciiArtConverter.java:32)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:128)
	at cchesser.javaperf.workshop.data.ConferenceSessionLoader$SessionLoadCallable.call(ConferenceSessionLoader.java:105)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
On thread:wkshp-conf-loader-0

However, this also happens with wkshp-conf-loader-1 , so no dice there :(

I've found a way to fix it (if the issue is not being able to create a file at a certain spot, concurrency problems are always tough).

Path tempFilePath = Files.createTempFile("text", "png");
File tempFile = tempFilePath.toFile();
tempFile.deleteOnExit();

ImageIO.write(image, "png", tempFile);

Was the intermittent failure an intended behavior for the purpose of the workshop? If so, we can keep the failures!

Make memory problem more obvious

The gatling simulation attempts to create a sort of real world scenario (using search/ , ascii/ search/context and conference/details). However the race condition that should trigger the memory leak sometimes is not reached (dumb threads not doing what I want).

We should:

  • Service work:
    • lower default cache settings size (from 10K to 250)
    • remove historyLog (if we trigger the memory leak, we don't need this to also waste memory)
    • get rid of ascii endpoint
  • Simulation work:
    • remove details endpoint from the simulation
    • remove ascii calls
    • hit /search 95% of the time and 5% with the context parameter.
    • increase number of users
    • mess with ramp up times

Ideally we could be able to create a situation where we can get an OutOfMemory exception when the service's memory is lowered (not using the default size)

Update JMC profile for OpenJDK

The JMC profile we provide was created for Oracle JVMs:

image

When using an OpenJDK JVM , the Template Manager will be smart enough to not let us select the profile provided by the guide. You can import it and select apply, BUT the resulting dropdown doesn't let you end up choosing that profile, so at a quick glance it seems like things didn't import but that's just JMC filtering down the select to only profiles that are applicable.

image

We should rename the template to be OracleJDK (or something that mentions oracle) and provide a new one for OpenJDK if continous/whatever don't suit our needs.

Update workshop to include containers

It is common where Java workloads are within a Linux container, and they aren't aware of all the sizing that can occur which feeds into the overall container size. Furthermore, using some of the available tooling requires making adaptations to use these and connect it to the container.

  • Provide prerequisite for running the service workload as a container locally (ex. Docker)
  • Simulate an example: OutOfMemoryError: Unable to create native thread
  • Share common tooling to understand to inspect contents of the container to understand the Java process and OS resource usage
  • Share differences and JVM options to acknowledge, like Metaspace limits (diff from PermGen -> Metaspace where it is unlimited by default). Also share documentation on what influences this (classloading).

Add a contributors page

We are wanting to have a contributors page to highlight those who contribute to the content. This would include a short bio, reference to their github account, and photo.

Add clear prerequisites for those going through the workshop

There will be some implied knowledge about Java, but it may help share those expectations with references to good learning resources before going through this workshop.

This should include content from #27 on anything additional that might be needed for the inclusion of containers.

Transition content into a Github Pages site

We are wanting to change the organization of this site to be hosted in as a website, vs just Markdown files within the folder structure. This will help in guiding the flow of the workshop, making a better user experience, and then can have references to the code they run in the project.

Add a guided flow to the workshop

Add some sort of navigation to the workshop that leads to the next page, the pages are sorted by weight already but that won't guarantee someone will know where to go next, something like this should work:

{{/* 
  Iterates over the set of pages in the current section, locating the current page and creating a link with the contents of the next page.
*/}}
{{ $scratch := newScratch }}
{{ range $index, $element := $.Page.CurrentSection.Pages.ByWeight }} 
  {{ if (eq $.Page.Params.weight .Params.weight) }}
    {{ $scratch.Set "nextIndex" (add 1 $index)}}
  {{ end }}
{{ end }}
{{ with index $.Page.CurrentSection.Pages.ByWeight ($scratch.Get "nextIndex") }}
<div class="card mb-3" style="width: 80%;">
	<div class="card-header text-white border-info bg-info">
        <i class="fas fa-arrow-alt-circle-right"></i>&nbsp;&nbsp;Up Next</div>
	<div class="card-body">
	  <p class="card-text">{{ $.Inner }}</p>
      <a href="{{ .Permalink }}">{{ .Params.title | humanize | title }}</a></i>
	</div>
</div>
{{ end}}

Renders something like:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.