2013-10-10 46 views
0
  • 創建了帶有2個EC2微型背景的Amazon負載均衡器。
  • 2個EC2微型實例具有python服務。
  • 服務運行良好,直接呼叫時響應
  • 當我們通過負載平衡器的公共DNS調用它們時,服務不運行。 ELB拋出500錯誤。

直接調用EC2實例的服務實例: ec2-54-200-1-2.us-west-2.compute.amazonaws.com/myservice ==>返回數據Amazon ELB無法正常運行並且投擲500服務器錯誤

調用的

例負載均衡: test-12345678.us-west-2.elb.amazonaws.com/myservice ==>返回500條錯誤

進一步指出: DJANGO屬性ALLOWED_HOSTS設置爲[ '*'],但沒有奏效。 使用HTTP協議即映射負載平衡器協議= HTTP端口80到實例協議= HTTP與端口80

+0

這已解決。還有一個settings.py文件覆蓋了以前的django設置文件。 一旦我們在正確的文件中將ALLOWED_HOSTS更新爲['*'],那麼它就起作用了。 – user2653294

回答

1

我承認這是一個非常古老的問題,但我使用了一種解決方案,我認爲是更好的,不會危害系統的安全性通過設置ALLOWED_HOSTS = ['*']

這是我寫的一箇中間件類,我覺得可以隨意重用。

它繼承自CommonMiddleware,它是settings.pyMIDDLEWARE_CLASSES設置中應該用來代替CommonMiddleware的人。

from django.middleware.common import CommonMiddleware 
from django.conf import settings 
from django.http.response import HttpResponse 
from django.utils import importlib 

class CommonWithAllowedHeartbeatMiddleWare(CommonMiddleware): 
    """ 
    A middleware class to take care of LoadBalancers whose HOST headers might change dynamically 
    but are supposed to only access a specific path that returns a 200-OK status. 
    This middleware allows these requests to the "heartbeat" path to bypass the ALLOWED_HOSTS mechanism check 
    without jeopardizing the rest of the framework. 
    (for more details on ALLOWED_HOSTS setting, see: https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts) 

    settings.HEARTBEAT_PATH (default: "/heartbeat/"): 
     This will be the path that is cleared and bypasses the common middleware's ALLOWED_HOSTS check. 

    settings.HEARTBEAT_METHOD (default: None): 
     The full path to the method that should be called that checks the status. 
     This setting allows you to hook a method that will be called that can perform any kind of health checks and return the result. 
     If no method is specified a simple HttpResponse("OK", status_code=200) will be returned. 
     The method should expect the HttpRequest object of this request and return either True, False or a HttpResponse object. 
     - True: middleware will return HttpResponse("OK") 
     - False: middleware will return HttpResponse("Unhealthy", status_code=503) [status 503 - "Service Unavailable"] 
     - HttpResponse: middleware will just return the HttpResponse object it got back. 

    IMPORTANT NOTE: 
    The method being called and any method it calls, cannot call HttpRequest.get_host(). 
    If they do, the ALLOWED_HOSTS mechanism will be called and SuspeciousOperation exception will be thrown. 
    """ 

    def process_request(self, request): 
     # Checking if the request is for the heartbeat path 
     if request.path == getattr(settings, "HEARTBEAT_PATH", "/heartbeat/"): 
      method_path = getattr(settings, "HEARTBEAT_METHOD", None) 

      # Checking if there is a method that should be called instead of the default HttpResponse 
      if method_path: 
       # Getting the module to import and method to call 
       last_sep = method_path.rfind(".") 
       module_name = method_path[:last_sep] 
       method = method_path[(last_sep+1):] 
       module = importlib.import_module(module_name) 

       # Calling the desired method 
       result = getattr(module, method)(request) 

       # If the result is alreay a HttpResponse object just return it 
       if isinstance(result, HttpResponse): 
        return result 
       # Otherwise, if the result is False, return a 503-response 
       elif not result: 
        return HttpResponse("Unhealthy", status_code=503) 

      # Just return OK 
      return HttpResponse("OK") 

     # If this is not a request to the specific heartbeat path, just let the common middleware do its magic 
     return CommonMiddleware.process_request(self, request) 

當然我知道這完全機制繞過CommonMiddleware,但它只有在請求心跳路徑,所以我覺得這是一個小的代價。

希望別人認爲它有用。