溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何理解keycloak集群化

發(fā)布時(shí)間:2021-10-20 13:43:00 來源:億速云 閱讀:231 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“如何理解keycloak集群化”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

keycloak中的集群

我們知道,keycloak中有兩種模式,一種叫做Standalone,一種叫做domain。

這兩種模式的區(qū)別只是在于部署文件是否被集中管理,如果部署文件需要一個(gè)一個(gè)的手動拷貝,那么就是standalone模式。如果是一鍵化的自動安裝,那么就是domain模式。

standalone模式下有一個(gè)配置文件叫做 /standalone/configuration/standalone-ha.xml,這個(gè)就是在standalone模式下配置集群的xml文件了。

而domain模式下,配置文件都是在domain controller這個(gè)機(jī)子上進(jìn)行配置的,具體的文件是 domain/configuration/domain.xml 。

我們看下ha具體是用的集群相關(guān)的組件:

<profile name="full-ha">
...
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
                <proxy name="default" advertise-socket="modcluster" listener="ajp">
                    <dynamic-load-provider>
                        <load-metric type="cpu"/>
                    </dynamic-load-provider>
                </proxy>
</subsystem>

<subsystem xmlns="urn:jboss:domain:infinispan:11.0">
...
</subsystem>

<subsystem xmlns="urn:jboss:domain:jgroups:8.0">
                <channels default="ee">
                    <channel name="ee" stack="udp" cluster="ejb"/>
                </channels>
                <stacks>
                    <stack name="udp">
                       ...
                    </stack>
                    <stack name="tcp">
                       ...
                    </stack>
                </stacks>
            </subsystem>
...
</profile>

主要用的是modcluster,infinispan和jgroups。

除此之外,keycloak還介紹了一種叫做跨數(shù)據(jù)中心的集群

如何理解keycloak集群化

這種模式主要用在服務(wù)是跨數(shù)據(jù)中心的情況,比如說異地機(jī)房這樣的容災(zāi)性特別強(qiáng)的情況。

看完keycloak的基本集群搭建之后,我們來講一下keycloak集群中一些比較關(guān)鍵的概念和使用。

load balancing負(fù)載均衡

因?yàn)槭羌航Y(jié)構(gòu),所以我們后端是有多臺服務(wù)器的,那么用戶通過客戶端來訪問我們服務(wù)的時(shí)候,究竟應(yīng)該定位到哪一臺服務(wù)器呢?

這時(shí)就要用到負(fù)載均衡軟件了,也就是load balancing。

一般來說三種負(fù)載均衡的方式:

第一種,就是客戶端負(fù)載均衡,客戶端已經(jīng)知道了服務(wù)端的多個(gè)服務(wù)地址,在發(fā)送請求的時(shí)候由客戶端自行選擇要請求的服務(wù)地址。

這種模式一般都要配置一個(gè)強(qiáng)力的客戶端API,通過這個(gè)客戶端API來進(jìn)行路由功能,比如說Memcached。

Memcached的神奇來自兩階段哈希(two-stagehash)。Memcached就像一 個(gè)巨大的、存儲了很多<key,value>對的哈希表。通過key,可以存儲或查詢?nèi)我獾臄?shù)據(jù)。

客戶端可以把數(shù)據(jù)存儲在多臺memcached上。當(dāng)查詢數(shù)據(jù)時(shí),客戶端首 先參考節(jié)點(diǎn)列表計(jì)算出key的哈希值(階段一哈希),進(jìn)而選中一個(gè)節(jié)點(diǎn);客戶端將請求發(fā)送給選中的節(jié)點(diǎn),然后memcached節(jié)點(diǎn)通過一個(gè)內(nèi)部的哈希算法(階段二哈希),查找真正的數(shù)據(jù)(item)。

第二種,就是代理服務(wù)負(fù)載均衡,這種模式下,會有一個(gè)代理服務(wù)器和后端的多個(gè)服務(wù)進(jìn)行連接,客戶端是和這個(gè)代理服務(wù)器進(jìn)行交互,由代理服務(wù)器來代替客戶端選擇到底要路由到哪個(gè)服務(wù)。

