locking in cfml. locking in cfml - warum - wie - wobei - wann } soll gelockt werden? locking...
TRANSCRIPT
Locking In CFML
Locking in CFML
- Warum
- Wie
- Wobei
- Wann}soll gelockt werden?
Locking verstehen
Locking in CFML
Agenda Das Problem
Kritische Ressourcen
Shared Scope Variablen
<CFLOCK>
Geschachtelte Locks
Locks um Pointer
Name Locks
Links *
Client Variablen *
* Folie nicht in Original-Präsentation enthalten* Folie nicht in Original-Präsentation enthalten
Zugriffe beschränken *
Lock Administration
Fragen und Antworten *
Locking in CFML
Symptome für ein Locking-Problem
- unerklärliche Verluste von Session- oder Application-Variablen
- Serverabstürze
- speichergierige CF-Server
- langsame Anwendungen
Obwohl diese Symptome nicht bedeuten, dass ein Locking Problem vorhanden sein MUSS, ist falsches (oder gänzlich fehlendes) Locking eine der wahrscheinlichsten Ursachen.
Obwohl diese Symptome nicht bedeuten, dass ein Locking Problem vorhanden sein MUSS, ist falsches (oder gänzlich fehlendes) Locking eine der wahrscheinlichsten Ursachen.
Locking in CFML
MultithreadingDie Fähigkeit eines Programms, mehrere Aktivitäten parallel auszuführen
Beispiel: eMail-Programm
Gleichzeitig Nachrichten lesen und neue Mails vom Server downloaden
Locking in CFML
MultithreadingVorteile - Performance/Zeitersparnis
- (System-) Sicherheit
Nachteile- Programme werden aufwendiger
- nicht einfach zu implementieren
Locking in CFML
Multithreading in ColdFusion
ColdFusion kann mehrere Requests gleichzeitig bearbeiten
Jeder Request wird einem Thread zugeordnet
“Überzählige” Requests werden in Warte-schlange eingereiht
Im Thread wird jeder Request serialisiert
Anzahl der Worker Threads kann im CF-Administrator eingestellt werden
Locking in CFML
Kritische Ressourcen
Shared Scope Variablen
Dateien
Komponenten (COM, CORBA, Java)
Alle Ressourcen, die zugriffskritisch sind oder bei zu vielen gleichzeitigen Zugriffen inperformant werden
Concurre
nt Acc
ess
Locking in CFML
Shared Scope Variablen
Server-Scope
Application-Scope
Session-Scope
Variablen können von jedem User JEDER Anwendung genutzt werden
Variablen können von jedem User EINER Anwendung genutzt werden
Variablen können von EINEM User innerhalb EINER Anwendung genutzt werden
Frames, Mehrfache Submits, Reload/RedirectionFrames, Mehrfache Submits, Reload/Redirection
Locking in CFML
<CFLOCK>
Identifikation
Typ
Fehlerbehandlung
NAME oder SCOPE
TYPE=“Exclusive”vs.
TYPE=“ReadOnly”
TIMEOUT und THROWONTIMEOUT
Locking in CFML
<CFLOCK> und Shared Scope Variablen
JEDEN Zugriff locken
den gesamten Scope locken
den richtigen Typ einsetzen
nur das locken, was gelockt werden muss
Siehe Pointer und Strukturen, sowie Fragen
und Antworten!
Siehe Pointer und Strukturen, sowie Fragen
und Antworten!
Locking in CFML
Beispiel: Query-Ergebnis in Application- Variable speichern
Falsch:<CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFQUERY datasource="#DSN#" name="application.kunden"> SELECT * FROM tblKunden </CFQUERY></CFLOCK>
Besser:<CFQUERY datasource="#DSN#" name="kunden"> SELECT * FROM tblKunden</CFQUERY><CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.kunden = kunden></CFLOCK>
Locking in CFML
Client Variablen und Locking
Client Variablen werden NICHT im RAM gespeichert,Sondern in DB, Registry oder Cookies
Das Betriebssystem oder die DB kümmern sich um Zugriffsprobleme In ColdFusion brauchen wir Client Variablen NICHT zu locken
Locking in CFML
Geschachtelte Locks Gefahr von Deadlocks
<CFLOCK scope="Application" Timeout="10" type="ReadOnly"> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> Code... </CFLOCK></CFLOCK>
Template 1:<CFLOCK scope="Application" Timeout="10" type="Exclusive">
<CFLOCK scope="Session" Timeout="10" type="Exclusive">Code...
</CFLOCK></CFLOCK>
Template 2:<CFLOCK scope="Session" Timeout="10" type="Exclusive"> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> Code... </CFLOCK></CFLOCK>
Ansonsten nicht möglich!
Ansonsten nicht möglich!
Locking in CFML
Geschachtelte Locks vermeiden<CFLOCK scope="Application" Timeout="10" type="Exclusive">
<CFLOCK scope="Session" Timeout="10" type="Exclusive"> <CFSET session.DSN = application.DSN> <CFSET application.bgcolor = session.bgcolor>
</CFLOCK></CFLOCK>
<CFLOCK scope="Application" Timeout="10" type="ReadOnly"> <CFSET dsn = application.DSN></CFLOCK> <CFLOCK scope="Session" Timeout="10" type="ReadOnly"> <CFSET bgcolor = session.bgcolor></CFLOCK> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.bgcolor = bgcolor></CFLOCK> <CFLOCK scope="Session" Timeout="10" type="Exclusive"> <CFSET session.DSN = DSN></CFLOCK>
Gleiches Ergebnis ohne geschachtelte Locks:
Locking in CFML
Geschachtelte LocksFalls möglich, geschachtelte Locks
vermeiden (Performance-Nachteile, Deadlock-Gefahr)
1. Session-Scope
Falls das Schachteln von Locks unvermeidbar
wird, dann immer in der Reihenfolge
2. Application-Scope
3. Server-Scope
“Local out” - Ansatz
Locking in CFML
Locking von Pointern
Pointer: Verweis auf eine Struktur
<CFSET application.userData = session>
Änderung am Pointer ändert auch Original-Struktur
<CFSET myPointer = myStruct>
Shared Scope Variablen sind auch Strukturen
<CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.userData = session> </CFLOCK>
<CFLOCK scope="Session" Timeout="10" type="ReadOnly"> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.userData = session> </CFLOCK> </CFLOCK>
<CFLOCK scope="Application" Timeout="10" type="ReadOnly"> <CFSET temp = application.userData.bgcolor> </CFLOCK> <CFSET temp = application.userData.bgcolor>
<CFLOCK scope="Session" Timeout="10" type="ReadOnly"> <CFLOCK scope="Application" Timeout="10" type="ReadOnly"> <CFSET temp = application.userData.bgcolor> </CFLOCK> </CFLOCK>
<CFSET application.userData.bgcolor = "##EEEEEE"> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.userData.bgcolor = "##EEEEEE"> </CFLOCK>
<CFLOCK scope="Session" Timeout="10" type="Exclusive"> <CFLOCK scope="Application" Timeout="10" type="Exclusive"> <CFSET application.userData.bgcolor = "##EEEEEE"> </CFLOCK> </CFLOCK>
<CFSET application.myVar = “123“> greift nicht nur auf “myVar“ zu, sondern auf die gesamte Struktur ”application“, deshalb den ganzen Scope locken! Immer!!
<CFSET application.myVar = “123“> greift nicht nur auf “myVar“ zu, sondern auf die gesamte Struktur ”application“, deshalb den ganzen Scope locken! Immer!!
Locking in CFML
Name LocksLock wird durch Name identifiziert und sperrt
denRessourcen-Zugriff für alle Locks mit
gleichemNamen Verwendung bei allen kritischen Ressourcen
außerShared Scope Variablen, z.B.
Verity
<CFFILE>
COM-Objekte
Sinnvoll: Benennung nach einem Schema
Locking in CFML
Anzahl gleichzeitiger Zugriffe beschränken
Einige Ressourcen werden sehr inperformant, wenn zu viele gleichzeitige
Zugriffe vorkommen oder erlauben nur eine bestimmte Anzahl gleichzeitiger
Verbindungen von einem Client (z.B. manche FTP-Server).Mit Name Locks kann man dafür sorgen, dass nicht mehr gleichzeitige
Zugriffe als vorgesehen vorkommen.
<CFSET myLockName = "Lock_FTP_MyServer_" & RandRange(1,3)><CFLOCK name=“#myLockName#" timeout="10" type=“Exclusive"> <CFFTP . . .></CFLOCK>
Dazu muss man eine festgelegte Anzahl möglicher Lock-Namen für die
Ressource haben, z.B. mit Hilfe der Random-Funktionen:
Da drei verschiedene Namen möglich sind, können zum FTP-Server
“MyServer” maximal drei gleichzeitige Verbindungen aufgebaut werden.
Locking in CFML
Lock-Administration
Single Threaded SessionsAlle Threads mit der gleichen sessionID werden
serialisiert Keine Gefahr von Concurrent Access bei
Sessions u.U. Performance-Nachteile (z.B. bei
Frames) Erhöhte Gefahr von Template-
Timeouts
Locking in CFML
Lock-Administration
Variable Scope Lock Settings
No automatic checking or locking
Full checking
Automatic read locking
Locking in CFML
Lock-Administration
Variable Scope Lock SettingsNo automatic checking or locking
Locking liegt in der Verantwortung des Entwicklers
Performant aber gefährlich
Bei Produktiv-Servern mit GETESTETEN Anwendungen
Locking in CFML
Lock-Administration
Variable Scope Lock SettingsFull checking
Jeder nicht gelockte Zugriff erzeugt Fehler
Sicher, hat aber leichte Performance-Nachteile
Auf Entwicklungsservern
Auf shared Servern
Name Locks erzeugen ebenfalls Fehler
Achtung Bug!
Ein fehlender Lock um IsDefined() bei Shared Scope Variablen erzeugt auch bei Full Checking keinen Fehler! Aber auch IsDefined(“shared_scope_var”) MUSS gelockt werden!
Achtung Bug!
Ein fehlender Lock um IsDefined() bei Shared Scope Variablen erzeugt auch bei Full Checking keinen Fehler! Aber auch IsDefined(“shared_scope_var”) MUSS gelockt werden!
Locking in CFML
Lock-Administration
Variable Scope Lock SettingsAutomatic read locking
Jeder Lesezugriff erhält seinen eigenen Lock
Relativ sicher, aber definitve Performance-Nachteile Wenn alte Anwendungen nachträglich mit Locks
versehen werden müssen
Schreibende Zugriffe müssen manuell gelockt werden
Locking in CFML
Zusammenfassung
1. Jeden Zugriff locken
2. Wenn möglich, mehrere Zugriffe in einen Lock packen, aber
3. Nur das locken, was auch gelockt werden muss
4. Für Shared Scope Variablen immer das SCOPE-Attribut verwenden
5. Den richtigen Lock-Typ verwenden
6. Bei shared Servern den Server-Scope vermeiden
Locking in CFML
Zusammenfassung
8. THROWONERROR=“Yes” ist nützlich, erfordert aber die Verwendung von CFTRY/CFCATCH9. Pointer zwischen verschiedenen Scopes vermeiden. (Besser StructCopy() oder Duplicate() verwenden)10. Wenn Pointer unvermeidbar sind: Beide Scopes
locken11. Für Produktiv-Server: “No automatic
checking or locking” aktivieren (bei GETESTETEN Anwendungen)12. Für Entwicklungs-Server: “Full checking”
aktivieren
7. Geschachtelte Locks vermeiden, wenn geschachtelt werden muss: “Local out”
Locking in CFML
Fragen und Antworten<CFLOCATION URL=“seite.cfm“ ADDTOKEN=“Yes“> hängt doch automatisch das session.URLToken an die URL an, muss ich das nicht auch locken?
Es wird nicht das SESSION.URLToken angehängt, sondern das CLIENT.URLToken. Das ist in der CF-Dokumentation zu CFLOCATION leider nur dem kleinen Vermerk „clientManagement must be enabled“ zu entnehmen. Da es sich also um eine Client Variable handelt, muss nicht gelockt werden.
Es wird nicht das SESSION.URLToken angehängt, sondern das CLIENT.URLToken. Das ist in der CF-Dokumentation zu CFLOCATION leider nur dem kleinen Vermerk „clientManagement must be enabled“ zu entnehmen. Da es sich also um eine Client Variable handelt, muss nicht gelockt werden.
Warum muss bei Shared Scope Variablen der ganze Scope gelockt werden, es sollte doch reichen, die einzelne Variable zu locken, oder?
Wenn wir auf eine Shared Scope Variable zugreifen, dann greifen wir immer auf eine Struktur zu. Es nutzt nichts, ein einzelnes Element zu locken, wenn die übergeordnete Einheit ungeschützt ist und durch concurrent access kompromitiert werden kann. Deswegen IMMER den ganzen Scope locken.
Beim Server-Scope können zwar aus Sicherheitsgründen die Struktur-Funktionen von CF nicht verwendet werden (auch <CFLOOP collection=“#server#“ item=“key“> funktioniert nicht), es aber dennoch eine Struktur und muss dementsprechend geschützt werden.
Wenn wir auf eine Shared Scope Variable zugreifen, dann greifen wir immer auf eine Struktur zu. Es nutzt nichts, ein einzelnes Element zu locken, wenn die übergeordnete Einheit ungeschützt ist und durch concurrent access kompromitiert werden kann. Deswegen IMMER den ganzen Scope locken.
Beim Server-Scope können zwar aus Sicherheitsgründen die Struktur-Funktionen von CF nicht verwendet werden (auch <CFLOOP collection=“#server#“ item=“key“> funktioniert nicht), es aber dennoch eine Struktur und muss dementsprechend geschützt werden.
Locking in CFML
Fragen und AntwortenWarum muss denn partout JEDER Zugriff gelockt werden? Ein einzelner ungelockter Zugriff beeinflusst doch die anderen gelockten Zugriffe nicht....
FALSCH! Ganz wichtig ist das richtige Verständnis von Locks. Ein Lock schützt nur vor Zugriffen aus anderen gleichartigen Locks heraus. Ein Lock um eine Application-Variable schützt diese Variable nicht vor ungelockten Zugriffen, sondern nur vor Zugriffen aus Locks mit dem gleichen Scope-Attribut.
Deswegen ist Name-Locking auch so kritisch. Zwei Locks mit unterschiedlichem Namen können auf die gleiche geschützte Ressource zugreifen. Um da nicht die Übersicht zu verlieren sollte man bei Shared Scope Variablen immer das SCOPE-Attribut benutzen und für Name Locks eine Naming Convention einhalten.
FALSCH! Ganz wichtig ist das richtige Verständnis von Locks. Ein Lock schützt nur vor Zugriffen aus anderen gleichartigen Locks heraus. Ein Lock um eine Application-Variable schützt diese Variable nicht vor ungelockten Zugriffen, sondern nur vor Zugriffen aus Locks mit dem gleichen Scope-Attribut.
Deswegen ist Name-Locking auch so kritisch. Zwei Locks mit unterschiedlichem Namen können auf die gleiche geschützte Ressource zugreifen. Um da nicht die Übersicht zu verlieren sollte man bei Shared Scope Variablen immer das SCOPE-Attribut benutzen und für Name Locks eine Naming Convention einhalten.
Welche Naming Convention soll ich für Name Locks verwenden?
Ganz egal, es sollte nur eine Systematik dahinterstecken. So könnte der Lock-Name grundsätzlich aus „Lock“ + geschützte Ressource bestehen, also z.B.
“Lock_files” oder “Lock_ftp”.
Ganz egal, es sollte nur eine Systematik dahinterstecken. So könnte der Lock-Name grundsätzlich aus „Lock“ + geschützte Ressource bestehen, also z.B.
“Lock_files” oder “Lock_ftp”.
Locking in CFML
Links
Best practices:http://www.macromedia.com/v1/Handlers/index.cfm?ID=20370&Method=Full
A comprehensive guide:http://www.depressedpress.com/DepressedPress/Content/ColdFusion/Guides /Locking/Index.cfm
BF on CF: Lock it or loose it!http://www.sys-con.com/coldfusion/article.cfm?id=135
Locking in CFML
Weitere Fragen?
Christoph SchmitzeMail: [email protected]
Jeweils aktuelle Version der Präsentation zu finden unter http://www.procept.net