Archive for the ‘Architektúra’ Category

Gondolatok a queue alapú kliens-szerviz kommunikációhoz

Thursday, June 16th, 2011

Az előző post kommentjei alapján (amit nagyon köszönök mindenkinek) nem kaptam sok bátorítást az aszinkron, queue alapú, kérés-választ különválasztó gazdag kliens - szerviz kommunikációhoz, úgy tűnik senki nem csinált ilyet, így nem akarok úttörő lenni a témában.
Ehhez még hozzájárul, hogy hétvégén méregettem az MSMQ teljesítményét. Azért ezt, mert a WCF is erre épít, és pl. az NServiceBus is.

A tesztkód 1.5kByteos üzeneteket rak át egyik sorból a másikba. Az ötlet innen jött, csak többszálasítottam.

A tesztkód:


using System;
using System.Diagnostics;
using System.Messaging;
using System.Threading;

namespace MsmqTran
{
    class Program
    {
        private const int NumberOfTests = 1000;
        private const int MaxDop = 10;
        private static readonly ManualResetEvent[] WaitForEmpty = new ManualResetEvent[MaxDop];

        static void Main()
        {
            var q1 = new MessageQueue(@".\private$\test_queue1");
            var q2 = new MessageQueue(@".\private$\test_queue2");

            Console.WriteLine("Filling source queue...");
            var b = new byte[1500];
            using (var msmqTx = new MessageQueueTransaction())
            {
                msmqTx.Begin();
                for (int i = 0; i < NumberOfTests; i++)
                {
                    q1.Send(b, msmqTx);
                }
                msmqTx.Commit();
            }

            q2.Purge();
            Console.WriteLine("Starting to move data from source queue to destination queue");

            var sp = Stopwatch.StartNew();

            for (int i = 0; i < MaxDop; i++)
            {
                WaitForEmpty[i] = new ManualResetEvent(false);
                ThreadPool.QueueUserWorkItem(o => ProcessMsg(q1, q2, (ManualResetEvent)o), WaitForEmpty[i]);
            }

            WaitHandle.WaitAll(WaitForEmpty);

            Console.WriteLine("Duration: {0}ms, throughput: {1:F0} messages/s", sp.ElapsedMilliseconds, 1000.0 * NumberOfTests / sp.ElapsedMilliseconds);
        }

        private static void ProcessMsg(MessageQueue q1, MessageQueue q2, ManualResetEvent w)
        {
            while (true)
            {
                using (var msmqTx = new MessageQueueTransaction())
                {
                    msmqTx.Begin();

                    Message message;
                    try
                    {
                        message = q1.Receive(TimeSpan.FromMilliseconds(0), msmqTx);
                    }
                    catch (MessageQueueException e)
                    {
                        Console.WriteLine(e);
                        w.Set();
                        break;
                    }

                    q2.Send(message, msmqTx);

                    msmqTx.Commit();
                }
            }
        }
    }
}

A gépemen 50 tran/sec-kel megy 1 szálon, és 200 fölé nem nagyon megy. Jó, ez laptop, de relációs adatbáziskezelővel (sql server és oracle is fut a gépen) több ezer tran/seccel mennek a dolgok. Szóval ez elég gázosan lassú. Emellett csúnya leállásokról is írnak a blogokban, amikor beáll az msmq.

Marad a aszinkronított WCF egyelőre, csak a szerverről visszafelé hívásokat tervezem queue alapon megcsinálni, WCF msmq bindinggal. Így tudom értesíteni az appokat polling nélkül. Erre 3 okom van most:
1. Az offline (disconnected) pessimistic lock feloldódott, lehet szerkeszteni valamit.
2. Frissíteni kell a kliens cache-ben valamit.
3. Email jellegű üzenetküldés az appok között.

Köszönöm még egyszer az építő javaslatokat.

Message alapú LOB app tervezés

Saturday, June 11th, 2011

