Megosztás a következőn keresztül:


Egyéni gyorsítótárazás az Azure API Managementben

A KÖVETKEZŐRE VONATKOZIK: Minden API Management-szint

Az Azure API Management szolgáltatás beépített támogatást nyújt a HTTP-válasz gyorsítótárazására az erőforrás URL-címének kulcsként való használatával. A kulcs a tulajdonságok használatával vary-by módosítható kérelemfejlécekkel. Ez a teljes HTTP-válaszok (más néven reprezentációk) gyorsítótárazásához hasznos, de néha hasznos lehet egy reprezentáció egy részének gyorsítótárazása. A gyorsítótár-keresési érték és a gyorsítótár-tároló érték szabályzatai lehetővé teszik tetszőleges adatrészek tárolását és lekérését a szabályzatdefiníciókban. Ez a képesség a küldési kérések házirendjéhez is hozzáad értéket, mivel a külső szolgáltatásokból érkező válaszokat gyorsítótárazhatja.

Architektúra

Az API Management szolgáltatás bérlőnként megosztott belső adatgyorsítótárat használ, így több egységre skálázva továbbra is hozzáférhet ugyanazokhoz a gyorsítótárazott adatokhoz. Többrégiós üzembe helyezés esetén azonban mindegyik régióban vannak független gyorsítótárak. Fontos, hogy ne kezelje a gyorsítótárat adattárként, ahol ez az egyetlen információforrás. Ha igen, és később úgy döntött, hogy kihasználja a többrégiós üzembe helyezés előnyeit, akkor az utazó felhasználók elveszítik a hozzáférést a gyorsítótárazott adatokhoz.

Feljegyzés

A belső gyorsítótár nem érhető el az Azure API Management használati szintjén. Ehelyett használhat külső Azure Cache for Redist. A külső gyorsítótár minden szinten nagyobb gyorsítótár-vezérlést és rugalmasságot tesz lehetővé az API Management-példányok számára.

Töredék gyorsítótárazása

Vannak olyan esetek, amikor a visszaadott válaszok olyan adatok egy részét tartalmazzák, amelyek meghatározása költséges, és ésszerű ideig friss marad. Vegyük például azt a szolgáltatást, amelyet egy légitársaság készített, amely a repülőjegy-foglalásokkal, a repülési állapottal stb. kapcsolatos információkat nyújt. Ha a felhasználó tagja a légitársaságok pont programjának, akkor a jelenlegi állapotukkal és a halmozott futásteljesítményükkel kapcsolatos információkkal is rendelkeznének. Előfordulhat, hogy a felhasználóval kapcsolatos információkat egy másik rendszerben tárolják, de célszerű lehet belefoglalni a járat állapotára és foglalásaira adott válaszokba. Ez egy töredék gyorsítótárazás nevű folyamattal végezhető el. Az elsődleges ábrázolás visszaadható a forráskiszolgálóról valamilyen jogkivonat használatával, amely jelzi a felhasználóval kapcsolatos információk beszúrásának helyét.

Fontolja meg a következő JSON-választ egy háttér API-ból.

{
  "airline" : "Air Canada",
  "flightno" : "871",
  "status" : "ontime",
  "gate" : "B40",
  "terminal" : "2A",
  "userprofile" : "$userprofile$"
}  

És a másodlagos erőforrás, /userprofile/{userid} hogy úgy néz ki,

{ "username" : "Bob Smith", "Status" : "Gold" }

A megfelelő felhasználói adatok meghatározásához az API Managementnek azonosítania kell, hogy ki a végfelhasználó. Ez a mechanizmus implementációfüggő. Az alábbi példa egy JWT jogkivonat jogcímét használjaSubject.

<set-variable
  name="enduserid"
  value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />

Az API Management egy környezeti változóban tárolja az enduserid értéket későbbi használatra. A következő lépés annak megállapítása, hogy egy korábbi kérés már lekérte-e a felhasználói adatokat, és tárolta-e őket a gyorsítótárban. Ehhez az API Management a szabályzatot cache-lookup-value használja.

