星期三 九月 12, 2007

Access Manager Authentication Module and UI 102


由於自動中翻英的平台對我寫的中文不太"友善",我決定改以英文來分享較技術性的內容。

Hope you have read the 101 article regarding Access Manager (OpenSSO) Authentication Module and UI. This article go further to dig into the Callback XML and corresponding HTML display. The information here is purely from my own test, if anything incorrect, please drop me a comment or send email to me directly (You should know how to get my email from my PGP Key ID).

Authentication Module Callback XML and coressponding HTML display

Take a look at a Authentication Module Callback XML file such as LDAP.xml. You can see a few <Callbacks> elements in the <Module> root element. Each <Callbacks> element represents a HTTP response to user browser and can have various number and type of callback elements. Rendered by a template JSP, the NameCallback, PasswordCallback, ChoiceCallback, and ConfirmationCallback in a Callbacks element will result in HTML elements in one page; Other callbacks such as HttpCallback and RedirectCallback will result in non-200 HTTP response. Out of box, HttpCallback is used by HTTPBasic and Windows Desktop Authentication Module which send HTTP 401 (Unauthorized) to browser to trigger HTTP Basic/Challenge-Response authentication interaction. The RedirectCallback ....is still a mystery to me.

According to the DTD file Auth_Module_Properties.dtd, a <Callbacks> element may have the following attributes:

  • length: integer, should be the number of callback elements in this <Callbacks> element. ie the number of chidren.
  • order: integer, the order number of this <Callbacks> element in the authentication module. The one with order=1 will be automatically picked and displayed by Access Manager when a login request hit the module first time.
  • timeout: "Callback" means server needs "feedback" from user to continue the login process. But what if the user never reply to Access Manager ? How long should we keep his authentication context on server ? A default 120 seconds count down starts at each <Callbacks> UI display. So when a lazy end user submit his callbacks 2 minutes after the page shown, he will be told the session was expired. This is not the SSO Session because he's not login yet. During an authentication process, there is an Authentication Context object created on server side and being kept traced by AMAuth cookie.
  • header: this is the text title on the <Callbacks> page. Like the message "This Server uses LDAP Authentication" on LDAP login page. It is not necessary a static text. In default LDAP module, this header message is altered on the fly to show how mucht time left before password expiration (see source code LDAP.java). AM replaces #REPLACE# string in the LDAP.xml. This attribute will be insert into HTML content, so you can use HTML tag in it and remember to escape "<" and ">".
  • template: a JSP template file name. If not assigned, AM will try to use "Login.jsp" in the same file directory.
  • error: true or false, optional. Default is false. Set this attribute to true when you want to show error message to end user and DO NOT NEED his feedback. Similar to throw LoginException in process( ), the subsequence <Callbacks> will not execute.

Let's dig into the six type of callback elements and what they will be rendered by the default Login.jsp template. Auth_Module_Properties.dtd tells us all the information.

Type Allowed Attributes Allowed Elements
NameCallback

isRequired (true|false)

Prompt
PasswordCallback

isRequired (true|false)
echoPassword (true|false)

Prompt
ChoiceCallback isRequired (true|false)
multipleSelectionsAllowed (true|false)
( Prompt
, ChoiceValues)
ConfirmationCallback None OptionValues
HttpCallback None

( HttpHeader
, Negotiation
, HttpErrorCode)

RedirectCallback method (get|post)

( RedirectUrl
| RedirectData\*
| RedirectStatusParam
| RedirectBackUrlCookie)


Remember, Callback XML file only specifies the skeleton of callback field set, not the HTML presentation. It is Callback UI template's (JSP's) job to produce the final HTML tags. You certainly can create and assign your own template JSP (by using template attribute) for each <Callbacks>, but I don't think many people do so. In all my deployments, template is not customized and default Login.jsp is used everywhere. Once there is a need to change template, I suggest you not to modify Login.jsp directly but create a new one with different name. Login.jsp is too generic to be hacked without side-effect.

