JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Application Server  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
作者 高速Web Server G-WAN 介紹
kentyeh





發文: 643
積分: 6
於 2014-11-29 07:13 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
如果您想要要蒐集很多資料,然後寫到NoSql資料庫(RDB太慢了),例如像 Googl analysis,亦或是
股票報價,或是Chat程式,那麼也許須要一個很快的WebServr。

原本以為nginx已經夠快了,上網查了一下”最快的 web server” 居然跑出一個cherokee, 但是很可惜
找不到相關的benchmark,倒是發現了一個叫做G-Wan(freeware,若要source code或服務需要花白
花花的銀子)的Server提出一堆測試報告(在1GbLan+CPU6核下最快每秒可接受85萬request,測試
Java也比Tomca快了十倍以上,記憶體用量也只有1/4),表現出服務人次多、記憶體用量小的特點
(當然你說快,還是有人更快,例如Monkey),但是有一個特點就是G-Wan它可以處理包含C、C#、
Java、Go在內的16種語言(除了C外其功能它都很陽春),而nginxMonkey都只能處理一兩種Script,
大概這兩個只是為了取代apache http(我覺得nginx最重要的功能是做reverse proxy)。

在G-Wan的首頁上開宗明義的寫道:C、C#或Java可以用更少的CPU與記憶體執行更
多的Request,對其它的語言只能受益於多核執行(也許是說如果是單核CPU,那就沒
有特別優勢),但從它的首頁圖表來看,除了C與PHP外,其它每秒所能接受的reqeust
差異不大。

安裝

若是嫌麻煩,可以下載這個這個Scirpt檔,解開後(GO版本有點舊,自行開啟修改)執行,則會用互動
式問題安裝。

目前試裝(手動與自動都試了)的結果,在Centos 7無法執行(不知道為什麼),以下是我在Fedora 20
下手動安裝的過程(golang一定要裝,不然會無法啟動)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$yum -y install tar bzip2 wget golang gcc
#因為它要求執行 /usr/loca/go/bin/go
$cd /usr/local
$ln -s /usr/lib/golang go
$cd /usr/local/go/bin
$ln -s ./linux_amd64/go go
$ln -s ./linux_amd64/gofmt gofmt
#下載G-Wan
$cd /opt
$wget http://gwan.com/archives/gwan_linux64-bit.tar.bz2
$tar -xjf gwan_linux64-bit.tar.bz2; cd gwan_linux64-bit
#自行安裝JDK,安裝JDK後export  JAVA_HOME,CLASS_PATH(如果用scala則還要
#加入scala-library.jar),其它OS或許要再把$JAVA_HOME/bin加入PATH並export
#因為我用的是Oracle JVM
$export JAVA_HOME=/usr/java/default 

建議把以下內容(由上面那個安裝Script加的)加入 /etc/sysctl.conf
$vi /etc/sysctl.conf
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fs.file-max = 5000000
net.core.netdev_max_backlog = 400000
net.core.optmem_max = 10000000
net.core.rmem_default = 10000000
net.core.rmem_max = 10000000
net.core.somaxconn = 100000
net.core.wmem_default = 10000000
net.core.wmem_max = 10000000
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_congestion_control = bic
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_max_syn_backlog = 12000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_mem = 30000000 30000000 30000000
net.ipv4.tcp_rmem = 30000000 30000000 30000000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_wmem = 30000000 30000000 30000000
#
# Optionally, avoid TIME_WAIT states on localhost no-HTTP Keep-Alive tests:
# "error: connect() failed: Cannot assign requested address (99)"
# On Linux, the 2MSL time is hardcoded to 60 seconds in /include/net/tcp.h:
# define TCP_TIMEWAIT_LEN (60*HZ). This option is safe to use in production.
#
net.ipv4.tcp_tw_reuse = 1
#
 
#
# WARNING:
# --------
# The option below lets you reduce TIME_WAITs by several orders of magnitude
# but this option is for benchmarks, NOT for production servers (NAT issues)
# So, uncomment the line below if you know what you're doing.
#
#net.ipv4.tcp_tw_recycle = 1
#
 
#
# other settings found from various sources tp be included into sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.ip_forward = 0
net.ipv4.tcp_dsack = 0
net.ipv4.tcp_fack = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_retries2 = 15
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_moderate_rcvbuf = 1
kernel.sysrq = 0
kernel.shmmax = 67108864
#
# End of modifications


試用, 第一步先建立Jar檔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$vi HelloWorld.java
  public class HelloWorld{
     public String greet(String name){
          return "Hello "+name+".";
     }
  }
$javac HelloWorld.java
$jar cvf HelloWorld.jar HelloWorld.class && rm -f HelloWorld.class 
$cp HelloWorld.jar /somewhere/ 
#設定環境變數CLASSPATH指到剛建立的Jar檔
$export CLASSPATH=.:/somewhere/HelloWorld.jar
$cd /opt/gwan_linux64-bit
$vi ./0.0.0.0_8080/#0.0.0.0/csp/hello2.java
  import api.Gwan;
 
  public class hello2 // the class name MUST match the script *.java filename{
     public static int jmain(long env, String[] args){
     //無法使用UTF8字元,必須編碼
         Gwan.xbufCat(Gwan.getReply(env), new HelloWorld().greet("您好")+(args.length>0?args[0]:""));
            return 200;//回覆http statuc code,若不回覆內容可回覆 204
     }
  }
$curl http://192.168.10.xx:8080/?hello2.java 
#開啟網頁, 注意到了嗎,執行程式一律放在/csp目錄內,且要用/?程式名稱開啟,有參數再用 &variable=value 串起來,還有編碼要自行處理

