很久没有写的什么了。一是因为工作有点忙,二是准备写user profile的,可是一开始调查才发现比我想象的要复杂。倒不是User Profile Manager这个产品复杂,而是User Profile本身有很多种应用方式,使用中又会有很多问题,一下子很难整理清楚。一直不更新又有点对不起大家,干脆换个我比较熟悉的话题先发一个。
有关XenApp的一些基本概念希望大家先读一下eDocs里面的文档http://support.citrix.com/proddocs/index.jsp?topic=/xenapp6-w2k8/ps-designing-wrapper.html。建议对场(Farm),区域(Zone),数据存储(Data Store),数据收集器(Data Collector),XML Broker等概念有所理解的前提下继续往下读。

下面这张图显示了一个XenApp场的基本构成。
一个场里只有一个数据存储。静态的设定信息都在数据存储里面。数据存储可以是Access MDB,也可以是SQL Server,Oracle等服务器。XenApp服务器访问数据存储有两种方式:直接访问和间接访问。直接访问指的是通过ODBC等访问数据库的协议直接访问数据库,而间接访问是指通过访问别的XenApp服务器上的IMA服务来间接访问。一般来说,如果是使用SQL Server和Oracle这类的数据库,场中的所有的XenApp服务器都是直接访问数据存储。而如果使用Access的数据存储,则只有保存数据存储的XenApp服务器是直接访问,其他的XenApp服务器都是通过第一台XenApp服务器来间接访问数据存储。Access数据存储只用于小规模的场,在设计系统时要保证作为数据存储的XenApp服务器处于一个健康状态,因为如果它出现问题将导致其他的XenApp服务器无法访问数据存储。那么当数据存储无法访问的情况下,XenApp的场是否还能继续工作呢?答案是可以,每个XenApp服务器上都有LHC(Local Host Cache)。这个LHC里面保存的是数据存储里面的一部分信息,这些本地的信息可以让XenApp服务器在无法访问数据存储的情况下继续工作。同时LHC的存在也可以大大减少XenApp服务器访问数据存储的次数,只有需要的数据LHC里面没有,或是接到了更新通知的情况下才会去访问数据存储。
每个场中可以有多个区域,而每个区域里有一台数据收集器。数据收集器就是一台XenApp服务器。在同一个区域内的XenApp服务器的其中一台会自动成为数据收集器。当数据收集器出现问题的时候,会有另外一台XenApp服务器自动变成数据收集器。关于如何划分区域,一般来说是以网段为单位。将同一个网段的XenApp服务器放到一个区域内。一个区域内的XenApp服务器会向自己的数据收集器发送自己的负载信息。区域间的负载信息则是数据收集器之间互相通信完成的。
有关详细信息,大家不妨阅读一下这个文档IMA and Zone Data Collector Communication (http://support.citrix.com/article/CTX112525)

接下来,我们就结合XenApp服务器场如何处理客户端的访问要求来深入看一下负载管理的内部。新版本的online plug-in提供两种访问方式,浏览器访问Web Interface站点或者PNAgent,不论哪种方式都要通过Web Interface来访问。Web Interface通过XenApp服务器上的XML服务来取得应用程序的信息。登录在Web Interface站点上的XenApp服务器就被称作XML Broker。XML服务首先会访问同一台服务器上的IMA服务。如果这台XenApp服务器是数据收集器,IMA服务就会先检查有没有这个用户的切断进程,如果没有就会将负载最低的XenApp服务器的地址发送给客户端。如果不是数据服务器,IMA服务会和数据收集器上的IMA服务联系取得负载信息。指定的XenApp服务器的地址通过XML服务传给WI。WI再以ICA文件的方式传给客户端,客户端就会去访问那个XenApp服务器并在那里创建一个进程。如果把每个细节都展开来讲的话,就有点太长了。在这里就将XenApp场如果保存和管理负载信息展开一下。

负载信息是保存在一个叫做Dynamic Store的内存空间的。Dynamic Store内的信息可以通过一个叫做QueryDS的工具来访问。这个工具可以在XenApp DVD的Support\debug文件夹里找到。首先,在命令行执行queryds tables命令就可以看到Dynamic Store内的table列表。然后用queryds /table:<table名>命令就可以访问指定的table内的数据。详细的使用方法请参照这里QueryDS(http://support.citrix.com/article/CTX106318)。

接下来让我们一起看看一个两台XenApp服务器构成的场,用户进程登录进来之前和之后的Dynamic Store的变化。XenApp服务器的负载信息是保存在LMS_ServerLoadTable里面的,在没有用户进程的情况下访问得到下面的结果。这个场里包含了两台XenApp服务器(TKOLSSJ2K3B和TKOLSSJ2K3A),区域名是10.128.5.0。

C:\Program Files\Citrix\debug>queryds /table:LMS_ServerLoadTable

[LMS_ServerLoadTable]: 2 records.

name            : 55cc-000c-000003d3
host            : TKOLSSJ2K3B
zone            : 10.128.5.0
Load            : 0
RealTimeRules   :
LoadBias        : 64
LTLoad          : 0
LTMultiplier    : 2
RuleLoads       : d:0;b:0;

name            : 6f25-000c-000000c1
host            : TKOLSSJ2K3A
zone            : 10.128.5.0
Load            : 0
RealTimeRules   :
LoadBias        : 64
LTLoad          : 0
LTMultiplier    : 2
RuleLoads       : d:0;b:0;

当客户端访问XenApp服务器场并在TKOLSSJ2K3A上建立了一个进程以后,再次访问LMS_ServerLoadTable。我们可以看到TKOLSSJ2K3A服务器的记录多了一行”Load : 64″。64是16位进制的,10进制就是100。如果我们执行qfarm /load命令就会看到A服务器的负载值是100。负载的最大值是10000。因为默认的负载评价设定是100个用户进程,所以每个进程的负载值就是100。

C:\Program Files\Citrix\debug>queryds /table:LMS_ServerLoadTable

[LMS_ServerLoadTable]: 2 records.

name            : 55cc-000c-000003d3
host            : TKOLSSJ2K3B
zone            : 10.128.5.0
Load            : 0
RealTimeRules   :
LoadBias        : 64
LTLoad          : 0
LTMultiplier    : 2
RuleLoads       : d:0;b:0;

name            : 6f25-000c-000000c1
host            : TKOLSSJ2K3A
zone            : 10.128.5.0
RealTimeRules   :
LoadBias        : 64
LTLoad          : 1388
LTMultiplier    : 2
RuleLoads       : d:0;b:0;
Load            : 64

执行queryds /table:Conn_Sessions和queryds /table:Disc_Sessions命令就会看到Conn_Sessions里面有一条记录,而Disc_Sessions里面什么都没有。如果切断这个用户进程,A服务器的负载仍然是100,因为切断不是登出进程仍然在那里。Conn_Sessions的记录就跑到Disc_Sessions里面去了。下次同一个用户再来访问是,就可以根据Disc_Sessions里面的记录将访问引向A服务器。

这个文档对负载管理做了很详细的介绍,有时间不妨读一下Case Study: Load Management Case Study for Presentation Server 4.0 (http://support.citrix.com/article/CTX111035)

XenApp服务器会在新的进程建立后向自己的区域的数据存储器更新负载信息。区域间的负载信息的更新则是由数据存储器之间的通信完成的。再有新的访问要求进来的 时候,数据存储器就可以根据自己的Dynamic Store内的负载信息计算负载最低的XenApp服务器并将其地址发送给客户端。

XenApp服务器的大规模场结构有时会出现黑洞现象(black hole effect)。黑洞现象的原因是多方面的,比如当一台XenApp服务器刚刚启动并通知数据存储器自己的负载的时候,老版本的XenApp会通知自己的 负载为0。这样就会导致数据存储器将新的访问要求转向这台正在启动的XenApp服务器。我们都知道Windows系统刚刚启动的状态负载并不低,CPU 和内存都在忙着启动服务,将很多程序调入内存。通常要等待一会儿CPU使用率才会下降。在这个状态下新的进程要求可能会被处理的很慢,而数据存储器却一直 认为这台XenApp服务器的负载很低,于是不停的将新的进程发到这台XenApp服务器上。结果就是这台XenApp服务器越来越慢进入一种类似死机的 状态,这台XenApp服务器就成了类似宇宙里的黑洞一样,把新的进程要求不断的”吸”进去却无法启动进程。新的HRP导入了对这个问题的对 策,XenApp服务器刚刚启动的时候,如果看ServerLoadTable或是用qfarm /load来查询负载,会发现没有任何进程而负载值却是10000。这不是问题,而是为了防止黑洞效应,启动之后过了一段时间负载值就会开始下降并开始接受新的进程。有关HRP的功能加强可以参照这里IMA Performance and Resiliency Enhancements in Hotfix Rollup Pack 3 for XenApp 5.0 and Presentation Server 4.5 (http://support.citrix.com/article/CTX118658)。这个文档里谈到的是用Farm Monitoring功能来防止黑洞现象。

2010年6月1日

崔嵩