Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 this issue Aug 1, 2024 · 7 comments

Comments

@wind-c
Copy link

wind-c commented Aug 1, 2024

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
Copy link
Author

wind-c commented Aug 1, 2024

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
Copy link
Collaborator

rgrandl commented Aug 7, 2024

@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
Copy link
Author

wind-c commented Aug 8, 2024

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
Copy link
Collaborator

rgrandl commented Aug 8, 2024

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
Copy link
Author

wind-c commented Aug 9, 2024

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
Copy link
Collaborator

rgrandl commented Aug 12, 2024

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
Copy link
Author

wind-c commented Aug 13, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants