I have an application that sends video and a text file on different http post request. I have multiple ec2 instances under a loadbalancer. The video and text from a user must be sent to the same instance. Since I'm using a loadbalancer, is there any way to make sure that the both requests are sent to the same instance? Loadbalancer distributes traffic on multiple instances so I don't want the video to be routed to one instance and the text file to another instance. Can sticky session be used to solve this issue?
Sticky Sessions seems to be an answer for this.
Related
I am trying to use a kubernetes cluster to do on-demand live transcoding of a video stream from multiple ip cameras, and send via websocket to a website.
I've modified a project I found online written in go, which takes a web request with a payload of the rtsp feed URL, it then uses the url to start a FFMPEG process to access the stream and transcode it to MPEG and sends the mpeg data to another endpoint on the go app, which starts a websocket connection. The response to the orignal request includes a websocket url when the stream can be accessed. Which the url can be put into a mpeg js player and viewed in a browser over the websocket. Main advantage is multiple clients can view the stream while there is only one stream coming from camera which reduces mobile data. I will also add that the FFMPEG automatically stops after 60 seconds with a request isn't set to endpoint.
The problem I can't find a solution to, is how can I scale the above application in a kubernetes cluster, so when I request comes in it does the below.
-> Checks to see if someone is already viewing stream
----> If someone is viewing, means a pod and websocket connection is already created. So a url that points to the pod just needs to be sent back to client.
----> If no one is viewing, a streaming/websocket pod needs to be created and once created a url sent back to the client to access stream.
I've looked at ingress controllers possibly dynamically updating the ingress resource is a solution, or even possible using a service mesh, but these are all new to me.
If anyone has any input to give me a bit of direction down a path, it would be much appreciated.
Many Thanks
Luke
Having your application dynamically configure K8s sounds like a complicated solutions with possible performance implications due to a very large object of ingress objects. You might have to look into how to clean those up. Also, doing this requires a K8s client in your app.
I would suggest to solve this without the help of K8s resources by simply having your application return a HTTP redirect (301) to that websocket URL if need be.
I have an online whiteboard where users connect to the same room depending on the last part of the url where the room name is present. The urls are dynamic and is created per new room.
Eg: https://.../room/123456
I use web sockets to communicate between client and server. The users are subscribed to the same channel based on the room name. I'm going to implement a load balancer server to handle the traffic. Since we create a session on the server for that particular room it is essential that every user in the room is directed to that particular server. How can I achieve this?
I think creating a proxy with the uri balancing method may be what you're looking for. By default, it will distribute traffic based on the hash of your URL path.
backend bk_whiteboard
balance uri
For the application server set as clustering in glass fish. I have sent request through jmeter and all the requests hits to only one server . Expected was requests should be distributed to multiple servers in the cluster. But if sent requests manually clustering is working. Please help to sort out this issue
There could be different clustering load balancing mechanisms, as far as I can see from the GlassFish Server High Availability Administration Guide:
Cookie Method
The Loadbalancer Plug-In uses a separate cookie to record the route information. The HTTP client (typically, the web browser) must support cookies to use the cookie based method. If the HTTP client is unable to accept cookies, the plug-in uses the following method.
Explicit URL Rewriting
The sticky information is appended to the URL. This method works even if the HTTP client does not support cookies. To implement explicit URL rewriting, the application developer must use HttpResponse.encodeURL() and encodeRedirectURL() calls to ensure that any URLs in the application have the session information appended to them.
So depending on your Load Balancer configuration you need to
Either define either different cookies in the HTTP Cookie Manager
Or make sure different threads send requests to different URLs i.e. via HTTP URL Re-writing Modifier
In any case it is recommended to add DNS Cache Manager so each virtual user would resolve the underlying IP address of the application under test on its own.
I have a question about how to load balance web sockets with AWS elastic load balancer.
I have 2 EC2 instances behind AWS elastic load balancer.
When any user login, the user session will be established with one of the server, say EC2 instance1. Now, all the requests from the same user will be routed to EC2 instance1.
Now, I have a different stateless request coming from a different system. This request will have userId in it. This request might end up going to a EC2 instance2. We are supposed to send a notification to the user based on the userId in the request.
Now,
1) Assume, the user session is with the EC2 instance1, but the notification is originating from the EC2 instance2.
I am not sure how to notify the user browser in this case.
2) Is there any limitation on the websocket connection like 64K and how to overcome with multiple servers, since user is coming thru Load balancer.
Thanks
You will need something else to notify the browser's websocket's server end about the event coming from the other system. There are a couple of publish-subscribe based solution which might help, but without knowing more details it is a bit hard to figure out which solution fits the best. Redis is generally a good answer, and Elasticache supports it.
I found this regarding to AWS ELB's limits:
http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_elastic_load_balancer
But none of them seems to be related to your question.
Websocket requests start with HTTP communication before handing over to websockets. In theory if you could include a cookie in that initial HTTP request then the sticky session features of ELB would allow you to direct websockets to specific EC2 instances. However, your websocket client may not support this.
A preferred solution would be to make your EC2 instances stateless. Store the websocket session data in AWS Elasticache (Either Redis or Memcached) and then incoming connections will be able to access the session regardless of which EC2 instance is used.
The advantage of this solution is that you remove the dependency on individual EC2 instances and your application will scale and handle failures better.
If the ELB has too many incoming connections, then it should scale automatically. Although I can't find a reference for that. ELB's are relatively slow to scale - minutes rather than seconds, if you are expecting surges in traffic then AWS can "pre-warm" more ELB resource for you. This is done via support requests.
Also, factor in the ELB connection time out. By default this is 60 seconds, it can be increased via the AWS console or API. Your application needs to send at least 1 byte of traffic before the timeout or the ELB will drop the connection.
Recently had to hook up crossbar.io websockets with ALB. Basically there are two things to consider. 1) You need to set stickiness to 1 day on the target group attributes. 2) You either need something on the same port that returns static webpage if connection is not upgraded, or a separate port serving a static webpage with a custom health check specifying that port on the target group. Go for a ALB over ELB, ALB's have support for ws:// and wss://, they only lack the health check over websockets.
I am working on a small project to help me understand websockets better. I am making a simple browser game that connects to an ip via a websocket. There will be 3 ip addresses however I want to assign the user an ip and not have them able to modify it so they are unable to get on the same server as friends.
I will assign the ip based on how full the games are etc and this will be down via php. Currently although it connects to this ip, the user is able to use the console in a browser to modify the ip to one of the other ones.
I was thinking of sending a check number, so the web server sends this to the user along with the ip. It also sends it to the websocket server. Then when a user connects if the check number doesn't match it rejects the connection.
I'm new to websockets so I'm not sure if this would be easy to implement, so are there any easy solutions to this?
That seems to be the duty of other element, in particular the load balancer. How are you balancing the requests across those 3 servers? Does your load balancer support sticky sessions?
If not, probably you can record to which IP address the user connected first, and they if it connects to one of the other two later, you can return a HTTP 302 (Redirect) pointing to the server you want.
Cheers.