<cache-lookup-value
key="@("userprofile-" + context.Variables["enduserid"])"
variable-name="userprofile" />

Ha a gyorsítótárban nincs olyan bejegyzés, amely megfelel a kulcsértéknek, akkor a rendszer nem userprofile hoz létre környezeti változót. Az API Management a vezérlőfolyamat-szabályzattal choose ellenőrzi a keresés sikerességét.

<choose>
    <when condition="@(!context.Variables.ContainsKey("userprofile"))">
        <!-- If the userprofile context variable doesn’t exist, make an HTTP request to retrieve it.  -->
    </when>
</choose>

Ha a userprofile környezeti változó nem létezik, akkor az API Managementnek HTTP-kérést kell küldenie a lekéréséhez.

<send-request
  mode="new"
  response-variable-name="userprofileresponse"
  timeout="10"
  ignore-error="true">

  <!-- Build a URL that points to the profile for the current end-user -->
  <set-url>@(new Uri(new Uri("https://apimairlineapi.azurewebsites.net/UserProfile/"),
      (string)context.Variables["enduserid"]).AbsoluteUri)
  </set-url>
  <set-method>GET</set-method>
</send-request>

Az API Management a enduserid felhasználóiprofil-erőforrás URL-címét hozza létre. Miután az API Management megkapta a választ, lekéri a törzsszöveget a válaszból, és egy környezeti változóba tárolja.

<set-variable
    name="userprofile"
    value="@(((IResponse)context.Variables["userprofileresponse"]).Body.As<string>())" />

Annak érdekében, hogy az API Management ismét végrehajtsa ezt a HTTP-kérést, amikor ugyanaz a felhasználó egy másik kérést küld, megadhatja, hogy a felhasználói profilt a gyorsítótárban tárolja.

<cache-store-value
    key="@("userprofile-" + context.Variables["enduserid"])"
    value="@((string)context.Variables["userprofile"])" duration="100000" />

Az API Management a gyorsítótárban tárolja az értéket ugyanazzal a kulccsal, amellyel az API Management eredetileg megpróbálta lekérni. Az API Management által az érték tárolására választott időtartamnak azon kell alapulnia, hogy milyen gyakran változnak az információk, és milyen toleránsak a felhasználók az elavult információkhoz.

Fontos tisztában lennie azzal, hogy a gyorsítótárból való lekérés továbbra is folyamaton kívüli hálózati kérés, és akár több tíz ezredmásodpercet is hozzáadhat a kéréshez. Az előnyök akkor jelentkeznek, ha a felhasználói profil adatainak meghatározása hosszabb időt vesz igénybe, mivel adatbázis-lekérdezéseket kell végeznie, vagy több háttérrendszerből kell összesítenie az adatokat.

A folyamat utolsó lépése a visszaadott válasz frissítése a felhasználói profil adataival.

<!-- Update response body with user profile-->
<find-and-replace
    from='"$userprofile$"'
    to="@((string)context.Variables["userprofile"])" />

Dönthet úgy, hogy az idézőjeleket a jogkivonat részeként adja meg, így a válasz akkor is érvényes JSON marad, ha a csere nem történik meg.

A lépések kombinálása után a végeredmény egy szabályzat, amely az alábbihoz hasonlóan néz ki.

