update 2.3md,3.1md,3.2md,3.3md

This commit is contained in:
chenwenli
2012-10-30 13:09:07 +08:00
parent 5a26305ce7
commit 1ec4314932
4 changed files with 61 additions and 63 deletions

2
2.3.md
View File

@@ -3,7 +3,7 @@
## 流程控制
流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑。流程控制包含分三大类:条件判断,循环控制和无条件跳转。
### if
`if`也许是各种编程语言中最常见的了,它的语法概括起来就是:`如果满足条件就做某事,否则做另一件事`
`if`也许是各种编程语言中最常见的了,它的语法概括起来就是:如果满足条件就做某事,否则做另一件事
Go里面`if`条件判断语句中不需要括号,如下代码所示

92
3.1.md
View File

@@ -1,21 +1,21 @@
# 3.1 Web工作方式
我们平时浏览网页的时候,打开浏览器,输入网址按下回车键,然后就出来了内容。在这个看似简单的行为背后,到底隐藏了些什么呢?
我们平时浏览网页的时候,打开浏览器,输入网址按下回车键,然后就会显示出你想要浏览的内容。在这个看似简单的用户行为背后,到底隐藏了些什么呢?
上面这个普通的浏览过程,底层其实是这样做的浏览器是一个客户端当你输入URL的时候首先浏览器会去请求DNS服务器通过DNS获取相应的域名对应的IP然后通过IP和服务器建立socket连接发送http请求信息服务器接收到请求信息之后处理相应的请求返回http response信息,客户端收到http信息之后开始渲染这些http response里面的content信息断开和服务器的socket链接。
对于普通的上网过程,系统其实是这样做的:浏览器本身是一个客户端当你输入URL的时候首先浏览器会去请求DNS服务器通过DNS获取相应的域名对应的IP然后通过IP地址找到IP对应的服务器后要求建立TCP连接等浏览器发送完HTTP Request请求包后服务器接收到请求包之后才开始处理请求包服务器调用自身服务返回HTTP Response(响应)包;客户端收到来自服务器的响应后开始渲染这个Response包里的主体body等收到全部的内容随后断开与该服务器之间的TCP连接。
![](images/3.1.web2.png?raw=true)
一个Web服务器也被称为HTTP服务器它通过HTTP协议与客户端通信。这个客户端通常指的是Web浏览器(手机端客户端其实内部也是浏览器实现)。
一个Web服务器也被称为HTTP服务器它通过HTTP协议与客户端通信。这个客户端通常指的是Web浏览器(其实手机端客户端内部也是浏览器实现)。
Web服务器的工作原理简单的可以归纳为:
Web服务器的工作原理可以简单地归纳为:
- 客户机通过socket建立到服务器的连接
- 客户端向服务器发送请求http协议包请求转化成服务器对应的文档
- 服务器向客户机发送应答http协议包请求的如果包含有动态语言的部分,那么动态语言把相应的数据结果返回给客户端
- 客户机与服务器断开。客户端解释HTML文档在客户端屏幕上显示结果
- 客户机通过TCP/IP协议建立到服务器的TCP连接
- 客户端向服务器发送HTTP协议请求包请求服务器里的资源文档
- 服务器向客户机发送HTTP协议应答包如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据返回给客户端
- 客户机与服务器断开。客户端解释HTML文档在客户端屏幕上渲染图形结果
一个简单的事务处理事件就是这样实现的,看起来很复杂,做起来其实是挺简单的需要注意的是客户机与服务器之间的通信是非连接的,也就是当服务器发送了应答后就与客户机断开连接,等待下一次请求。
一个简单的HTTP事务就是这样实现的,看起来很复杂,原理其实是挺简单的需要注意的是客户机与服务器之间的通信是非持久连接的,也就是当服务器发送了应答后就与客户机断开连接,等待下一次请求。
## URL和DNS解析
我们浏览网页都是通过URL访问的那么URL到底是怎么样的呢
@@ -62,24 +62,22 @@ HTTP协议是Web工作的核心所以要了解清楚Web的工作方式就需
HTTP是一种让Web服务器与浏览器(客户端)通过Internet发送与接收数据的协议,它建立在TCP协议之上一般采用TCP的80端口。它是一个请求、响应协议--客户端发出一个请求服务器响应这个请求。在HTTP中客户端总是通过建立一个连接与发送一个HTTP请求来发起一个事务。服务器不能主动去与客户端联系也不能给客户端发出一个回调连接。客户端与服务器端都可以提前中断一个连接。例如当浏览器下载一个文件时你可以通过点击“停止”键来中断文件的下载关闭与服务器的HTTP连接。
HTTP协议是无状态的同一个客户端的这次请求和上次请求是没有对应关系对HTTP服务器来说它并不知道这两个请求来自同一个客户端。 为了解决这个问题, Web程序引入了Cookie机制来维护状态。
HTTP协议是无状态的同一个客户端的这次请求和上次请求是没有对应关系对HTTP服务器来说它并不知道这两个请求是否来自同一个客户端。为了解决这个问题, Web程序引入了Cookie机制来维护连接的可持续状态。
>HTTP协议是建立在TCP协议之上的因此TCP攻击一样会影响HTTP的通讯例如比较常见的一些攻击SYN Flood是当前最流行的DoS拒绝服务攻击与DdoS分布式拒绝服务攻击的方式之一这是一种利用TCP协议缺陷发送大量伪造的TCP连接请求从而使得被攻击方资源耗尽CPU满负荷或内存不足的攻击方式。
### HTTP请求信息(浏览器信息)
### HTTP请求包(浏览器信息
我们先来看看Request消息的结构, Request 消息分为3部分第一部分叫Request line, 第二部分叫Request header,第三部分是body。header和body之间有个空行详细的如下所示
我们先来看看Request的结构, Request分为3部分第一部分叫Request line(请求行), 第二部分叫Request header(请求头),第三部分是body(主体)。header和body之间有个空行请求包的例子所示:
- 请求行GET/POST(流的组织(请求)方式) URL(地址+目录) 版本
- 请求头:
Host:客户端IP和端口
User-Agent:浏览器信息
Accept:客户端能接收的数据类型
Accept-encoding是否支持压缩的流
Accept-charset客户端字符编码集
- 空行:分割请求头和消息体
- 消息体:请求的参数
GET /domains/example/ HTTP/1.1 //请求行: 请求方法 请求URI HTTP协议/协议版本
Hostwww.iana.org //服务端的主机名
User-AgentMozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 //浏览器信息
Accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //客户端能接收的mine
Accept-Encodinggzip,deflate,sdch //是否支持流压缩
Accept-CharsetUTF-8,*;q=0.5 //客户端字符编码集
//空行,用于分割请求头和消息体
//消息体,请求资源参数,例如POST传递的参数
我们通过fiddler抓包可以看到如下请求信息
@@ -87,36 +85,36 @@ HTTP协议是无状态的同一个客户端的这次请求和上次请求是
![](images/3.1.httpPOST.png?raw=true)
我们可以看到GET请求消息体为空POST请求带有消息体。
**我们可以看到GET请求消息体为空POST请求带有消息体**
Http协议定义了很多与服务器交互的方法最基本的有4种分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查删4个操作。 我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息而POST一般用于更新资源信息.
HTTP协议定义了很多与服务器交互的请求方法最基本的有4种分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查删4个操作。 我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息而POST一般用于更新资源信息.
我们看看GET和POST的区别
1. GET提交的数据会放在URL之后以?分割URL和传输数据参数之间以&相连如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.
2. GET提交的数据大小有限制因为浏览器对URL的长度有限制而POST方法提交的数据没有限制.
3. GET方式提交数据会带来安全问题比如一个登录页面通过GET方式提交数据时用户名和密码将出现在URL上如果页面可以被缓存或者其他人可以访问这台机器就可以从历史记录获得该用户的账号和密码。
### HTTP响应信息(服务器信息)
我们再来看看HTTP的response信息,他的结构如下:
### HTTP响应包(服务器信息
我们再来看看HTTP的response,他的结构如下:
- 状态行HTTP版本 服务器状态(比如404找不到...) 描述信息
- 响应头
HTTP/1.1 200 OK //状态行
Server: nginx/1.0.8 //服务器使用的WEB软件名及版本
Date:Date: Tue, 30 Oct 2012 04:14:25 GMT //发送时间
Content-Type: text/html //服务器发送信息的类型
Transfer-Encoding: chunked //表示发送HTTP包是分段发的
Connection: keep-alive //保持连接状态
Content-Length: 90 //主体内容长度
//空行 用来分割消息头和主体
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... //消息体
Content-Type服务器发送信息的类型
Date发送时间
Server服务器类型
- 消息体:服务器发送给客户端的页面内容
Response包中的第一行叫做状态行由HTTP协议版本号 状态码, 状态消息 三部分组成。
Response 消息中的第一行叫做状态行由HTTP协议版本号 状态码, 状态消息 三部分组成。
状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response。HTTP/1.1协议中定义了5类状态码 状态码由三位数字组成,第一个数字定义了响应的类别
状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response.
HTTP/1.1中定义了5类状态码 状态码由三位数字组成,第一个数字定义了响应的类别
- 1XX 提示信息 - 表示请求已被成功接收,继续处理
- 2XX 成功 - 表示请求已被成功接收,理解,接受
- 3XX 重定向 - 要完成请求必须进行更进一步的处理
- 4XX 客户端错误 - 请求有语法错误或请求无法实现
- 5XX 服务器端错误 - 服务器未能实现合法的请求
- 1XX 提示信息 - 表示请求已被成功接收,继续处理
- 2XX 成功 - 表示请求已被成功接收,理解,接受
- 3XX 重定向 - 要完成请求必须进行更进一步的处理
- 4XX 客户端错误 - 请求有语法错误或请求无法实现
- 5XX 服务器端错误 - 服务器未能实现合法的请求
我们看下面这个图展示了详细的返回信息左边可以看到有很多的资源返回码200是常用的表示正常信息302表示跳转。response header里面展示了详细的信息。
@@ -126,11 +124,11 @@ HTTP/1.1中定义了5类状态码 状态码由三位数字组成,第一个
### HTTP协议是无状态的和Connection: keep-alive的区别
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。
HTTP是一个无状态的面向连接的协议无状态不代表HTTP不能保持TCP连接更不能代表HTTP使用的是UDP协议无连接
HTTP是一个无状态的面向连接的协议无状态不代表HTTP不能保持TCP连接更不能代表HTTP使用的是UDP协议面对无连接)。
从HTTP/1.1起默认都开启了Keep-Alive保持连接特性简单地说当一个网页打开完成后客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭如果客户端再次访问这个服务器上的网页会继续使用这一条已经建立的连接。
从HTTP/1.1起默认都开启了Keep-Alive保持连接特性简单地说当一个网页打开完成后客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭如果客户端再次访问这个服务器上的网页会继续使用这一条已经建立的TCP连接。
Keep-Alive不会永久保持连接它有一个保持时间可以在不同服务器软件如Apache中设这个时间
Keep-Alive不会永久保持连接它有一个保持时间可以在不同服务器软件如Apache中设这个时间
## 请求实例
@@ -138,9 +136,9 @@ Keep-Alive不会永久保持连接它有一个保持时间可以在不同
上面这张图我们可以了解到整个的通讯过程同时细心的读者是否注意到了一点一个URL请求但是左边栏里面为什么会有那么多的资源请求(这些都是静态文件go对于静态文件有专门的处理方式)。
这个就是浏览器的功能第一次请求url服务器端返回的是html页面然后浏览器开始渲染html当解析到src里面的img资源、css资源、js资源浏览器就会自动发起http请求把需要的资源从服务器请求回来,然后浏览器就会宣布渲染出来,这样就是完整展现在我们面前的一个网页了
这个就是浏览器的一个功能第一次请求url服务器端返回的是html页面然后浏览器开始渲染HTML当解析到HTML DOM里面的图片连接css脚本和js脚本的链接浏览器就会自动发起一个请求静态资源的HTTP请求获取相对应的静态资源,然后浏览器就会渲染出来,最终将所有资源整合、渲染,完整展现在我们面前的屏幕上
>网页优化方面有一项是减少http请求次数就是把尽量多的css和js合并在一起尽量做到少的http请求
>网页优化方面有一项措施是减少HTTP请求次数就是把尽量多的css和js资源合并在一起,目的是尽量减少网页请求静态资源的次数,提高网页加载速度,同时减缓服务器的压力
## links
* [目录](<preface.md>)

8
3.2.md
View File

@@ -50,13 +50,13 @@
我们看到上面的代码要编写一个web服务器很简单只要调用http包的两个函数就可以了。
>- 如果你以前是PHP程序员那你也许就会问我们的nginx、apache服务器不需要吗Go就是不需要这些因为他直接就监听tcp端口了做了nginx做的事情然后sayhelloName这个其实就是我们写的逻辑函数了也就是php里面的执行逻辑类似。
>如果你以前是PHP程序员那你也许就会问我们的nginx、apache服务器不需要吗Go就是不需要这些因为他直接就监听tcp端口了做了nginx做的事情然后sayhelloName这个其实就是我们写的逻辑函数了也就是php里面的控制层controller函数类似。
>- 如果你以前是python程序员那么你一定听说过tornado这个代码和他是不是很像没错go就是拥有类似python这样动态语言的特性写web应用很方便。
>如果你以前是python程序员那么你一定听说过tornado这个代码和他是不是很像没错go就是拥有类似python这样动态语言的特性写web应用很方便。
>- 如果你以前是ruby程序员那么和ROR的/script/server启动有点类似。
>如果你以前是ruby程序员那么和ROR的/script/server启动有点类似。
我们看到Go通过简单的几行代码就已经运行起来一个web服务了而且这个Web服务内部已经支持高并发的特性我将会在接下来的两个小节里面详细的讲解一下go是如何实现Web高并发的。
我们看到Go通过简单的几行代码就已经运行起来一个web服务了而且这个Web服务内部支持高并发的特性我将会在接下来的两个小节里面详细的讲解一下go是如何实现Web高并发的。
## links
* [目录](<preface.md>)

22
3.3.md
View File

@@ -1,9 +1,9 @@
# 3.3 Go如何使得Web工作
前面小节介绍了如何通过Go搭建一个Web服务我们可以看到简单应用一个net/http包就方便的搭建起来了。那么底层到底是怎么做的呢万变不离其宗Go也离不开我们第一小节介绍的Web工作方式。
前面小节介绍了如何通过Go搭建一个Web服务我们可以看到简单应用一个net/http包就方便的搭建起来了。那么Go在底层到底是怎么做的呢万变不离其宗Go的Web服务工作也离不开我们第一小节介绍的Web工作方式。
## 对应web工作方式的几个概念
## web工作方式的几个概念
以下均是服务器端的相应概念
以下均是服务器端的几个概念
Request用户请求的信息用来解析用户的请求信息包括post、get、cookie、url等信息
@@ -15,15 +15,15 @@ Handler处理请求和生成返回信息的处理逻辑
## 分析http包运行机制
如下图所示是Go实现Web工作模式的流程图
如下图所示是Go实现Web服务的工作模式的流程图
![](images/3.3.http.png?raw=true)
(1) 创建listen socket, 指定的端口监听, 等待客户端请求到来。
1. 创建Listen Socket, 监听指定的端口, 等待客户端请求到来。
(2) listen socket接受客户端的请求, 得到client socket, 接下来通过client socket与客户端通信。
2. Listen Socket接受客户端的请求, 得到Client Socket, 接下来通过Client Socket与客户端通信。
(3) 处理客户端的请求, 首先从client socket读取http请求的协议头, 如果是post协议, 还可能要读取客户端上传的数据, 然后给相应的handler处理请求, handler处理完毕准备好客户端需要的数据, 通过client socket写给客户端。
3. 处理客户端的请求, 首先从Client Socket读取HTTP请求的协议头, 如果是POST方法, 还可能要读取客户端提交的数据, 然后给相应的handler处理请求, handler处理完毕准备好客户端需要的数据, 通过Client Socket写给客户端。
这整个的过程里面我们只要了解清楚下面三个问题也就知道Go是如何让Web运行起来了
@@ -31,17 +31,17 @@ Handler处理请求和生成返回信息的处理逻辑
- 如何接收客户端请求?
- 如何分配handler
前面小节的代码里面我们可以看到Go是通过一个函数来操作这个事情的`ListenAndServe`来监听起来的这个底层其实这样处理的初始化一个server对象然后调用了`net.Listen("tcp", addr)`,也就是底层起的是TCP协议然后监控我们设置的端口。
前面小节的代码里面我们可以看到Go是通过一个函数来操作这个事情的`ListenAndServe`来监听起来的这个底层其实这样处理的初始化一个server对象然后调用了`net.Listen("tcp", addr)`,也就是底层TCP协议搭建了一个服务,然后监控我们设置的端口。
监控之后如何接收客户端的请求呢?上面监控端口之后,调用了`srv.Serve(net.Listener)`函数,这个函数就是处理接收客户端的请求信息。这个函数里面起了一个`for{}`首先通过Listener接收请求其次一个Conn最后单独开了一个goroutine把这个请求的数据当做参数扔给这个conn去服务`go c.serve()`。这个就是高并发体现了,用户来的请求都是goroutine去服务相互不影响。
监控之后如何接收客户端的请求呢?上面代码执行监控端口之后,调用了`srv.Sere(net.Listener)`函数,这个函数就是处理接收客户端的请求信息。这个函数里面起了一个`for{}`首先通过Listener接收请求其次创建一个Conn最后单独开了一个goroutine把这个请求的数据当做参数扔给这个conn去服务`go c.serve()`。这个就是高并发体现了,用户的每一次请求都是在一个新的goroutine去服务相互不影响。
那么如何具体分配到相应的函数来处理请求呢conn首先会解析request:`c.readRequest()`,然后获取相应的handler:`handler := c.server.Handler`,也就是我们刚才在调用函数`ListenAndServe`时候的第二个参数我们前面例子传递的是nil也就是为空那么默认获取`handler = DefaultServeMux`,那么这个变量用来做什么的呢?对,这个变量就是一个路由器,它用来url匹配到其相应的handle函数那么这个我们有设置过吗?有,我们调用的代码里面第一句不是调用了`http.HandleFunc("/", sayhelloName)`嘛。这个就是注册了相应的路由,url为"/"的请求到函数sayhelloNameDefaultServeMux会调用ServeHTTP方法这个方法内部其实就是调用sayhelloName本身最后通过写入response的信息反馈到客户端。
那么如何具体分配到相应的函数来处理请求呢conn首先会解析request:`c.readRequest()`,然后获取相应的handler:`handler := c.server.Handler`,也就是我们刚才在调用函数`ListenAndServe`时候的第二个参数我们前面例子传递的是nil也就是为空那么默认获取`handler = DefaultServeMux`,那么这个变量用来做什么的呢?对,这个变量就是一个路由器,它用来匹配url跳转到其相应的handle函数那么这个我们有设置过吗?有,我们调用的代码里面第一句不是调用了`http.HandleFunc("/", sayhelloName)`嘛。这个作用就是注册了请求`/`的路由规则,当请求uri为"/",路由就会转到函数sayhelloNameDefaultServeMux会调用ServeHTTP方法这个方法内部其实就是调用sayhelloName本身最后通过写入response的信息反馈到客户端。
详细的整个流程如下图所示:
![](images/3.3.illustrator.png?raw=true)
至此我们的三个问题已经全部得到了解答你现在对于Go如何让Web跑起来的是否已经大概清楚了呢?
至此我们的三个问题已经全部得到了解答你现在对于Go如何让Web跑起来的是否已经基本了解呢?
## links