[关闭]
@JunQiu 2018-11-26T17:05:31.000000Z 字数 2537 阅读 5200

Py http.server 使用 HTTPServer 阻塞问题

language_py summary_2018/11


1、背景

2、查阅资料

  1. // class http.server.HTTPServer(server_address, RequestHandlerClass)¶
  2. This class builds on the TCPServer class by storing the server address as instance variables named server_name and server_port. The server is accessible by the handler, typically through the handlers server instance variable.
  3. // class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)
  4. This class is identical to HTTPServer but uses threads to handle requests by using the ThreadingMixIn. This is useful to handle web browsers pre-opening sockets, on which HTTPServer would wait indefinitely.(多线程实现)

3、实践

  1. // 单进程 HTTPServer
  2. from http.server import BaseHTTPRequestHandler, HTTPServer
  3. import time
  4. class MyHandler(BaseHTTPRequestHandler):
  5. def do_GET(self):
  6. if self.path == '/sleep':
  7. time.sleep(7)
  8. self.send_response(200)
  9. self.wfile.write(bytes('sleep 7s', 'UTF-8'))
  10. if self.path == '/':
  11. self.send_response(200)
  12. self.wfile.write(bytes('not sleep', 'UTF-8'))
  13. if __name__ == '__main__':
  14. host = '0.0.0.0'
  15. port = 3004
  16. httpd = HTTPServer((host, port), MyHandler)
  17. try:
  18. httpd.serve_forever()
  19. except KeyboardInterrupt:
  20. httpd.server_close()
  21. // 多线程 ThreadingMixIn
  22. from http.server import BaseHTTPRequestHandler, HTTPServer
  23. from socketserver import ThreadingMixIn
  24. import time
  25. class MyHandler(BaseHTTPRequestHandler):
  26. def do_GET(self):
  27. if self.path == '/sleep':
  28. time.sleep(7)
  29. self.send_response(200)
  30. self.wfile.write(bytes('sleep 7s', 'UTF-8'))
  31. if self.path == '/':
  32. self.send_response(200)
  33. self.wfile.write(bytes('not sleep', 'UTF-8'))
  34. # 混合类重写了process_request
  35. class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
  36. pass
  37. if __name__ == '__main__':
  38. host = '0.0.0.0'
  39. port = 3004
  40. httpd = ThreadingHTTPServer((host, port), MyHandler)
  41. try:
  42. httpd.serve_forever()
  43. except KeyboardInterrupt:
  44. httpd.server_close()

4、结论

  1. // 结论:
  2. 1、单进程HTTPServer调用‘/sleep’会阻塞后面的请求7s
  3. 2、多线程ThreadingMixIn不会被阻塞,因为会建立一个线程去请求;当然在实际情况中,会设置线程的池的大小,避免线程被无止尽创建
  4. // 原理:ThreadingMixIn源码,通过混合类重写了process_request方法,通过每次新建立一个线程来处理请求,达到并发处理请求的效果
  5. class ThreadingMixIn:
  6. daemon_threads = False
  7. def process_request_thread(self, request, client_address):
  8. try:
  9. self.finish_request(request, client_address)
  10. self.shutdown_request(request)
  11. except:
  12. self.handle_error(request, client_address)
  13. self.shutdown_request(request)
  14. def process_request(self, request, client_address):
  15. t = threading.Thread(target = self.process_request_thread,
  16. args = (request, client_address))
  17. t.daemon = self.daemon_threads
  18. t.start()
  19. // 建议
  20. 1、官方文档已经说过:Warning http.server is not recommended for production. It only implements basic security checks.

5、参考文献

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注