The following tables show the callback xml and the corresponding HTML display rendered by Login.jsp.


NameCallback (rendered to INPUT type=textbox)

<NameCallback>
<Prompt>First callback:</Prompt>
</NameCallback>

<NameCallback isRequired="true">
<Prompt>Second callback:</Prompt>
</NameCallback>

NOTE: The slight difference between isRequired=true or false is a leading \* symbol.


PasswordCallback (rendered to INPUT type=password)

<PasswordCallback>
<Prompt>Third callback:</Prompt>
</NameCallback>

20070912-1-3.JPG

<PasswordCallback isRequired="true">
<Prompt>Fourth callback:</Prompt>
</NameCallback>

20070912-1-4.JPG

<PasswordCallback isRequired="true"
echoPassword="true"
>
<Prompt>Sixth callback:</Prompt>
</NameCallback>

20070912-1-6.JPG

NOTE: Login.jsp does NOT recognize echoPassword, it always render a PasswordCallback to
<INPUT type="password"..>. Is it a bug ??

ChoiceCallback (rendered to RADIO)

<ChoiceCallback order="1">
<Prompt>Seventh callback:</Prompt>
<ChoiceValues>
<ChoiceValue>
<Value>Choice 1</Value>
</ChoiceValue>
<ChoiceValue isDefault="true">
<Value>Choice 2</Value>
</ChoiceValue>
<ChoiceValue>
<Value>Choice 3</Value>
</ChoiceValue>
</ChoiceValues>

</ChoiceCallback>

20070912-1-7.JPG

<ChoiceCallback order="1"
multipleSelectionsAllowed="true">
<Prompt>Eighth callback:</Prompt>
<ChoiceValues>
<ChoiceValue>
<Value>Choice 1</Value>
</ChoiceValue>
<ChoiceValue isDefault="true">
<Value>Choice 2</Value>
</ChoiceValue>
<ChoiceValue>
<Value>Choice 3</Value>
</ChoiceValue>
</ChoiceValues>

</ChoiceCallback>

20070912-1-8.JPG

NOTE: Login.jsp does NOT recognize multipleSelectionsAllowed, it always render a ChoiceCallback
to Radio box (Single Selection). Is it a bug ??

ConfirmationCallback (rendered to java script, run onLoad at client side to create HTML button)

<ConfirmationCallback order="1">
<OptionValues>
<OptionValue>
<Value>Option 1</Value>
</OptionValue>
<OptionValue>
<Value>Option 2</Value>
</OptionValue>
</OptionValues>
</NameCallback>

20070912-1-9.JPG


The following tables show the callback xml and the corresponding HTTP response. Login.jsp do nothing with HttpCallback and RedirectCallback.

HttpCallback

<HttpCallback>
<HttpHeader>Authorization</HttpHeader>
<Negotiation>WWW-Authenticate:BASIC realm="basic_realm"</Negotiation>
<HttpErrorCode>401</HttpErrorCode>
</HttpCallback>

Response HTTP 401 (Unauthrozied) with the following headers:

WWW-Authenticate:BASIC realm="basic_realm"

starts Http basic authentication handshake, the AM HTTP Basic Module uses this callback

<HttpCallback>
<HttpHeader>Authorization</HttpHeader>
<Negotiation>WWW-Authenticate:Negotiate
</Negotiation>
<HttpErrorCode>401</HttpErrorCode>
</NameCallback>

Response HTTP 401 (Unauthrozied) with the following headers:

WWW-Authenticate:Negotiate

starts Http chanllenge-response authentication handshake, the AM Windows Desktop Module uses this callback.

RedirectCallback

RedirectCallback is actually a black box to me and nothing can put here. If you know how it could be used, please let me know.


About Localization

AM leverage Java internationalization feature and allow appropriate message display according to browser's language setting. Please take a look at the webapp root directory on your deployment, you may see:

