在配置web服务器的时候,我们经常遇到这样的问题,由于某些原因,该服务器只能拥有一个公网IP,但是可能需要提供其他机器或者本机上其他webserver的服务器给访问者,同时又不希望使用其他端口,如果在linux下,常见的解决方案是使用nginx作为前端server,通过反向代理间接访问其他webserver,在IIS上,通过Application Request Routing模块,我们可以轻松实现反向代理。
此Demo完成内容是:在服务器上创建三个网站,分别对应80,8081,8082三个端口,但在生产环境中,这些非80或443端口通常不会暴露给外部访问,采用ARR反向代理的访问,外部通过http://myexample.com/first来实际访问localhost:8081,通过http://myexample.com/second来实际访问localhost:8082。
网址 | IIS上的网站 | 实际站点 |
http://myexample.com | t | localhost |
http://myexample.com/first/ | first | localhost:8081 |
http://myexample.com/second/ | second | localhost:8082 |
在上节中,我们开启了server farm,加了重写规则,完成了load balance的功能,所有的请求会直接分发到server farm下任意一台服务器,但在本节中,我们不再使用load balance,在下面的窗口中,不选中下面的URL重写规则,相当于禁用了load balance,我们接下来试一下反向代理。
修改C:\Windows\System32\drivers\etc\hosts文件,以便通过域名myexample.com能访问本地, 然后新建两文件夹first 和second,在这两文件夹里分别创建index.html文件,在IIS中创建first和second这两网站并物理路径指向相应的文件夹。创建后的IIS网站如下:
下面是相应的文件夹和文件
PS C:\apps\test> ls
Directory: C:\apps\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 12/10/2018 2:24 PM first
d----- 12/10/2018 2:26 PM second
-a---- 12/9/2018 5:23 PM 42 index.html
PS C:\apps\test> cat index.html
this is the data from localhost----server0
PS C:\apps\test> cat first/index.html
this is the first page here
PS C:\apps\test> cat second/index.html
this is the second page here
PS C:\apps\test> invoke-webrequest -uri myexample.com
StatusCode : 200
StatusDescription : OK
Content : this is the data from localhost----server0
RawContent : HTTP/1.1 200 OK
PS C:\apps\test> invoke-webrequest -uri http://localhost:8081
StatusCode : 200
StatusDescription : OK
Content : this is the first page here
PS C:\apps\test> invoke-webrequest -uri http://localhost:8082
StatusCode : 200
StatusDescription : OK
Content : this is the second page here
点击上图中的Application Request Routing,选中启用代理,再点击Apply。
接下来,配置路由重写规则,在t网站上,点击Url Rewrite——Add Rules——Blank rule——Ok。
重写规则增加后的界面如下:
重写规则增加后在此网站对应的文件夹下,多出来了一个web.config文件,其中{R:1} 代表MatchUrl中的第一个匹配括号。
PS C:\apps\test> cat web.config
到这里就配置完成了,我们来验证一下。当访问 myexample.com/first时,实际上请求转发到localhost:8081,访问myexample.com/second时,请求转发到localhost:8082。
PS C:\apps\test> invoke-webrequest -uri myexample.com/first
StatusCode : 200
StatusDescription : OK
Content : this is the first page here
RawContent : HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Type: text/html
ETag: "bcd86c505190d41:0"
Last-Modified: Mon, 10 Dec 2018 06:26:41 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET,ARR/3.0,ASP.N...
Forms : {}
Headers : {[Accept-Ranges, bytes], [Content-Type, text/html], [ETag, "bcd86c505190d41:0"], [Last-Modified,
Mon, 10 Dec 2018 06:26:41 GMT]...}
Images : {}
InputFields : {}
Links : {@{innerHTML=here; innerText=here; outerHTML=here; outerText=here;
tagName=A; href=/index.html}}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 55
PS C:\apps\test> invoke-webrequest -uri myexample.com/second
StatusCode : 200
StatusDescription : OK
Content : this is the second page here
RawContent : HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Type: text/html
ETag: "7cca275c5190d41:0"
Last-Modified: Mon, 10 Dec 2018 06:27:01 GMT
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET,ARR/3.0,ASP.N...
Forms : {}
Headers : {[Accept-Ranges, bytes], [Content-Type, text/html], [ETag, "7cca275c5190d41:0"], [Last-Modified,
Mon, 10 Dec 2018 06:27:01 GMT]...}
Images : {}
InputFields : {}
Links : {@{innerHTML=here; innerText=here; outerHTML=here; outerText=here;
tagName=A; href=/index.html}}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 56
细心的你一定发现网页有一个链接,这个链接当从http://myexample.com/second来实际访问localhost:8082时,这网址的链接始终是here,直接点击这个链接,得不到预期的结果,因为它直接跳转到http://myexample.com/index.html,明显不对,如下图:
接下我们改一下它的出站规则,更改后的web.config内容如下,其中{C:1} 代表condition中的第一个匹配括号
PS C:\apps\test> cat web.config
最终我们来看看,点击一下,它会跳转到http://myexample.com/second/index.html,这样就对啦。
实际上大多数情况下我们都不需要配置出站规则,我们在原网页中写得内容是:this is the second page here,这样在index.html加一个斜杠写法就不太好,一般我们这样写:this is the second page here 或者 this is the second page here,如果是这种写法的话,出规规则就可以不用设置了,浏览器会直接找相对路径。
https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing
修改Location 3xx的出站规则的例子:
https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers
写到这里,发现在使用ARR来配置负载均衡或反向代理,最核心的模块是使用了URL Rewrite。
负载均衡和反向代理有什么区别?有反向代理,那有正向代理吗?
答:正向代理代理客户端,反向代理代理服务器,负载均衡将请求分发到多个服务器。