Neulich stellte sich auf Arbeit das Problem, dass ein Ressourcenpool erschöpft war, da augenscheinlich die ausgereichten Ressourcen nicht wieder zurückgelegt wurden. Die restlichen Randbedingungen machten die ganze Sache noch mysteriöser. Daraus entwickelten sich bei mir verschiedene Gedanken zu dem Thema wie man dem Problem auf die Schliche kommen könnte...
Ich überlegte mir zwei verschiedene Varianten: Zum einen dachte ich über einen Watchdog nach, der Alarm schlagen könnte, wenn eine Ressource nach einer bestimmten, festzulegenden Zeitspanne nicht wieder zurückgegeben würde. Diese Alarmierung könnte zum einen ganz simpel über eine Warnung im Log geschehen oder etwa über eine JMX-Notification. Wichtig wäre dabei nur, dass auch der Stacktrace mit übermittelt würde, der zeigt, durch wen oder von wo aus die Ressource beim letzten Mal allokiert wurde.
Diese Idee gepaart mit der zweiten - sämtliche Objekte über JMX recherchierbar zu machen und zu jedem Objekt ebenfalls über JMX den Stacktrace recherchieren zu können, der zeigt, durch wen oder von wo aus die Ressource beim letzten Mal allokiert wurde - sollte solche Probleme eigentlich sehr einfach disgnostizierbar machen.
Tatsächlich erschienen diese Ideen als so einfach und gleichzeitig zwingend, dass ich mir überlegte, wieso nicht schon andere vor mir darauf gekommen waren - woraufhin ich mir die Frage stellte, ob wirklich noch niemand darauf gekommen war.
Ich holte mir also eine der üblichen Verdächtigen (Implementierungen) und sah nach...
Diese Implementierung registriert zwar den ObjectPool, die einzelnen PooledObjects - für die existiert ein Wrapper - können über entsprechende JMX-Methoden recherchiert werden. Wichtig ist hierbei noch zu erwähnen, dass der Stacktrace nicht per default mitprotokolliert wird, sondern die Konfiguration erst dahingehend angepasst werden muss.
Nichtsdestotrotz habe ich mir eine eigene minimale ObjectFactory geschrieben und darin die Objekte einzeln in JMX registriert um die Wirksamkeit dieser Methode zu testen:
public class StringBufferFactory
extends BasePooledObjectFactory<StringBuffer> {
private final static org.apache.log4j.Logger CLASS_LOGGER =org.apache.log4j.Logger.getLogger(StringBufferFactory.class);
@Override
public StringBuffer create() {
return new StringBuffer();
}
/**
* Use the default PooledObject implementation.
*/
@Override
public PooledObject<StringBuffer> wrap(StringBuffer buffer) {
JMXPooledObject<StringBuffer> obj=new JMXPooledObject<StringBuffer>(buffer);
return obj;
}
/**
* When an object is returned to the pool, clear the buffer.
*/
@Override
public void passivateObject(PooledObject<StringBuffer> pooledObject) {
pooledObject.getObject().setLength(0);
}
// for all other methods, the no-op implementation
// in BasePooledObjectFactory will suffice
}
Der Code für die benötigten JMXPooledObjects ist hier zu finden:
public class JMXPooledObject<T> extends org.apache.commons.pool2.impl.DefaultPooledObject implements JMXPooledObjectMBean
{
private final static org.apache.log4j.Logger CLASS_LOGGER =org.apache.log4j.Logger.getLogger(JMXPooledObject.class);
private java.lang.Throwable throwable;
public JMXPooledObject(T client)
{
super(client);
javax.management.MBeanServer mbeanServer=java.lang.management.ManagementFactory.getPlatformMBeanServer();//createMBeanServer();
javax.management.ObjectName objectName=null;
try
{
java.lang.String fqcn=client.getClass().getSimpleName();
java.lang.String packageName=client.getClass().getPackageName();
java.lang.String objn=this.getClass().getName()+"."+packageName+":type="+fqcn+",name="+(java.util.UUID.randomUUID().toString().replace(':','_').replace(' ','_'));
CLASS_LOGGER.trace(objn);
objectName=new javax.management.ObjectName(objn);
}
catch(javax.management.MalformedObjectNameException exp)
{
CLASS_LOGGER.error("Error creating object name for use in JMX environment!",exp);
}
try
{
mbeanServer.registerMBean(this,objectName);
}
catch(javax.management.JMException exp)
{
CLASS_LOGGER.error("Error registering connection into JMX environment!",exp);
}
}
public boolean allocate()
{
throwable=new java.lang.Throwable();
return super.allocate();
}
@Override
public java.lang.StackTraceElement[] getStackframe()
{
return throwable!=null?throwable.getStackTrace():null;
}
}
Traceroute Visualisierung mittels GeoJSON
29.05.2021
Dieses Wochenende war es wieder einmal an der Zeit für ein Kaninchenbau-Projekt. Es gibt inzwischen einige kostenlose Geolocation-APIs im Netz und ich wurde - durch das Internet - auf die Idee gebracht, das Ergebnis eines Aufrufs von traceroute auf einer Landkarte zu visualisieren
WeiterlesenAI und ML Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Go GUI Hardware Java Jupyter JupyterBinder Komponenten Links Linux Markdown Markup Music Numerik OpenSource PKI-X.509-CA Präsentationen Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Es geht hier speziell um das Modell s920. Bei Recherchen zu meinen letzten Experimenten hatte ich auch realisiert, dass ich einen solchen Thin Client mit montiertem TPM besitze - das musste natürlich ausprobiert werden!
WeiterlesenIch habe vor geraumer Zeit immer wieder einmal das Mandelbrotfraktal berechnet - auf der Kommandozeile genauso wie mittels Shadern auf der Graphikkarte. Nun bin ich dahin zurückgekehrt: Ich wollte wissen, ob dieser Code heute noch funktioniert und mit einer Nvidia-Karte ebenso funktioniert, wie damals mit meiner guten alten Radeon...
Weiterlesen
Asymmetrische KryptographieIch habe mich mit der Idee schon länger getragen: Nochmal einen Rundumschlag zu asymmetrischer Kryptographie zu machen. Dabei werde ich mich auf Demonstrationen der einzelnen Konzepte und Operationen mit Beispielcode konzentrieren und zu jedem der vorgestellten Konzepte mehr oder weniger ausführlich bezüglich der Einsatzszenarien und Vor- und Nachteile Stellung beziehen
WeiterlesenManche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.
Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.
Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...
PS: Meine öffentlichen Codeberg-Repositories findet man hier.