中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

聽說你要做網站?可你知道這些嗎

2018-07-20    來源:編程學習網

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

現(xiàn)代 Web 后端技術超入門


引言


現(xiàn)在房價這么高,作為一個程序員只能靠做個網站看能不能賣出 100 萬這樣搏一手了。這里嘗試介紹一下現(xiàn)代 Web 后端并解釋一些常見術語,希望能夠幫助平常不做 Web 的程序員迅速上手。


我非常確信這篇文章里有很多概念不太對,如果發(fā)現(xiàn)哪里不太對的話請跟我講...


實現(xiàn)一個手動的 Web 服務器!


1、這里的手動真的就是字面上的意思,這里我們要實現(xiàn)的效果是:


2、在命令行中運行 Server。


3、在瀏覽器中打開 http://localhost ,也就是你本機的地址。


4、在命令行中輸入你想在瀏覽器中顯示的結果,然后...


在瀏覽器里看到你之前輸入的結果!


更棒的是整個過程我們一行代碼都不用寫!


ncat


如果你是在 Windows 上的話,請在這里下載 ncat,放到任何地方并在命令行里執(zhí)行。ncat 的基本功能一方面是用來像任意 TCP/UDP 服務器發(fā)送數(shù)據,另一方面可以作為一個非常簡單基本的 TCP/UDP 服務器來接受任何數(shù)據并顯示出來。這里我們要用的顯然是后者。


首先,在命令行里運行 ncat --listen 80,意思是監(jiān)聽 80 端口,并把接受到的數(shù)據顯示在命令行里。其中 80 就是著名的 HTTP 端口。如果你使用的是 Linux 的話這里需要 sudo,而且如果你的機器上已經有網站在跑的話那么這里可以把 80 改成8080,對應瀏覽器里的地址也需要用 http://localhost:8080/。

C:\Bin>ncat -l
_ <---- 閃動的光標

然后,打開你最喜歡的瀏覽器打開地址 http://localhost/ 。這時你應該會看到瀏覽器顯示正在鏈接,而命令行窗口里應該是可以看到這樣的東西:

