cancel
Showing results for 
Search instead for 
Did you mean: 
angelborroy
Community Manager Community Manager
Community Manager

When dealing with performance issues, configuring the right tools is required in order to collect relevant data from your running environment. This blog post describes how to use Java Profilers (like VisualVM and YourKit Java Profiler) and PostgreSQL stats when using Docker Compose to deploy Alfresco Community 6.2.

Sample Docker Compose templates are available in https://github.com/aborroy/alfresco-6-profiling

VisualVM

This app uses JMX to gather JVM stats from a running Java process.

In order to have access from your computer to Repository and Search service, following configuration must be added to JAVA_OPTS variables in docker-compose.yml file.

-Dcom.sun.management.jmxremote.rmi.port=9091
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=9091
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=127.0.0.1

Exposing the port (9090, 9091) is also required in docker-compose.yml file.

Once Docker Compose is running, Visual VM app can be connected to Repository and Search JVMs by using the following settings:

  • Alfresco Repository > jmx://localhost:9091
  • Search Service > jmx://localhost:9090

imageVisualVM

This tool provide access to configuration, environment settings, process and memory performance and threads. Thread and Core dumps can be also generated for further analysis.

Sample configuration is available in https://github.com/aborroy/alfresco-6-profiling/tree/master/visual-vm

YourKit Java Profiler

This app can use different protocols to gather JVM stats from a running Java process. It's available a trial license, but YourKit Java Profiler requires a paid subscription.

In order to have access from your computer to Repository, following configuration must be added to Alfresco Repository image in docker-compose.yml file.

CATALINA_OPTS: '
-agentpath:/usr/local/YourKit-JavaProfiler-2019.8/bin/linux-x86-64/libyjpagent.so=port=10001,listen=all
'

Exposing the port (10002) is also required in docker-compose.yml file.

Additionally, installing YourKit server agent must be added to Alfresco Dockerfile.

USER root

RUN set -x \
    && yum install -y wget \
    && yum install -y unzip

# YourKit
RUN wget https://www.yourkit.com/download/docker/YourKit-JavaProfiler-2019.8-docker.zip -P /tmp/ && \
  unzip /tmp/YourKit-JavaProfiler-2019.8-docker.zip -d /usr/local && \
  rm /tmp/YourKit-JavaProfiler-2019.8-docker.zip

EXPOSE 10001

For Search Services, exposing the port (10001) in docker-compose.yml file is required and also the agent installation to SOLR Dockerfile.

USER root

RUN set -x \
    && yum install -y wget

# YourKit
RUN wget https://www.yourkit.com/download/docker/YourKit-JavaProfiler-2019.8-docker.zip -P /tmp/ && \
  unzip /tmp/YourKit-JavaProfiler-2019.8-docker.zip -d /usr/local && \
  rm /tmp/YourKit-JavaProfiler-2019.8-docker.zip

EXPOSE 10001

USER solr

CMD $DIST_DIR/solr/bin/search_config_setup.sh "$DIST_DIR/solr/bin/solr start -f -a \"-agentpath:/usr/local/YourKit-JavaProfiler-2019.8/bin/linux-x86-64/libyjpagent.so=port=10001,listen=all\""

Once Docker Compose is running, YourKit Java Developer app can be connected to Repository and Search JVMs by using the following settings:

  • Alfresco Repository > localhost:10002
  • Search Service > localhost:10001

imageYourKit Java ProfilerThis tool provide advanced access to configuration, environment settings, process and memory performance, exceptions and threads. Thread and Core dumps can be also generated for further analysis.

Sample configuration is available in https://github.com/aborroy/alfresco-6-profiling/tree/master/yourkit

PostgreSQL

The pg_stat_statements module provides a means for tracking execution statistics of all SQL statements executed by a server.

In order to have access to this feature, following configuration must be added to Postgres Docker image command in docker-compose.yml file.

-c shared_preload_libraries='pg_stat_statements'
-c pg_stat_statements.max=10000
-c pg_stat_statements.track=all

Once Docker Compose is running, access to PostgreSQL Docker Image and enable the module.

$ docker exec -it postgres_postgres_1 sh

# psql -U alfresco

alfresco=# CREATE EXTENSION pg_stat_statements;
alfresco=# SELECT pg_stat_statements_reset();

Different metrics can be obtained from database queries by using pg_stat_statements table.

# select substr(replace(regexp_replace(query, E'[\\n\\r]+', ' ', 'g'), ' ', ''),0,80), calls, total_time
  from pg_stat_statements
  order by total_time desc
  limit 20;

substr                                      | calls |    total_time
---------------------------------------------------------------------------------+-------+------------------
SELECT$1ASTABLE_CAT,n.nspnameASTABLE_SCHEM,ct.relnameASTABLE_NAME,NOTi.indisuni |   142 |       856.017925
insertintoalf_node_properties(node_id,qname_id,locale_id,list_index,actual_type |  2736 |       685.161372
SELECT$1::textASPKTABLE_CAT,pkn.nspnameASPKTABLE_SCHEM,pkc.relnameASPKTABLE_NAM |   142 |       652.549819
insertintoalf_child_assoc(id,version,parent_node_id,child_node_id,type_qname_id |   891 | 411.546461999999
insertintoalf_node(id,version,store_id,uuid,type_qname_id,locale_id,acl_id,tran |   819 |       400.114111
insertintoalf_node_aspects(node_id,qname_id)values($1,$2)                       |  1677 |       269.889251
SELECT$1ASTABLE_CAT,n.nspnameASTABLE_SCHEM,ct.relnameASTABLE_NAME,a.attnameASCO |   142 |       218.917234
select$1[s],s-pg_catalog.array_lower($1,$2)+$3frompg_catalog.generate_series(pg | 74266 |       121.553584
insertintoalf_content_data(id,version,content_url_id,content_mimetype_id,conten |   242 |       120.325833
updatealf_nodesetversion=$1,audit_creator=$2,audit_created=$3,audit_modifier=$4 |   609 |       103.211222
insertintoalf_node(id,version,store_id,uuid,type_qname_id,locale_id,acl_id,tran |    43 |        98.873413
CREATETABLEalf_applied_patch(idVARCHAR(64)NOTNULL,descriptionVARCHAR(1024),fixe |     2 |        77.130529
SELECT$1ASTABLE_CAT,n.nspnameASTABLE_SCHEM,c.relnameASTABLE_NAME,CASEn.nspname~ |    16 |        75.544505
insertintoalf_node_assoc(id,version,source_node_id,target_node_id,type_qname_id |    15 |        75.363276
deletefromalf_nodewhereid=$1                                                    |     1 |         74.94232
insertintoalf_acl_member(id,version,acl_id,ace_id,pos)values($1,$2,$3,$4,$5)    |   151 |        68.966517
SELECT*FROM(SELECTn.nspname,c.relname,a.attname,a.atttypid,a.attnotnullOR(t.typ |   142 |        61.701457
insertintoalf_qname(id,version,ns_id,local_name)values($1,$2,$3,$4)             |   230 |        54.407586
insertintoalf_prop_link(root_prop_id,prop_index,contained_in,key_prop_id,value_ |     9 |        49.142844
insertintoalf_access_control_entry(id,version,permission_id,authority_id,allowe |    20 |         46.05998

Sample configuration is available in https://github.com/aborroy/alfresco-6-profiling/tree/master/postgres

Other alternatives

Above some alternatives are described, but check out some other contributions from the Community related with the same topic. Like Using Elastic APM for Alfresco Performance Monitoring by @cesarista and stagemonitor.