6

I am creating a Facebook multiplayer game and am currently evaluating my tech stack.

My game would need to use websockets and I would like to use Spring Boot. Now, I can not find the info if websocket server will work nicely in Kubernetes? For example if I deploy 5 instances of the server in Kubernetes pods will load balancing/forwarding work correctly for websockets between game clients loaded in browsers and servers in Kubernetes and is there any additional work to enable it? Each pod/server would be stateless and current game info for each player will be stored/read from redis or some other memory db.

If this would not work, how can I work around it and still use Kubernetes? Maybe add one instance of rabbitmq to the stack just for the websockets?

Saša Šijak
  • 8,717
  • 5
  • 47
  • 82
  • 2
    The "problem" with websockets is that they do not load balance well because the connection is persistent. If you have 3 severs and during connection time you round robin which server the users connects to you will initially have an equal load across the servers. As users disconnect you will start having unequal load. Depending on your system design this may not be a problem. The idea of backing your sockets with a queue server is good, but also look at using redis for that. – Leon Jun 23 '16 at 06:00
  • K8S is just an instrument of orchestration. Its network runs over the transport layer (TCP/UDP) or over HTTP if Ingress is used. So there will be no problem with Kubernetes. However, as @Leon said in the comments, you need to think carefully about the balancing and distribution of the websocket connections. – Yanislav Kornev May 22 '18 at 06:51

1 Answers1

0

An adequate way to handle this would be to use "sticky sessions". This is where the user is pinned down to a specific pod based on the setting of a cookie.

Here is an example of configuring the Ingress resource object to use sticky sessions:

#
# https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/affinity/cookie
#
apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  name: nginx-test-sticky
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/affinity: "cookie"
    ingress.kubernetes.io/session-cookie-name: "route"
    ingress.kubernetes.io/session-cookie-hash: "sha1"
spec:
  rules:
  - host: $HOST
    http:
      paths:
      - path: /
        backend:
          serviceName: $SERVICE_NAME
          servicePort: $SERVICE_PORT

Now with that being said, the proper way to handle this would be to use a message broker or a websocket implementation that supports clustering such as socketcluster (https://socketcluster.io).

yomateo
  • 2,078
  • 12
  • 17