這種代理的路由的軟件就多了,比如我們熟悉的nginx和HTTPD,還有ildFly with mod_cluster, HA Proxy, 或者其他的硬件負(fù)載均衡。

第三種,是路由負(fù)載均衡,在這種模式下,用戶隨機(jī)選擇一個(gè)后端服務(wù)器進(jìn)行請求連接,然后在服務(wù)器內(nèi)部進(jìn)行路由,將這個(gè)請求發(fā)送到其他的服務(wù)器中。

這種模式下,一般需要在服務(wù)器內(nèi)部實(shí)現(xiàn)特定的負(fù)載均衡功能。

暴露客戶端IP地址

不管使用的是什么模式的負(fù)載均衡,我們都有可能在業(yè)務(wù)中需要使用到客戶訪問的IP地址。

我們在特定的業(yè)務(wù)中需要獲取到用戶的ip地址來進(jìn)行一些操作,比如記錄用戶的操作日志,如果不能夠獲取到真實(shí)的ip地址的話,則可能使用錯(cuò)誤的ip地址。還有就是根據(jù)ip地址進(jìn)行的認(rèn)證或者防刷工作。

如果我們在服務(wù)之前使用了反向代理服務(wù)器的話,就會有問題。所以需要我們配置反向代理服務(wù)器,保證X-Forwarded-For和X-Forwarded-Proto這兩個(gè)HTTP header的值是有效的。

然后服務(wù)器端就可以從X-Forwarded-For獲取到客戶的真實(shí)ip地址了。

在keycloak中,如果是http forwarding,則可以這樣配置:

<subsystem xmlns="urn:jboss:domain:undertow:10.0">
   <buffer-cache name="default"/>
   <server name="default-server">
      <ajp-listener name="ajp" socket-binding="ajp"/>
      <http-listener name="default" socket-binding="http" redirect-socket="https"
          proxy-address-forwarding="true"/>
      ...
   </server>
   ...
</subsystem>

如果是AJP forward, 比如使用的是Apache HTTPD + mod-cluster, 則這樣配置:

<subsystem xmlns="urn:jboss:domain:undertow:10.0">
     <buffer-cache name="default"/>
     <server name="default-server">
         <ajp-listener name="ajp" socket-binding="ajp"/>
         <http-listener name="default" socket-binding="http" redirect-socket="https"/>
         <host name="default-host" alias="localhost">
             ...
             <filter-ref name="proxy-peer"/>
         </host>
     </server>
        ...
     <filters>
         ...
         <filter name="proxy-peer"
                 class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"
                 module="io.undertow.core" />
     </filters>
 </subsystem>

sticky sessions 和 非sticky sessions

如果是在存在session的環(huán)境中,比如說web應(yīng)用程序中,如果后端服務(wù)器是cluster的情況下還需要考慮session共享的問題。

因?yàn)閷τ诿總€(gè)服務(wù)器來說,它的session都是本地維護(hù)的,如果是多臺服務(wù)器想要session共享該怎么辦呢?

一種辦法就是所有的服務(wù)器都將session存放在同一個(gè)外部緩存系統(tǒng)中,比如說redis。這樣不管用戶訪問到哪個(gè)server,都可以讀取到同一份session數(shù)據(jù)。

當(dāng)然,這個(gè)緩存系統(tǒng)可以是單點(diǎn)也可以是集群,如果是不同的數(shù)據(jù)中心的話,緩存集群甚至還需要跨數(shù)據(jù)中心進(jìn)行同步。

緩存同步當(dāng)然是一個(gè)很好的辦法,但是同步行動自然是有開銷的。有沒有更加簡單方便的處理方式呢? 比如固定一個(gè)用戶只訪問同一個(gè)服務(wù)器這樣是不是就能解決緩存同步的問題呢?

