使用Nginx 讓IIS和Tomcat等多個站點一起飛
前言:
養成一個好習慣,解決一個什么問題之后就記下來,畢竟“好記性不如爛筆頭”。
這樣也能幫助更多的人 不是嗎?
最近閑着沒事兒瞎搞,自己在寫一個ASP.NET MVC的系統,所以理所當然的 在服務器上搭建了一個IIS。
可是,學員要做JSP的項目了,涉及一些在線API回調的問題,所以沒招,給他們又搭建了一個Tomcat。
那么、問題來了。。
我IIS里面的這些站點,可以使用IIS自帶的綁定功能,分別綁定多個域名共享80端口。
但是,Tomcat呢?肯定不能綁定80了吧?可如果不綁定80。難道我要“http://www.xxx.com:8080”這么訪問Tomcat里面的站點嗎?!
於是乎,各種解決方案在腦子里想了個遍。甚至修改hosts、使用FastCGI等等都想過了。可我又不想這么玩。唉。
沒招,最后想到了Nginx這個神器。因為它 支持反向代理。而且Linux也能用哦~
問:IIS7之后不也支持反向代理了嘛?你這多此一舉。
大哥。我這講的是Nginx,不要打擾我裝X好嘛。。呵呵,開個玩笑。其實裝X是次要的,主要還是我服務器想換成Linux的。(說的自己都不信了 哈哈)
廢話不多說,開始正文。O(∩_∩)O哈哈~
目錄:
1. Nginx介紹
如我“前言”所說,在IIS里面,我們搭建多個站點可以使用自帶的綁定端口的方式實現。
但是如果這時候又加一個Tomcat呢?沒法綁定80端口了,因為已經被IIS占用了。可是我又不可能“http://www.xxx.com:8080”去訪問吧?
當然我們可以像我發過的一篇文章《IIS8 使用FastCGI配置PHP環境支持 過程詳解》那樣,在IIS中添加PHP的cgi映射,來添加對php的支持。
JSP也同樣可以使用FastCGI。但是我不想這么玩了,個人覺得 老是用IIS沒啥技術含量,如果以后還遇到什么東西,不支持FastCGI怎么辦呢?
對吧。你沒法改變這個社會,沒招,只能改變自己去適應社會的變化。
所以最后就想到了咱們的Nginx。
簡單介紹一下,Nginx主要支持反向代理,什么意思呢?
說白了就是,你把80端口綁定給Nginx,然后通過配置文件告訴它:我訪問www.aaa.com域名,你給我把請求轉發到www.aaa.com:81上面;我訪問www.bbb.com域名,你給我把請求轉發到www.bbb.com:8080上面。等等等等。。
這時候大概大家已經明白了我這里為啥用Nginx了吧。呵呵。就是因為這個功能。
當然,如果你認為它只是做代理轉發的,那你就錯了。
Nginx除了可以實現反向代理來自定義轉發你的請求,它還能通過配置文件實現Session跨域、請求過濾、負載均衡等等等的功能。
詳細的介紹和使用,大家可以去官網或自行Google查閱。各種用法,各種介紹。特別詳細的。
是不是有點兒意思哈?呵呵。分享一下我這里的IIS+Tomcat的多個站點是怎么弄的吧。
2. 下載&安裝Nginx
進入官網http://nginx.org/,下載Nginx程序文件,最新版本列表如圖:
不像其他軟件那樣,下載還需要注冊登錄啥的,這個什么都不需要,直接選擇版本就可以免費下載。而且程序僅1.xMB大小。
點擊版本連接進入后,會讓您選擇平台Windows還是Linux:
這里我下載的是Windows的1.10.0:
Nginx是綠色解壓版的,不需要運行安裝程序,直接解壓完就能用。
這里,我將其解壓到了D:\Nginx目錄了,目錄文件如下:
雙擊運行nginx.exe,只見一DOS界面一閃而過,我特么還以為眼花了呢。再雙擊。還是一閃而過。
WTF?!什么鬼?!
按照網上教程里面的劇本兒來說,雙擊運行后,確實是一閃而過,不過訪問http://localhost可以看到Nginx的歡迎界面。
但是我打開瀏覽器,訪問后,直接找不到服務器。頓時我方了。啥玩意兒?!
機智的我看到了D:\Nginx\logs\error.log錯誤日志文件,日志內容如下:
1 2016/05/16 23:55:32 [emerg] 6488#7044: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions) 2 2016/05/16 23:55:32 [emerg] 6488#7044: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions) 3 2016/05/16 23:55:32 [emerg] 6488#7044: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)
很明顯,提示綁定當前計算機的80端口失敗了。
我又打開DOS,切換到D:\Nginx,輸入nginx.exe,提示錯誤也是這個。
於是乎,立馬想到了IIS。因為如果綁定80端口失敗,肯定是80被占用了啊。
我就把所有網站都停止了,甚至IIS服務都停了,還是不行。
你妹妹的,逼我,查看80端口到底是被誰占用了。
大家可以使用netstat的DOS命令查看,也可以使用任務管理器中的資源查看器查看,當然如果都不會用,你也可以使用360的網絡連接查看器查看。
找到之后kill結束掉它。
最后發現,不是IIS的問題,因為IIS並不綁定什么80端口,頂多也只是IIS里面的網站綁定的80訪問端口罷了。
罪魁禍首是另一個服務:Web Deploy服務,這個是我安裝IIS的時候額外安裝的一個東西,為了遠程發布部署用的。
當然,現在並不用,停止服務即可。
然后再回去運行nginx.exe,同樣是一閃而過(因為nginx是隱式運行在進程中的),但是http://localhost已經可以訪問了。
Nginx的歡迎界面如下所示:
看到這個界面了,給我激動的,真想抱着媳婦兒狠親一口。(然而卻是單身狗依舊)
3. 小試Nginx
我打開了IIS,新建了一個站點,域名是www.geeksss.com,綁定的端口是81。
下面我想使用Nginx,配置之后,通過www.geeksss.com,自動將請求代理轉發到www.geeksss.com:81上。
步驟如下:
之前說過,Nginx只需要設置好配置文件就可以了。
打開D:\Nginx\conf\nginx.conf配置文件,准備自定義修改一下。
橋豆麻袋、等一下。
萬一一會兒改叉劈了程序報廢了改不回去了怎么辦?還是先備份一下。哈哈。
(養成個習慣)
配置文件注釋都是英文的,我就不一一介紹了,文章也不太好介紹着每個參數。
所以我就簡單地配置了一項,順便把主要的注釋都翻譯過來了,修改后的內容如下:

