Информация по семинару
Мастер-класс прошёл 23 января 2024.
Описание мастер-класса
В экосистеме Java существует большое количество инструментов диагностики и профилирования. Но есть нюанс , как правило инструменты с графическим интерфейсом работают либо с локальными процессами (а у нас сервер-сайд), либо требуют инфраструктуры и предварительной интеграции (например решения класса APM ).
А можно ли просто зайти в консоль и понять, что происходит с нашим приложением?
Можно! - и это будет предметом данного семинара.
JDK включает в свой состав ряд важных инструментов доступных из командной строки. Например, JDK Flight Recorder - мощный инструмент, все возможности, которого доступны из командной строки. Помимо этого мы поработаем с SJK open source инструментом, созданным автором данного семинара.
В рамках семинара будет две основные темы.
Видео запись
Подготовка к семинару
Важно!
Для выполнения практической части вебинара, пожалуйста, заранее, проведите подготовку по инструкции представленной ниже.
Необходимое ПО
Для выполнения практической части семинара вам понадобится компьютер. Материал протестирован на Windows 10/11, Linux и MacOS.
У вас долноам понадобиться следующее ПО.
TCP порты
Следующие порты используются тестовыми приложениями и должны быть заняты другим ПО в ходе мастер-класса:
Погдотовка ПО
Java 17
Вам потребуется OpenJDK 17. Существует несколько дистрибутивов, вы може использовать любой. Ниже не полный список дистрибьюторов OpenJDK.
- Adoptium (необходим вариант с HotSpot JVM)
- Azul Zulu
- Amazon Corretto
После установке убедитесь, что бинарники JDK доступны в $PATH. Комманда java -version должна выкодить корректную версию.
git
Для работы с материалом семинара вам понадобится git клиент с поддержкой коммандной строки.
Maven
Для запуска демонстрационных проектов необходим Maven версии 3.8 или выше.
После инсталяции убедитесь, что команда mvn --version корректно работает из консоли и возвращает правильные номера версий Java и Maven.
Загрузка материалов
Дальнейшие инструкции предполагают, что директория LABDIR используется для установки учебных материалов.
Директории LABDIR выполните команду:
git clone -b perfdemo-5.2.x https://github.com/aragozin/BroadLeafCommerce-DemoSite.git blf-demo
SJK - консольный профайлер, который мы так же будем использовать.
Скачайте sjk.jar и поместите в дидекториюLABDIR/blf-demo.
В директории LABDIR/blf-demo проверьте запуск SJK
java -jar sjk.jar --commands
Команда должна распечатать список инструментов SJK, аналогичный примеру ниже.
ssa - [Stack Sample Analyzer] Analyzing stack trace dumps
hh - [Heap Histo] Prints class histogram, similar to jmap -histo
stcpy - [Stack Copy] Stack dump copy/filtering utility
vminfo - [VMINFO] Dumps various from local VM
mx - [MBean] MBean query and invokation
jps - [JPS] Enhanced version of JDK's jps tool
mxping - [MXPING] Verify JMX connection to target JVM
mxdump - null
ttop - [Thread Top] Displays threads from JVM process
dexp - [Dump Export] Extract metrics form compressed dump into tabular format
jfr2json - [JFR 2 JSON] Flight decoder, command translates JFR files into JSON
mprx - JMX proxy - expose target process' MBeans for remote access
stcap - [Stack Capture] Dumps stack traces to file for further processing
gc - [Print GC] Print GC log like information for remote process
flame - Generates flame graph from stack traces
Запуск тетового примера
В директории LABDIR/blf-demo выполните команду
mvn -P run_n_load test
Первый запуск потребует несколько минут, по итогу maven сборка должна завершиться успешно.
После завершения сбоки зайдите на URL http://127.0.0.1:8080/ Вы должны увидеть фронтэнд магазина “HEAT CLINIC”
CPU системы должен быть загружен java процессами, так как предыдущая команда включает генератор нагрузки.
В директории LABDIR/blf-demo выполните команду
mvn clean
Если директория LABDIR/blf-demo/pids не была удалена предидущей коммандой. Удалите её врeчную (например rm -rf LABDIR/blf-demo/pids).
Запущенные на предыдущем шаге java процессы должны завершиться.
Запуск тестового приложения в контейнере
В директории LABDIR/blf-demo выполните команду
mvn -P build_image,run_n_load_docker package
Как и в предыдущем примере, после завершения сбоки зайдите на URL http://127.0.0.1:8080/ и проверте наличие страницы тестового приложения.
CPU системы должен быть загружен java процессами как и в предидущем случае.
Остановите контейнер и вспомогательные процессы
docker stop storefront
mvn clean
Если директория LABDIR/blf-demo/pids не была удалена предидущей коммандой.
Удалите её вручную (например rm -rf LABDIR/blf-demo/pids).
Выполните команду jcmd чтобы убидится, что процессы лаборатоного стенда не запущены.
Практическая часть
Основы работы из коммандной строки
Для работы нам понадобяться две консоли (условно A и B).
Обновим демострационные материалы.
1
в директории LABDIR/blf-demo выполним команду
git pull
так нужно скачать и поместить в LABDIR/blf-demo последнюю версию sjk.jar
Запустим демонстрационный стенд.
2
в директории LABDIR/blf-demo выполним команду
mvn -P run_n_load test
Команда требует значительного времени для запуска окружения. Сборка должна завершиться успешно.
Проверим доступность приложения по ссылке http://127.0.0.1:8080.
Оценим загрузку ЦПУ в системе.
3 Воспользуйтесь коммандой top или менеджером процессов чтобы получить список процесов потребляющих ЦПУ.
Воспользуемся средствани OpenJDK для поиска java процессов
4
выполним команду
jps
резудьтатом команды будет список java процессов.
13793 LoadGenStarter
13444 HsqlStarter
13478 SolrStarter
13884 Jps
13535 SiteApplication
5
далее выполним комманду
jcmd
и также получим список процессов
13793 info.ragozin.loadgen.LoadGenStarter
13906 jdk.jcmd/sun.tools.jcmd.JCmd
13444 info.ragozin.hsql.HsqlStarter
13478 info.ragozin.solr.SolrStarter
13535 com.community.SiteApplication
SJK так же имеет аналогичную команду.
6
в директории LABDIR/blf-demo выполним команду
java -jar sjk.jar jps
13793 info.ragozin.loadgen.LoadGenStarter
13444 info.ragozin.hsql.HsqlStarter
13478 info.ragozin.solr.SolrStarter
13929 sjk.jar jps
13948 org.gridkit.jvmtool.SJK jps
13535 com.community.SiteApplication
7
затем
java -jar sjk.jar jps -pd PID MAIN XMaxHeapSize
13793 LoadGenStarter -XX:MaxHeapSize=4120903680
13444 HsqlStarter -XX:MaxHeapSize=314572800
13478 SolrStarter -XX:MaxHeapSize=314572800
14027 sjk.jar -XX:MaxHeapSize=4120903680
14046 SJK
13535 SiteApplication -XX:MaxHeapSize=536870912
данная команда успользует кастомизированный формат вывода, включающий размер Java кучи для каждного процесса.
8
подробную информацию об опциях данной команды можно получить из встроенной справки
java -jar sjk.jar jps --help
Вернёмся к jcmd и посмотрим на её возможности
9
выполним команду
jcmd
нас интересует PID Spring приложения SiteApplication
14081 jdk.jcmd/sun.tools.jcmd.JCmd
13793 info.ragozin.loadgen.LoadGenStarter
13444 info.ragozin.hsql.HsqlStarter
13478 info.ragozin.solr.SolrStarter
13535 com.community.SiteApplication
10
затем выполним
jcmd $PID help
The following commands are available:
Compiler.CodeHeap_Analytics
Compiler.codecache
Compiler.codelist
Compiler.directives_add
Compiler.directives_clear
Compiler.directives_print
Compiler.directives_remove
Compiler.perfmap
Compiler.queue
GC.class_histogram
GC.finalizer_info
GC.heap_dump
GC.heap_info
GC.run
GC.run_finalization
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
JVMTI.agent_load
JVMTI.data_dump
ManagementAgent.start
ManagementAgent.start_local
ManagementAgent.status
ManagementAgent.stop
System.trim_native_heap
Thread.print
VM.cds
VM.class_hierarchy
VM.classloader_stats
VM.classloaders
VM.command_line
VM.dynlibs
VM.events
VM.flags
VM.info
VM.log
VM.metaspace
VM.native_memory
VM.print_touched_methods
VM.set_flag
VM.stringtable
VM.symboltable
VM.system_properties
VM.systemdictionary
VM.uptime
VM.version
help
список комманд может отличаться для различных версий JVM.
Информация о потоках JVM
Дамп потоков может нам помочь оцениться состояние приложения
11
в директории LABDIR/blf-demo выполним команду
jcmd $PID Thread.print
12
Комады jcmd могут принимать дополнительные парамерты.
Выполните команду
jcmd $PID help Thread.print
Thread.print
Print all threads with stacktraces.
Impact: Medium: Depends on the number of threads.
Permission: java.lang.management.ManagementPermission(monitor)
Syntax : Thread.print [options]
Options: (options must be specified using the <key> or <key>=<value> syntax)
-l : [optional] print java.util.concurrent locks (BOOLEAN, false)
-e : [optional] print extended thread information (BOOLEAN, false)
13
Aналогично можно использовать команду jstack
jstack $PID
Команда SJK ttop позволяет получить "top" по потокам в java процесса.
14
выполним команду
java -jar sjk.jar ttop -p $PID
Restarting java with unlocked package access
Monitoring threads ...
2024-01-23T14:25:27.582+0300 Process summary
process cpu=274.22%
application cpu=134.08% (user=121.50% sys=12.58%)
other: cpu=140.14%
thread count: 88
heap allocation rate 76mb/s
[000096] user= 8.65% sys= 0.81% alloc= 6090kb/s - http-nio-8080-exec-16
[000091] user= 8.23% sys= 1.20% alloc= 5850kb/s - http-nio-8080-exec-11
[000097] user= 8.23% sys= 0.78% alloc= 5638kb/s - http-nio-8080-exec-17
[000094] user= 7.17% sys= 0.69% alloc= 4721kb/s - http-nio-8080-exec-14
[000092] user= 7.17% sys= 0.51% alloc= 4328kb/s - http-nio-8080-exec-12
[000081] user= 6.96% sys= 0.56% alloc= 4706kb/s - http-nio-8080-exec-7
[000076] user= 6.54% sys= 0.84% alloc= 4101kb/s - http-nio-8080-exec-2
[000082] user= 6.96% sys= 0.41% alloc= 4023kb/s - http-nio-8080-exec-8
[000095] user= 6.54% sys= 0.32% alloc= 3878kb/s - http-nio-8080-exec-15
[000079] user= 6.12% sys= 0.65% alloc= 4136kb/s - http-nio-8080-exec-5
[000084] user= 5.91% sys= 0.78% alloc= 3906kb/s - http-nio-8080-exec-10
[000075] user= 6.33% sys= 0.33% alloc= 3897kb/s - http-nio-8080-exec-1
[000078] user= 5.27% sys= 0.81% alloc= 3652kb/s - http-nio-8080-exec-4
[000080] user= 5.48% sys= 0.37% alloc= 3233kb/s - http-nio-8080-exec-6
[000083] user= 5.06% sys= 0.27% alloc= 3135kb/s - http-nio-8080-exec-9
[000077] user= 4.01% sys= 0.85% alloc= 2609kb/s - http-nio-8080-exec-3
[000098] user= 4.43% sys= 0.33% alloc= 2854kb/s - http-nio-8080-exec-18
[000024] user= 3.38% sys= 0.76% alloc= 2775kb/s - bl%004frder%0045lements.data
[000093] user= 3.16% sys= 0.42% alloc= 2023kb/s - http-nio-8080-exec-13
[000101] user= 2.32% sys= 0.17% alloc= 614kb/s - RMI TCP Connection(1)-127.0.0.1
для продолжения работы нужно остановть процесс (например Ctrl-C).
Работа с JFR из командой строки
JFR - профайлер встроеный в OpenJDK. Воспользуется его возможностями из коммандной строки
15
выполним команду
jcmd $PID JFR.configure stackdepth=512
Stack depth: 512
данная комманда нужна чтобы полностью получать стэк-трейсы потоков нашего приложения
16
затем выполним
jcmd $PID JFR.start settings=profile filename=dump1.jfr duration=30s
Started recording 1. The result will be written to:
/home/boss/gigs/java-training/blf-demo/var/storefront/dump1.jfr
17
спустя 30 секунд проверим, что снятие дампа завершено
jcmd $PID JFR.check
No available recordings.
Use jcmd 13535 JFR.start to start a recording.
обратите внимание, путь к файлу дампа определяется относитель директории запуска java процесса
OpenJDK включает консолный инструмент для работы с файлами дампов - jfr
18
выполним команду
jfr
Tool for working with Flight Recorder files
Before using this tool, you must have a recording file.
A file can be created by starting a recording from command line:
java -XX:StartFlightRecording:filename=recording.jfr,duration=30s ...
A recording can also be started on already running Java Virtual Machine:
jcmd (to list available pids)
jcmd <pid> JFR.start
Recording data can be dumped to file using the JFR.dump command:
jcmd <pid> JFR.dump filename=recording.jfr
The contents of the recording can then be printed, for example:
jfr print recording.jfr
jfr print --events CPULoad,GarbageCollection recording.jfr
jfr print --json --events CPULoad recording.jfr
jfr print --categories 'GC,JVM,Java*' recording.jfr
jfr print --events 'jdk.*' --stack-depth 64 recording.jfr
jfr summary recording.jfr
jfr metadata recording.jfr
jfr metadata --categories GC,Detailed
For more information about available commands, use 'jfr help'
19
затем
jfr summary var/storefront/dump1.jfr
Version: 2.1
Chunks: 3
Start: 2024-01-23 11:27:51 (UTC)
Duration: 30 s
Event Type Count Size (bytes)
==================================================================
jdk.ObjectAllocationSample 8720 143514
jdk.GCPhaseParallel 6860 178915
jdk.SocketRead 5786 262037
jdk.ModuleExport 5667 61827
jdk.ClassLoaderStatistics 4943 127804
jdk.ThreadPark 2237 83619
jdk.PromoteObjectInNewPLAB 2154 39989
jdk.ExecutionSample 1861 23360
jdk.BooleanFlag 1602 48993
jdk.NativeMethodSample 1315 16371
jdk.ActiveSetting 1040 34948
jdk.JavaMonitorWait 612 17926
jdk.LongFlag 594 19740
jdk.ThreadAllocationStatistics 569 6599
jdk.SocketWrite 518 21899
jdk.ModuleRequire 459 4590
jdk.UnsignedLongFlag 435 14853
jdk.CheckPoint 420 39858380
jdk.SystemProcess 372 78649
jdk.TenuringDistribution 270 3499
jdk.ThreadCPULoad 152 2593
jdk.NativeLibrary 150 10836
jdk.InitialSecurityProperty 138 10981
jdk.InitialEnvironmentVariable 129 10947
jdk.JavaMonitorEnter 120 3038
jdk.StringFlag 87 2658
jdk.MetaspaceChunkFreeListSummary 72 1440
jdk.GCReferenceStatistics 72 864
jdk.GCPhasePauseLevel1 72 3049
jdk.ThreadSleep 60 1098
jdk.PromoteObjectOutsidePLAB 59 1030
jdk.Compilation 55 1701
jdk.SafepointBegin 51 837
jdk.ExecuteVMOperation 51 927
jdk.InitialSystemProperty 45 57414
jdk.GCHeapSummary 36 1440
jdk.MetaspaceSummary 36 1908
jdk.G1HeapSummary 36 846
jdk.GCPhasePauseLevel2 35 1426
jdk.DoubleFlag 33 1329
jdk.CPULoad 29 580
jdk.JavaThreadStatistics 29 348
jdk.ClassLoadingStatistics 29 348
jdk.CompilerStatistics 29 957
jdk.ExceptionStatistics 29 463
jdk.GarbageCollection 18 432
jdk.YoungGarbageCollection 18 270
jdk.G1GarbageCollection 18 270
jdk.G1MMU 18 270
jdk.EvacuationInformation 18 522
jdk.G1EvacuationYoungStatistics 18 482
jdk.G1EvacuationOldStatistics 18 374
jdk.G1BasicIHOP 18 735
jdk.G1AdaptiveIHOP 18 738
jdk.GCPhasePause 18 450
jdk.CodeCacheStatistics 18 600
jdk.IntFlag 18 672
jdk.UnsignedIntFlag 18 618
jdk.NetworkUtilization 10 145
jdk.OldObjectSample 7 231
jdk.PhysicalMemory 6 108
jdk.CodeSweeperStatistics 6 156
jdk.GCConfiguration 6 156
jdk.DirectBufferStatistics 6 156
jdk.Deoptimization 4 108
jdk.Metadata 3 288780
jdk.ContainerConfiguration 3 218
jdk.JVMInformation 3 1281
jdk.OSInformation 3 708
jdk.VirtualizationInformation 3 108
jdk.CPUInformation 3 5088
jdk.CPUTimeStampCounter 3 60
jdk.ThreadContextSwitchRate 3 36
jdk.SymbolTableStatistics 3 117
jdk.StringTableStatistics 3 117
jdk.PlaceholderTableStatistics 3 102
jdk.LoaderConstraintsTableStatistics 3 102
jdk.ProtectionDomainCacheTableStatistics 3 102
jdk.CompilerConfiguration 3 30
jdk.CodeCacheConfiguration 3 138
jdk.CodeSweeperConfiguration 3 39
jdk.GCSurvivorConfiguration 3 33
jdk.GCTLABConfiguration 3 39
jdk.GCHeapConfiguration 3 78
jdk.YoungGenerationConfiguration 3 54
jdk.ActiveRecording 3 193
jdk.FileRead 2 111
jdk.ThreadStart 1 15
jdk.ContainerCPUUsage 1 27
jdk.ContainerCPUThrottling 1 17
jdk.ContainerMemoryUsage 1 25
jdk.ContainerIOUsage 1 22
jdk.ThreadEnd 0 0
jdk.JavaMonitorInflate 0 0
jdk.SyncOnValueBasedClass 0 0
jdk.BiasedLockRevocation 0 0
jdk.BiasedLockSelfRevocation 0 0
jdk.BiasedLockClassRevocation 0 0
jdk.ReservedStackActivation 0 0
jdk.ClassLoad 0 0
jdk.ClassDefine 0 0
jdk.ClassRedefinition 0 0
jdk.RedefineClasses 0 0
jdk.RetransformClasses 0 0
jdk.ClassUnload 0 0
jdk.IntFlagChanged 0 0
jdk.UnsignedIntFlagChanged 0 0
jdk.LongFlagChanged 0 0
jdk.UnsignedLongFlagChanged 0 0
jdk.DoubleFlagChanged 0 0
jdk.BooleanFlagChanged 0 0
jdk.StringFlagChanged 0 0
jdk.MetaspaceGCThreshold 0 0
jdk.MetaspaceAllocationFailure 0 0
jdk.MetaspaceOOM 0 0
jdk.PSHeapSummary 0 0
jdk.SystemGC 0 0
jdk.ParallelOldGarbageCollection 0 0
jdk.OldGarbageCollection 0 0
jdk.ObjectCountAfterGC 0 0
jdk.PromotionFailed 0 0
jdk.EvacuationFailed 0 0
jdk.ConcurrentModeFailure 0 0
jdk.GCPhasePauseLevel3 0 0
jdk.GCPhasePauseLevel4 0 0
jdk.GCPhaseConcurrent 0 0
jdk.GCPhaseConcurrentLevel1 0 0
jdk.AllocationRequiringGC 0 0
jdk.G1HeapRegionTypeChange 0 0
jdk.JITRestart 0 0
jdk.CompilerPhase 0 0
jdk.CompilationFailure 0 0
jdk.CompilerInlining 0 0
jdk.SweepCodeCache 0 0
jdk.CodeCacheFull 0 0
jdk.SafepointStateSynchronization 0 0
jdk.SafepointCleanup 0 0
jdk.SafepointCleanupTask 0 0
jdk.SafepointEnd 0 0
jdk.Shutdown 0 0
jdk.ObjectAllocationInNewTLAB 0 0
jdk.ObjectAllocationOutsideTLAB 0 0
jdk.DumpReason 0 0
jdk.SecurityProviderService 0 0
jdk.DataLoss 0 0
jdk.ThreadDump 0 0
jdk.ObjectCount 0 0
jdk.G1HeapRegionInformation 0 0
jdk.ZAllocationStall 0 0
jdk.ZPageAllocation 0 0
jdk.ZRelocationSet 0 0
jdk.ZRelocationSetGroup 0 0
jdk.ZStatisticsCounter 0 0
jdk.ZStatisticsSampler 0 0
jdk.ZThreadPhase 0 0
jdk.ZUncommit 0 0
jdk.ZUnmap 0 0
jdk.ShenandoahHeapRegionStateChange 0 0
jdk.ShenandoahHeapRegionInformation 0 0
jdk.Flush 0 0
jdk.HeapDump 0 0
jdk.GCLocker 0 0
jdk.Deserialization 0 0
jdk.FileForce 0 0
jdk.FileWrite 0 0
jdk.JavaExceptionThrow 0 0
jdk.JavaErrorThrow 0 0
jdk.ProcessStart 0 0
jdk.SecurityPropertyModification 0 0
jdk.TLSHandshake 0 0
jdk.X509Validation 0 0
jdk.X509Certificate 0 0
20
затем
jfr print --events MethodSample,NativeMethodSample var/storefront/dump1.jfr
jdk.NativeMethodSample {
startTime = 14:28:18.821
sampledThread = "ProcessWatchDog" (javaThreadId = 13)
state = "STATE_RUNNABLE"
stackTrace = [
sun.nio.ch.Net.poll(FileDescriptor, int, long)
sun.nio.ch.NioSocketImpl.park(FileDescriptor, int, long) line: 186
sun.nio.ch.NioSocketImpl.timedAccept(FileDescriptor, FileDescriptor, InetSocketAddress[], long) line: 715
sun.nio.ch.NioSocketImpl.accept(SocketImpl) line: 757
java.net.ServerSocket.implAccept(SocketImpl) line: 675
...
]
}
jdk.NativeMethodSample {
startTime = 14:28:18.842
sampledThread = "NioBlockingSelector.BlockPoller-1" (javaThreadId = 59)
state = "STATE_RUNNABLE"
stackTrace = [
sun.nio.ch.EPoll.wait(int, long, int, int)
sun.nio.ch.EPollSelectorImpl.doSelect(Consumer, long) line: 118
sun.nio.ch.SelectorImpl.lockAndDoSelect(Consumer, long) line: 129
sun.nio.ch.SelectorImpl.select(long) line: 141
org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run() line: 339
...
]
}
jdk.NativeMethodSample {
startTime = 14:28:18.866
sampledThread = "https-jsse-nio-8443-ClientPoller-0" (javaThreadId = 70)
state = "STATE_RUNNABLE"
stackTrace = [
sun.nio.ch.EPoll.wait(int, long, int, int)
sun.nio.ch.EPollSelectorImpl.doSelect(Consumer, long) line: 118
sun.nio.ch.SelectorImpl.lockAndDoSelect(Consumer, long) line: 129
sun.nio.ch.SelectorImpl.select(long) line: 141
org.apache.tomcat.util.net.NioEndpoint$Poller.run() line: 785
...
]
}
jdk.NativeMethodSample {
startTime = 14:28:18.886
sampledThread = "https-jsse-nio-8443-ClientPoller-1" (javaThreadId = 71)
state = "STATE_RUNNABLE"
stackTrace = [
sun.nio.ch.EPoll.wait(int, long, int, int)
sun.nio.ch.EPollSelectorImpl.doSelect(Consumer, long) line: 118
sun.nio.ch.SelectorImpl.lockAndDoSelect(Consumer, long) line: 129
sun.nio.ch.SelectorImpl.select(long) line: 141
org.apache.tomcat.util.net.NioEndpoint$Poller.run() line: 785
...
]
}
...
jfr так позволяет экспортировать данные в формате JSON
SJK позволяет строить отчёты по данным из различных источников, включая JFR
21
выполним команду
java -jar sjk.jar flame -f var/storefront/dump1.jfr -o dump1.html
откройте файл dump1.html, файл может открываться несколько секунд
Возможна так же генерация SVG формата.
SJK может осуществлять сбор сэмплсетов на прямую, без использования JFR или других инструментов.
22
выполним команду
java -jar sjk.jar stcap -p $PID -o dump2.sjk
Restarting java with unlocked package access
Writing to /home/boss/gigs/java-training/blf-demo/dump2.sjk
Collected 521
Collected 1043
Collected 1565
Collected 2000
Collected 2522
Collected 3044
Collected 3566
Collected 4001
Collected 4523
Collected 5045
Collected 5567
Collected 6002
Collected 6524
Collected 7046
Collected 7568
Collected 8003
Collected 8525
Collected 9047
Collected 9569
Collected 10004
Collected 10526
Collected 11048
Collected 11570
Collected 12005
Collected 12527
Collected 13049
Collected 13571
Collected 14006
Collected 14528
Collected 15050
Collected 15572
Collected 16007
Collected 16529
Collected 17051
Collected 17573
Collected 18008
Collected 18530
Collected 19052
Collected 19574
Collected 20009
Collected 20531
Collected 21053
Collected 21575
Collected 22010
Collected 22532
Collected 23054
Collected 23576
Collected 24011
Collected 24533
Collected 25055
Collected 25577
Collected 26012
Collected 26534
Collected 27056
Collected 27578
Collected 28013
Collected 28535
Collected 29057
Collected 29579
Collected 30014
Collected 30536
Collected 31058
Collected 31580
Collected 32015
Collected 32537
Collected 33059
Collected 33581
Collected 34016
Collected 34538
Collected 35060
Collected 35582
Collected 36017
Collected 36539
Collected 37061
Collected 37583
Collected 38018
Collected 38540
Collected 39062
Collected 39584
Collected 40019
Collected 40541
Collected 41063
Collected 41585
Trace dumped: 41933
23
а после её окончания
java -jar sjk.jar flame -f dump2.sjk -o dump2.html
откройте файл dump2.html, файл может открываться несколько секунд
Возможна так же генерация SVG формата.
Метод сэмплирования SJK отличается от JFR и результаты могут быть слегка дригие.
Работа с MBean`ами
OpenJDK включает в свой состав инструмент jconsole, который позволяет посмотреть дерево MBean`ов JVM.
24
запустим jconsole в терминале B
jconsole
выберите процесс ... из списка и подключитесь
SJK позволяет сделать полный дамп дерева MBean`ов в JSON формате.
25
выполним команду
java -jar sjk.jar mxdump -p $PID > mbeans.json
файл mbeans.json содержит информацию по всем MBean`ам опубликованным JVM
SJK так позволяет читать данные отдельных MBean`ов и их атрибутов.
26
выполним команду
java -jar sjk.jar mx -p $PID -mg -b '**:*,type=MemoryPool' -f Usage -all
Restarting java with unlocked package access
java.lang:name=Metaspace,type=MemoryPool
Usage
committed: 110034944
init: 0
max: -1
used: 109092768
java.lang:name=CodeHeap 'non-nmethods',type=MemoryPool
Usage
committed: 2555904
init: 2555904
max: 5836800
used: 1449088
java.lang:name=CodeHeap 'profiled nmethods',type=MemoryPool
Usage
committed: 64552960
init: 2555904
max: 122908672
used: 18529664
java.lang:name=Compressed Class Space,type=MemoryPool
Usage
committed: 12255232
init: 0
max: 1073741824
used: 11693656
java.lang:name=G1 Eden Space,type=MemoryPool
Usage
committed: 138412032
init: 14680064
max: -1
used: 10485760
java.lang:name=G1 Old Gen,type=MemoryPool
Usage
committed: 267386880
init: 243269632
max: 536870912
used: 220839424
java.lang:name=G1 Survivor Space,type=MemoryPool
Usage
committed: 7340032
init: 0
max: -1
used: 7317624
java.lang:name=CodeHeap 'non-profiled nmethods',type=MemoryPool
Usage
committed: 42467328
init: 2555904
max: 122912768
used: 42174720
27
затем
java -jar sjk.jar mx -p $PID -mg -b '**:*,type=MemoryPool' -f Usage -all --csv --add-mbean-name
Restarting java with unlocked package access
MBean,Attribute,committed,init,max,used
"java.lang:name=Metaspace,type=MemoryPool",Usage,110100480,0,-1,109114976
"java.lang:name=CodeHeap 'non-nmethods',type=MemoryPool",Usage,2555904,2555904,5836800,1449088
"java.lang:name=CodeHeap 'profiled nmethods',type=MemoryPool",Usage,64552960,2555904,122908672,18591744
"java.lang:name=Compressed Class Space,type=MemoryPool",Usage,12255232,0,1073741824,11694176
"java.lang:name=G1 Eden Space,type=MemoryPool",Usage,123731968,14680064,-1,114294784
"java.lang:name=G1 Old Gen,type=MemoryPool",Usage,281018368,243269632,536870912,233039360
"java.lang:name=G1 Survivor Space,type=MemoryPool",Usage,8388608,0,-1,8064976
"java.lang:name=CodeHeap 'non-profiled nmethods',type=MemoryPool",Usage,42467328,2555904,122912768,42078208
28
затем
java -jar sjk.jar mx -p $PID -mg -b '**:*,type=MemoryPool' -f Usage -all --json-array
Restarting java with unlocked package access
[
{"Usage": {"committed": 110100480, "init": 0, "max": -1, "used": 109127736}},
{"Usage": {"committed": 2555904, "init": 2555904, "max": 5836800, "used": 1449088}},
{"Usage": {"committed": 64552960, "init": 2555904, "max": 122908672, "used": 18751616}},
{"Usage": {"committed": 12255232, "init": 0, "max": 1073741824, "used": 11694176}},
{"Usage": {"committed": 119537664, "init": 14680064, "max": -1, "used": 49283072}},
{"Usage": {"committed": 285212672, "init": 243269632, "max": 536870912, "used": 238071296}},
{"Usage": {"committed": 8388608, "init": 0, "max": -1, "used": 7729496}},
{"Usage": {"committed": 42467328, "init": 2555904, "max": 122912768, "used": 42163328}}
]
мы получили аттрибьют "Usage" с MBean`ов отвечающих на пулы памяти JVM, в различных форматах.
SJK так позволяет менят значение атрибьютов MBean`ов, для которых, такая операция доступна.
29
выполним команду
java -jar sjk.jar mx -p $PID -mg -b '**:*,type=Connector,port=8080' -all -f maxThreads
Restarting java with unlocked package access
Tomcat:type=Connector,port=8080
maxThreads 200
30
зафиксируем текущее значение, затем выполним
java -jar sjk.jar mx -p $PID -ms -b '**:*,type=Connector,port=8080' -f maxThreads -v 100
Restarting java with unlocked package access
Tomcat:type=Connector,port=8080
31
затем
java -jar sjk.jar mx -p $PID -mg -b '**:*,type=Connector,port=8080' -all -f maxThreads
Restarting java with unlocked package access
Tomcat:type=Connector,port=8080
maxThreads 100
мы можем убедиться, что значение аттрибьюта было изменено.
Дамп памяти и гистограмы классов
Иногда для диагностики, нам необходимо проанализировать память Java процесса.
Дамп памяти JVM можно получить с помощью комманды jcmd или jmap
32
выполним команду
jcmd $PID help GC.heap_dump
GC.heap_dump
Generate a HPROF format dump of the Java heap.
Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified.
Permission: java.lang.management.ManagementPermission(monitor)
Syntax : GC.heap_dump [options] <filename>
Arguments:
filename : Name of the dump file (STRING, no default value)
Options: (options must be specified using the <key> or <key>=<value> syntax)
-all : [optional] Dump all objects, including unreachable objects (BOOLEAN, false)
-gz : [optional] If specified, the heap dump is written in gzipped format using the given compression level. 1 (recommended) is the fastest, 9 the strongest compression. (INT, 1)
-overwrite : [optional] If specified, the dump file will be overwritten if it exists (BOOLEAN, false)
33
затем
jcmd $PID GC.heap_dump -all -gz=1 -overwrite appdump.hprof.gz
Dumping heap to appdump.hprof.gz ...
Heap dump file created [71822848 bytes in 2.017 secs]
Файл записывается относительно директории запуска приложения. В наше случае var/storefront.
Для работы с дампом нужны дополнительные инструменты. Иногда бывает полезно взглянуть на гистограму классов.
34
выполним команду
jcmd $PID help GC.class_histogram
GC.class_histogram
Provide statistics about the Java heap usage.
Impact: High: Depends on Java heap size and content.
Permission: java.lang.management.ManagementPermission(monitor)
Syntax : GC.class_histogram [options]
Options: (options must be specified using the <key> or <key>=<value> syntax)
-all : [optional] Inspect all objects, including unreachable objects (BOOLEAN, false)
-parallel : [optional] Number of parallel threads to use for heap inspection. 0 (the default) means let the VM determine the number of threads to use. 1 means use one thread (disable parallelism). For any other value the VM will try to use the specified number of threads, but might use fewer. (INT, 0)
35
затем
jcmd $PID GC.class_histogram
num #instances #bytes class name (module)
-------------------------------------------------------
1: 264074 25506808 [B (java.base@17.0.9)
2: 193454 6190528 java.util.HashMap$Node (java.base@17.0.9)
3: 253077 6073848 java.lang.String (java.base@17.0.9)
4: 68005 5984440 java.lang.reflect.Method (java.base@17.0.9)
5: 110832 4433280 java.util.LinkedHashMap$Entry (java.base@17.0.9)
6: 43121 4088248 [Ljava.util.HashMap$Node; (java.base@17.0.9)
7: 91774 3670960 java.util.TreeMap$Entry (java.base@17.0.9)
8: 102365 3275680 java.util.concurrent.ConcurrentHashMap$Node (java.base@17.0.9)
9: 58198 2659944 [Ljava.lang.Object; (java.base@17.0.9)
10: 99245 2362368 [Ljava.lang.String; (java.base@17.0.9)
11: 19213 2308736 java.lang.Class (java.base@17.0.9)
12: 40132 2247392 java.util.LinkedHashMap (java.base@17.0.9)
13: 24172 1933760 net.sf.ehcache.Element
14: 6155 1905000 [C (java.base@17.0.9)
15: 15930 1653504 [I (java.base@17.0.9)
16: 59308 1423392 java.lang.Long (java.base@17.0.9)
17: 28326 1359648 java.util.TreeMap (java.base@17.0.9)
18: 1537 1293040 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@17.0.9)
19: 26725 1282800 java.util.HashMap (java.base@17.0.9)
20: 20637 1155672 net.sf.ehcache.store.disk.DiskStorageFactory$DiskMarker
21: 20147 807880 [Ljava.io.Serializable; (java.base@17.0.9)
22: 33376 801024 java.util.ArrayList (java.base@17.0.9)
23: 36088 765776 [Ljava.lang.Class; (java.base@17.0.9)
24: 22100 707200 net.sf.ehcache.util.concurrent.ConcurrentHashMap$Node
25: 21714 694848 java.util.Hashtable$Entry (java.base@17.0.9)
26: 42902 686432 java.lang.Object (java.base@17.0.9)
27: 28287 678888 org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource$DefaultCacheKey
28: 28084 674016 javax.management.openmbean.CompositeDataSupport (java.management@17.0.9)
29: 20638 660416 net.sf.ehcache.store.disk.HashEntry
30: 20478 655296 org.hibernate.cache.spi.CacheKey
31: 8483 610776 java.lang.reflect.Field (java.base@17.0.9)
32: 18425 589600 antlr.ANTLRHashString
33: 29538 472608 java.lang.Integer (java.base@17.0.9)
34: 28106 449696 java.util.TreeMap$KeySet (java.base@17.0.9)
35: 18469 443256 org.springframework.core.MethodClassKey
36: 12678 405696 java.lang.ref.WeakReference (java.base@17.0.9)
37: 7975 398592 [[Ljava.lang.String; (java.base@17.0.9)
38: 7924 380352 net.sf.ehcache.store.disk.ods.Region
39: 9465 378600 java.lang.ref.SoftReference (java.base@17.0.9)
40: 7789 373872 org.hibernate.hql.internal.ast.tree.Node
41: 11481 367392 java.util.LinkedList (java.base@17.0.9)
42: 3729 357984 org.springframework.beans.GenericTypeAwarePropertyDescriptor
43: 5352 342528 java.util.concurrent.ConcurrentHashMap (java.base@17.0.9)
44: 14093 338232 java.util.Collections$UnmodifiableRandomAccessList (java.base@17.0.9)
45: 4672 336384 java.lang.reflect.Constructor (java.base@17.0.9)
46: 20825 333200 java.util.concurrent.atomic.AtomicBoolean (java.base@17.0.9)
47: 13733 329592 java.util.Arrays$ArrayList (java.base@17.0.9)
48: 6087 292176 java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync (java.base@17.0.9)
49: 7047 281880 org.terracotta.statistics.archive.StatisticSampler
50: 1280 243584 [Lnet.sf.ehcache.store.disk.HashEntry;
51: 4277 239512 org.hibernate.cache.spi.QueryKey
52: 7304 233728 org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item
53: 9737 233688 java.beans.MethodRef (java.desktop@17.0.9)
54: 9564 229536 org.hibernate.engine.spi.TypedValue
55: 7081 226592 org.hibernate.cache.spi.entry.CacheEntry
56: 5491 219640 org.hibernate.loader.DefaultEntityAliases
57: 13455 215280 java.util.LinkedHashSet (java.base@17.0.9)
58: 7946 213200 [Z (java.base@17.0.9)
59: 8711 209064 sun.reflect.annotation.AnnotationInvocationHandler (java.base@17.0.9)
60: 13060 208960 org.hibernate.cache.spi.entry.CollectionCacheEntry
61: 4264 204672 org.hibernate.cfg.annotations.reflection.JPAOverriddenAnnotationReader
62: 226 179856 [J (java.base@17.0.9)
63: 7402 177648 java.util.concurrent.CopyOnWriteArrayList (java.base@17.0.9)
64: 7047 169128 net.sf.ehcache.statistics.extended.SampledStatistic
65: 7047 169128 org.terracotta.statistics.archive.StatisticArchive
66: 7047 169128 org.terracotta.statistics.archive.StatisticSampler$SamplingTask
67: 2988 167328 org.thymeleaf.engine.Text
68: 2944 164864 net.sf.ehcache.store.chm.SelectableConcurrentHashMap$Segment
69: 965 164080 [Ljava.util.Hashtable$Entry; (java.base@17.0.9)
70: 1015 162400 org.springframework.beans.factory.support.RootBeanDefinition
71: 2475 158400 org.springframework.core.annotation.AnnotationAttributes
72: 4942 158144 org.hibernate.annotations.common.reflection.java.JavaXSimpleType
73: 1620 155520 org.hibernate.loader.entity.EntityLoader
74: 3804 152160 java.math.BigInteger (java.base@17.0.9)
75: 2371 151744 org.springframework.core.MethodParameter
76: 3118 149664 org.hibernate.engine.spi.CollectionEntry
77: 2982 143136 org.thymeleaf.engine.Attribute
78: 3535 141400 net.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry
79: 2488 139328 org.hibernate.collection.internal.PersistentBag
80: 4277 136864 org.hibernate.transform.CacheableResultTransformer
81: 4259 136288 org.terracotta.statistics.jsr166e.LongAdder
82: 3340 133600 com.sun.beans.util.Cache$Kind$Soft (java.desktop@17.0.9)
83: 4168 133376 java.util.RegularEnumSet (java.base@17.0.9)
84: 5404 129696 org.hibernate.annotations.common.reflection.java.JavaReflectionManager$MemberKey
85: 5335 128040 java.util.LinkedList$Node (java.base@17.0.9)
86: 3105 124200 org.hibernate.engine.spi.CollectionKey
87: 5061 121464 java.util.Date (java.base@17.0.9)
88: 2980 119200 java.math.BigDecimal (java.base@17.0.9)
89: 4960 119040 sun.reflect.generics.tree.SimpleClassTypeSignature (java.base@17.0.9)
90: 7272 116352 java.util.LinkedHashMap$LinkedKeySet (java.base@17.0.9)
...
7990: 1 16 sun.security.ssl.ServerHello$T13HelloRetryRequestProducer (java.base@17.0.9)
7991: 1 16 sun.security.ssl.ServerHello$T13HelloRetryRequestReproducer (java.base@17.0.9)
7992: 1 16 sun.security.ssl.ServerHello$T13ServerHelloProducer (java.base@17.0.9)
7993: 1 16 sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer (java.base@17.0.9)
7994: 1 16 sun.security.ssl.ServerHelloDone$ServerHelloDoneProducer (java.base@17.0.9)
7995: 1 16 sun.security.ssl.ServerKeyExchange$ServerKeyExchangeConsumer (java.base@17.0.9)
7996: 1 16 sun.security.ssl.ServerKeyExchange$ServerKeyExchangeProducer (java.base@17.0.9)
7997: 1 16 sun.security.util.ByteArrayLexOrder (java.base@17.0.9)
7998: 1 16 sun.security.util.ByteArrayTagOrder (java.base@17.0.9)
7999: 1 16 sun.security.util.KeyStoreDelegator$$Lambda$141/0x00007fbd40853c60 (java.base@17.0.9)
8000: 1 16 sun.util.calendar.Gregorian (java.base@17.0.9)
8001: 1 16 sun.util.calendar.JulianCalendar (java.base@17.0.9)
8002: 1 16 sun.util.cldr.CLDRBaseLocaleDataMetaInfo (java.base@17.0.9)
8003: 1 16 sun.util.cldr.CLDRLocaleProviderAdapter$$Lambda$57/0x80000005e (java.base@17.0.9)
8004: 1 16 sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar (java.base@17.0.9)
8005: 1 16 sun.util.locale.provider.CalendarDataUtility$CalendarFieldValueNamesMapGetter (java.base@17.0.9)
8006: 1 16 sun.util.locale.provider.CalendarDataUtility$CalendarWeekParameterGetter (java.base@17.0.9)
8007: 1 16 sun.util.locale.provider.CalendarNameProviderImpl$LengthBasedComparator (java.base@17.0.9)
8008: 1 16 sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter (java.base@17.0.9)
8009: 1 16 sun.util.logging.PlatformLogger (java.base@17.0.9)
8010: 1 16 sun.util.logging.internal.LoggingProviderImpl (java.logging@17.0.9)
8011: 1 16 sun.util.resources.LocaleData$LocaleDataStrategy (java.base@17.0.9)
8012: 1 16 sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo (jdk.localedata@17.0.9)
Total 2697492 116703832
SJK позволяет получить дополнительны типы гистограм классов, например гистограмму "мёртвых" объектов.
36
выполним команду
java -jar sjk.jar hh --dead -n 100 -p $PID
# Instances Bytes Type
1: 60664 2426560 org.hsqldb.ColumnBase
2: 40896 1963008 org.springframework.core.ResolvableType
3: 5249 1436584 [Lorg.thymeleaf.engine.IEngineTemplateEvent;
4: 21247 1189832 org.hsqldb.types.CharacterType
5: 21040 1009920 org.thymeleaf.engine.Attribute
6: 17384 973504 org.thymeleaf.engine.Text
7: 19844 952512 org.thymeleaf.engine.OpenElementTag
8: 21775 871000 org.hibernate.engine.spi.CollectionKey
9: 32927 790248 org.springframework.expression.TypedValue
10: 5838 747264 org.hsqldb.result.Result
11: 19715 658944 [Lorg.thymeleaf.processor.element.IElementProcessor;
12: 24316 583584 org.springframework.core.convert.TypeDescriptor
13: 24316 583584 org.springframework.core.convert.TypeDescriptor$AnnotatedElementAdapter
14: 19188 510792 [Lorg.thymeleaf.engine.Attribute;
15: 10545 506160 org.thymeleaf.engine.ElementProcessorIterator
16: 10126 486048 org.hibernate.engine.spi.CollectionEntry
17: 19538 468912 org.thymeleaf.engine.Attributes
18: 8262 462672 org.hibernate.collection.internal.PersistentBag
19: 7214 461696 org.springframework.core.MethodParameter
20: 18829 451896 org.hibernate.internal.util.collections.IdentityMap$IdentityKey
21: 9245 443760 org.hibernate.engine.spi.EntityKey
22: 11076 443040 org.springframework.expression.spel.ExpressionState
23: 5789 416808 org.hibernate.engine.spi.EntityEntry
24: 8623 413904 org.thymeleaf.engine.CloseElementTag
25: 16598 398352 org.springframework.expression.spel.support.ReflectivePropertyAccessor$PropertyCacheKey
26: 4783 382640 net.sf.ehcache.Element
27: 22923 366768 org.springframework.core.ResolvableType$DefaultVariableResolver
28: 11370 363840 org.thymeleaf.cache.ExpressionCacheKey
29: 7298 350304 org.hsqldb.types.NumberType
30: 10545 337440 org.thymeleaf.engine.ProcessorExecutionVars
31: 3407 309368 [Lorg.hsqldb.types.Type;
32: 2635 287744 [Lorg.hsqldb.ColumnBase;
33: 8443 270176 org.hibernate.cache.spi.CacheKey
34: 11152 267648 org.hibernate.internal.util.collections.IdentityMap$IdentityMapEntry
35: 8205 262560 org.springframework.core.SerializableTypeWrapper$MethodParameterTypeProvider
36: 4532 217536 net.sf.ehcache.store.disk.ods.Region
37: 6703 214496 net.sf.ehcache.store.disk.HashEntry
38: 8612 206688 org.hibernate.type.AbstractStandardBasicType$1
39: 8474 203376 org.springframework.expression.spel.support.ReflectivePropertyAccessor$OptimalPropertyAccessor
40: 4177 200496 org.hsqldb.result.ResultMetaData
41: 3465 194040 net.sf.ehcache.store.disk.DiskStorageFactory$DiskMarker
42: 7839 188136 org.hibernate.engine.spi.TypedValue
43: 7656 183744 org.thymeleaf.spring4.expression.SPELContextMapWrapper
44: 5477 175264 net.sf.ehcache.util.concurrent.ConcurrentHashMap$Node
45: 3467 166416 org.thymeleaf.engine.StandaloneElementTag
46: 3982 159280 org.hibernate.event.spi.LoadEvent
47: 4945 158240 org.hibernate.LockOptions
48: 4714 150848 org.hibernate.engine.internal.Cascade
49: 4421 141472 org.thymeleaf.engine.Model
50: 5730 137520 org.springframework.core.SerializableTypeWrapper$2
51: 5657 135768 org.springframework.core.convert.support.GenericConversionService$ConverterCacheKey
52: 5515 132360 net.sf.ehcache.store.CacheStore$4
53: 1489 131032 org.hibernate.engine.spi.QueryParameters
54: 2325 130200 org.hibernate.ejb.criteria.path.SingularAttributePath
55: 3973 127136 org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue
56: 2990 119600 org.hibernate.ejb.criteria.expression.PathTypeExpression
57: 4839 116136 org.hibernate.collection.internal.AbstractPersistentCollection$IteratorProxy
58: 4788 114912 org.broadleafcommerce.common.money.Money
59: 1657 106048 org.hibernate.collection.internal.PersistentMap
60: 774 105264 org.hsqldb.jdbc.JDBCPreparedStatement
61: 1863 104328 org.hsqldb.navigator.RowSetNavigatorClient
62: 2410 96400 org.hibernate.ejb.criteria.expression.LiteralExpression
63: 891 92664 org.hibernate.internal.QueryImpl
64: 3744 89856 org.broadleafcommerce.common.extension.ExtensionResultHolder
65: 1595 89320 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation
66: 2790 89280 org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$2
67: 2761 88352 org.springframework.beans.BeanWrapperImpl$BeanPropertyHandler
68: 2672 85504 net.sf.ehcache.store.cachingtier.OnHeapCachingTier$Fault
69: 3546 85104 org.thymeleaf.standard.expression.ExpressionParsingNode
70: 1725 82800 org.hibernate.ejb.criteria.predicate.ComparisonPredicate
71: 3110 81544 [Lorg.springframework.core.ResolvableType;
72: 2488 79616 org.hibernate.engine.query.spi.QueryPlanCache$HQLQueryPlanKey
73: 3088 74112 org.springframework.aop.framework.AdvisedSupport$MethodCacheKey
74: 2310 73920 org.springframework.expression.spel.ast.MethodReference$MethodValueRef
75: 2305 73760 org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$2
76: 2286 73152 org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1
77: 1139 72896 net.sf.ehcache.util.PreferredLoaderObjectInputStream
78: 1771 70840 org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider
79: 1095 70080 org.thymeleaf.engine.Comment
80: 2124 67968 org.hibernate.event.spi.PostLoadEvent
81: 2777 66648 org.hibernate.ejb.QueryImpl$ParameterImpl
82: 1958 62656 org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item
83: 1490 59600 org.hibernate.event.spi.FlushEntityEvent
84: 530 59360 org.broadleafcommerce.core.catalog.domain.ProductImpl
85: 337 59312 org.broadleafcommerce.core.catalog.domain.CategoryImpl
86: 1825 58400 org.hibernate.cache.spi.entry.CacheEntry
87: 378 57456 org.broadleafcommerce.core.catalog.domain.SkuImpl
88: 1009 56504 org.hibernate.cache.spi.QueryKey
89: 2351 56424 org.hibernate.event.spi.PersistEvent
90: 703 56240 org.hsqldb.jdbc.JDBCResultSet
91: 1386 55440 org.springframework.web.context.request.ServletWebRequest
92: 550 52800 org.thymeleaf.engine.IteratedGatheringModelProcessable
93: 891 49896 org.hibernate.ejb.QueryImpl
94: 306 48960 org.broadleafcommerce.core.order.domain.DiscreteOrderItemImpl
95: 1516 48512 org.thymeleaf.cache.StandardCache$CacheEntry
96: 1177 47080 net.sf.ehcache.store.disk.DiskStorageFactory$Placeholder
97: 1470 47040 org.springframework.expression.spel.standard.Token
98: 2505 45392 [Lorg.hibernate.type.Type;
99: 895 42960 org.springframework.expression.spel.ast.PropertyOrFieldReference
100: 1762 42288 org.springframework.beans.AbstractNestablePropertyAccessor$PropertyTokenHolder
Total 830075 32242064
комманда hh также есть возможность ограничить размер гистограмы.
Завершим работу тестового стенда.
37
Удалите директорию LABDIR/blf-demo/pids (например rm -rf pids).
Остановите jconsole в терминале B.
Проверьте выполняющиеся java процессы с помощью jcmd и остановие процессы демострационного стенда если они попрежнему выполняются.
Работа с контейнером
Запустим демонстрационный стэнд в режиме контейнера.
38
в директории LABDIR/blf-demo выполним команду
mvn -P build_image,run_n_load_docker package
Команда требует значительного времени для запуска окружения. Сборка должна завершиться успешно.
Проверим доступность приложения по ссылке http://127.0.0.1:8080.
Удостоверимся, что контейнер запущен командой docker ps.
Выполним листинг java процессов.
39
выполним команду
jcmd
20807 info.ragozin.hsql.HsqlStarter
20840 info.ragozin.solr.SolrStarter
21355 info.ragozin.loadgen.LoadGenStarter
21468 jdk.jcmd/sun.tools.jcmd.JCmd
в списке отсутсвует процесс прилежения (который сейчас запущен в контейнере).
40
Если у вас Linux, перезапустите jcmd под root
sudo $JAVA_HOME/bin/jcmd
20807 info.ragozin.hsql.HsqlStarter
20840 info.ragozin.solr.SolrStarter
21355 info.ragozin.loadgen.LoadGenStarter
21551 jdk.jcmd/sun.tools.jcmd.JCmd
21039 com.community.SiteApplication
теперь процесс приложения должен быть в списке.
Другие операции jcmd так же доступны с хоста. Например
sudo $JAVA_HOME/bin/jcmd $PID Thread.print
позволяет получить дамп потоков.
Зайдём в контейнер используя консоль B
41
Выполните команду
docker exec -it storefront bash
затем в консоли контейнера
jcmd
145 jdk.jcmd/sun.tools.jcmd.JCmd
1 com.community.SiteApplication
изнутри мы видим 2 процесса jcmd и процесс приложения с PID 1.
Для удалённого доступа диагностического инструментария к процессу в контейнере мы должно открыть порт JMX агента.
42
В консоли контейнера выполните
jcmd 1 ManagementAgent.start jmxremote.authenticate=false jmxremote.ssl=false jmxremote.port=11122 jmxremote.rmi.port=11122
данная команда стартует JMX агент на порте 11122.
Данный порт уже опубликован в комманде запуска контейнера (в Docker порт не может быть опубликован динамически, но в Kubernetes есть комманда port-forward).
В терминале B завершите сессию в контейнере коммнадой exit.
Проверим доступность JMX end point для подключения из вне.
43
выполните комманду
java -jar sjk.jar mxping -s 127.0.0.1:11222
SJK is running on: OpenJDK 64-Bit Server VM 17.0.9+9 (Eclipse Adoptium)
Java home: /home/boss/gigs/java-training/jdk/jdk-17.0.9+9
Try to connect via TLS
Establishing connection to 127.0.0.1:11222
Failed to connect using TLS: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
Try to use plain socket
Establishing connection to 127.0.0.1:11222
Establishing connection to 127.2.2.2:11122
JMX Connection failed: java.rmi.ConnectException: Connection refused to host: 127.2.2.2; nested exception is:
java.net.ConnectException: Connection refused
тестовое соединение не проходит из-за несоответсвия сетевых адресов.
44
повторим комманду с ключём --force-address
java -jar sjk.jar mxping -s 127.0.0.1:11222 --force-address
SJK is running on: OpenJDK 64-Bit Server VM 17.0.9+9 (Eclipse Adoptium)
Java home: /home/boss/gigs/java-training/jdk/jdk-17.0.9+9
Try to connect via TLS
Establishing connection to 127.0.0.1:11222
Failed to connect using TLS: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
Try to use plain socket
Establishing connection to 127.0.0.1:11222
Establishing connection to 127.0.0.1:11222 (overriden from 127.2.2.2:11122)
Establishing connection to 127.0.0.1:11222 (overriden from 127.2.2.2:11122)
Remote VM: OpenJDK 64-Bit Server VM 17.0.9+9 (Eclipse Adoptium)
Теперь тестовое соединение работает, SJK имеет модифицированный JXM стэк для решение подобных проблем.
Команда mprx, доступная в SJK, позволяет запустить локальный прокси для JMX протокола.
45
Выполните команду в консоли B из директории LABDIR/blf-demo
java -jar sjk.jar mprx -s 127.0.0.1:11222 --force-address -b 127.0.0.1:5555
Connected to target JMX endpoint
Open proxy JMX end point on URI - service:jmx:rmi://127.0.0.1:5555/jmxrmi
JMX proxy is running - 127.0.0.1:5555
Interrupt this command to kill proxy
Прокси будет работать пока процесс не будет остановлен.
Проверим работу через прокси.
46
Запустим ttop через прокси.
java -jar sjk.jar ttop -s 127.0.0.1:5555
Monitoring threads ...
2024-01-23T16:10:28.223+0300 Process summary
process cpu=55.50%
application cpu=3.49% (user=2.87% sys=0.62%)
other: cpu=52.00%
thread count: 180
heap allocation rate 1072kb/s
[000200] user= 2.68% sys= 0.56% alloc= 1006kb/s - RMI TCP Connection(11)-172.17.0.1
[000202] user= 0.00% sys= 0.07% alloc= 1249b/s - JMX server connection timeout 202
[000013] user= 0.19% sys=-0.14% alloc= 63kb/s - ProcessWatchDog
[000052] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-7
[000048] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-3
[000085] user= 0.00% sys= 0.01% alloc= 53b/s - http-nio-8080-ClientPoller-0
[000047] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-2
[000055] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-10
[000071] user= 0.00% sys= 0.01% alloc= 64b/s - https-jsse-nio-8443-ClientPoller-1
[000050] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-5
[000059] user= 0.00% sys= 0.01% alloc= 0b/s - NioBlockingSelector.BlockPoller-1
[000053] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-8
[000086] user= 0.00% sys= 0.01% alloc= 53b/s - http-nio-8080-ClientPoller-1
[000056] user= 0.00% sys= 0.01% alloc= 36b/s - rebuildIndexScheduler_QuartzSchedulerThread
[000074] user= 0.00% sys= 0.01% alloc= 0b/s - NioBlockingSelector.BlockPoller-2
[000054] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-9
[000088] user= 0.00% sys= 0.01% alloc= 53b/s - http-nio-8080-AsyncTimeout
[000049] user= 0.00% sys= 0.01% alloc= 0b/s - rebuildIndexScheduler_Worker-4
[000070] user= 0.00% sys= 0.01% alloc= 64b/s - https-jsse-nio-8443-ClientPoller-0
[000043] user= 0.00% sys= 0.01% alloc= 1079b/s - ContainerBackgroundProcessor[StandardEngine[Tomcat]]
Остановите команду после получения результата.
Так же мы можем использовать функционал jcmd через JMX прокси.
47
Зарустите команду
java -jar sjk.jar jcmd -s 127.0.0.1:5555 -c help
The following commands are available:
Compiler.CodeHeap_Analytics
Compiler.codecache
Compiler.codelist
Compiler.directives_add
Compiler.directives_clear
Compiler.directives_print
Compiler.directives_remove
Compiler.perfmap
Compiler.queue
GC.class_histogram
GC.finalizer_info
GC.heap_info
GC.run
GC.run_finalization
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
JVMTI.agent_load
JVMTI.data_dump
System.trim_native_heap
Thread.print
VM.cds
VM.class_hierarchy
VM.classloader_stats
VM.classloaders
VM.command_line
VM.dynlibs
VM.events
VM.flags
VM.info
VM.log
VM.metaspace
VM.native_memory
VM.print_touched_methods
VM.set_flag
VM.stringtable
VM.symboltable
VM.system_properties
VM.systemdictionary
VM.uptime
VM.version
help
48
затем
java -jar sjk.jar jcmd -s 127.0.0.1:5555 -c Thread.print
"http-nio-8080-exec-116" #209 daemon prio=5 os_prio=0 cpu=33.38ms elapsed=124.75s tid=0x00007f197c041320 nid=0xf9 waiting on condition [0x00007f192520e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@17.0.9/Native Method)
- parking to wait for <0x00000000f85af2a8> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@17.0.9/LockSupport.java:252)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.9/AbstractQueuedSynchronizer.java:717)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(java.base@17.0.9/AbstractQueuedSynchronizer.java:1074)
at java.util.concurrent.CountDownLatch.await(java.base@17.0.9/CountDownLatch.java:276)
at org.apache.tomcat.jdbc.pool.FairBlockingQueue.poll(FairBlockingQueue.java:153)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:682)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132)
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:169)
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.extractPhysicalConnection(ConnectionProxyHandler.java:82)
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:138)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at jdk.proxy2.$Proxy243.prepareStatement(jdk.proxy2/Unknown Source)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:147)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:166)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:145)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1854)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1831)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1811)
at org.hibernate.loader.Loader.doQuery(Loader.java:899)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
at org.hibernate.loader.Loader.doList(Loader.java:2516)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2361)
at org.hibernate.loader.Loader.list(Loader.java:2324)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1247)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl.findDefaultBroadleafCurrency(BroadleafCurrencyDaoImpl.java:49)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl$$FastClassBySpringCGLIB$$a820f414.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl$$EnhancerBySpringCGLIB$$6c4cbe9c.findDefaultBroadleafCurrency(<generated>)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl.findDefaultBroadleafCurrency(BroadleafCurrencyServiceImpl.java:47)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl$$FastClassBySpringCGLIB$$6e082cf4.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl$$EnhancerBySpringCGLIB$$f35d7848.findDefaultBroadleafCurrency(<generated>)
at org.broadleafcommerce.common.web.BroadleafCurrencyResolverImpl.resolveCurrency(BroadleafCurrencyResolverImpl.java:98)
at org.broadleafcommerce.common.web.BroadleafRequestProcessor.process(BroadleafRequestProcessor.java:138)
at org.broadleafcommerce.common.web.BroadleafRequestFilter.doFilterInternalUnlessIgnored(BroadleafRequestFilter.java:109)
at org.broadleafcommerce.common.web.filter.AbstractIgnorableOncePerRequestFilter.doFilterInternal(AbstractIgnorableOncePerRequestFilter.java:58)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178)
at org.broadleafcommerce.common.web.filter.IgnorableOpenEntityManagerInViewFilter.doFilterInternal(IgnorableOpenEntityManagerInViewFilter.java:54)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.broadleafcommerce.common.web.filter.SecurityBasedIgnoreFilter.doFilter(SecurityBasedIgnoreFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
- locked <0x00000000f7ebf170> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@17.0.9/ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@17.0.9/ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(java.base@17.0.9/Thread.java:840)
"http-nio-8080-exec-117" #210 daemon prio=5 os_prio=0 cpu=26.24ms elapsed=124.48s tid=0x00007f19800455b0 nid=0xfa waiting on condition [0x00007f192510e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@17.0.9/Native Method)
- parking to wait for <0x00000000f878d3e0> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@17.0.9/LockSupport.java:252)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.9/AbstractQueuedSynchronizer.java:717)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(java.base@17.0.9/AbstractQueuedSynchronizer.java:1074)
at java.util.concurrent.CountDownLatch.await(java.base@17.0.9/CountDownLatch.java:276)
at org.apache.tomcat.jdbc.pool.FairBlockingQueue.poll(FairBlockingQueue.java:153)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:682)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132)
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:70)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:169)
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.extractPhysicalConnection(ConnectionProxyHandler.java:82)
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:138)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at jdk.proxy2.$Proxy243.prepareStatement(jdk.proxy2/Unknown Source)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:147)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:166)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:145)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1854)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1831)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1811)
at org.hibernate.loader.Loader.doQuery(Loader.java:899)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
at org.hibernate.loader.Loader.doList(Loader.java:2516)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2361)
at org.hibernate.loader.Loader.list(Loader.java:2324)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1247)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl.findDefaultBroadleafCurrency(BroadleafCurrencyDaoImpl.java:49)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl$$FastClassBySpringCGLIB$$a820f414.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.broadleafcommerce.common.currency.dao.BroadleafCurrencyDaoImpl$$EnhancerBySpringCGLIB$$6c4cbe9c.findDefaultBroadleafCurrency(<generated>)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl.findDefaultBroadleafCurrency(BroadleafCurrencyServiceImpl.java:47)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl$$FastClassBySpringCGLIB$$6e082cf4.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
at org.broadleafcommerce.common.currency.service.BroadleafCurrencyServiceImpl$$EnhancerBySpringCGLIB$$f35d7848.findDefaultBroadleafCurrency(<generated>)
at org.broadleafcommerce.common.web.BroadleafCurrencyResolverImpl.resolveCurrency(BroadleafCurrencyResolverImpl.java:98)
at org.broadleafcommerce.common.web.BroadleafRequestProcessor.process(BroadleafRequestProcessor.java:138)
at org.broadleafcommerce.common.web.BroadleafRequestFilter.doFilterInternalUnlessIgnored(BroadleafRequestFilter.java:109)
at org.broadleafcommerce.common.web.filter.AbstractIgnorableOncePerRequestFilter.doFilterInternal(AbstractIgnorableOncePerRequestFilter.java:58)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178)
at org.broadleafcommerce.common.web.filter.IgnorableOpenEntityManagerInViewFilter.doFilterInternal(IgnorableOpenEntityManagerInViewFilter.java:54)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.broadleafcommerce.common.web.filter.SecurityBasedIgnoreFilter.doFilter(SecurityBasedIgnoreFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
- locked <0x00000000f8699238> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@17.0.9/ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@17.0.9/ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(java.base@17.0.9/Thread.java:840)
49
затем
java -jar sjk.jar jcmd -s 127.0.0.1:5555 -c JFR.start settings=profile filename=dump1.jfr duration=30s
Started recording 1. The result will be written to:
/app/dump1.jfr
мы смогли получить дамп потоков и запустить сессию JFR для процесса в контейнере.
Инструменты, такие как jconsole или MissionControl так же смогут работать через прокси.
50 Зарустите jconsole и попробуйте подключиться к процесу в контейнере используя адресс 127.0.0.1:5555.
Завершение работы
Завершим работу тестового стенда.
Остановите JMX прокси процесс в консоле B.
Удалите директорию LABDIR/blf-demo/pids (например rm -rf pids).
Остановите jconsole.
Проверьте выполняющиеся java процессы с помощью jcmd и остановие процессы демострационного стенда если они попрежнему выполняются.
Удалите контейнер демонстрационного приложения
docker rm -f storefront