這種固定用戶訪問特定某個(gè)服務(wù)器的模式,我們叫做sticky sessions模式。在這種模式下,可以不用考慮session同步的問題。當(dāng)然,這種模式下,如果某個(gè)服務(wù)器down機(jī)了,用戶的session就會丟失。所以還是要做一些session同步的工作,只不過不需要實(shí)時(shí)的同步而已。

另外,sticky session還有一個(gè)缺點(diǎn):如果是后臺的請求,則獲取不到session的信息,也就無法實(shí)現(xiàn)sticky session,這個(gè)時(shí)候就需要進(jìn)行后臺數(shù)據(jù)的拷貝,這樣才能保證不管請求發(fā)送到哪里都能夠表現(xiàn)一致。

shared databases

所有的應(yīng)用都需要保存數(shù)據(jù)。通常來說,我們會有兩種數(shù)據(jù):

一種是數(shù)據(jù)庫數(shù)據(jù),這種數(shù)據(jù)將會永久存儲用戶信息。

一種是cache,用作數(shù)據(jù)庫和應(yīng)用程序的緩沖。

不管是哪種數(shù)據(jù),都可以有集群模式,也就是多臺服務(wù)器同時(shí)讀寫數(shù)據(jù)。這樣對于共享的數(shù)據(jù)就涉及到了集群數(shù)據(jù)更新的問題。

集群數(shù)據(jù)的更新有兩種更新模式:

一種是可靠優(yōu)先,Active/Active mode,一個(gè)節(jié)點(diǎn)更新的數(shù)據(jù)會立馬同步到另外一個(gè)節(jié)點(diǎn)。

一種是性能優(yōu)先,Active/Passive mode,一個(gè)節(jié)點(diǎn)更新的數(shù)據(jù)不會立馬同步到另外一個(gè)節(jié)點(diǎn)中。

可靠優(yōu)先的運(yùn)行邏輯是,一個(gè)更新請求需要等待所有的集群服務(wù)返回更新成功才算成功。而性能優(yōu)先的運(yùn)行邏輯就是更新完主數(shù)據(jù)就算成功了,其他的節(jié)點(diǎn)會去異步和主數(shù)據(jù)節(jié)點(diǎn)進(jìn)行同步。

keycloak中使用的緩存是infinispan,并且構(gòu)建了多種session緩存,不同的緩存使用的是不同的同步策略:

  • authenticationSessions:這個(gè)緩存保存的是登錄用戶的信息,如果在sticky sessions模式下,是不需要進(jìn)行數(shù)據(jù)同步的。

  • Action tokens:如果用戶需要異步的進(jìn)行郵件驗(yàn)證,比如說忘記密碼等操作,則需要用到這種類型的緩存。因?yàn)檫@種操作中的token只能夠被使用一次,所以需要數(shù)據(jù)的同步。

  • 非認(rèn)證的session信息:因?yàn)椴荒鼙WCsticky session模式的使用,所以需要復(fù)制。

  • loginFailures: 統(tǒng)計(jì)用戶的登錄異常情況,不需要被復(fù)制。

在緩存保存數(shù)據(jù),需要注意數(shù)據(jù)更新后的失效問題。

在keycloak中,使用了一個(gè)單獨(dú)的work緩存,這個(gè)緩存是所有數(shù)據(jù)中心同步的,它不存儲實(shí)際的數(shù)據(jù),只存儲要無效的數(shù)據(jù)通知。各個(gè)數(shù)據(jù)的服務(wù)從work緩存中讀取無效的數(shù)據(jù)列表,進(jìn)行相應(yīng)的數(shù)據(jù)緩存無效化處理。

multicasting

最后,如果集群需要動態(tài)發(fā)現(xiàn)和管理節(jié)點(diǎn)的功能的話,還需要進(jìn)行IP廣播。比如說可以使用JGroups來實(shí)現(xiàn)這個(gè)功能。

“如何理解keycloak集群化”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI