程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Weblogic中的load banlance問題

Weblogic中的load banlance問題

編輯:關於JAVA

在一個復雜的企業應用環境中,往往一個application server無法承擔所有的服務請求,所以很多企業都為此架起了多個服務器實例。這些服務器實例結合在一起,可以組織成一個強健的企業運行環境,它易於擴展、支持load banlance, 支持fail over, 可以做到backend server的failure對於客戶是透明的。這樣的一個企業環境就是我們常說的Cluster。Weblogic Cluster提供了多種load banlance的可能, 比如web application請求處理,可以通過proxy來實現(e.g. apache, HttpClusterServlet, IIS), 不同的J2EE Component在Weblogic有不同的load banlance實現.下面我們來逐一看看,

1: Http請求通過proxy實現的load banlance

當客戶端通過proxy訪問Cluster中的業務頁面時,proxy通過自身的算法(round-robin)來實現load banlance.當然這些請求要求是從不同的客戶端(或者不帶session的同一客戶端的請求)發起的.對於同一客戶端,如果頁面中使用了 session, 那麼Weblogic 通過session粘連來實現同一客戶端的請求會被dispatch到primary server上.如果primary server無法提供服務,那麼請求會被dispatch到其他server上。session粘連可以通過以下幾種方式實現:

1.1:browser支持cookie的話,weblogic會把jsession id寫入到cookie中,下次請求提交的時候jseeion id會被提交到proxy端,proxy通過jseeion id 來決定請求的dispatch。

1.2:browser不支持cookie,server端在處理返回頁面時,調用response.encodeURL()來將session id附在url上。

1.3:post-data方式,直接將session作為數據,post到proxy端。

我們來看看weblogic提供的HttpClusterServlet是如何實現load banlance的,

public synchronized Server next() {
       if (list.size() == 0) return null;
       if (index == -1) index = (int)(java.lang.Math.random() * list.size());
       else index = ++index % list.size();
       Object[] servers = list.values().toArray();
       return (Server) servers[index];
}

HttpClusterServlet維護一個managed servlet list,每當一個請求被dispatch到某個managed server後,server list的index加1,這樣在下次dispatch請求的時候,請求將會被dispatch到server list中的其他server上去。邏輯很簡單,但基本也實現了load banlance功能。

2:InitialContext的load banlance

我們知道,每次我們需要獲取jdbc connection, jms connection,ejb stub這類RMI Object的時候,我們都要初始化一個上下文,問題是我們初始化上下文的時候,連接的到底是哪個managed server?

初始化上下文的時候,我們需要提供一個provider url, 如下:

PROVIDER_URL = "t3://localhost:7011";

這種寫法很簡單,直接連接7001對應的server, 但如果寫法如下呢?

CLUSTER_PROVIDER_URL="t3://localhost:7011,localhost:7021";

這時候,load banlance就又來了。10個客戶端(weblogic server或者thin client)new 10個InitialContext的話,這10個客戶端將55分別連接到後端的兩台server上去。實際上客戶端在new InitialContext的時候,weblogic會創建一個T3連接到對應的managed server上(RJVMConnection),注意這個RJVMConnection是個長連接,在同一個JVM中,連向同一managed server的連接只有一個。即如果一個客戶端,連續new 10個 InitialContext, 這10個Context實際上是同一對象,weblogic server這時根本不會和後端的server通訊,因為對象已經在client JVM中有了。

new InitialContext的load banlance算法基本和proxy的算法一樣,都是維護一個server list, 通過index遞增的方法實現。不同的是:在連接某個managed server的connection遇到peer gone的時候, proxy可以recover server list, 而jndi context的load banlance算法則不能。也就是說如果後端有三個managed server, server1, server2相繼出現故障的話,所有客戶端的context將都會連接到server3, 即使server1, server2能夠恢復過來,後續請求也不會連接到他們,除非server3後來出現問題。

值得一提的是:context所有的相關操作時server affinity的,而非load banlance。比如:2個客戶端分別new了個context, 分別連接到server1和server2上,連接到server1的context,做了10次lookup,那麼這10次操作,都在server1上完成,不會在server2上作任何操作。所以說jndi級別的load banlance不是絕對均衡的。

3: JMS Distributed Queue的load banlance

Distributed Queue(簡稱DQ),顧名思義,分布式隊列。在不同的JMS Server上,我們會創建不同的物理Queue, 按照傳統方式,我們在發送消息(或者創建JMSSession)的時候,需要指定一個物理Queue,這樣我們可以將消息發送到固定的Queue上。 由於在Weblogic server上, JMS Server是一個pin service,即只能運行於單個managed server上的服務實例。 如果我們發送消息的時候,指定Queue對應的jms server出現了問題,這樣消息無法發送出去。基於這個原因, Weblogic上提出了DQ,DQ是個邏輯Queue,並沒有時間的物理Queue與其對應,它用於管理多個、分布於不同jms server上的物理Queue, 這樣客戶發送、接受消息的時候,需要指定的是DQ,而不是物理Queue。客戶端知道的只是將消息發送到了DQ,而無法知道到底發送到哪個具體的物理 Queue上了。那麼Weblogic是如何計算消息該發送到具體物理Queue呢?