<policies>
    <inbound>
        <!-- How you determine user identity is application dependent -->
        <set-variable
          name="enduserid"
          value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />

        <!--Look for userprofile for this user in the cache -->
        <cache-lookup-value
          key="@("userprofile-" + context.Variables["enduserid"])"
          variable-name="userprofile" />

        <!-- If API Management doesn’t find it in the cache, make a request for it and store it -->
        <choose>
            <when condition="@(!context.Variables.ContainsKey("userprofile"))">
                <!-- Make HTTP request to get user profile -->
                <send-request
                  mode="new"
                  response-variable-name="userprofileresponse"
                  timeout="10"
                  ignore-error="true">

                   <!-- Build a URL that points to the profile for the current end-user -->
                    <set-url>@(new Uri(new Uri("https://apimairlineapi.azurewebsites.net/UserProfile/"),(string)context.Variables["enduserid"]).AbsoluteUri)</set-url>
                    <set-method>GET</set-method>
                </send-request>

                <!-- Store response body in context variable -->
                <set-variable
                  name="userprofile"
                  value="@(((IResponse)context.Variables["userprofileresponse"]).Body.As<string>())" />

                <!-- Store result in cache -->
                <cache-store-value
                  key="@("userprofile-" + context.Variables["enduserid"])"
                  value="@((string)context.Variables["userprofile"])"
                  duration="100000" />
            </when>
        </choose>
        <base />
    </inbound>
    <outbound>
        <!-- Update response body with user profile-->
        <find-and-replace
              from='"$userprofile$"'
              to="@((string)context.Variables["userprofile"])" />
        <base />
    </outbound>
</policies>

Ezt a gyorsítótárazási módszert elsősorban olyan webhelyeken használják, ahol a HTML a kiszolgáló oldalán áll, így egyetlen oldalként jeleníthető meg. Olyan API-kban is hasznos lehet, amelyekben az ügyfelek nem végezhetnek ügyféloldali HTTP-gyorsítótárazást, vagy kívánatos, hogy ne hárítsa ezt a felelősséget az ügyfélre.

Ugyanez a fajta töredék-gyorsítótárazás a háttérbeli webkiszolgálókon is elvégezhető Redis-gyorsítótárazási kiszolgálóval, azonban az API Management szolgáltatással ezt a munkát akkor lehet elvégezni, ha a gyorsítótárazott töredékek más háttérrendszerből származnak, mint az elsődleges válaszok.

Transzparens verziószámozás

Gyakori eljárás, hogy egy API több különböző implementációs verziója is támogatott egyszerre. Például különböző környezetek (fejlesztés, tesztelés, éles környezet stb.) támogatása, vagy az API régebbi verzióinak támogatása, hogy időt biztosítson az API-felhasználók számára az újabb verziókra való migrálásra.

A kezelés egyik módszere ahelyett, hogy az ügyfélfejlesztőknek át kellene változtatniuk az URL-címeket /v1/customers/v2/customers , az az, hogy a fogyasztó profiladataiban tárolják az API aktuálisan használni kívánt verzióját, és meghívják a megfelelő háttér URL-címet. Egy adott ügyfél meghívásához a megfelelő háttérRENDSZER-URL-cím meghatározásához le kell kérdezni néhány konfigurációs adatot. A konfigurációs adatok gyorsítótárazásával az API Management minimálisra csökkentheti a keresés teljesítménybeli büntetését.

Az első lépés a kívánt verzió konfigurálásához használt azonosító meghatározása. Ebben a példában úgy döntöttem, hogy a verziót a termék-előfizetés kulcsához társítom.

<set-variable name="clientid" value="@(context.Subscription.Key)" />

Az API Management ezután gyorsítótár-kereséssel ellenőrzi, hogy az már lekérte-e a kívánt ügyfélverziót.

<cache-lookup-value
key="@("clientversion-" + context.Variables["clientid"])"
variable-name="clientversion" />

Ezután az API Management ellenőrzi, hogy nem található-e a gyorsítótárban.

<choose>
    <when condition="@(!context.Variables.ContainsKey("clientversion"))">

Ha az API Management nem találta meg, az API Management lekéri.

<send-request
    mode="new"
    response-variable-name="clientconfiguresponse"
    timeout="10"
    ignore-error="true">
            <set-url>@(new Uri(new Uri(context.Api.ServiceUrl.ToString() + "api/ClientConfig/"),(string)context.Variables["clientid"]).AbsoluteUri)</set-url>
            <set-method>GET</set-method>
