ServiceWeaver / weaver

Programming framework for writing and deploying cloud applications.
https://serviceweaver.dev
Apache License 2.0
4.79k stars 229 forks source link

How do I identify which replica a client tcp connection is on, and how do I route messages with rpc to that replica? #788

Open wind-c opened 3 months ago

wind-c commented 3 months ago

I wrote the tcp server example and the single-process mode is fine. The new question is, in the multi-process, multi-machine, or multi-replica deployment, how do you find out which replica a given client tcp connection is on? How do you route messages to this tcp connection?

Http is used for request-response services, but for push, notification, chat, pub-sub and other types of services are based on tcp connections, and messages must be routed to the specified client tcp connection.

wind-c commented 3 months ago

I looked at the Weaver project source code and found no relevant object and API exposure. If so, Weaver is only suitable for HTTP-based applications.

rgrandl commented 2 months ago

@wind-c, you can interact with a Service Weaver application based on whatever you can export a listener. Our examples expose a http server, but you can use something else too (e.g., a grpc server).

Now, for communication between different components we use RPCs on top of TCP. The weaver runtime is responsible to start components, and component replicas and propagate their addresses to all the other components that want to talk to.

What exactly are you trying to do?

wind-c commented 2 months ago

Maybe I don't understand weaver's architecture. So there's this doubt. I have written a tcp server example, the code file is attached. client.txt main.txt weaver.txt


The single process deployment worked fine: D:\GolandProjects\ServiceWeaver> weaver single deploy weaver.toml ╭───────────────────────────────────────────────────╮ │ app : hello.exe │ │ deployment : a1becea0-ac30-48f5-98a8-34861380a8c3 │ ╰───────────────────────────────────────────────────╯ hello listener available on 127.0.0.1:8080 app deployment_id: e19d61b9-2b19-4b9e-9bfa-6ecc3376b2cf wait for the client to connect ... hello listener available on 127.0.0.1:8080 reverse deployment_id: e19d61b9-2b19-4b9e-9bfa-6ecc3376b2cf Hello, 44605:1.0.0.721! wait for the client to connect ... 127.0.0.1:50644 client is connected! server received the data: hello

D:\GolandProjects\ServiceWeaver> .\client.exe hello client received data: HELLO


The multi-process deployment is abnormal:

D:\GolandProjects\ServiceWeaver> weaver multi deploy weaver.toml ╭───────────────────────────────────────────────────╮ │ app : hello.exe │ │ deployment : 293b392b-d73d-445e-9183-b8bb971d438e │ ╰───────────────────────────────────────────────────╯ S0101 08:00:00.000000 stdout 457a567f │ hello listener available on 127.0.0.1:8080 S0101 08:00:00.000000 stdout 91d737a8 │ hello listener available on 127.0.0.1:8080 S0101 08:00:00.000000 stdout 457a567f │ app deployment_id: 293b392b-d73d-445e-9183-b8bb971d438e S0101 08:00:00.000000 stdout 457a567f │ wait for the client to connect ... S0101 08:00:00.000000 stdout 91d737a8 │ app deployment_id: 293b392b-d73d-445e-9183-b8bb971d438e S0101 08:00:00.000000 stdout 91d737a8 │ wait for the client to connect ...

D:\GolandProjects\ServiceWeaver> .\client.exe hello client received data: HTTP/1.1 400 Bad Request Content-Type: text/plain; charset=utf-8 Connection: close

400 Bad Request server is down and the client is also down.


rgrandl commented 2 months ago

Got it.

The problem is the way you're trying to send requests from the client to the server using raw TCP in case of the multi deployer. Our multi deployer implementation uses a HTTP proxy to export the hello listener, and under the hood the HTTP proxy will send the client request to one of the server replicas. Server replicas accept traffic using TCP, however, because the HTTP proxy speaks HTTP, when you send a raw TCP message the HTTP proxy gets confused and returns a BAD Request. I believe that we're using a HTTP proxy in case of the SSH deployer as well.

However, Service Weaver DOES NOT make any assumptions about the kind of traffic you can send as long as it's TCP traffic. For example, if you try your example with the Kube deployer, it will work just fine. Same for the GKE deployer.

So: 1) Service Weaver framework should handle any kind of traffic as long as it's TCP based 2) the fact that multi doesn't work for your example, is because the way we implemented the multi deployer. However, you can modify the multi deployer to have a proxy that accepts raw TCP requests (or implement your own); I will look at this thing as well, but it's not a high priority right now. 3) It's on my list to provide examples on how to do raw TCP and grpc traffic and hopefully will get to that soon (that might also be an opportunity to enhance the multi deployer to support raw TCP requests) 4) you can use the Kube deployer to run it locally in multiple processes for now. Otherwise you can tweak multi for your usecase

Is this something that blocks you to deploy weaver in production or just playing around on your local machine?

wind-c commented 2 months ago

I see. I still hope that you can support the compatibility of the original TCP in various deployment modes, because you are more professional. Although Kube and GKE are commonly used, they are not suitable for all deployment scenarios.

Another question: Check deployment status, there is one replica of Main, Adder, and Reverser, and one Listener. The Listener loads requests to the Main component? How do you control the number of replica per component?

rgrandl commented 2 months ago

Will do. However, it's not a priority short term, because the multi deployer is intended to be used mostly for testing on the local machine. However, if this blocks you from adopting Service Weaver in production, please let us know.

Listeners are intended to be the way you interact with a Service Weaver application. In your example, the main component exports a listener that receives requests.

Number of replicas per component - the deployer computes the number of replicas. In case of multi, each component is replicated twice. The GKE/Kubernetes deployers rely on Kubernetes autoscalers to scale up/scale down then number of replicas based on load (a combination of cpu and memory usage on each pod).

wind-c commented 2 months ago

@rgrandl ,thank you very much for your reply. I really appreciate the architecture and the idea of ServiceWeaver. I'm eager to refactor my project Comqtt(https://github.com/wind-c/comqtt) using ServiceWeaver. Comqtt is tcp-based mqtt broker, so weaver support raw tcp in a multi-process and multi-machine deployment mode will greatly speed up my refactoring and testing.