When I make an RPC (service remoting) call to a service that is deployed on multiple nodes from another service in the same application, it appears to be going to all nodes at once. I only want it to go to one each time the call is made.
Does Service Fabric have a way to do that? How can I leverage the built-in load balancing to control where the call goes to?
This deployed on a local cluster
If your service is stateless and uses Singleton partitioning, calling an operation using the ServiceProxy will invoke the operation on one random service instance. Using SF remoting, you can't target a specific instance.
If your service is stateful, calling an operation using the ServiceProxy (created with a specific ServicePartitionKey) will invoke the operation on one of the replicas of your service, using the primary replica by default.
Related
In my current application server which currently runs not in a Kubernetes environment, we use IPS in order to communicate with a specific instance of the same application agent.
the application is stateful and therefore we have to communicate each time with the same instance, with IP as an identifier.
Now we want to deploy this agent application to Kubernetes, however, because it's a stateful application I am a bit confused. How can I communicate each time I start a session with the same instance application? Can I have an IP or some another identifier of the pod? how will it work with the Ingress resource?
I looked at the Statefulset object but also did not understand how can it help me.
I also looked at "sticky session", but I don't want to define an amount of time in order to define one session. I want to be able to access the same pod, and if the pod dies I want to get an exception.
How can I do it in Kubernetes? is it possible?
In my SF application a stateful Worker service communicates with a stateless Logging service using service remoting. The stateful Worker service creates the Logging proxy in its constructor using ServiceProxy.Create<ILoggingService>(loggingServiceUri) and keeps the returned reference for its entire lifetime. There are several stateless Logging service instances running on the cluster (i. e. Instance Count == -1). My question is:
Are calls to the ILoggingService proxy form the Worker service routed to different Logging service instances?
Yes, when you are using SF remoting to talk to a stateless service, your message will be delivered to a random instance. The proxy will keep track of healthy instances for you, and deal with transient errors.
If I have an ECS service, which can scale out, or always runs more than one task, is load balancing handled by the built-in service discovery?
I mean, if my service A is running 3 tasks, and another service B is making requests using the domain name, generated for A by service discovery, how will it decide where a request goes?
From this Medium article, it appears that route 53 is going to use its own catalog of healthy instances to determine which service to route to. So yes, load balancing will occur in that way.
I understand what the Loadbalancer service type does. i.e it creates spins up a LB instance in your cloud instance, NodePorts are created and traffic is sent to the VIP onto the NodePorts.
However, how does this actually work in terms of kubectl and the LB spin up. Is this a construct within the CNI? What part of K8 sends the request and instructs the cloud provider to create the LB?
Thanks,
In this case the CloudControllerManager is responsible for the creation. The CloudControllerManager contains a ServiceController that listens to Service Create/Update/Delete events and triggers the creation of a LoadBalancer based on the configuration of the Service.
In general in Kubernetes you have the concept of declaratively creating a Resource (such as a Service), of which the state is stored in State Storage (etcd in Kubernetes). The controllers are responsible for making sure that that state is realised. In this case the state is realised by creating a Load Balancer in a cloud provider and pointing it to the Kubernetes Cluster.
I have a scenario where one of our services exposes WCF hosts that receive callbacks from an external service.
These hosts are dynamically created and there may be hundreds of them. I need to ensure that they are all up and running on the node before the node starts receiving requests so they don't receive failures, this is critical.
Is there a way to ensure that the service doesn't receive requests until I say it's ready? In cloud services I could do this by containing all this code within the OnStart method.
My initial thought is that I might be able to bootstrap this before I open the communication listener - in the hope that the fabric manager only sends requests once this has been done, but I can't find any information on how this lifetime is handled.
There's no "fabric manager" that controls network traffic between your services within the cluster. If your service is up, clients or other services inside the cluster can choose to try to connect to it if they know its address. With that in mind, there are two things you have control over here:
The first is whether or not your service's endpoint is discoverable by other services or clients. This is the point at which your service endpoint is registered with Service Fabric's Naming Service, which occurs when your ICommunicationListener.OpenAsync method returns. At that point, the service endpoint is registered and others can discover it and attempt to connect to it. Of course you don't have to use the Naming Service or the ICommunicationListener pattern if you don't want to; your service can open up an endpoint whenever it feels like it, but if you don't register it with the Naming Service, you'll have to come up with your own service discovery mechanism.
The second is whether or not the node on which your service is running is receiving traffic from the Azure Load Balancer (or any load balancer if you're not hosting in Azure). This has less to do with Service Fabric and more to do with the load balancer itself. In Azure, you can use a load balancer probe to determine whether or not traffic should be sent to nodes.
EDIT:
I added some info about the Azure Load Balancer to our documentation, hope this helps: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-connect-and-communicate-with-services/