欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Caddy 一個用Go實現(xiàn)的Web Server

 更新時間:2016年11月27日 13:22:27   作者:Tony Bai  
這篇文章主要介紹了Caddy 一個用Go實現(xiàn)的Web Server,簡潔易用,需要的朋友可以參考下

這是一個Web Server的時代,apache2nginx共舞,在追求極致性能的路上,沒有最高,只有更高。但這又是一個追求個性化的時代,有些Web Server并沒有去擠“Performance提升”這一獨木橋,而是有著自己的定位,Caddy就是這樣一個開源Web Server。

Caddy的作者Matt Holt在caddy官網(wǎng)以及FAQ中對caddy的目標闡釋如下: 其他Web Server為Web而設計,Caddy為human設計。功能定位上,與經(jīng)常充當最前端反向代理的nginx不同,caddy致力于成為一個易用的靜態(tài) 文件Web Server。可以看出Caddy主打易用性,使用配置簡單。并且得益于Go的跨平臺特性,caddy很容易的支持了三大主流平臺:Windows、 Linux、Mac。在Caddy開發(fā)者文檔中,我們可以看到caddy還可以在Android(linux arm)上運行。caddy目前版本為0.7.1,還不穩(wěn)定,且后續(xù)版本可能變化較大,甚至與前期版本不兼容,因此作者目前不推薦caddy在生產(chǎn)環(huán)境被 重度使用。

關注caddy,是因為caddy填補了go在通用web server這塊的空白(也許有其他,但我還不知道),同時Web server in go也“響應”了近期Golang去C化的趨勢(Go 1.5中C is gone!),即便caddy作者提到caddy的目標并非如nginx那樣。但未來誰知道呢?一旦Go性能足夠高時,一旦caddy足夠穩(wěn)定時,自然而 然的就會有人將其用在某些應用的生產(chǎn)環(huán)境中替代nginx或apache2了。一套全Go的系統(tǒng),在部署、運維方面也是有優(yōu)勢的。

一、安裝和運行caddy

和諸多go應用一樣,我們可以直接從caddy的github.com releases頁中找到最新發(fā)布版(目前是0.7.1)的二進制包。這里使用的是caddy_darwin_amd64.zip。

下載解壓后,進入目錄,直接執(zhí)行./caddy即可將caddy運行起來。

$caddy
0.0.0.0:2015

在瀏覽器里訪問localhost:2015,頁面上沒有預期顯示的類似"caddy works!”之類的默認Welcome頁面,而是“404 Not Found"。雖然這說明caddy已經(jīng)work了,但沒有一個default welcome page畢竟對于caddy beginer來說并不友好。這里已經(jīng)向作者提了一個sugguestion issue。

二、caddy原理

Go的net/http標準庫已經(jīng)提供了http server的實現(xiàn),大多數(shù)場合這個http server都能滿足你的需要,無論是功能還是性能。Caddy實質(zhì)上也是一個Go web app,它也import net/http,嵌入*http.Server,并通過handler的ServeHTTP方法為每個請求提供服務。caddy使用 http.FileServer作為處理 靜態(tài)文件的基礎。caddy的誘人之處在于其middleware,將諸多middleware串成一個middleware chain以提供了靈活的web服務。另外caddy中的middleware還可以獨立于caddy之外使用。

caddy從當前目錄的Caddyfile(默認)文件中讀取配置,當然你也可以通過-conf指定配置文件路徑。Caddyfile的配置格式 的確非常easy,這也符合caddy的目標。

Caddyfile總是以站點的Addr開始的。

單一站點的Caddyfile樣例如下:

//Caddyfile
localhost:2015
gzip
log ./2015.log

Caddy也支持配置多個站點,類似virtualhost的 配置(80端口多路復用):

//Caddyfile
foo.com:80 {
log ./foo.log
gzip
}

bar.com:80 {
log ./bar.log
gzip
}

為了實現(xiàn)風格上的統(tǒng)一,單一站點也最好配置為如下這種格式(代碼內(nèi)部稱之為 Server Block):

localhost:2015 {
gzip
log ./2015.log
}

這樣Caddyfile的配置文件模板樣式類似于下面這樣:

host1:port {
middleware1
middleware2 {
… …
}
… …
}

host2:port {
middleware1
middleware2 {
… …
}
… …
}
… …

關于middleware,在caddy文檔中有較為詳細的說明和例子。對于caddy這樣一個年輕的開源項目而言,其文檔還算是相對較全的,雖 然現(xiàn)在還不能和nginx、 apache比。

caddy中的middleware就是一個實現(xiàn)了middleware.Handler接口的struct,例如gzip這個 middleware:

// middleware.go
type Middleware func(Handler) Handler
type Handler interface {
ServeHTTP(http.ResponseWriter, *http.Request) (int, error)
}

// gzip/gzip.go
type Gzip struct {
Next middleware.Handler
}

func (g Gzip) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
return g.Next.ServeHTTP(w, r)
}
…. …
gz := gzipResponseWriter{Writer: gzipWriter, ResponseWriter: w}

// Any response in forward middleware will now be compressed
status, err := g.Next.ServeHTTP(gz, r)
… …
}

middleware.Handler的函數(shù)原型與http.Handler的不同,不能直接作為http.Server的Handler使用。caddy使用了下面這個idiomatic go pattern:

type appHandler func(http.ResponseWriter, *http.Request) (int, error)

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if status, err := fn(w, r); err != nil {
http.Error(w, err.Error(), status)
}
}