</send-request>

Bontsa ki a válasz törzsszövegét a válaszból.

<set-variable
      name="clientversion"
      value="@(((IResponse)context.Variables["clientconfiguresponse"]).Body.As<string>())" />

Tárolja újra a gyorsítótárban későbbi használatra.

<cache-store-value
      key="@("clientversion-" + context.Variables["clientid"])"
      value="@((string)context.Variables["clientversion"])"
      duration="100000" />

Végül frissítse a háttér URL-címét, hogy kiválassza az ügyfél által kívánt szolgáltatás verzióját.

<set-backend-service
      base-url="@(context.Api.ServiceUrl.ToString() + "api/" + (string)context.Variables["clientversion"] + "/")" />

A teljes szabályzat a következő:

<inbound>
    <base />
    <set-variable name="clientid" value="@(context.Subscription.Key)" />
    <cache-lookup-value key="@("clientversion-" + context.Variables["clientid"])" variable-name="clientversion" />

    <!-- If API Management doesn’t find it in the cache, make a request for it and store it -->
    <choose>
        <when condition="@(!context.Variables.ContainsKey("clientversion"))">
            <send-request mode="new" response-variable-name="clientconfiguresponse" timeout="10" ignore-error="true">
                <set-url>@(new Uri(new Uri(context.Api.ServiceUrl.ToString() + "api/ClientConfig/"),(string)context.Variables["clientid"]).AbsoluteUri)</set-url>
                <set-method>GET</set-method>
            </send-request>
            <!-- Store response body in context variable -->
            <set-variable name="clientversion" value="@(((IResponse)context.Variables["clientconfiguresponse"]).Body.As<string>())" />
            <!-- Store result in cache -->
            <cache-store-value key="@("clientversion-" + context.Variables["clientid"])" value="@((string)context.Variables["clientversion"])" duration="100000" />
        </when>
    </choose>
    <set-backend-service base-url="@(context.Api.ServiceUrl.ToString() + "api/" + (string)context.Variables["clientversion"] + "/")" />
</inbound>

Elegáns megoldás, amely lehetővé teszi, hogy az API-felhasználók transzparens módon szabályozzák, hogy az ügyfelek melyik háttérverzióhoz férnek hozzá anélkül, hogy frissíteni és újra üzembe helyezni kellene az ügyfeleket, egy elegáns megoldás, amely számos API-verziószámozási problémát kezel.

Bérlői elkülönítés

A nagyobb, több-bérlős üzemelő példányokban egyes vállalatok külön bérlőcsoportokat hoznak létre a háttérhardverek különböző központi telepítéseihez. Ez minimalizálja azoknak az ügyfeleknek a számát, akiket a háttérrendszer hardverproblémái érintenek. Emellett lehetővé teszi az új szoftververziók fázisokban történő bevezetését is. Ideális esetben ennek a háttérarchitektúrának átláthatónak kell lennie az API-felhasználók számára. Ez a transzparens verziószámozáshoz hasonlóan érhető el, mivel a háttérRENDSZER URL-címének API-kulcsonkénti konfigurációs állapot használatával történő manipulálásának ugyanaz a technikája.

Ahelyett, hogy az API előnyben részesített verzióját adná vissza az egyes előfizetési kulcsokhoz, egy olyan azonosítót adna vissza, amely a bérlőt a hozzárendelt hardvercsoporthoz kapcsolja. Ez az azonosító használható a megfelelő háttér URL-cím létrehozásához.

Összegzés

Az Azure API felügyeleti gyorsítótárának bármilyen adat tárolására való használatának szabadsága lehetővé teszi a konfigurációs adatok hatékony elérését, amely befolyásolhatja a bejövő kérések feldolgozásának módját. Emellett olyan adattöredékek tárolására is használható, amelyek képesek a válaszok kiegészítésére, amelyeket egy háttér API-ból ad vissza.