Próbálom megtörni magamban a megszokott gondolkodási sémákat. Tervezek egy nagy, többrétegű LOB alkalmazást. A szervizrétegnek elsődlegesen a WPF rich klienst kell kiszolgálni, de jó lenne, ha mobil kliensek is tudnák ezt fogyasztani.
Ha a szerviz interfész finom felbontású, sok kicsi metódussal, akkor a kommunikáció sok időt rabol el, lassú lesz az app (chatty interfész).
Ha durva felbontású (chunky), akkor megvan a veszélye, hogy a fogyasztó WPF app formjaihoz lesz illesztve, célirányosan, így akkor meg mobil kliensek nem fogják tudni hatékonyan fogyasztani.
Egy érdekes alternatívát láttam a probléma feloldására itt és itt.
Ebben az összes kliens-szerviz kommunikáció message alapú, teljesen aszinkron. Egy kitöltött form adatait elküldik egy queueba, a szerver pedig egy másik üzenettel válaszol erre. Azaz a kliens alapjaiban aszinkron, és a válaszok események formájában jönnek vissza.
A message alapú kommunikáció nagy előnye, hogy az üzeneteket össze lehet nyalábolni, és egyben elküldeni. Így a szerviz lehet finom felbontású, de a kommunikáció mégis gyors, nem sok kis darabból áll. Érthetően ezt szinkron, rpc jellegű szerviz hívásokkal nem lehet megcsinálni.
Ez a fajta queued, service bus alapú gondolkodásmód szokatlan nekem, de nagyon szimpatikus. Van valakinek tapasztalata ilyen rendszer tervezésével? Bármilyen url, pointer, könyv, személyes tapasztalat érdekelne. Úgy érzem nagy dolgokat lehet ezzel összerakni, csak meg kell alaposan értenem.

Még egy gondolat. WCF proxyk használatával az alapban message alapú, asszinkron kérés-válaszokból összeraknak egy RPC jellegű kommunikációt, úgy, hogy a kliens vár a szerver válaszára. Aztán a kliens kedvéért, hogy ne blokkoljuk le a GUIt csinálunk háttérszálat, ahol bevárjuk a szerviz válaszra váró szálat. :)
Miért nem használunk eleve aszinkron üzenetváltásokat, és akkor sokkal egyszerűbb lesz a kép. A kliens bepostázza a kérést a buszra, és megy tovább. Amikor a válasz megjön, akkor meg erről eseményben értesül. Nyilván itt is vannak háttérszálak, hisz ki fogadná akkor a szervertől jövő választ, és ki hívná vissza a kliens eseményeken keresztül, de valahogy akkor is tisztábbnak tűnik a kép, mint az erőltetett RCP-jellegű módszernél. Nem?

Alternatíva a gonosz EAV-val szemben?

Thursday, May 19th, 2011

Az üzleti igény egy olyan adatbázis struktúra létrehozása, amelyben az előre definiált táblák adatai mellé a kusztomerek saját maguk is fel tudnak venni plusz adatokat, anélkül, hogy ehhez az adatbázistáblákat és az alkalmazást módosítani kellene. Sajnos nem csak letárolják ezeket, de még keresni is akarnak egyesekre. Azaz egyfajta open schemat kellene megvalósítani. Erre jó lehet az Entity-Attribute-Value megoldás, de úton-útfélen gonosznak van kinevezve. Értem én, hogy szar belőle lekérdezni, marha nagy lehet, ha egyszerűen csinálják meg nem típusos (én minden típushoz akarok egy oszlopot létrehozni), de milyen használható alternatíva van vele szemben?
Olvastam a serialized blobot, pl. egy xml oszlopba rakjuk a plusz dolgokat. Elvileg lehet xqueryzni, meg indexelni, de érzésre ez se egyszerű, se gyors nem lesz.
A sparse colum esetén séma módosítással jár az új adat definíciója. Ez egyrészt nem tetszik secu okokból (alter table kell hozzá), másrészt elég gáz szervizelni az alkalmazást, ha 50 ügyfél saját oszlopokkal bővítheti a tábláinkat.
Szóval, mi a jó a feladatra? Nekem még mindig az EAV tűnik a legkezelhetőbbnek.

Modernizált Design Patterns tanfolyam - 2010. május 4-7