C:\Users\jagt>ncat --listen 80
GET / HTTP/1.1
Host: localhost
User-Agent: Chrome
Accept: */*
_ <---- 閃動的光標

這里顯示的東西就是 HTTP 請求,也就是瀏覽器發(fā)送的數(shù)據。那么現(xiàn)在我們要輸入想要顯示在瀏覽器里的內容。很容易想像,既然請求看起來有些格式,我們輸入的內容也必須有些格式才行?截愊旅娴膬热莸矫钚兄,如果沒反應就多按下幾次回車。

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 14 

Hello Browser!

然后再看看你的瀏覽器里面,應該就出現(xiàn)了 Hello Browser!,也就是你剛剛輸入的內容。


Web 后端基礎原理


事實上無論是怎樣的網站,只要你用瀏覽器去訪問的時候就會有一臺遠方的電腦再以非?斓乃俣戎貜椭覀兩厦媸謩油瓿傻牟襟E。整個過程簡單概括的話大概就是這樣幾個步驟:


1、用戶在瀏覽器里輸入網站,瀏覽器負責找到這個網址對應的計算機,并嘗試連接其 80 端口。


2、服務器接收請求,建立 TCP 連接。


3、瀏覽器通過建立的的連接發(fā)送 HTTP 請求 (HTTP Request),也就是上面例子中ncat 里最開始顯示的內容。


4、服務器根據請求的內容返回 HTTP 響應 (HTTP Response),也就是我們上面手動輸入的東西。


5.瀏覽器根據返回的內容來顯示頁面。


對于這個過程額外有幾點很重要的是:


●瀏覽器總是連接 80 端口 (HTTPS 除外),但是你應該知道標準的 TCP 連接監(jiān)聽的是一個端口(在這個例子是 80),而真正傳送數(shù)據的是另外一個隨機的高位端口(比如 54321)。如果每個用戶都占用 80 端口傳數(shù)據的話那就麻煩了。


●雖然 TCP 協(xié)議是兩邊都可以主動發(fā)起消息,但 HTTP 額外規(guī)定了一個 HTTP 連接的過程是,瀏覽器發(fā)送 HTTP 請求,服務器收到請求全文后,返回 HTTP 響應,在瀏覽器接受到之后就算結束?梢宰⒁獾降氖,瀏覽器和服務器只有一次互動的機會,而且一定是瀏覽器主動發(fā)起,而服務器只能被動的根據收到的請求內容返回結果。


●這里講的請求 (HTTP Request) 和響應 (HTTP Response) 真的就是上面看到的那樣是純文本。瀏覽器和服務器之間除了在 Request 和 Response 內的內容外不應該需要額外的信息。


上面描述的基本就是 HTTP 協(xié)議 的工作方式,F(xiàn)在流行的很多輕量級的 Web 框架都在按照這個模式進行抽象。首先看看當下最新潮的 node.js 官網上的例子:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

其中的 req 和 res 完完全全對應的就是 HTTP Request 和 Response。里面的函數(shù)最主要的工作就是讀 req 的內容,把你想顯示在用戶瀏覽器里的東西寫到 res里面。這里也反映了很多 HTTP 協(xié)議的特性,在一個連接的過程中你的起始條件就只有 Request,唯一能做的就是把需要顯示的東西寫到 Response 里。你沒機會函數(shù)里面再向瀏覽器索取信息,也不能在 Response 寫完后再向瀏覽器發(fā)送任何內容。


把這段代碼里的內容跟最終的 HTTP 響應對比一下:


HTTP/1.1 200 OK
Content-Type: text/plain

Hello World!


其中的 200 所在的位置是 HTTP Status Code,常見的就是 200 OK 和404 Not Found,瀏覽器會根據其值來做各種行為,像如果是 301 Moved Permanently 的話瀏覽器就會自動跳轉到另外一個頁面。Content-Type 這里先不管他... 下面空一行后面的就是 HTTP message body data,很明顯就是顯示在瀏覽器中的內容。


接下來是 Python 的 flask 的例子:

@app.route('/')
def index():
    username = request.cookies.get('username')
    return 'hello, ', username

應該可以很明顯的感覺 flask 抽象的層次的要比 node.js 更高一點。這里回頭看看最開始在 ncat 里面看到的 HTTP 請求中的第一行:

GET / HTTP/1.1

這基本上也是其中最重要的一部分,讀出來就是 "我要 GET 這個網站上地址為 / 的頁面"。其中 GET 是請求的方法 (method),而 / 就是路徑。由于 GET 是最常見的一個方法,flask 中可以省略這個參數(shù)。這個請求根據方法和路徑被 route 到了我們這個 index() 函數(shù)。其中 request 毫無懸念的對應的就是 HTTP 請求。整個東西的意思,讀出來就是 "遇到要 GET 路徑為 / 的請求,從 request 里面拿到用戶名并返回響應 hello, 加上它的用戶名。"


如果上面的都明白了的話,到這里就只剩下一個問題了:request 里面的 cookies 是從哪里來的?其實 cookies 也是包含在 HTTP 請求的內容里的,下面是一個例子:

GET / HTTP/1.1
Cookie: name=value; name2=value2

這里 Cookie: name=value1; name2=value2 這種格式的東西叫做 HTTP Headers。HTTP 標準中規(guī)定了一系列的請求和響應中可能會出現(xiàn)的鍵和值的規(guī)則,用于控制服務器和瀏覽器的行為,比如:


●Response 中的 Content-Type: 你應該發(fā)現(xiàn)有時候你打開一個鏈接會顯示頁面,有時候卻會彈出另存為的對話框。決定這個行為的就是這個 Header,其值是一個 MIME Type。如果是 Content-Type: text/html 的話,瀏覽器就會把后面的文字顯示出來。如果是 Content-Type: application/octet-stream 的話,一般就會彈出"另存為"的對話框。


●Response 中的 Set-Cookie:瀏覽器看到 Set-Cookie: 12345 的話,瀏覽器再之后的訪問該網站的 HTTP 請求中都會帶上 Cookie: 12345。像用戶登錄驗證等等很多都是靠 Set-Cookie 和 Cookie 來實現(xiàn)的。


●Request 中的 User-Agent:記得原來剛上網的時候有那種很流弊的圖片,可以顯示你的地理位置,瀏覽器版本和操作系統(tǒng)。其實這個就是用 User-Agent 來實現(xiàn)的。一個例子:Mozilla/5.0 (Windows NT 6.1; WOW64) Chrome/33.0.1750.154,很容易看到相關的信息。


●Request 中的 Referer:記得原來剛上網的時候有那種防盜鏈的圖片,如果圖片是被嵌入在別的網站上的話會變成什么“此圖片來自于哪里哪里”這樣。這個就是用 Referer 實現(xiàn)的,其內容是你鏈到這里之前訪問的一個地址。


這里的中心思想就是,大部分這些控制行為的東西都是用 HTTP Headers 來實現(xiàn)的。好消息是大部分 Web 框架中你不太需要顯示的控制他們。


HTTP 小結


再回頭看看最開始手動 HTTP 服務器里的請求和響應,這里我們給每個部分加上注釋。

請求的方法

|

| 請求的地址

| |

GET / HTTP/1.1

User-Agent: Chrome -|

Host: localhost:1337 -|

Accept: */* -|--- 請求的 Headers


響應的 status code

|

HTTP/1.1 200 OK

Content-Type: text/html -|

Content-Length: 14 -|--- 響應的 Headers


Hello Browser! ----- 響應的 Message Body

應該就很清楚了。接下來我們不妨直接來看看當下最流行的 Web 后端開發(fā)技術。


"我的網站要用 nginx + node.js + mongodb!"


不管怎樣,這里先分析一下這三樣現(xiàn)在很有代表性的技術在后端中處于什么樣的層面。


nginx


nginx 官網的描述是 "HTTP 和反向代理服務器",所以這兩個部分可以分開來看。"HTTP 服務器" 的意思我覺得就是它可以接受 HTTP 請求,根據其內容作出不同的處理。一個非常重要的例子就是用來 "serve" 對靜態(tài)內容(圖片,css) 。無論你的網站用什么語言寫,最終部署上線的時候靜態(tài)內容都應當是由 nginx 這一層來處理,因為這是它的核心功能之一,效率和安全性都會很有保證。而 "反響代理服務器" 看起來很玄乎其實也很好理解。我們知道向一臺機器上的 80 端口只能有一個進程在監(jiān)聽,那么比如你有兩個應用,一個是你重要的網站程序,一個是記錄你開發(fā)心路歷程的博客,你可以用兩個地址分別訪問到:


http://localhost:8080/ - 我的網站


http://localhost:9009/ - 開發(fā)博客


明顯的你不希望用戶在訪問的時候也要輸入端口號碼。如果把 nginx 放在最前面來監(jiān)聽 80 端口的話,它可以把一個請求根據你的配置來"反向代理"到你的網站或者博客。針對上面這個例子,我們可以這樣配置:

server {
    listen 80;
    location /site {
        proxy_pass http://localhost:8080;
    }

    location /blog {
        proxy_pass http://localhost:9090;
    }
}

這樣兩個應用的現(xiàn)在分別可以用更好看的地址訪問到:


●http://localhost/site - 我的網站


●http://localhost/blog - 開發(fā)博客


當然現(xiàn)實生活中你的應用代碼里可能也要根據這樣的配置做一些處理。但是總體感覺就是這樣。nginx 還有很多高端功能可以來控制反向代理的細節(jié),可以很靈活的做各種事。所以預先的考慮把 nginx 放在最前面是很有幫助的。當你真的要用的時候可以到處搜搜會有很多教程。


node.js


node.js 可能是當下最火熱的后端技術。你的網站邏輯就是要在這里來寫了。比起之前其他的 web 技術 node.js 其實位置有點特殊,它給人的感覺應該像是 "可以用 JavaScript 控制邏輯的 nginx" 這樣。上手相當容易,看看教程寫個程序然后node foo.js,打開瀏覽器就能看到了。


因為 node.js 功能是偏向底層的,所以當你真正要寫網站的時候可能需要一個高層一點點的框架,可以自行搜索。


關于 node.js 還有一點需要提到的就是其 "async" 的意思。它這里的 "async" 僅僅是說的是 IO,即讀文件寫文件和一些先關的操作是異步的,跟多線程并行什么的是一點關系都沒有。舉一個例子:

http.createServer(function (req, res) {
    setTimeout(function(){
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
    }, 10000) // 返回前 "sleep" 10秒
}).listen(1337, '127.0.0.1');

打開瀏覽器訪問發(fā)現(xiàn)要等 10 秒。在等待過程中你可以再開一個窗口也訪問這個地址,你會發(fā)現(xiàn)在之前那個請求結束之前新的那一個也會在等待。如果這個行為跟你想象的不太一樣的話,你可能需要看一看 js "Event-Based Programming" 是怎么回事。


mongodb