config/auth/default
config/auth/default/Login.jsp
config/auth/default/LDAP.xml
config/auth/default_en/
config/auth/default_en/LDAP.xml
config/auth/default_zh_TW/
config/auth/default_zh_TW/LDAP.xml

My browser language is zh-tw. when I access AM LDAP login page, AM will first look for "config/auth/default_zh_TW/LDAP.xml", if not found, then try to look for "config/auth/default/LDAP.xml". Similar lookup procedure applys to JSP template. Such mechanism allow you to only override the file you need. In addition to localization file lookup, you can even have separate XML and JSP template per Organization(Realm) per Device Type... it is too far away for me.

There are also lots of amXXXXX.properties file in /opt/SUNWam/locale (for AM) or in /WEB-INF/classes (for OpenSSO). You can also localize them by creating amXXXXX_zh_TW.properties file. A handy Java Developer should know what I'm saying.


星期一 九月 10, 2007

Access Manager Authentication Module and UI 101

由於自動中翻英的平台對我寫的中文不太"友善",我決定改以英文來分享較技術性的內容。

Many people who deploy SJS Access Manager first time often want to customize the default login page. It could be piece of cake if you only need to change the UI Layout or swap some canned image file. However, most real-life deployment are not so straightforward. I wish this blog provides you more knowledge on such tasks. Well, SJS Access Manager now is open sourced as OpenSSO Project and the move makes thing easier because we can look into Login Module source.

Let's talk about some basic thing, in case you don't know yet.

Authentication Module and Chainning

SJS Access Manager (AM) is designed to be able to support multiple authentication modules. When a user login against AM, he in fact authenticate against an Authentication Chain. An authentication chain consists of one or more than one Authentication Modules. To setup an authentication chain, you need to select a few modules, define their processing order, and assign each module's significance to entire authentication result. The "significance" I mentioned is called Condition. There are four Condition options you can assign to an authentication module:

  • SUFFICIENT : A successful authentication to this module means successful authentication to the chain. Follow-up authentication modules in the chain WILL NOT be proceed. A failed authentication attempt to this module doesn't mean failure of chain and AM WILL process the follow-up modules to determine the final result.
  • REQUIRED : An attempt to authenticate this module MUST be successful. However, AM WILL STILL process the follow-up modules even a failed authentication attempt occurs. In addition, although this module is required to pass, a user MAY NOT need to authenticate to this module if he already successfully authenticate to a SUFFICIENT module earlier.
  • REQUISITE : An attempt to authenticate this module MUST be successful. If a failure authentication attempt to this module occurs, AM WILL NOT process the follow-up modules and the chain result is failed. In addition, although this module is required to pass, a user MAY NOT need to authenticate to this module if he already successfully authenticate to a SUFFICIENT module earlier.
  • OPTIONAL : I don't know how to describe this type of condition. AM always process the follow-up modules no matter the authentication result to this module.

Let's create an authentication chain like this :




The snapshot from AM console shows an authentication chain having three authentication modules: LDAP, LocalMySQL, and LocalSolaris. They are a instance of built-in LDAP, JDBC, and Unix authentication module respectively. When a user try to authenticate to this chain, he will see LDAP login page first. He is lucky to pass this LDAP authentication, then go straight into the amconsole (or a welcome page). AM won't show him MySQL and Solaris credentials because LDAP is configured as SUFFICIENT. On the other hand, if he failed to login to LDAP, he will be prompt by LocalMySQL login page. He has to pass LocalMySQL authentication because it is a REQUISITE module, otherwise the login to chain will fail.

OK, assume he pass LocalMySQL login, he will see LocalSolaris login page and he has to pass it as well. At this point, the result of LocalSolaris authentication will determine the result of the entire authentication chain.

