martedì 27 aprile 2021

Spring - JPA - Monitor Log Slow Query

 

Per eseguire un monitoraggio delle tempistiche di esecuzione delle query è possibile creare un file di log che contenga i tempi in modo da verificare l'eventuale aggiunta di indici.

Definire le tempistiche di monitoraggio di esecuzione della query nel file di properties:

spring.jpa.properties.hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=50



Aggiungere il logger nel file logback-spring.xml

<!-- query time debug -->

<appender name="query" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>queryLog.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>queryLog.log.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>3</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%m%n</pattern>
</encoder>
</appender>


<logger name="org.hibernate.SQL_SLOW" level="INFO">
<appender-ref ref="query"/>
</logger>

il file generato contiene:

SlowQuery: 297 milliseconds. SQL: 'HikariProxyPreparedStatement@984805610 wrapping com.mysql.cj.jdbc.ClientPreparedStatement: select a.id as col_0_0_ from abc a where a.id > 10'


venerdì 26 febbraio 2021

HAProxy - Halog


HaProxy possiede un suo log analyzer che si chiama halog

halog -srv -ut -H < haproxy.log | column -t
halog -u -H -q < haproxy.log | column -t | more
halog -u -H -q -hs 404 < haproxy.log | column -t | more

viene estratta questa lista dove vengono evidenziate gli errori le chiamate etc per ogni occorrenza.


domenica 13 dicembre 2020

InfluxDB

 Qualche esperimento veloce con un db time series come Influx DB. Questi db sono specifici per utilizzare dati temporali ed è fornito di alcuni strumenti molto comodi di visualizzazione come Chronograf

Per prima cosa ho installato su una vmware una debian 8, successivamente ho installato influxDB e Chronograf dalla repo seguendo le info sul sito.

Como dataset ho utilizzato il db del meteo sono circa 3M di righe. Importando con un semplice programmino in java.

A questo punto ho iniziato a fare qualche esperimento con Chronograf ottenendo delle visualizzazioni molto esplicative con pochi click.





lunedì 22 luglio 2019

SqlServer - conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS"



Capita spesso di avere problemi di collate sui db SqlServer quando si utilizza Hibernate. Soprattuto quando cambia la codifica del db o la versione dello stesso:


Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.

SELECT SERVERPROPERTY('EditionId') AS EditionId
GO
use master
GO
ALTER DATABASE [dbaname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
GO
use [dbaname];
GO
USE [master]
GO
ALTER DATABASE [dbaname] COLLATE Latin1_General_CI_AS
GO
ALTER DATABASE [dbaname] SET MULTI_USER
GO

un query che genera uno script di alter potrebbe essere di aiuto per eseguire la modifica sul singolo campo [via]:


SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name + 
    CASE systypes.NAME
    WHEN 'text' THEN ' '
    ELSE
    '(' + RTRIM(CASE SYSCOLUMNS.length
    WHEN -1 THEN 'MAX'
    ELSE CONVERT(CHAR,SYSCOLUMNS.length)
    END) + ') ' 
    END

    + ' ' + ' COLLATE Latin1_General_CI_AS ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
    FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
    WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
    AND SYSOBJECTS.TYPE = 'U'
    AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
    AND SYSCOLUMNS.COLLATION IS NOT NULL
    AND NOT ( sysobjects.NAME LIKE 'sys%' )
    AND NOT ( SYSTYPES.name LIKE 'sys%' )
    GO

giovedì 13 giugno 2019

SqlServer - Verificare lo stato degli indici

Query di comodità per verificare lo stato di deframmentazione degli indici.

L'ultima colonna contiene il comando di rebuild dell'indice.


domenica 28 ottobre 2018

Comunicazione tra MicroServices in Spring Boot con RabbitMQ


Dopo attenta lettura di documentazione on-line e suggerimenti da amici provo ad eseguire qualche test di comunicazione tra Micro Services utilizzando un gestore di code di messaggi RabbitMQ.

Con una semplice app in Spring Boot, con interfaccia rest,  al richiamo di una path, viene spedito un messaggio al RabbitMQ installato sullo stesso PC in locale.

Per RabbitMQ vi consiglio vivamente di installare il plugin per il management da web

 http://localhost:15672/ guest/guest.





La parte di controller è molto semplice, è un api rest che quando viene richiamata spedisce un messaggio al RabbitMQ e nella stessa classe un metodo che rimane in ascolto sulla stessa coda.


Adesso eseguiamo alcuni stress test:

  1.  creiamo diversi file di configurazione di spring per ogni file cambiamo semplicemente la porta.
  2. eseguiamo la build del progetto e lanciamo n jar per ogni profiles creato nel file di configurazione yaml.

java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9001
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9002
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9003
java -jar rabbit-spring-test-0.0.1.jar  --spring.profiles.active=9004


il vostro desktop diventa qualcosa di delirante...

3. Configuro il jMeter per iniziare ad eseguire chiamate sui quattro server 
http://localhost:900{1-4}/sendMessage


C:\dev\apache-jmeter-5.0\bin> .\jmeter -n -t .\sendmessage.jmx -l tmp\jmeter-o.log -o tmp\dashboard

il file sendmessage.jmx



Client web di RabbitMQ



Riassumendo con jMeter abbiamo spedito 48000 richiese di invio di messaggi alle 4 app Spring Boot.
Le app hanno inviato una richiesta in coda al RabbitMQ che a sua volta per ognuno dei suddetti ha reinviato il messaggio alle 4 app.

In ingresso ha processato 48000 messaggi.
In uscita ha processato 192000 messaggi.
Tutto questo in 1 minuto.


martedì 9 ottobre 2018

Nginx, Angular 6 e FontAwesome 4.7 - Problemi Url

I Modulo npm dei FontAwesome 4.7.0 in Angular aggiunge alla path chiamante del file css l'estensione con la versione:

es: http://xxx.xxx.xx/static/fontawesome-webfont.af7ae505a9eed503f8b8.woff2?v=4.7.0

Nginx non accetta di default la tipologia di file, quindi è necessario modificare il file mime.types, aggiungendo le seguenti tipologie:

application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/font-woff  woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;

Questa cosa causa nella risposta standard del browser un errore OTP, a questo punto è necessario inserire un regola di rewrite su Nginx per eliminare la parte di estensione non prevista ?v=4.7.0

    location /static/ {
         alias  /opt/static/html/;
         index index.html;

        if ($request_uri ~* ^.+\.(woff2|otf|woff|tff)\?v=(.*)$){
             rewrite ^(.*)$ $uri? permanent;
         }
         try_files $uri$args $uri$args/ $uri/ /index.html =404;
         error_log /var/log/nginx/static_error.log;
         access_log /var/log/nginx/static_access.log;
     }

Esempio completo: