分類
程式技術

Apache的PreFork MPM功能

Apache, 用了很久, 但的確沒有好好研究過有關於 performance tuning 這塊. 事實上, 這個免費的 web server 功能真的十分強大, 尤其是可以載入的模組也多, 在使用上, 真的有許多沒有深入研究就學不到的內容.

首先我們來看有關於 MPM 的一些資料:
http://dz.adj.idv.tw/archiver/tid-214.html
在 MPM中, prefork 及 worker 是兩種不同的 multi-processing module, 在 apache 管方網站上分別有對這兩個 module 有深入的介紹:
http://httpd.apache.org/docs/2.0/mod/prefork.html
http://httpd.apache.org/docs/2.0/mod/worker.html
這二者只能擇其一來使用, 一般來說, 雖然 prefork 比較佔用記憶體, 但相容性及穩定性較佳, 也是在 FreeBSD 下安裝 Apache 的預設 MPM module.

事實上, 預設的 prefork mpm 參數如下:

<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>
分類
Database

SQL 2005的HashBytes function (MD5, SHA1)

在 SQL 2005版本中, 已內建了 HashBytes function 用來做 Hash 的功能, 可以參考該 function 的用法: http://msdn.microsoft.com/en-us/library/ms174415.aspx. 不過這個功能在 SQL 2000 的版本內並無內建, 若有需要可以參考 code project 上的 MD5 Hash SQL Server Extended Stored Procedure, 或是使用純 T-SQL 的方式的 MD5 : MD5算法的T-SQL實現(FOR SQL2000) .

使用方式很簡單, 直接呼叫 HashBytes 函數並指定演算法即可, 如下:

select HashBytes('MD5', '1234')

不過傳回的是 varbinary , 若是要取回為字串的型態, 得再用 sys.fn_VarBinToHexStr() 這個 function 來轉換, 如下:

select sys.fn_VarBinToHexStr(HashBytes('MD5', '1234'))

參考文章:
好用的 MS SQL 2005 欄位字串加密應用 ( MD5 與 SHA1 )
SQL Server 数据库中的 MD5 和 SHA1

另外若是要作密碼加密使用的話, 在 SQL 2000 中有內建 PWDCOMPARE, PWDENCRYPT 這些函數可供使用, 可以參考 BlueShop 討論.

分類
ASP

自訂host的方式進行webrequest (ASP)

XML HTTPRequest , 是 ajax 的一個重要元件, 不過一直有一個問題就是指定 Request Header 的這個部分, 在 XML HTTPReqeust 裡, 使用 setRequestHeader 的這些 header 有些是可以指定的, 有些是似乎是 read-only 的, 這裡要談的就是 host 這個標題.

在 client side 的狀況下, 這件事似乎是完全不用考慮的, 因為 client-side javascript 在瀏覽器的控制下, 本來就不允許做 crossdomain 的 access 的(這是基於安全性的考量), 即使是相同子網域也一樣, 相關資料可以參考: Javascript的同一父網域下的crossdomain問題. 不過若是在 server side 就不是這樣了, 在 server side 有時可能需要做為 client 的 remoting 或 gateway 的關係, 也會利用相同的方式進行 http reqeust, 在 asp 程式碼中, 若是需要做這個功能, 一樣是起 MSXML2.XMLHTTP 這組 xml webreqeust, 不過仍有指定 host header 的問題, 即使使用了 setRequestHeader “Host”, “bbb.com.tw” 的方式, 仍無法變更原來在 Open 方法內使用的 url 指定為 http://10.10.10.10/xxx 中的 10.10.10.10 的 host header , 不過用 setRequestHeader “Host”, “bbb.com.tw” 也不會有任何錯誤.

這裡將介紹另一組 api 供類似功能, 但又可以指定 Host Header 功能的一組元件, Windows HTTP Services, 這組元件用法幾乎和 MSXML2.XMLHTTP 完全相同, 而且又可以指定 Host, 所以在使用上可以有更多的應用, 例如多主機架構下, 指定 ip 方式訪問主機, 並帶上對應的主機標題(Host Header), 如此一來便能在指定 ip 下的 http 訪問又能加上 host header.

以下為範例程式碼:

Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
WinHttpReq.Open "GET", "http://192.168.1.1/test.php", false
WinHttpReq.SetRequestHeader "Host", "myurl.com.tw"
WinHttpReq.Send
httprsp = WinHttpReq.ResponseText
Set WinHttpReq = Nothing

這個最大的用途是做測試環境及主機標題限制狀況下使用, 又或多主機(平衡負載)對應時, 要指定訪問固定主機的頁面時會使用到.

分類
.net

StringDictionary強制型別字字典class