What is the very first authentication chain you need to login to before creating any other authentication chain ? The Access Manager installer create a default authentication chain called "ldapService" for the use. This default chain only contains one authentication module -- LDAP (or DataStore if you install OpenSSO with local file repository). That's what you usually authenticate to. One important thing is AM separates the login handler for admin console from the one for /UI/Login. As the following picture shown, the Administrator Authentication Chain configuration is for admin console access (/amserver/console); the Default Authentication Chain configuration is for access Login servlet (/amserver/UI/Login). AM installer assigns both to ldapService chain and I altered the upper one to my own chain. My advice is to leave Administrator Authentication Chain unchanged. A bad assignment will result amadmin lockout, be careful.


Login process for a single Module

Now we're going to see how AM navigate login page and the process flow for credential validation.

The diagram on the bottom tells the trick. Before talking about the diagram, you should understand the nut & bolt of AM Authentication Module : Authentication Module Class, UI Callback XML, and UI Callback Template. Here are the details.

Authentication Module Class

It is a Java program. One authentication module typically has 2-3 java classes. The am_services.jar file contains the classes of all built-in Authentication Modules. We usually don't need to touch them (and better not to). It execute the logic to validate credentials given by user, and also callback to UI component when more information needed from user. An authentication module class is a subclass of com.sun.identity.authentication.spi.AMLoginModule, and certainly need to implements the necessary methods such as init( ), process( ), and getPrintcipal( ). AM creates a instance of the module class for each authentication request to this module.

UI Callback XML

Every authentication module should have its own UI Callback XML file, even though it is a zero size file (like Certificate login module). Callback is the fundamental concept brought in by JAAS (Java Authentication Authorization Service). It assume the authentication process may be complex and involve multiple client-server interaction. Server can use callback to request more credential input from client when necessary and the callback question may change on the fly by server due to the result from previous callback. OK, it is just...complex...but flexible.

A UI Callback XML file defines the "questions" AM may ask to user during a authentication process. For better mapping to web interface, AM pre-define several types of callback for your use, such as Text-like, Password-like, or HTTPResponse-like callback. You can find the UI Callback XML files for the built-in authentication module at (assume you install AM on SJSWS7)

/var/opt/SUNWwbsvr/https-yourinstance/web-app/
yourinstance/amserver/config/auth/default/\*.xml

Check out LDAP.xml, AD.xml, and JDBC.xml for reference.

UI Callback Template

A UI Callback Template is a JSP file. Typically it contains HTML tag and AM UI specific tag. It is referred and used by the Callbacks element in UI Callback XML file to render the Callback XML to actual HTML page. You can find the UI Callback Template files at

/var/opt/SUNWwbsvr/https-yourinstance/web-app/
yourinstance/amserver/config/auth/default/\*.jsp

Each <Callbacks> element in Callback XML has an attribute "template" indicating the template JSP for this <Callbacks>. But you may hardly to find a <Callbacks> with template value from all built-in Callback XML files. In fact, AM will use "Login.jsp" as the template JSP for this case. Out of box, the Login.jsp is used by almost all modules for all login page. So be careful of the side effect results from a hacked Login.jsp. My advice is to create your own template JSP.

