How cluster event bus in Vertx works? - vert.x

I am new to Vertx. I am confused about event bus in clustering environment.
As documentation of vertx
The event bus doesn’t just exist in a single Vert.x instance. By
clustering different Vert.x instances together on your network they
can form a single, distributed event bus.
How exactly event bus of different Vert.x instances are joined together in cluster to form a single distributed event bus and the role of ClusterManager in this case? How the communication between nodes work in distributed event bus? Please explain me this in detail of technical. Thanks

There is more info about clustering in the cluster managers section of the docs.
The key points are:
Vert.x has a clustering SPI; implementations are named "cluster managers"
Cluster managers, provide Vert.x with discovery and membership management of the clustered nodes
Vert.x does not use the cluster manager for message transport, it uses its own set of TCP connections
If you want to try this out, take a look at Infinispan Cluster Manager examples.
For more technical details, I guess the best option is to go to the source code.

Related

Representing consume/produce event as UML components from microservice to Message queue[Kafka] in sequence/class diagram

I have a usecase of producing some event, consuming event produced by other microservice & also produced by own.
How to represent the Kafka system, microservice in play & producing/consuming event in the sequence diagram/class diagram.
In the UML we have a special digram from DB, do we have any thing for Kafka & cron job?
The core of a microservice architecture using Kafka is asynchronous communication of event messages. The UML equivalent are UML signals. In a sequence diagram, you could show the exchange of messages/signals between participating lifelines. The name of the message would be the name of the signal (probably the Kafka topic) optinally followed by the attributes of the signal between parenthesis.
You would probably want to show the big picture, showing producers and consumers (classes or even microservice components) dialoguing, as if it would be directly between them, without showing the plumbing (Kafka, or other event-queues). But if you prefer to show the full picture, you could insert a lifeline for Kafka and let consumers and producers exchange messages with Kafka. But that would make the diagram much more complex, exspecially if you have more than one producer and one consumer.
In a class diagram, you'd probably focus on your own classes and the description of the signals:
Signals are like classes and allow to describe the content of Kafka event/messages (attributes of the signal).
You can show consumer classes by showing that they have receptions (i.e. they can receive some signals). There's nothing foreseen for production os signals, but you could show with a dependency arrow for the relevant operations of your class what signals they could send.
It's not fully clear what other diagrams you are looking for:
In a component diagram, Kafka would be a component, with a Subscriber, and a Publisher interface provided. Maybe a couple more interfaces depending on your needs. Your microservices would be other components.
In a deployment diagram, you'd show the real distribution of all your Kafka nodes, with some annotations about what each is doing (e.g. Topics and Kafka partitions).
Activity diagrams can show complex workflows (including sending and accepting events). You could also use them to document a flow of events across several microservices (each represented with a partition in the UML diagram) if deemed useful.
P.S: There is no DB diagram in UML: you'd use a class diagram and show only the classes relevant for the DB. For cron jobs you need to be more specific: it is possible to show timing events/constraints in several behavioral diagrams (see this question for example). But you'd not show cron itself.
I would make a more radical proposal, yes Activity Diagrams are useful to present parallel workflows but in my opinion the ultimate tool to represent parallelity / multi-threaded flows are State Machines and State Machine Diagrams.
In this diagram in my blog, you can see how I have represent a parallel Workflow. In which Credit State Machine, Credit Score State Machine, Fraud Prevention State Machine and Adress Check State Machine working in parallel to fulfil a Business Case with the help of Apache Kafka.

Stateful or Stateless service for processing servicebus queues

I have a Session enabled Azure servicebus queue. I need some form of service that can read from the queue and process them and save the result (in memory for later retrieval). We are using azure servicefabric in our current architecture. I got few questions regarding which one to choose Stateful or Stateless service.
If I use Stateful service, then based on the documentation my understanding is, service will be running on 1 primary node (assuming 1 partition) and 2 active secondary nodes. That means, if I have a 10 node Service fabric cluster, then this stateful service will be utilizing only one node (VM) primarily.
So if I add a listener to this stateful service to read messages from Queues then that service on primary node will read messages from queues and all other remaining 9 nodes wont be able to utilized. Is this correct?
Whereas if I use Stateless service, I can create instances on all 10 nodes and all of them could listen to the message in Queues and process them in parallel. However, I will loose the option to save the results.
Please advise.
So if I add a listener to this stateful service to read messages from Queues then that service on primary node will read messages from queues and all other remaining 9 nodes wont be able to utilized. Is this correct?
That is correct. With stateful service scenario, only the primary replica will have it's listener executed, and work will be done. Other replicas can be used in read-only mode, but they would not be writing anything into reliable collections.
Whereas if I use Stateless service, I can create instances on all 10 nodes and all of them could listen to the message in Queues and process them in parallel.
Exactly. Stateless services can perform their work in parallel and no state is persisted. That's also the reason whey there's no reliable collection available for this Service Fabric model.
However, I will loose the option to save the results.
Not necessarily true. You could still save your data in a centralized/shared DB, just like you'd do with stateless solutions in the past (for example Cloud Services, or a Azure WebApp).
What you should ask yourself is what problem are you solving. If you have data sharding, the Statful makes more sense. If you don't have data sharding and/or you need to scale out your processing power, rather that scale up, Stateless is a better approach.

How to run something on each node in service fabric

In a service fabric application, using Actors or Services - what would the design be if you wanted to make sure that your block of code would be run on each node.
My first idea would be that it had to be a Service with instance count set to -1, but also in cases that you had set to to 3 instances. How would you make a design where the service ensured that it ran some operation on each instance.
My own idea would be having a Actor with state controlling the operations that need to run, and it would itterate over services using serviceProxy to call methods on each instance - but thats just a naive idea for which I dont know if its possible or if it is the proper way to do so?
Some background info
Only Stateless services can be given a -1 for instance count. You can't use a ServiceProxy to target a specific instance.
Stateful services are deployed using 1 or more partitions (data shards). Partition count is configured in advance, as part of the service deployment and can't be changed automatically. For instance if your cluster is scaled out, partitions aren't added automatically.
Autonomous workers
Maybe you can invert the control flow by running Stateless services (on all nodes) and have them query a 'repository' for work items. The repository could be a Stateful service, that stores work items in a Queue.
This way, adding more instances (scaling out the cluster) increases throughput without code modification. The stateless service instances become autonomous workers.
(opposed to an intelligent orchestrator Actor)

Changing number of partitions for a reliable actor service

When I create a new Service Fabric actor the underlying (auto generated) actor service is configured to use 10 partitions.
I'm wondering how much I need to care about this value?
In particular, I wonder whether the Actor Runtime has support for changing the number of partitions of an actor service on a running cluster.
The Partition Service Fabric reliable services topic says:
In rare cases, you may end up needing more partitions than you have initially chosen. As you cannot change the partition count after the fact, you would need to apply some advanced partition approaches, such as creating a new service instance of the same service type. You would also need to implement some client-side logic that routes the requests to the correct service instance, based on client-side knowledge that your client code must maintain.
However, due to the nature of Actors and that they are managed by the Actor Runtime I'm tempted to believe that it would indeed be possible to do this. -- That the Actor Runtime would be able to take care of all the heavylifting required to re-partition actor instances.
Is that at all possible?
The number of partitions in a running service cannot be changed. This is true of Actors as well as Reliable Services. Typically, you would want to pick a large number of partitions (more than the number of nodes) up front and then scale out the number of nodes in the cluster instead of trying to repartition your data on the fly. Take a look at Abhishek and Matthew's comments in the discussion here for some ideas on how to estimate how many partitions you might need.

HornetQ clustering topologies

I understand that in HornetQ you can do live-backup pairs type of clustering. I also noticed from the documentation that you can do load balancing between two or more nodes in a cluster. Are those the only two possible topologies? How would you implement a clustered queue pattern?
Thanks!
Let me answer this using two terminologies: One the core queues from hornetq:
When you create a cluster connection, you are setting an address used to load balance hornetq addresses and core-queues (including its direct translation into jms queues and jms topics), for the addresses that are part of the cluster connection basic address (usually the address is jms)
When you load balance a core-queue, it will be load balanced among different nodes. That is each node will get one message at the time.
When you have more than one queue on the same address, all the queues on the cluster will receive the messages. In case one of these queues are in more than one node.. than the previous rule on each message being load balanced will also apply.
In JMS terms:
Topic subscriptions will receive all the messages sent to the topic. Case a topic subscription name / id is present in more than one node (say same clientID and subscriptionName on different nodes), they will be load balanced.
Queues will be load balanced through all the existent queues.
Notice that there is a setting on forward when no consumers. meaning that you may not get a message if you don't have a consumer. You can use that to configure that as well.
How would you implement a clustered queue pattern?
Tips for EAP 6.1/HornetQ 2.3 To implement a distributed queue/topic:
Read the official doc for your version: e.g. for 2.3 https://docs.jboss.org/hornetq/2.3.0.Final/docs/user-manual/html/clusters.html
Note that the old setting clusterd=true is deprecated, defining the cluster connection is enough, check that internal core bridges are created automatically / clustered=true is deprecated in 2.3+
take the full-ha configuration as a baseline or make sure you have jgroups properly set. This post goes deeply into the subject: https://developer.jboss.org/thread/253574
Without it, no errors are shown, the core bridge connection is
established... but messages are not being distributed, again no errors
or warnings at all...
make sure security domain and security realms, users, passwords, roles are properly set.
E.g. I confused the domain id ('other') with the realm id
('ApplicationRealm') and got auth errors, but the errors were
generic, so I wasted time checking users, passwords, roles... until I
eventually found out.
debug by enabling debug (logger.org.hornetq.level=DEBUG)