在 .NET 裡有個內建的 Hashtable (System.Collections.Hashtable) 可供做 Key/Value Pair 使用, 不過若是要再增加效能, 可以考慮使用 StringDictionary 強制型別字串對照字典, 名稱空間是在 System.Collections.Specilized.StringDictionary . 使用強制型別可以有效提升效能, 原本的 Hashtable 是可以存放 object / object 的方式, 當然也可以存放 string / string , 但總是多了 object 與 string 間的轉換, 而且也容易放錯資料進去, 若是有強制型別的 StringDictionary class 來存放這樣的資料, 在型態上及在效能上都能有效提升.

該 StringDictionary 的使用方式請參考: MSDN Link

其他相關的資料可以參考 Hashtable, 泛型的 Dictionary, 泛型的 KeyValuePair,

其中泛型的 Dictionary 就是利用 Template 進行 Dictionary 的宣告, 讓 Dictionay 的存放資料的型別為指定的型別, 例如:

Dictionary<string, string> dicData = new Dictionary<string, string>();

dicData.Add("a","apple");
dicData.Add("b","banana");
分類
Database

利用CTE將分頁資料取出-Stored Procedure篇

之前在 用CTE來取出指定筆數 – SQL2005 這篇介紹了如何利用 CTE 來取出指定的筆數, 這篇文章將進一步實作一支 stored procedure 做為方便分頁的方式.

主要是為了方便取出指定的筆數來實作的, 所以傳入的參數很單純, 就是原本的查詢指令, 將查詢及排序條件分開, 並指定開始的索引值和結束的索引值即可, 建立的程式碼如下:

create proc sp_getRecordByCTE 
@sqlcmd nvarchar(4000),
@ordercmd nvarchar(1000),
@startindex int,
@endindex int
as
declare @mycmd nvarchar(4000)
select @mycmd = '
with myctequery as (
select row_number() over ( ' + @ordercmd + ' ) 
as CTESN, '+replace(@sqlcmd,'select ',' ')+' )
select * from myctequery 
where CTESN between ' + convert(nvarchar,@startindex) + ' and '+convert(nvarchar,@endindex) 
exec sp_executesql @mycmd

其中比較特別的是為了方便輸入起見, 只要將原來查詢指令的非排序部分和排序部分分開即可, 簡單範列如下:

原來的查詢是:

select a.orderid, a.orderdate, b.custname, b.custaddr from orders a inner join cust b on a.ordercustid = b.custid order by a.orderdate desc

利用上面的 stored procedure 做指定分頁的筆數若為 51~100 (每頁50筆的第二頁), 先將指令區分為紅色查詢及藍色排序, 並且如下輸入給 sp_getRecordByCTE:

exec sp_getRecordByCTE
'select a.orderid, a.orderdate, b.custname, b.custaddr from orders a inner join cust b on a.ordercustid = b.custid',
'order by a.orderdate desc',
51,100

便能將指定的分頁第二頁(51~100)這些資料取出, 這樣和使用 ADO 分頁比較, 不僅可以降低 network IO 外, 更能在複雜查詢時提升效能, 減少不必要的資源浪費, 對於網頁分頁使用時有很大的幫助. 不過目前尚有一個問題無法解決, 就是總筆數這個部分, 因為利用 ADO 查詢時, 可以取得總筆數這個資料, 利用這個 stored procedure sp_getRecordByCTE 將無法取得這個資訊, 看是否有沒有什麼好方法來做這個資料的取得及回傳, 若各位有什麼好建議也歡迎給我建議!

希望這個 stored procedure 對各位能有所幫助.

繼續閱讀:

分類
.net

C#判定BIG5字碼的方式

繼上一篇 如何在ASP內判定BIG5碼中文字 之後, 再來整理一下在 ASP.NET C# 中判定 BIG5 碼的方式, 其實方式一樣很單純, 不過不需要利用到轉碼的 code page, 只需要利用 System.Text.Encoding 即可順利判讀, 程式碼如下:

Boolean IsBig5(string strOne)
{
    Boolean bIsBig5 = false;
    byte[] ByteArrayBig5 = System.Text.Encoding.GetEncoding("big5").GetBytes(strOne);
    if (ByteArrayBig5.Length == 2)
    {

        //check A440~C67E 常用字, C940~F9D5 次常用字 

        //42048~50814, 51520~63957            
         
        int iCode = ByteArrayBig5[0] * 256 + ByteArrayBig5[1];
        if ((iCode >= 42048 && iCode <= 50814) || (iCode >= 51520 && iCode <= 63957))
        {
            // chinese char big5 
            bIsBig5 = true;
        }
    }
    return bIsBig5;      
}