Be aware that the template JSP is just a template used by AM authentication service. The service utilize JATO framework (a Sun's own MVC framework, like struts), so don't expect you can access the Login.jsp by put its name in URL. It just won't work !!!



OK, let's take a look at the Login Flow Chart step by step :

  1. User bring up browser and access http://yourhost.yourdomain.com/amserver/UI/Login (or via a URL link, or redirect by Policy Agent). Then AM check the domain name and parameters in this request to determine which Authentication Chain should be used. Assume the chain was found and its first login module is "XModule" (maybe somebody else made it), then a instance (Left block in the diagram) of XModule class is created by AM, its init( ) get called for initialization work. After this, AM check XModule's UI Callback XML file "XModule.xml", pick the first <Callbacks> element -- Callbacks Order 1。
  2. Access Manager parse Callbacks Order 1 (2 callbacks and no template assigned). Then it use default Login.jsp as HTML template to render the UI page. The outcome page will contain two HTML input fields. One is for NameCallback; the other is for PasswordCallback. AM also assign IDTokenN as the filed identifier to them. N is the position in <Callbacks> element. For NameCallback and PasswordCallback, their <Prompt> sub-element value will also be shown as leading label text.
  3. User then see the login page with two input fileds, key in the ID & Password.
  4. Then he click "Submit" button, an HTTP POST send the credential (in IDToken1=theid&IDToken2=thepass in body) back to /amserver/UI/Login servlet.
  5. Now it is the show time for module class. Its process( ) method is called with two arguments : a Callback[ ] array containing what user just key in and a Callbacks order number, currently should be 1 telling process( ) to validate credential for <Callbacks order="1"..>. At this point, the control is in XModule program. It should now verify the credentials and return a order number for next <Callbacks> if new question need to ask to user. For most case, the ID & Password pair is sufficient to determine the authenticaiton result and module class can simply return -1 for valid credentials to finish the module. The built-in LDAP module does so, that's why we usually see only one page before LDAP login. However, sometimes you get another page asking you to Change Password because your current password is going to expired. Under the hood, LDAP Server tells LDAP module the password is expiring in xxx days and the module process( ) return 2 to ask for password change. Let's assume our XModule need to ask more and return 2.
  6. Then AM internal found that process( ) returns 2, then check the Callback Order 2 XML-- one PasswordCallback, no template.
  7. AM then use Login.jsp as HTML tempate again, render a HTML page with only one input box for password (IDToken1).
  8. User see the 2nd page, then type in the password as requested.
  9. Then he click "Submit" button again. an HTTP POST send the credential back to /amserver/UI/Login again. The same XModule instance's process( ) get called again, but with new callback[ ] and State argument values. This time the State =2. You surely know why.
  10. The process( ) run different logic according to different State value (You should code it so). But the basic rule doesn't change:
    > return -1 if the credentail is valid and no more question for user OR
    > throws AuthLoginException if you're sure the login attempt is failed OR
    > return another order number if you need to ask more
    To complete my long diagram, we assume the picky XModule still need to ask more, and return 3.
  11. AM get 3 as return, similar to step 7, callback to user, and then get back... the interaction keep going.
  12. Finally, during processing Callback Order 4, module class can determine it is a successful login (Thanks God), return -1.

Above is a perfect scenario, but what if an error occurs in module class and you need to terminate the process immediately? You just need to throws a AuthLoginException anywhere anytime in process( ) method. When AM caught such exception, the follow-up order will not be executed and usually user get authentication failed or server internal error message. Depends on the severity of the error and module Condition, sometimes AM will forward user to next module.



星期一 四月 09, 2007

Sun Web Server 連線要求處理機制

時常被問到 Sun Java System Web Server (SJSWS) 有那些調校的空間。其實可調的參數很多,看你要調的是那一方面的功能。完整的調校除了 Web Server 本身設定之外、也必須包括底層作業系統的 TCP/IP 參數及檔案系統等非直接由 Web Server 控制但會被利用到的元件。建議先詳閱 Sun 官方調校文件,7.0版的文件為 Sun Java System Web Server 7.0 Performance Tuning, Sizing, and Scaling Guide,6.1 版的文件為 Sun Java System Web Server 6.1 SP4 Performance Tunning, sizing, and Scaling Guide,二個版本的調校原理是一樣的,能調的參數也差不多,最大的不同點是在於 7.0 大改管理架構,所以很多參數的名稱及設定位置在 7.0 及 6.1 是不一樣的。

由於參數很多,初閱調校文件時,你大概不太能了解每個參數彼此間的差異。我想最重要的是先了解 SJSWS 處理 HTTP 要求整個流程,才不會迷失在冗長的調校文件中。這是本篇重點,OK,進入主題吧 !

當遠端使用者以瀏覽器向你的 SJSWS 伺服器存取網頁時,在伺服器端發生下面的動作:

  1. TCP 連線 (Connection) 建立。
  2. 由接收緒 (Acceptor Thread) 接收來自遠端的 TCP 連線。
  3. 將接收的 TCP 連線排入佇列,等待工作緒 (Session Thread) 處理
  4. 工作緒處理 Http Request 。
  5. JVM 處理及回應 。

請不要忘記:雖然大多數人佈署 Java Web Application (WAR file) 在 SJSWS 上,但是這只是其中一種應用。SJSWS 並不是僅能處理 Servlet/JSP 要求。它是一個多功能的 HTTP Server ,也非常適合佈署 PHP、Perl、CGI 等程式。在以上的五個動作中,1-3 是處理 Connection 的動作,是由 Native Code 執行,4-5才是處理 HTTP 要求的動作,視所要求的程式為何,若為 Servlet/JSP 要求則由內部 in-process 的 JVM 處理,若為 PHP要求 則由 PHP 的 plugin 處理。習慣用 Apache 或是 Tomcat 的人常希望能以 Apache vs SJSWS 或 Tomcat vs SJSWS 來做評比,我認為以功能面來看,SJSWS = Apache + Tomcat。有與趣的請參考我之前的 Blog

好,細說各動作如下。

TCP 連線 (Connection) 建立

這一個階段和 SJSWS 沒有直接關連,而是使用者及伺服器二方 TCP/IP 層的互動。HTTP 依賴 TCP/IP,所以瀏覽器要送 HTTP request 前需先建立 TCP 連線。連線建立過程是利用所謂的 three way handshake (見 RFP 793 3.4 節) ,如下:

  1. 瀏覽器 --- [SYN] ---> Web伺服器
  2. 瀏覽器 <--- [SYN+ACK] --- Web伺服器
  3. 瀏覽器 --- [ACK] ---> Web伺服器

此時連線正在建立(也就是還沒有建立完成), 伺服器端 TCP 層需暫存住已發出 SYN+ACK 但還未收到 ACK 的連線要求。這一個暫存空間的大小由作業系統控制,以 Solaris 為例,是 tcp_conn_req_max_q0 參數(預設值為 1024)。

由接收緒 (Acceptor Threads) 接收來自遠端的 TCP 連線

當 handshake 完成後,二端 Socket Pair 確立,連線建立完成,SJSWS 隨時可接收(accept) 這一個連線。在被接收前,會被暫放在 listen backlog 中,SJSWS 的 listenQ 參數 (預設值為 128) 及 Solaris tcp_conn_req_max_q (預設值為 128) 都會對這個 backlog 的大小有影響,調整時二個參數要一起調。

官方文件建議將 tcp_conn_req_max_q0, tcp_conn_req_max_q, 以及 Web Server 的 listenQ 參數設定成同樣的值,如 8192 (視伺服器大小而異)。

接收連線是 Acceptor 的工作,SJSWS 的 Acceptor 是指一個或多個 Acceptor Thread(s),負責將 listen backlog 中的連線接收進來放到 Connection Queue 中。可調的參數為 Acceptor Thread 數目 (預設值為 1),建議設定值為 CPU 的數目,但 loading 很大的伺服器可調為 CPU 數的二倍。

將接收的 TCP 連線排入佇列,等待工作緒 (Session Threads) 處理

如前所述,連線被Acceptor 接收後即被丟入 Connection Queue 中,等著被 Session Thread 處理。後方 Session Thread 的執行往往是最花時間的(真正在執行 Servlet/JSP, PHP 等程式碼),所以連線在 Connection Queue 中等待的時間通常會最久。Connection Queue 的大小是由 SJSWS 的 connQueueSize 參數 (預設 4096) 決定。

HTTP 1.1 版有所謂的 Connection Keep Alive 功能,不必每一個 HTTP Request 都重建 TCP Connection,這一類的 Connection 在第一次被 Acceptor 接近來並處理後,就會由 Keep Alive Thread 及單獨的 Poll 接管以處理後續的 HTTP 要求。SJSWS 對於 Keep Alive 機制也有參數可調,如 MaxKeepAliveConnections 指定同時可保留的數目、 KeepAliveTimeout 指定連線最大閒置時間 (防止不負責任的客戶端程式不結束連線) 等。


工作緒處理 Http Request

到此之前,SJSWS 都是在消化及暫存 TCP 連線 ,還沒正真開始處理 HTTP 要求。處理 HTTP 要求是工作緒 (Session Thread) 的責任。

當連線進了 Connection Queue 後,SJSWS 會檢查是否有空閒的 Session Thread 可消化 Queue 中的連線,若有,則將其拉出 Queue 並等給一個空閒的 Session Thread 處理。若沒有空閒的 Session Thread,則會視設定來判定是否要動態增加 Session Thread。Session Thread 的數量等於是伺服器能同時平行處理 HTTP 要求 (通常是指執行 JSP/Servlet) 的能力。Session Thread 的多少是由 SJSWS 的 RqThrottle (預設值為 128) 及 RqThrottleMin (預設值為 48) 來決定。

RqThrottleMin 決定伺服器在剛啟動後或空閒時最少要保持的 Session Thread 數目;RqThrottle 則決定伺服器最多能保有的 Session Thread 數目。調整這個參數要小心,不要太大以免用光系統資源。RqThrottle 是 128,通常不會加到 500 以上。

JVM 處理及回應

Session Thread 是 Language Neutual 的,也就是說 Session Thread 並不是專門處理 JSP/Servlet。在處理 HTTP 要求時,Session Thread 會依據 mine.conf 及 obj.conf 檔中所定義的指令來決定由何種 plug-in (Perl Plug-in, PHP Plug-in, J2EE Plug-in, 或 ReverseProxy Plug-in)來接手。 各種不同型式的 plug-in 也都有自有的調較方法,而且這程調校通常對效能影響最直接也最大。

例如你若用 SJSWS 來佈署 Java Web Application (JSP/Servlet) ,就不要忘記調校 JVM 的設定。最常調的 JVM 設定就是 Heap Memory Size,若 Heap Size 不夠會嚴重影響 Java 程式效能。它的大小由 SJSWS 的 JVMOPTION Xms 及 Xmx來設定。要小心,不要太大,否則易導致 Out of Memeory Exception。

SJSWS 還有很多很多的參數可以調,實在是族繁不及備載。一般在做效能調校時最常要動到的有 :

  • SJS Web Server (以 SJSWS 6.1 為例)
    • JVM Heap size (server.xml)
    • RqThrottle, RqThrottleMin (magnus.conf)
    • connQueueSize (magnus.conf)
    • listenQ (magnus.conf)
    • MaxKeepAliveConnections (magnus.conf)
    • Access & Error Log (server.xml)
  • TCP/IP (以 Solaris 為例)
    • tcp_conn_req_max_q (ndd command)
    • tcp_conn_req_max_q0 (ndd command)
    • tcp_time_wait_interval (ndd command)
    • file descriptor size (etc/system)

效能調校是取捨的藝術,管理者必須決定應該來者不拒(但回應超慢);或是拒絕過多要求(但保持原有連線的服務品質)。盲目地加大參數值只會吃掉資源,但不見得真的會用到 ?

還有,參數和實際效能不是線性關係,只有"合理"的壓測結果才能推估真實的效能。有時會看到效能需求如 "系統應可承受2000人同時使用".....但是沒有服務水準的要求。若平均回應速度慢到 3 分鐘,是否也合乎客戶的要求 ? 還有 "2000 人同時" 的情境要如何在壓測中模擬,也要很小心。2000 Active Users 和 2000 Concurrent Connections 和 2000 Concurrent Requests 是很不一樣的。

星期四 三月 08, 2007

Java Enterprise System 5 已經出爐!!

Java Enterprise System (JavaES) 5 已經推出了。從 Sun 的網站上可以下載,有很多新的功能等你來發掘。今後 Java ES 版本的命名改用數字制,不再使用以往的 YYYYQX 年季制。英文的縮寫也要"正名"一下,請用 "Java ES" ,而不是 "JES"。另外原本在舊版中的 Communication Suite (Messaging, Calendar, Instant Messaging Server 之類的) 產品自本版起不再包含於 Java ES 之中。在 Java ES 5 各產品的新功能裡面,最引人注意的是在 SJS Web Server 和 Directory Server 的大改版。

Java ES 5 中的 Web server 已由 6.1 昇級為 7.0 版,相關的改變我已在前一則 blog中提過。

Java ES 5 中的 Directory Server 已由 5.2 昇級為 6.0 版,這是一個很大很大的更新。6.0 版的管理架構是全新的概念,原有的 Java Console 介面已不再使用,改以 web based 的管理介面代之。這個管理介面主要是給管理者用來對多個 Directory Instance 及 Directory Proxy Instance 做集中管理,並且大幅減化設定及管理 replication 所需要的工作。並且可以看到 replication 的 topology diagram。

你若是 DS 5.x 的愛用者,在使用 6.0 時會找不到 o=NetscapeRoot 這樣的 suffix 。由於整個管理的方式不再依靠 Java Admin Console,所以原來的 o=NetscapeRoot 沒有存在的必要。

Directory Proxy Server 也加入了 virtualization 的功能,可以將一個 RDBMS 做為其後端的資料源。還有提供 affinity 的功能,在較多層的架構中能避免掉寫後即讀動作因 replication latency 所造成的問題。由於這項功能的突破,加上沒有 Master 數目的限制,以及支援 binary copy 的起始化方式,自 Directory Server 6 之後,也漸漸不需要 read only 模式的 replica了,建議以 Directory Proxy + Master instances 做為最基本的組合 。

我想大家都需要一段適應期。畢竟改的更多是為了要改的更好。

星期四 二月 01, 2007

簡單最好

大部份企業客戶對目錄服務的需求不外乎是要把"人"及"組織"放在目錄服務中。但是如何放是見人見智的。有些人認為目錄服務樹既然是多層次的,所以就是要用來存放公司組織架構,並把人員分散在各組織中。然而也有人習慣平坦的架構,把所有的"人"都放在同一層內。那一種好 ? 簡單最好。

根據 Sun 原廠目錄服務課程 DIR-2217 (Directory Service: Analysis and Planning) ,在選擇目錄服務的樹狀分支(branch) 時,要避免以組織架構做為依據,尤其是組織架構是常會修改的。這種設計會增加很多管理上的負擔。

並建議以以下三種物件為分支原則:
  • People
  • Places
  • Things
其中在處理 People 時,特別建議使用平坦式的架構
People are normally defined at the end of a branch in a directory (some may call this a leaf point). Consider putting all people together on one branch point. This will save you from moving them every time they change positions within the company or organization. Use an attribute within the entry to describe the organization where they work instead of using a branch point to describe the organization.
Places 是地域性的考量,若你需要將部份資料複製到遠端,就要建立對應的分支:
Places are physical locations. Consider a tree design that is structured by places when you plan to replicate branches out to remote site. Consider a tree structure that is easy to replicate when the data needs to be mastered in various locations.
至於 Things 就其他所有非人非地域性考量的物件。目錄服務不是只用來存帳號密碼及組織的,目錄可以是任何事物的列表。如伺服器、印表機、大樓、會議室、或 Internet Domain 等。

DIT 設計是 art,所以沒有準則。但是依經驗來看,層次多的DIT 往往在管理上很痛苦。所以簡單最好。




powered by performancing firefox

About

純粹個人經驗分享,並非官方立場。

Search

Archives
« 四月 2014
星期日星期一星期二星期三星期四星期五星期六
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今日