mongodb 是一個面向文檔的數(shù)據庫。跟傳統(tǒng) SQL 數(shù)據庫比起來 mongodb 剛開始給人的感覺是更容易入門,但實際情況感覺也是有好有壞。你可以這樣想,你網站的復雜度是固定的,那么其實不論用什么技術要解決的問題其實是差不多的,所以技術的選擇在我們這種入門級選手來說其實不會是致命的。


不過說到為什么做網站一定要用個數(shù)據庫,我覺得原因是因為網站不像很多普通的應用程序有一個明顯的開始和結束的過程。像一個命令行程序你可以把大部分的程序狀態(tài)都放在局部變量里面,有需要再序列化到文件中;而網站的話你需要有一個可靠而持久的地方來存放數(shù)據。另一方面像 mongo 和 SQL 都有可以讓你很方便的對數(shù)據進行處理的操作,對于很多類型的應用來說也是很必要的。


不過反過來講,網站程序中最好不要使用全局變量或者類似的東西。這里有一個例子,比如你想實現(xiàn)一個計數(shù)器,每次有人訪問顯示的數(shù)量就會增加。node.js 的話可以寫成這樣:

var http = require('http');
var counter = 0;
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(""+counter++);
}).listen(1337, '127.0.0.1');

這樣其實是可以正常工作的,先不考慮說斷電,程序異常退出之類的高端問題,這種做法還是有一個很要命的問題。你在開發(fā)的時候命令行里面跑跑發(fā)現(xiàn)沒問題,但是后來又聽說 node.js 支持 cluster 或者類似的東西, 可以起多份進程來做服務,這樣可以 "scale" 你的網站。結果試了試發(fā)現(xiàn)計數(shù)器顯示的數(shù)字變的很隨機,有增有減,這時候就蛋疼了。


發(fā)生這個的原因就是這里使用了對于單個進程內的全局變量,也就是多個進程之間是無法共享的東西。當 cluster 起了多份進程的時候,等于是每個里面自己都有一個 counter 變量。


實際上這個問題對于 node.js 還算好 (node.js 的整個模型都傾向于單線程)。但像 Python 或者其他這種,依靠某種協(xié)議來起 "worker" 的方式這種做法就會迅速出問題。所以網站的數(shù)據都會放到一個統(tǒng)一的,可以由多個進程共同使用的地方,一般就是各種數(shù)據庫。


選擇你的武器


我一直覺得做網站(或者任何開發(fā))最振奮人心的時刻就是最開始選擇技術 "stack" 的時候了。"用這個這個加上這個,高性能夠靈活上手簡單,肯定很牛逼!",這種感覺估計每個人都有。不過似乎對于業(yè)余開發(fā)來說真的不是太重要,選擇熟悉的或者感興趣的都可以,因為說到底差別都不是那么大,自己感覺好就可以了。


邁向人生巔峰的步驟


當你本地調試好了的時候,就要考慮上線了。在瀏覽器里輸入一個地址就能看到你精心設計的頁面,感覺不是一般的好。如果你是第一次的話,你需要按步驟做以下這些事:


1、購買一個 VPS,可以搜索 "vps 海外 支付寶"。不要考慮那種共享的 "支持 php, ruby" 這種,你需要的是一臺可以 ssh 進去有 root 權限的 VPS。


2、購買一個域名,可以搜索 "域名 海外 支付寶"。一定不要買國內的。


3、把你的域名遷移到 DNSPod。注冊后看文檔有很詳細的教程。


4、配置 Google Analytics, 可以監(jiān)測你網站的流量和用戶情況。如果擔心國內抽風的話可以搜 "網站流量統(tǒng)計" 尋找國內的代替品。


5、在 VPS 上裝好 nginx 或者 apache 或者什么別的都可以,配置到瀏覽器里輸入你的域名能刷出頁面來。


6、部署你的網站!最好能自動化這個過程不然會很痛苦。


最后


就我個人做過的軟件開發(fā)里面,似乎只有 Web 后端是入門就要牽涉到多種進程或服務的,開發(fā)部署和環(huán)境配置跟通常寫個程序然后點"編譯"都差別很大,總的來說應該還是蠻有意思的。

標簽: dns Google linux vps 安全 代理服務器 代碼 服務器 權限 數(shù)據庫 搜索 域名

版權申明:本站文章部分自網絡,如有侵權,請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:最讓程序員感到崩潰的10種編程語言

下一篇:Java Tcp協(xié)議socket編程學習