1 #運行用戶 2 #user www-data; 3 4 #啟動進程,通常設置成和cpu的數量相等 5 worker_processes 2; 6 7 #全局錯誤日志及PID文件 8 error_log logs/error.log; 9 error_log logs/error.log notice; 10 error_log logs/error.log info; 11 pid logs/nginx.pid; 12 13 #工作模式及連接數上限 14 events { 15 #單個后台worker process進程的最大並發鏈接數 16 worker_connections 1024; 17 } 18 19 #設定http服務器,利用它的反向代理功能提供負載均衡支持 20 http { 21 #設定mime類型,類型由mime.type文件定義 22 include mime.types; 23 default_type application/octet-stream; 24 25 #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 26 # '$status $body_bytes_sent "$http_referer" ' 27 # '"$http_user_agent" "$http_x_forwarded_for"'; 28 29 #設定日志格式 30 access_log logs/access.log; 31 32 #sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為 off,以平衡磁盤與網絡I/O處理速度,降低系統的uptime. 33 sendfile on; 34 #tcp_nopush on; 35 36 #連接超時時間 37 #keepalive_timeout 0; 38 keepalive_timeout 65; 39 40 #開啟gzip壓縮 41 gzip on; 42 gzip_disable "MSIE [1-6]\.(?!.*SV1)"; 43 44 #設定請求緩沖 45 client_header_buffer_size 1k; 46 large_client_header_buffers 4 4k; 47 48 # www.geeksss.com 49 server{ 50 listen 80; #偵聽端口 51 server_name www.geeksss.com; #定義使用www.xx.com訪問 52 53 #charset koi8-r; 54 55 access_log logs/www.geeksss.com.access.log; #設定本虛擬主機的訪問日志 56 57 #默認請求 58 location / { 59 root /; # 定義服務器的默認網站根目錄位置 60 index Home/Index; # 定義首頁索引文件的名稱 61 proxy_pass http://www.geeksss.com:81 ; #請求轉向mysvr 定義的服務器列表 62 } 63 64 #error_page 404 /404.html; 65 66 # redirect server error pages to the static page /50x.html 67 # 定義錯誤提示頁面 68 error_page 500 502 503 504 /50x.html; 69 location = /50x.html { 70 root /root; 71 } 72 } 73 }
可以發現,我修改了里面的“server”配置項,注釋已經很明確了,如果還不明白呢可以自行查閱相關文檔或留言。
這里簡單介紹一下server配置項中的幾個參數:
- listen:監聽的端口
- server_name:當前的配置可以通過什么域名訪問
- access_log:當前server的日志文件位置
- location:配置請求,類似路由的概念
- location->proxy_pass:當前請求代理轉發到哪
- error_page:重定向錯誤頁的位置
我上面的server意思就是:nginx監聽80端口的請求,如果是server_name過來的,則代理轉發到proxy_pass。
很簡單吧?
這樣,當我訪問www.geeksss.com的時候,實際上是通過Nginx將請求轉發到了IIS中的www.geeksss.com:81的站點了。
4. IIS+Tomcat並用
我搭建了兩個Tomcat站點,然后修改Tomcat\conf\server.xml文件,添加了兩個Host進行綁定,修改后的server.xml文件如下所示:

1 <?xml version='1.0' encoding='utf-8'?> 2 <Server port="8005" shutdown="SHUTDOWN"> 3 <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> 4 <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 5 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> 6 <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 7 <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> 8 9 <GlobalNamingResources> 10 <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> 11 </GlobalNamingResources> 12 13 <Service name="Catalina"> 14 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 15 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 16 17 <Engine name="Catalina" defaultHost="localhost"> 18 <Realm className="org.apache.catalina.realm.LockOutRealm"> 19 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> 20 </Realm> 21 <Host name="ts2121.bdqnbky.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> 22 <Alias>121.bdqnbky.com</Alias> 23 <Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="ts2121.bdqnbky.com_log." suffix=".txt" timestamp="true"/> 24 <Context path="" docBase="D:\WebSite\ts2121.bdqnbky.com\" reloadable="true" caseSensitive="false" debug="0"></Context> 25 </Host> 26 <Host name="ts2122.bdqnbky.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> 27 <Alias>122.bdqnbky.com</Alias> 28 <Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="ts2122.bdqnbky.com_log." suffix=".txt" timestamp="true"/> 29 <Context path="" docBase="D:\WebSite\ts2122.bdqnbky.com\" reloadable="true" caseSensitive="false" debug="0"></Context> 30 </Host> 31 </Engine> 32 </Service> 33 </Server>
詳細的Tomcat配置就不過多介紹了,不屬於本篇范圍之內。畢竟估計講詳細了,又得來個長篇大論了。。。
只需要在下面修改一下<Host>節點配置就可以了,每個Host對應一個Tomcat站點。
其中<Host>中的<Alias>表示的是當前<Host>配置的站點綁定的域名。
也就是說,現在我的Tomcat有兩個站點:http://ts2121.bdqnbky.com:8080和http://ts2122.bdqnbky.com:8080。
再加上我的IIS里面其中的兩個站點:http://www.geeksss.com:81和http://api.geeksss.com:82兩個站點。
額外再加上我的JetBrains在線注冊服務器:http://www.geeksss.com:1996。
現在一共是五個站點。而且域名都不一樣。
下面,配置Nginx,nginx.conf文件配置如下:

1 #運行用戶 2 #user www-data; 3 4 #啟動進程,通常設置成和cpu的數量相等 5 worker_processes 2; 6 7 #全局錯誤日志及PID文件 8 error_log logs/error.log; 9 error_log logs/error.log notice; 10 error_log logs/error.log info; 11 #pid logs/nginx.pid; 12 13 #工作模式及連接數上限 14 events { 15 #單個后台worker process進程的最大並發鏈接數 16 worker_connections 1024; 17 } 18 19 #設定http服務器,利用它的反向代理功能提供負載均衡支持 20 http { 21 #設定mime類型,類型由mime.type文件定義 22 include mime.types; 23 default_type application/octet-stream; 24 25 #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 26 # '$status $body_bytes_sent "$http_referer" ' 27 # '"$http_user_agent" "$http_x_forwarded_for"'; 28 29 #設定日志格式 30 access_log logs/access.log; 31 32 #sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為 off,以平衡磁盤與網絡I/O處理速度,降低系統的uptime. 33 sendfile on; 34 #tcp_nopush on; 35 36 #連接超時時間 37 #keepalive_timeout 0; 38 keepalive_timeout 65; 39 40 #開啟gzip壓縮 41 gzip on; 42 gzip_disable "MSIE [1-6]\.(?!.*SV1)"; 43 44 #設定請求緩沖 45 client_header_buffer_size 1k; 46 large_client_header_buffers 4 4k; 47 48 ############################################################ 49 # IIS 50 # listen : www.geeksss.com:80 51 # redirect : www.geeksss.com:81 52 ############################################################ 53 server{ 54 listen 80; #偵聽端口 55 server_name www.geeksss.com geeksss.com; #定義使用www.xx.com訪問 56 57 #charset koi8-r; 58 59 access_log logs/www.geeksss.com.access.log; #設定本虛擬主機的訪問日志 60 61 #默認請求 62 location / { 63 root /; # 定義服務器的默認網站根目錄位置 64 index Home/Index; # 定義首頁索引文件的名稱 65 proxy_pass http://www.geeksss.com:81 ; #請求轉向mysvr 定義的服務器列表 66 } 67 68 #error_page 404 /404.html; 69 70 # redirect server error pages to the static page /50x.html 71 # 定義錯誤提示頁面 72 error_page 500 502 503 504 /50x.html; 73 location = /50x.html { 74 root /root; 75 } 76 } 77 78 ############################################################ 79 # IIS 80 # listen : api.geeksss.com:80 81 # redirect : api.geeksss.com:82 82 ############################################################ 83 # api.geeksss.com 84 server{ 85 listen 80; #偵聽端口 86 server_name api.geeksss.com; #定義使用www.xx.com訪問 87 88 #charset koi8-r; 89 90 access_log logs/api.geeksss.com.access.log; #設定本虛擬主機的訪問日志 91 92 #默認請求 93 location / { 94 root /; # 定義服務器的默認網站根目錄位置 95 #index Home/Index; # 定義首頁索引文件的名稱 96 proxy_pass http://api.geeksss.com:82; #請求轉向mysvr 定義的服務器列表 97 } 98 99 #error_page 404 /404.html; 100 101 # redirect server error pages to the static page /50x.html 102 # 定義錯誤提示頁面 103 error_page 500 502 503 504 /50x.html; 104 location = /50x.html { 105 root /root; 106 } 107 } 108 109 ############################################################ 110 # IntelliJIDEALicenseServer 111 # listen : www.geeksss.com:2016 112 # redirect : www.geeksss.com:1996 113 ############################################################ 114 upstream JetbrainsRegister { 115 server 101.200.217.33:1996; 116 server www.geeksss.com:1996; 117 } 118 server{ 119 listen 2016; #偵聽端口 120 server_name www.geeksss.com; #定義使用www.xx.com訪問 121 122 #charset koi8-r; 123 124 access_log logs/www.geeksss.com.2016.access.log; #設定本虛擬主機的訪問日志 125 126 #默認請求 127 location / { 128 proxy_pass http://JetbrainsRegister; #請求轉向mysvr 定義的服務器列表 129 } 130 } 131 132 ############################################################ 133 # Tomcat 134 # listen : ts2121.bdqnbky.com:80 135 # redirect : ts2121.bdqnbky.com:8080 136 ############################################################ 137 server { 138 listen 80; #偵聽端口 139 server_name ts2121.bdqnbky.com; #定義使用www.xx.com訪問 140 141 #charset koi8-r; 142 143 access_log logs/ts2121.bdqnbky.com.access.log; #設定本虛擬主機的訪問日志 144 145 #默認請求 146 location / { 147 root /; # 定義服務器的默認網站根目錄位置 148 index index.jsp; # 定義首頁索引文件的名稱 149 proxy_pass http://ts2121.bdqnbky.com:8080 ; #請求轉向mysvr 定義的服務器列表 150 } 151 152 #error_page 404 /404.html; 153 154 # redirect server error pages to the static page /50x.html 155 # 定義錯誤提示頁面 156 error_page 500 502 503 504 /50x.html; 157 location = /50x.html { 158 root /root; 159 } 160 161 # proxy the PHP scripts to Apache listening on 127.0.0.1:80 162 # 163 #location ~ \.php$ { 164 # proxy_pass http://127.0.0.1; 165 #} 166 167 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 168 # 169 #location ~ \.php$ { 170 # root html; 171 # fastcgi_pass 127.0.0.1:9000; 172 # fastcgi_index index.php; 173 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 174 # include fastcgi_params; 175 #} 176 177 # deny access to .htaccess files, if Apache's document root 178 # concurs with nginx's one 179 # 180 #location ~ /\.ht { 181 # deny all; 182 #} 183 } 184 185 ############################################################ 186 # Tomcat 187 # listen : ts2122.bdqnbky.com:80 188 # redirect : ts2122.bdqnbky.com:8080 189 ############################################################ 190 server{ 191 listen 80; #偵聽端口 192 server_name ts2122.bdqnbky.com; #定義使用www.xx.com訪問 193 194 #charset koi8-r; 195 196 access_log logs/ts2122.bdqnbky.com.access.log; #設定本虛擬主機的訪問日志 197 198 #默認請求 199 location / { 200 root /; # 定義服務器的默認網站根目錄位置 201 #index Home/Index; # 定義首頁索引文件的名稱 202 proxy_pass http://ts2122.bdqnbky.com:8080; #請求轉向mysvr 定義的服務器列表 203 } 204 205 #error_page 404 /404.html; 206 207 # redirect server error pages to the static page /50x.html 208 # 定義錯誤提示頁面 209 error_page 500 502 503 504 /50x.html; 210 location = /50x.html { 211 root /root; 212 } 213 } 214 215 216 # another virtual host using mix of IP-, name-, and port-based configuration 217 # 218 #server { 219 # listen 8000; 220 # listen somename:8080; 221 # server_name somename alias another.alias; 222 223 # location / { 224 # root html; 225 # index index.html index.htm; 226 # } 227 #} 228 229 230 # HTTPS server 231 # 232 #server { 233 # listen 443 ssl; 234 # server_name localhost; 235 236 # ssl_certificate cert.pem; 237 # ssl_certificate_key cert.key; 238 239 # ssl_session_cache shared:SSL:1m; 240 # ssl_session_timeout 5m; 241 242 # ssl_ciphers HIGH:!aNULL:!MD5; 243 # ssl_prefer_server_ciphers on; 244 245 # location / { 246 # root html; 247 # index index.html index.htm; 248 # } 249 #} 250 251 }
可以看到,我配置了四個server,也就對應着每個站點。
其中的listen監聽端口都是80。但是server_name,也就是請求進入的域名卻不相同。
然后通過location -> proxy_pass代理轉發到了實際的每個站點。
這時,只需要如下訪問即可自動跳轉到對應的域名不同的各個站點,而且不需要添加任何端口號,因為Nginx自動給你轉發過去了:
http://www.geeksss.com,實際轉發:http://www.geeksss.com:81
http://api.geeksss.com,實際轉發:http://api.geeksss.com:82
http://ts2121.bdqnbky.com,實際轉發:http://ts2121.bdqnbky.com:8080
http://ts2122.bdqnbky.com,實際轉發:http://ts2122.bdqnbky.com:8080
http://www.geeksss.com:2015,實際轉發:http://www.geeksss.com:1996
OK。大功告成。
5. 啟動/停止/重啟 Nginx
DOS命令即可控制,為了使用方便,大家也可以將Nginx所在目錄配置到系統環境變量的path中,方便隨時隨地通過dos控制。
啟動:nginx -s start
停止:nginx -s stop
重啟:nginx -s reload
其它命令大家可以參閱官網文檔,其實暫時主要用到的也就上面這三個命令了。哈哈
6. 結尾
關於Nginx其他的配置,例如跨域和負載均衡等等,大家可以先把這個玩兒明白了,然后其實就很簡單了。
無非就是修改點兒配置文件而已。
而且Linux里面的用法和這個也是一樣的。
等有時間了,我再搞個相應的文章。
最后,覺得聽懂了,感覺還不錯的,記得點贊推薦哦~
O(∩_∩)O 摸摸噠~