Disable Reverse DNS Query For Ceilometer API

2014/03/12 openstack

The ceilometer-api serves its application via wsgiref.simple_server module, which depends on BaseHTTPServer, which will do a reverse DNS query when log message. In some network environment, it will cause around 10 seconds useless latency. Patch BaseHTTPServer.BaseHTTPRequestHandler.address_string will solve this issue.

My workmate complains that it always consume 10 extra seconds to get http response when test ceilometer havana rest api, I check my test environment and find that it is affected too. But nova, neutron and other openstack service is ok. so I think it may be the wsgiref problem, since this is the significant difference for ceilometer-api.

so i write a demo wsgi app to locate the problem:

1
2
3
4
import wsgiref.simple_server as ss

server = ss.make_server('0.0.0.0', 60000, ss.demo_app)
server.serve_forever()

it works fine in public network enviroment and my notebook, but has same 10 seconds latency in the LAN environment of company, so i think it may be the dns problem. after some search on google, i find that BaseHTTPServer.BaseHTTPRequestHandler.address_string will do a reverse dns query when log message, so i hacked it with ip address, then the 10 seconds latency no longer exists.

1
2
3
4
5
6
import wsgiref.simple_server as ss

bhs = __import__('BaseHTTPServer')
bhs.BaseHTTPRequestHandler.address_string = lambda x: x.client_address[0]
server = ss.make_server('0.0.0.0', 60000, ss.demo_app)
server.serve_forever()

for ceilometer, you need to patch it before make_server as well, for i.e., insert the following lines in Line 115 of /usr/lib64/python2.6/site-packages/ceilometer/api/app.py:

1
2
bhs = __import__('BaseHTTPServer')
bhs.BaseHTTPRequestHandler.address_string = lambda x: x.client_address[0]

then restart the ceilometer-api service, done.

But the ceilometer-drive (core developers) doesn’t accept monkypatch module, see https://review.openstack.org/#/c/79876/, so we need to use a special param in wsgiref.simple_server.make_server, which is handler_class. We can create a class inherits from wsgiref.simple_server.WSGIRequestHandler, and override its log_message or client_address method, thanks for the duck type of Python. The final solution for now is:

1
2
3
4
5
6
class CeiloWSGIRequestHandler(simple_server.WSGIRequestHandler):
    def address_string(self):
        return self.client_address[0]

srv = simple_server.make_server(host, port, root,
                                handler_class=CeiloWSGIRequestHandler)

materials:

License: (CC 3.0) BY-NC-SA

Search

    Table of Contents