註:
G-Wan執行中修改 .c 的檔案,可以更新,但是修改 .java 則無法重新載入(必須重啟G-Wan)

gwan的目錄結構
1
2
3
4
5
6
7
8
9
10
11
/gwan 目錄/0.0.0.0_80    /#0.0.0.0/www        #靜態文件放此
               聆聽所有網     |    /handlers    #處理 Server 行為
               卡的 Port 80  |    /csp           #c,java,c#...的程式碼放此
                             |    /gzip          #建一個暫存目錄
                             |    /cert          #憑證檔置放處
                             |    /log           #log 輸出位置,若不要則移除
                網域名或 IP 位址以#開頭的叫根 Host,
                一定要存在一個 root host,否則無法啟動。
                以$開頭的為 Virtual Host,可以有多個以服務不同內容,
                也可以 ln -s 到其它目錄,例如建立以下目錄
                /$www.example.com.tw


若是Virtual host的內容與Root Host的內容相同,可以不需要用ln -s 作連結,例如上述的
$www.example.com.tw直接開一個 #0.0.0.0:www.example.com.tw 空目錄即可,裡面不
須要放任何東西(官方稱為alias)。
如果有多個網路Interface, 上述的0.0.0.0可以改成實際IP,並建立不同 xxx.xxx.xxx.xxx_80,
可針對不同網路Interface進行服務
看了這麼多,也許有人會想那可以來設定SSL吧,開個0.0.0.0_443/#0.0.0.0/cert目錄,然後放入憑證
,事實上光是把憑證放到 cert 目錄下一點用也沒有,
因為下載版根本沒有 SSL 的Handler(也就是說要把處理SSL的程式碼放入/handler目錄),
且我也沒有發現善心人士,寫好免費的 Handler,
這裡有人回答說很困難,也有人建議外部再加一層SSL tunnel,例如stunnel,但是效能如何就很難說
了,我猜可能會讓速度下降,失去我們的初衷。

gwan的執行說明

立即執行,只能用 ctrl+c中止
1
$./gwan

設定working thread 數量,如果CPU只有單核,可加入參數w
1
$./gwan -w 1

若是沒有w參數,預設為CPU核數,若要working thread不限定為CPU核數則加入參數g
1
$./gwan -g

如果要以daemon執行(先確認程式沒錯),可加入參數d執行
1
$./gwan -d

執行以下指令可以中止執行中的gwan
1
$./gwan -k

若要將client request儲存於trace以便除錯, 加入參數t
1
$./gwan -t


API說明
除了C外,G-Wan只提供了5個函式可用
1
2
3
4
5
6
7
8
long getReply(long env)                         #取得回覆Buffer,env指向一個char*(不知道Java怎麼用)
void xbufCat (long ctx, String str)          #主機回覆,ctx指向一個回覆Buffer,str是回覆字串
long cycles64()                                     #CPU時脈週期
long getNs()                                         #EPOCH時間以秒x109表示
long getUs()                                         #EPOCH時間以秒x106表示
long getMs()                                         #EPOCH時間以秒x103表示
void logErr  (long env, String msg)          #輸出到host的error.log,env指向一個char*,msg為訊息
void report  (long reply, int html_format) #轉儲系統資訊,reply為輸出Buffer的指標,html_format:若為1為html格式,0為文字格式

因為太陽春所以無法取得request資訊、也無法作設定Cookie之類的處理

Centos6 install
1
2
$yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
#其它安裝與上述Fedora差不多

若是您使用Docker,以下Dockerfile可以建立上述範例
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
FROM    centos:centos6
MAINTAINER Your Name <you.name@farfaraway.com>
RUN yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && \
    yum -y install deltarpm tar bzip2 wget java-1.8.0-openjdk java-1.8.0-openjdk-devel golang gcc
RUN cd /usr/local && \
    ln -s /usr/lib/golang go && \
    cd /usr/local/go/bin && \
    ln -s ./linux_amd64/go go && \
    ln -s ./linux_amd64/gofmt gofmt
RUN cd /opt && wget http://gwan.com/archives/gwan_linux64-bit.tar.bz2 && \
    tar -xjf gwan_linux64-bit.tar.bz2
RUN cd /root
RUN echo -e "public class HelloWorld{\n \
   public String greet(String name){\n \
        return \"Hello \"+name+\".\";\n \
      }\n}" >> HelloWorld.java
RUN javac HelloWorld.java && jar cvf HelloWorld.jar HelloWorld.class && rm -f HelloWorld.class && \
    mv HelloWorld.jar /opt/gwan_linux64-bit/libraries/ 
RUN echo -e "import api.Gwan;\n\n \
public class hello2{\n \
   public static int jmain(long env, String[] args){\n \
    Gwan.xbufCat(Gwan.getReply(env), new HelloWorld().greet(\"&#x60A8;&#x597D;\")+(args.length>0?args[0]:\"\"));\n \
        return 200;\n \
   }\n}" >> /opt/gwan_linux64-bit/0.0.0.0_8080/#0.0.0.0/csp/hello2.java
ENV JAVA_HOME /usr/lib/jvm/java-openjdk
ENV CLASSPATH /opt/gwan_linux64-bit/libraries/HelloWorld.jar
WORKDIR /opt/gwan_linux64-bit
EXPOSE 8080
CMD ["/opt/gwan_linux64-bit/gwan", "-w", "1"]

建立好Dockerfile後
1
2
$docker build -t yourtag/gwan .
$docker run -d -p 80:8080 --name gwan yourtag/gwan

開啟 http://localhost/?hello2.java


kentyeh edited on 2014-11-29 08:02
reply to postreply to post
» JWorld@TW »  Application Server

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8