Monday, March 22nd, 2010

Szétestem az utóbbi két hónapban, annyi munkám volt (elnézést kis családomtól így nyilvánosan is), de most végre kicsit fellélegzek. Most sok időm lesz, elvégre a munkák mellé csak 6 MCP vizsgát raktam be áprilisra (.NET 4 béták). :)

Májusban viszont újra lesz Design Patterns tanfolyam, ahol az eddigi a Gof patternek mellett Unityről és általában a Dependency Injection frameworkökről, ViewModelről, Composite Application Block for WPF-ről, T4 template alapú kódgenerálásról, partial method alapú kibővíthetőségről és Entity Framework Portable Extensible Metadatáról (egyfajta DSL) is szó lesz.
Várok mindenkit szeretettel.

Aki a NetAcademiánál jelentkezéskor az alábbi C# kód által kiírt stringet bemutatja, 50e Ft kedvezményt kap az árból.


using System;

class Program
{
    static void Main(string[] args)
    {
        Allat a = new Emlos();
        a.Mozog();
    }
}

class Allat
{
    public virtual void Mozog()
    {
        Console.WriteLine("Állat vagyok, és mozgok");
    }
}

class Emlos : Allat
{
    public virtual void Mozog()
    {
        Console.WriteLine("Emlős vagyok, és mozgok");
    }
}

ViewModelek kérdésköre

Wednesday, March 3rd, 2010

Mostanában oktatok és prototípust írok, közben ezer design kérdést tisztázok a fejemben. Az egyik ilyen pl., hogy a ViewModel DependencyProperty vagy INotifyPropertyChanged módon közvetítse a változásokat a GUI-ra?
Én az INotifyPropertyChanged-re szavaznék, mert így a ViewModel és nem függ a GUI technológiától, eleve nekem fura a modellben pl. WPF fogalmakat látni.

Infók a kérdéskörben.

Általános áttekintés:
INotifyPropertyChanged vs. DependencyProperty in ViewModel

Egy POCO szavazat:
View Models: POCOs versus DependencyObjects

Én Expressionnel oldom meg, hogy ne legyenek property name stringek a kódban, ő nem, de az objektum pool ötlet tetszik benne, átveszem, de szemeteljünk.
A base class which implements INotifyPropertyChanged

Nagyon dicsérik a videót, még nem volt időm megnézni.
Jason Dolinger on Model-View-ViewModel

Jó kép az MVVM rétegekről.

Egyféle Validation megközelítés.
Using a ViewModel to Provide Meaningful Validation Error Messages

Jó Entity Framework architektúra cikkek

Tuesday, January 19th, 2010

Hogyan építsünk EF-re többrétegű appot?
1. Anti-Patterns To Avoid In N-Tier Applications
2. N-Tier Application Patterns
3. Building N-Tier Apps with EF4

Jó cikkek.

Hacktivity előadásom

Tuesday, September 15th, 2009

Hétvégén lesz a Hacktivity konferencia, ahol NEM arról fogok beszélni, ami ki van írva.
Gál Tamással ketten kaptunk 45 percet, amiben GT a VPN Windows7/R2 új alternatíváiról beszél, én pedig arról, hogy egy akkora cég, mint az MS hogyan képes felzárkózni a hekkerek generálta biztonsági kihíváshoz. Az előadásom fele érdekességekkel, történetekkel lesz tele, belső infók, mit tesz az ms a jobb kódminőség érdekében, a másik felében pedig konkrét példákat mutatok be, amelyek demonstrálják, hogy a különböző támadási típusok esetén (privilege escalation, stb.) hogyan zárkóztak fel a termékek, mint a Windowsok vagy az IIS.
Szeretettel várok mindenkit, aki ráér hétvégén hekkerkedni.

Előadásom az Architect Akadémián - SQL Server architect szemmel

Sunday, April 12th, 2009

