How to see the TCP Connection established between HAProxy and Flask app ? + Working of the event driven arch

Hi,

From book,

HAProxy uses a single-threaded, event-driven architecture to receive requests from clients and dispatch
them quickly to backend servers. It does not open a thread and wait for a server to respond. Instead, it
moves on to do other work and returns when it receives a callback. This allows it to scale to many
thousands of concurrent connections.

To visually see this happening, i created a flask app and some configured HAProxy.

HAproxy Config

frontend http_front
    bind *:8001
    default_backend servers
 
backend servers
    mode tcp
    balance roundrobin
    server server1 127.0.0.1:5001 check

Flask App

from flask import Flask
import time
 
app = Flask(__name__)
 
@app.route("/")
def hello():
    time.sleep(10)
    return "Hello from Flask App 1!"
 
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5001)


    

I am curious about

  1. How the connection is established and not closed between browser to haproxy. When the HAProxy is an event-driven . Does these entries are stored in some table or data structure ( like epoll ) ? How can i visually see it ?

  2. I am able to see the connection established between client (browser) and HAProxy (8001) using wireshark.

But not between HAProxy(8001) and my backend app (5001).

  1. Would like to know more about how this response from backend is triggering an event back to HAProxy.
1 Like
GET / HTTP/1.1

அந்த வரியை கிளிக் செய்யவும் அல்லது எக்ஸ்பேண்ட் செய்து பார்க்கவும். விரிவடைய செய்து tcp லேயரில் எந்த போர்டில் இருந்து எந்த போர்டுக்கு ரெக்வஸ்ட் செல்கின்றது என்று பார்க்கவும்.

The request to flask (5001) doesnt come from 8001 (proxy port). HAProxy uses some internal port of OS to send request.

from flask import Flask,request
import time
 
app = Flask(__name__)
 
@app.route("/")
def hello():
    print("remote: {}:{}\n".format(request.environ.get("REMOTE_ADDR"), request.environ.get("REMOTE_PORT")))
    return "Hello from Flask App!\n"
 
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=2201)

இந்த flask ஐ முயற்சித்து பார்க்கவும். இது ரெக்வெஸ்ட் எங்கிருந்து வருகின்றது என்பதை காட்டும்

Yeah, I got source port from tracing in wireshark itself. My query was how HAProxy and Flask is communicating.

Seems haproxy will store the tcp connection in a datastructure which is triggered from a different available port.

Thanks

எப்படி இருந்தாலும் HAProxy உங்கள் flask ன் 5001 போர்ட்டை ஏதேனும் ஒரு tcp போர்ட் வழியாக தொடர்புகொண்டுதான் தகவலை கிலைண்டிற்கு அனுப்பும். ஆனால் உங்கள் wireshark நிழற்படத்தில் அப்படிப்பட்ட தகவல் எங்கும் இல்லை, அதுதான் குழப்பம். எப்படியோ உங்களுக்கு HAProxy ஆனது flask ஐ tcp வழியாகத்தான் தொடர்பு கொள்கின்றது OS ன் மற்ற IPC வழிகளில் தெடர்புகொள்ளவில்லை என்று புரிந்துவிட்டால் நீங்கள் கேட்ட கேள்விக்கு விடை கிடைத்துவிட்டது.

yes

If you want to view the tcp request passing through HAProxy and Flask app you can use a proxy server in between them.

MITM proxy is one such tool that can help you achieve it.

I don’t think we can use wireshark for this as the packet is transferred between two app. Wireshark only listens on network interface as far as i know.

or if you like to create your own proxy server in python, check this video