利用了 Encoding 的 GetBytes 方式, 取出在 strOne 中的一個字元, 並判定是否為 2個 byte 後, 一樣利用了原來的判定方式, 若落在對應的區間內, 就可以判定為 BIG5 字元集內的字了!

分類
程式技術

好炫的不用javascript程式判定browser方式

一般我們在判斷 client 的 browser 時, 是利用 javascript 取得 client browser 屬性, 若是不使用 javascript 的狀況下, 如何能做到呢? 可以利用 html hack trick 方式來達成, 這篇文章
http://wafful.org/~takesako/html20hacks/browser-detect2.html
介紹了這個方式:

<img

 /''src="firefox.gif"
 /""src="sleipnir_gecko.gif"
    "src="safari.gif"
   ""src="konqueror.gif"
 /src="ie.gif"
   src="opera.gif"
   src="lynx.gif"
>

只能說真的太神奇了, 利用了 browser 的解析方式, 來判定 browser 的型態, 這篇同樣利用類似的方法達成:
http://wafful.org/~takesako/html20hacks/browser-detect.html
不過 html 碼就不是可視字元囉.
利用這種方式來判定 browser 真的很有趣.

相關文章:
http://www.hedgerwow.com/360/dhtml/html-browser-detection.html

分類
Javascript

Javascript的同一父網域下的crossdomain問題

今天在處理一個單純的 popup window (利用 window.open) 的子視窗, 在子視窗內進行 window.opener 的函數調用, 一般的狀況下, 都在同一網站(列如都在 www.foo.com)下沒有 cross domain 的問題, 但若是在兩個不同 domain 時(例如 www.foo.com 及 www.foo2.com), 就會有 cross domain 問題. 這個其實是一個單純的 security 問題.

不過若是今天是在同一家公司內的 cross domain, 例如 www1.foo.com 及 www2.foo.com 兩個 domain 下要執行這樣 cross domain 時, 是否能解決呢? 答案是肯定的, 其實和 cookie 域名共用設定方式相同, 上級域名共用的狀況下, 可以進行 document.domain 的設定以達成此項目的.

我們可以分別在 page1 在 www1.foo.com 及 page2 在 www2.foo.com 的網頁內 javascript 要執行 cross domain 指令前先執行

document.domain = "foo.com";

再繼續後續的程式碼即可, 這樣就不會有 cross domain 的問題囉.
不過也是有一些限制, 就是必須是在同樣的上級域名下, 才能使用, 而且也無法在 www1.foo.com 上將 document.domain 設定為 foo2.com 這樣的 domain, 這個原理其實和 cookie 的 domain 原理是相同的.

參考資料:
http://www.lhelper.org/tech/communicate_between_domains.html
http://www.cnblogs.com/xiaozhang/archive/2006/07/27/461306.html
http://www.mozilla.org/projects/security/components/same-origin.html
http://msdn2.microsoft.com/en-us/library/ms533028.aspx

分類
Database

查詢SQL Server中Table是否有Primary Key

資料庫中的 table, 大家都知道 primary key對 table的效能影響很大, 沒有主鍵的 table, 對於一般在程式實作時會有一定的困難, (某些狀況下例外, 例如 log), 尤其是在更新列時, 沒有 primary key時的時候, 效能根本是很糟糕的, 更危險的是可能會有資料本身邏輯上的問題. 今天我們不是來探討 primary key 的重要性, 而是找出資料庫中, 沒有 primary key 的 table.

其實很簡單地可以利用 sysobjects 這個系統表來查詢, 簡單描述如下, 我們利用 sysobjects 對自已對照, 並利用 parent_obj 這個欄位來串接起來自已對應自己的查詢, sysobjects 內有 table, view, primary key (index), 等資訊, 而我們就利用這樣的方式來進行查詢, 整理好的查詢如下:

分類
Database

x64下odbc建立問題

今天在處理一個 odbc 建立在 x64 (64bit) server 2003 上的狀況, 狀況十分奇妙, 一般我們在設定 odbc 時, 是直接使用 [系統管理工具] 裡的 odbc 來進行設置, 當我設置好了之後, 有趣的事發生了, 居然透過 odbc 連接 db 的程式有個這樣的 exception:

[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

如此一來設置好的 odbc 就形同虛設, 查了半天也查不出原因, 後來在 google 上找到一篇 citrix 的 kb (link) 試了一下, 居然就好了, 可以找得到了, 仔細檢查一下原因, 整理如下:

在 x64 內透過 ui 建立的 odbc 是 64bit 的 odbc, 而原來執行的程式若是 32bit 的話, 是看不到這組 odbc 的, 也就是說 odbc 也是有區分 64bit / 32bit 的. 如何判斷原來 ui 上的 odbc 是 64bit 的呢, 我們看一下畫面截圖: