RabbitMQ : Sending mail by schedule in Spring Boot? - java

In my Spring Boot app, I implement an endpoint to send email to a single user. At this stage, I need the following implementations:
Sending mail to multiple users (less than 100 users)
Schedule sending time
My questions:
1. Although I have no previous experience for RabbitMQ, I want to start to use it and I think I can use it for sending email to multiple user. Is this scenario suitable for using RabbitMQ?
2. At this stage, I think of using a proper scheduler for Spring Boot. Does RabbitMQ supports scheduling to periadically send mail to multiple user? If not, which library should I use for scheduling that is suitable for Spring Boot and RabbitMQ ?

No, RabbitMQ should not be used as a task scheduler. RabbitMQ is a message broker (for example, sending a message from one microservice to another).
For tasks scheduling, you can use the ScheduledThreadPoolExecutor/Timer,/Quartz(see: github repo)/Spring Scheduler...
Example: you can create a microservice that, using RabbitMQ, will receive asynchronous tasks to send/schedule emails, using, for example, Quartz + JDBC + Spring-mail.
I also advise you to look at the examples below:
example with Quartz + MySQL + SpringBoot
another example

Related

Is it possible to create a JmsListener for a specific Session in Spring Boot JMS with Azure Service Bus

I have a Service Bus Queue which is Session-enabled. For example, let's say that messages are divided into Session-1 and Session-2 in the queue.
I am trying to create two JmsListeners for the queue, one processing messages with Session-1 and another for Session-2.
In the Azure documentation for using Spring Boot with a Service Bus Queue I see that there is an example of how to set the Session ID while sending a message via JMSXGroupID, however there is no example on how to receive messages for a particular session.
My only idea at the moment is to use a MessageSelector to filter.
It looks like it is not possible as of now, see this Github issue.

Ways to implement Google Pub Sub

I found these 3 ways for implementing messaging with Google Pub Sub:
with client libraries
https://cloud.google.com/pubsub/docs/publisher
with spring integration message channels and PubSubTemplate API
https://dzone.com/articles/spring-boot-and-gcp-cloud-pubsub
without message channels but with PubSubTemplate API
https://medium.com/bb-tutorials-and-thoughts/gcp-how-to-subscribe-and-send-pubsub-messages-in-spring-boot-app-b27e2e8863e3
I want to understand the differences between them / when each is best to use and which would be useful for my case.
I have to implement a single Topic and a single Subscription to get the queue functionality. I think I'd rather not use Spring message channels if not needed , they seem to intermediate the communication between Pub Sub topic and the subscription and I don't want that. I want things simple , so I think the option 3 would be best but I am also wondering about option 1.
Option 1, client libraries, is universal. You don't need Spring to run it, you can use this library in Groovy or in Kotlin also.
Option 2, it's deeply integrated to Spring. It's quite invisible but if you have special thing to do, it's tricky to override this implementation
Option 3, it's a light spring integration. PubSubTemplate (the client in fact) is loaded automatically for you at startup, as any bean and you can use it easily in your code. It's my preferred option when I use Spring.
Google Cloud Pub/Sub Using Client Libraries :
Using Google Cloud Pub/Sub with Client libraries is one of the standard and easiest way to implement Cloud Pub/Sub.
A producer of the data publishes messages to Pub/Sub topic, a subscriber client then creates a subscription to that topic and consumes messages.
You need to install the client libraries. You can follow this setup and tutorial for further information.
Here you won't require Spring integration, you can directly use the client library to publish messages and pull it from subscription.
Spring Integration using spring channels :
This use case involves intensive integration of Spring Boot Application with Google Cloud Pub/Sub using Spring Integration to send and receive Pub/Sub messages. ie. Pub/Sub acts as intermediate messaging system
Here The Spring Application sends messages to Cloud Pub/Sub topic utilizing spring channels and the Application further receives messages from Pub/Sub through these channels.
Pub/Sub message in Spring-Boot App :
This use case is a simple and valid example of integrating Cloud Pub/Sub with Spring boot application.
The use case demonstrates how to subscribe to a subscription and send message to topics using Spring Boot Application
Message is published to the topic, queued in the respective subscription and then received by the subscriber Spring Boot Application

Publishing Spring Batch metrics using Micrometer

I have an app that contains 2 dozen of spring batch cron jobs.There is no rest controller as it is an analytics app and it runs daily and read data from db, process it, and then store aggregated data in another db.I want to have spring inbuilt metrics on the jobs using micrometer and push them to Prometheus .As my app is not a webserver app, so still micrometer will be publishing results on HOST:8080? Will actuator automatically start a new server on HOST:8080?or do we need to have application server running on 8080?
My understanding is that actuator and application server can run of different ports as these are different processes ?Even if application server is there or not, actuator should be able to either use same port as application server port, or it can use different port?
So if my application is not a webserver based app, still I can access metrics at localhost:8080/actuator/ and publish to Prometheus?
Prometheus is a pull-based system, meaning you give it a URL from your running application and it will go pull metrics from it. If your application is an ephemeral batch application, it does not make sense to make it a webapp for the only sake of exposing a URL for a short period of time. That's exactly why Prometheus folks created the Push gateway, see When to use the Push Gateway.
Now with is in mind, in order for your batch applications to send metrics to Prometheus, you need:
A Prometheus server
A Pushgateway server
An optional metrics dashbaord (Grafana or similar, Prometheus also provides a built-in UI)
Make your batch applications push metrics to the gateway
A complete example with this setup can be found in the Batch metrics with Micrometer. This example is actually similar to your use case. It shows two jobs scheduled to run every few seconds which store metrics in Micrometer's main registry and a background task that pushes metrics regularly from Micrometer's registry to Prometheus's gateway.
Another option is to use the RSocket protocol, which is provided for free if you use Spring Cloud Dataflow.
For Spring Boot, there are no actuator endpoints for Spring Batch, please refer to Actuator endpoint for Spring Batch for more details about the reasons about this decision.
#Mahmoud I think there are valid use cases for exposing the health endpoints optionally. The first question to consider is when we say a batch operation runs for a short time, how short is that time - a few minutes? I agree there's no need; but how about jobs that run for a few hours? it's important for some jobs that we get metrics especially when such jobs are bound by a business SLA and the operator needs to know if the job is processing at the required operations per second, has the right connection pool size etc.
There are also a variety of implementation details of the running platform - we can use Spring Batch without SCDF, not be in control of the Prometheus gateway to be able to use push, run in a cloud where Istio will pull the metrics automatically etc.
For the OPs question, in general one can run a spring batch job in web instance, as far as I have used Spring Batch with a web instance, the application does shut down after job completion.

How to handle Kafka container lifecycle using spring kafka in Kubernetes multipod deployment

I am using Spring kafka implementation and I need to start and stop my kafka consumer through an REST API. For that i am using KafkaListenerEndpointRegistry endpointRegistry
endpointRegistry.getListenerContainer("consumer1").stop();
endpointRegistry.getListenerContainer("consumer1").start();
We are deploying the microservice on kubernetes pod so there might be multiple deployments for the same microservice. how could i manage to start and stop the consumer on all the container.
Kubernetes offers nothing to automatically broadcast an http-request to all pods for a service; so you have to do it yourself.
Broadcasting over Kafka
You can publish the start/stop command from the single instance that receives the http-request to a topic, dedicated for broadcasting commands between all instances.
Of course, you must make sure that each instance can read all message on that topic, so you need to prevent the partitions from being balanced between these instances. You can achieve that by setting a unique group-id (e.g. by suffixing your normal groupId with a UUID) on the Consumer for that topic.
Broadcasting over Http
Kubernetes knows which pods are listening on which endpoints, and you can get that information in your service. Spring Cloud Kubernetes (https://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/2.0.0.M1/reference/html/#ribbon-discovery-in-kubernetes) makes it easy to get at that information; there's probably lots of different ways to do that, with Spring Cloud Kubernetes it would go something like this:
Receive the command on the randomly selected pod, get the ServerList from Ribbon (it contains all the instances and the ip-address/port where they can be reached) for your service, and send a new http-request to each of them.
I would prefer the Kafka-approach for its robustness, the http-approach might be easier to implement, if you're already using Spring Cloud.

Spring AMQP RPC vs Spring AMQP Request/Reply Messaging

I have been learning how to use spring framework and so far so good. I have created an app from Spring Initializr - http://start.spring.io/ and i have been able to setup numerous controllers and even setup security and everything works out.
I am running my app on Apache Tomcat. I now want to use Spring AMQP and the way i want to use it is like this. I shall execute a controller method in the browser and that adds a message in the queue which should be consumed by a consumer,possibly a threadpool powered consumer and return the result to the user.
For instance i want to add a message to the queue and return json to the user.
Since i executed the add message from a controller, i am expecting to show the response to the user.
After going through the rabbit mq docs, i think RPC would help me publish the message to the queue and it shall be consumed and the result returned to teh user. I setup the rabbit mq example using php and i saw it work.
However, upon looking through the spring amqp docs,i came across this three
-Message Listener https://docs.spring.io/spring-amqp/docs/1.3.5.RELEASE/reference/html/amqp.html#containerAttributes
-Listener Concurrency https://docs.spring.io/spring-amqp/docs/1.3.5.RELEASE/reference/html/amqp.html#listener-concurrency
-Request/Reply Messaging https://docs.spring.io/spring-amqp/docs/1.3.5.RELEASE/reference/html/amqp.html#request-reply
-RPC https://www.rabbitmq.com/tutorials/tutorial-six-spring-amqp.html
My question is,if i wanted to let the user get the result, would i pick RPC or Request/Reply Messaging or are they the same thing?
Second, in the last RPC example i did, i started the listener separately like java_listener.java to be able to consume the messages.
Since i started my app with spring intilizr and i am running tomcat, will i need to start the consumer separately from the tomcat process?.
Thanks.

Categories

Resources