Kicsit későn szólok, de ha valakit érdekel, még jelentkezhet, április 15-én lesz.
3×1 órában beszélek arról, hogyan lehet bevetni az SQL Serverek (2000-2008) okosságait egy új alkalmazásarchitektúra kidolgozása során. A cél nem annyira mélységi, mint szélességi bemutatása annak, mit lehet kihozni az SQL Serverből. Igyekszek olyan dolgokról is beszélni, amiről ritkán esik szó (pl. Query Notification, Service Broker), világnézet tágítás végett. Szeretném megmutatni, hogy az SQL Server nem egy egyszerű CRUD adatbázismotor, ahogy sajnos nagyon sokan használják.

Design Patterns tanfolyam - újra, kibővítve .NET 3.5-tel

Thursday, February 12th, 2009

Marcival újra összeállunk pár akcióra, ennek első megnyilvánulása, hogy újra lesz Design Patterns tanfolyam.
Már írom át az anyagot, a 3.5-ös .NET Fw. tele van szebbnél-szebb design példákkal, illetve az utóbbi 2 év gyakorlati programozása során jó pár dolog tovább formálódott, tisztult a fejemben, ezeket is beépítem az anyagba.

A referenciáim között megtekinthető, hogy volt, amikor cégek szinte összes programozója részt vett a tanfolyamon, felismerve a dolog hasznát a fejlesztési folyamatok minőségére.

És végül, aki bemásolja a következő kódot a jelentkezési lapjára, 20% kedvezményt kap a tanfolyam árából:


public class DP: Course, ISupportDiscount
{
    public HappyStudent GiveMeThisDirtyGoodCourseCheaply() { }
    public string Author { get { return "soci"; } }
    public string Trainer { get { return "soci"; } }
    public DateTime ActionTime { get { return DateTime.Parse("2009.03.09"); } }
}

Szeretettel várok mindenkit.

Szaktanácsadó születik :-)

Tuesday, October 14th, 2008

Örömmel és nagy reményekkel közzéteszem, hogy 2009. január 1.-től független szaktanácsadóként folytatom a szakmai pályafutásom. Ennek megfelelően év végére átalakítom a website-om főlapját is, a megfelelő üzleti, kontakt, stb. információkkal kiegészítve.
A blogom változatlanul fog üzemelni, sőt, várhatóan több időm lesz rá, és jóval több témával is fogok foglalkozni (WCF, WWF, Windows Internals, DP újult erővel, stb.).

Ha .NET-alapú fejlesztéssel, tervezéssel vagy SQL Serverrel kapcsolatban tudok valakinek segíteni, januártól szabad vagyok. Az utóbbi két évben jó pár felkérést utasítottam vissza, jövőre erre már nem lesz szükség.

Részletek később, most igen sok intéznivalóm van…

SQL Server 2008 Analysis Services Windows Server 2008-on vs. Windows Server 2003-on

Thursday, July 17th, 2008

Habár nem értek az Analysis Serviceshez (még, az SSIS után ez a következő falat), de ez a cikk igen érdekes. Nem annyira az SQL-es, inkább az operendszeres vonatkozásai miatt.
Az átlagfelhasználó az új Windowsokból csak az új shellt tapasztalja meg, meg, hogy több ram kell nekik. Ennek ellenére a háttérben keményen fejlesztik a rendszer magját, csak az nem annyira látványos, még, ha igen hasznos is.
A cikkben arról beszélnek, hogy a Windows 2008-ban új memóriakezelő van, ami sokkal jobban kezeli a sok, apró memóriafoglalást. Ez azonnal látszik, ha az Analysis Services-szel dolgoztatunk fel jelentős mennyiségű adatot, a 2008-on kapásból dupla olyan gyors lett a feldolgozás (tudom, minden teszt csal, de nem hiszem, hogy nagyot hazudnának).
A szerviznek meg lehet mondani, hogy előre allokálja le a memóriát, így 2003-on is hasonló teljesítményt érhetünk el, mint 2008-on.

Az egészből számomra az az érdekes, hogy gyorsabb Windows 2008-ban a memóriakezelés, amiből bármilyen app profitálni fog. Megvettük. :)

Supervising Controller pattern

Tuesday, April 24th, 2007

Architektúra kedvelőknek egy jó kis cikk a Supervising Controller pattern használatáról ASP.NET-ben.