JMS Connection Factroy的配置選項中load banlance參數:LoadBanlanceEnabled,ServerAffinityEnabled

Distributed Queue的配置選項中load banlance參數:LoadBanlancePolicy,默認為Round-Robin, 可選值包括:Round-Robin, Random

Load Balancing Enabled:

Specifies whether non-anonymous producers created through a connection factory are load balanced within a distributed destination on a per-call basis.

*

If enabled, the associated message producers are load balanced on every send() or publish() .

*

If disabled, the associated message producers are load balanced on the first send() or publish().

ServerAffinityEnabled:   

Specifies whether a server instance that is load balancing consumers or producers across multiple members destinations of a distributed destination, will first attempt to load balance across any other physical destinations that are also running on the same server instance.

Load Balancing Policy:

Determines how messages are distributed to the members of this destination.

Round-Robin

- The system maintains an ordering of physical topic members within the set by distributing the messaging load across the topic members one at a time in the order that they are defined in the configuration file. Each WebLogic Server instance maintains an identical ordering, but may be at a different point within the ordering. If weights are assigned to any of the topic members in the set, then those members appear multiple times in the ordering.

Random

- The weight assigned to the topic members is used to compute a weighted distribution for the members of the set. The messaging load is distributed across the topic members by pseudo-randomly accessing the distribution. In the short run, the load will not be directly proportional to the weight. In the long run, the distribution will approach the limit of the distribution. A pure random distribution can be achieved by setting all the weights to the same value, which is typically set to 1.

JMS Connection Factroy在創建JMSConnection的時候,這一層是load banlance的,即JMSConnection會連接到不同的後端managed server上。這個load banlance是基於round_robin的。一旦connection創建完成,所有通過該JMSConnection創建的consumer, producer會stick到JMSConnection對應的managed server上,即所有的message會被dispatch到該managed server的物理Queue上(因為sub-type的jms對象不是RMI對象,他們和後端managed server的通訊是基於dispatcher的,通過invocable id來識別對象)。如果producer send了很多條message, 那麼這些消息如何分發?這就是Load Balancing ,ServerAffinity要做的事兒。

Load Balancing Enabled被check的時候,消息分發是基於send()方法的,即send一條message, message都會被分發到不同的Queue上。如果Load Balancing Enabled沒有被check,那麼同一producer send的所有message會被分發到同一物理Queue上。而ServerAffinity則說明loadbalance Queue的范圍,如果serverAffinity為true,那麼說明load banlance的范圍為處理send request那台managed server上的Queues,如果為false,則說明在所有的queue間作load balance。

4:EJB的load banlance

EJB的load banlance比較復雜,涉及到如下三個方面:

1:IntitialContext

關於InitialContext, 前面已經談過,這裡不再做討論。

2:EJB Home

對於EJB Home,可以通過weblogic-ejb-jar.xml中的home-load-algorithm 配置,可選項包括:round-robin | random | weight-based | RoundRobinAffinity | RandomAffinity | WeightBasedAffinity, default依賴於weblogic.cluster.defaultLoadAlgorithm,如果沒有對應的system property, 則為round-robin。

如果home-load-algorithm為round-robin,則說明客戶端拿到initial context後,在做ejb home create的時候是round robin的(創建的的bean object位於不同的managed server上)。如果home-load-algorithm為 RoundRobinAffinity ,則表明home create是round robin的,但後續的home的操作則是server affinity的,比如,home位於serverA上,則該 home創建的所有bean object均位於serverA上。

其余算法基本類似,區別只是home create時候的算法不同而已。

3:EJB Object

對於Bean的load banlance,只有stateless session支持,可以通過stateless-bean-load-algorithm配置,可選項同EJB Home。因為stateful session bean及entity bean包含狀態數據,所以無法作laod banlance,否則在數據同步方面,weblogic需要付出的開銷要遠大於laod banlance帶來的收益。

如果stateless-bean-load-algorithm為round-robin,則說明bean操作是round-robin的。如果為RoundRobinAffinity ,則business method是affinity的,即所有的method都在object對應的server上被執行。

5:JDBC

對於JDBC,如果要使用load banlance的話,我們需要配置multi pool,multi pool和jms 的distribute destination類似,是一個邏輯pool,用於管理一組物理pool(通常位於不同的managed server上)。Multi pool的算法包括: HA(用於fail over), Load banlance。前者只是在某個物理pool出現故障的時候,用於fail over,而不提供load banlance。而後者則是兩種功能都提供,正常時作laod banlance,運行故障期間,fail over會起作用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved