關於HAProxy 的 acl配置隨機生效(失效)的問題

很簡單,需求是這樣的:css

就是把全部的 .js .css .html 之前 /image /img 下的文件使用另一臺專門處理靜態資源的機器nginx來處理。其它的請求發到後端的tomcat集羣去處理。html

從源裏安裝nginx

~ # aptitude show haproxy

版本是 1.4.18-0ubuntu3.1 .ubuntu

而後添加配置最小的配置後端

frontend http-frontend
        bind www.example.com:80
        acl url_static_begin    path_beg /images /img
        acl url_static_end    path_end .html .css .js
        acl url_service     path_beg /service
        use_backend servers if url_service
        use_backend statics if url_static_begin
        use_backend statics if url_static_end
        default_backend servers

backend statics
       server serverstatic static.example.com:80 check

backend servers
       server server01 server01.example.com:8080 maxconn 800 check
       server server02 server02.example.com:8080 maxconn 800 check

這裏的acl規則裏添加了一個 /service 是由於系統裏存在一些動態生成的js請求因此把這部分請求仍是轉發給了後端的tomcat集羣上去了。配置完成後測試的時候,奇怪的事情發生了。發現配置的規則好像生效了,又好像不生效。發現不是全部的 js, css,請求都轉發到static上去了。也不是全部的須要動態處理的請求都轉發到tomcat集羣上去了。某些請求轉到static上去了。這根本就不是acl配置所須要的效果啊。tomcat

可是更奇怪的是我用 curl -I 去請求任何一個資源的時候又是我想要的結果。請求 .js被髮送到static上去了。請求 .jsp 到tomcat去了。bash

google出來的文章都是這麼寫的看了官方的文檔說明也沒有看出有什麼問題。折騰半天后終於在stackoverflow上面找到有人和我同樣的狀況負載均衡

http://serverfault.com/questions/310338/haproxy-seems-to-be-load-balancing-instead-of-following-acl-rulesfrontend

這人是以爲請求沒有走acl配置的規則而走了負載均衡的配置,下面的人回答形成這個結果的緣由是因爲collection被重用了。這就對了。也能解釋上面我測試出的狀況了。curl

  1. 爲何會出現靜態資源還走到tomcat集羣去了,是因爲那個靜態資源的請求重用了尚未關閉的請求.jsp的那個連接。
  2. 一樣爲何會出現應該轉到tomcat集羣的請求被轉到了static去。那是因爲.jsp的請求使用了以前請求static的那個連接。
  3. 爲何用curl -I 測試的時候邏輯又徹底正確?由於curl測試的時候只有單個請求也就只有一個連接也就不存在使用以前使用過的keep-alive的連接。acl徹底正常。

在上個帖子的回答裏引用了另一個帖子。

http://serverfault.com/questions/104350/why-am-i-getting-errors-in-my-haproxy-content-switching-config

在這裏有詳細一點的說明

Also, you're doing content switching, so please add "option httpclose" in your frontend or defaults section, otherwise second requests of keep-alive connections will not be matched.

因此解決方法就是將 option httpclose 添加到 frontend 或者 defaults 的配置裏面。

frontend http-frontend
        option httpclose
        bind www.example.com:80
        acl url_static_begin    path_beg /images /img
        acl url_static_end    path_end .html .css .js
        acl url_service     path_beg /service
        use_backend servers if url_service
        use_backend statics if url_static_begin
        use_backend statics if url_static_end
        default_backend servers

這樣就能夠了。問題是解決了,但是若是禁用了keep-alive的話,那會極大的影響效率,那是否是能夠這麼理解,若是用到了acl的狀況其實就只能作性能的犧牲?

至於爲何haproxy不能實現即便在reuse以前的連接的時候也去作acl的判斷,我還不清楚,所在當我在shlug的郵件列表裏提這個問題的時候Choas大神還懷疑這是否是haproxy的bug,讓我去報一下bug。

這裏也向各位大神請教是否是別有他法?感謝。

相關文章
相關標籤/搜索