當然這個pattern有很多變種,但思路大致類似。一個middleware chain大致就是handler1(handler2(handler3))的調(diào)用傳遞。

前面說過caddy是基于http.FileServer的靜態(tài)文件Web Server,F(xiàn)ileServer總會作為middleware chain的最后一環(huán),如果沒有配置任何middleware,那你的server就是一個靜態(tài)文件server。

三、caddy典型應用

【靜態(tài)文件Server】

caddy的最基礎應用實際就是一個靜態(tài)文件Server,底層由http.FileServer承載,當然caddy封裝了http.FileServer,做了一些攔截處理,最后將w, r傳遞給http.ServeContent去處理文件數(shù)據(jù)。

第一次執(zhí)行./caddy,實際上就啟動了一個靜態(tài)文件Server。但這個server不默認支持你navigate directory。如果你知道website root目錄(如果沒有指定root,則caddy執(zhí)行的當前路徑會作為website的root路徑)下的文件名,比如foo.txt,你可以在瀏覽器 中輸入:localhost:2015/foo.txt,caddy會執(zhí)行正確的服務,瀏覽器也會顯示foo.txt的全文。

對于靜態(tài)文件Server,caddy支持在website的root路徑下首先查找是否有如下四個文件:

//caddy/middleware/browse/browse.go
var IndexPages = []string{
"index.html",
"index.htm",
"default.html",
"default.htm",
}

如果查到有其中一個,則優(yōu)先返回這個文件內(nèi)容,這就是靜態(tài)站點的首頁。

如果要支持目錄文件列表瀏覽,則需要為website配置browse middleware,這樣對于無index file的目錄,我們可以看到目錄文件列表。

localhost:2015 {
browse
} 

【反向代理】

caddy支持基本的反向代理功能。反向代理配置通過proxy middleware實現(xiàn)。

localhost:2015 {
log ./2015.log

proxy /foo localhost:9001
proxy /bar localhost:9002
}

當你訪問localhost:2015/foo時,實際上訪問的是9001端口的服務程序;
當你訪問localhost:2015/bar時,實際上訪問的是9002端口的服務程序。

【負載均衡】

Caddy支持負載均衡配置,并支持三種負載均衡算法:random(隨機)、least_conn(最少連接)以及round_robin(輪詢調(diào)度)。

負載均衡同樣是通過proxy middleware實現(xiàn)的。

localhost:2015 {
log ./2015.log

proxy / localhost:9001 localhost:9003 {
policy round_robin
}
proxy /bar localhost:9002 localhost:9004 {
policy least_conn
}
}

【支持fastcgi代理】

caddy同樣支持

mac os上自帶了php-fpm,一個實現(xiàn)了fastcgi的php cgi進程管理器。caddy將請求轉(zhuǎn)發(fā)給php-fpm監(jiān)聽的端口,后者會啟動php-cgi解釋器,解釋index.php,并將結(jié)果返回給caddy。

mac os上的php-fpm默認沒有隨機啟動。我們需要簡單配置一下:

$mkdir phptest
$mkdir -p phptest/etc
$mkdir -p phptest/log
$cd phptest
$sudo cp /private/etc/php-fpm.conf.default ./etc
$cd ./etc
$sudo chown tony php-fpm.conf.default
$mv php-fpm.conf.default php-fpm.conf

編輯php-fpm.conf,保證下面兩項是非注釋狀態(tài)的:

error_log = log/php-fpm.log
listen = 127.0.0.1:9000

我們通過network socket進行fastcgi通信。

回到phptest目錄下,執(zhí)行:

php-fpm -p ~/test/go/caddy/phptest

執(zhí)行后,php-fpm就會轉(zhuǎn)入后臺執(zhí)行了。

接下來我們來配置Caddyfile:

localhost:2015 {
fastcgi / 127.0.0.1:9000 php
log ./2015.log
}

這里配置的含義是:將全部請求轉(zhuǎn)發(fā)到9000端口,這里的php是一個preset(預配置集合),相當于:

ext .php
split .php
index index.php

我們在phptest目錄下創(chuàng)建一個index.php文件,內(nèi)容如下:

<?php echo "Hello World\n"; ?>

好了,現(xiàn)在啟動caddy,并使用瀏覽器訪問localhost:2015試試。你會看到"Hello World"呈現(xiàn)在瀏覽器中。

【git push發(fā)布】

對于一些靜態(tài)站點,caddy支持git directive,實現(xiàn)在server啟動以及運行時定期git pull你的項目庫,將最新更新pull到server上。

caddy文檔中給出兩個例子:

第一個是一個php站點,定期pull項目庫,實現(xiàn)server更新:

git git@github.com:user/myphpsite {
key /home/user/.ssh/id_rsa
}
fastcgi / 127.0.0.1:9000 php

第二個是一個hugo支撐的靜態(tài)站點,每次pull后,執(zhí)行hugo命令生成新的靜態(tài)頁面:

git github.com/user/site {
path ../
then hugo –destination=/home/user/hugosite/public
}

注意:git directive并非middleware,而是一個單獨的goroutine實現(xiàn)的。

四、小結(jié)

caddy的功能不局限于上面的幾個例子,上面只是幾個最為常見的場景而已。caddy目前還很年輕,應用不多,但知名golang網(wǎng)站 gopheracademy.com(GopherCon組織方)是由Caddy support的。caddy還在積極進化,有興趣的Gopher可持續(xù)關注。

相關文章

最新評論