Load balancing multiple http sources for a stream - spring-xd

I am getting started to play with Spring-XD. In my current architecture, i am planning on to have log events aggregation stream deployed to Spring-XD.
http|elastic or http|kafka or http|hadoop.
I am planning to have multiple http modules deployed one per xd-container to be able to handle the load of several log events coming from different applications. Per online forums, it was suggested that i use external load balancer to distribute the http load to several containers where http sources are deployed. This is doable, but not a good approach, if you plan on to have several streams with http sources (using different ports for each stream). You now have configuration information spread out to external LoadBalancer instead of xd-admin. Theoretically xd-admin has the information and it is best placed for distributing the load, if we can push the data to a xd-admin instead of directly to xd-containers.
Typical http post will look like
http://xd-admin-host-IPAddress:Port/StreamName
Then xd-admin with its knowledge can do the load balancing to several xd-containers where http sources are deployed.
Did anyone run into this scenario? Can this be a feature/enhancement request to spring-xd team?

Related

Is there any possible way to load test WOWZA Cloud Live streaming video?

I am using JMeter to test load /performance of live streaming severs including WOWZA live streaming engine. But I am unable to test Live streaming of WOWZA cloud, since I am getting a lot of Time out errors. I am very well aware that the timeout is not because of the delay in response because the live streaming is running smoothly when opened from an external network. I found out that, after some period of load request being send to Wowza cloud, the domain name itself is getting changed(its dynamic). I have created the config in jmeter in such a way that all the URL path, Playlist.m3u8, chunklist.m3u8, and corresponding stream(ts) files are dynamic. But, since the domain name itself is getting changed after a period of load test, the request sending are partially getting failed(maybe because the domain name which I am sending request is not responsible to handle all the requests anymore). Can anybody suggest what to do? And is there any way to test load in WOWZA cloud?
You can use this JMeter plugin.
It is a plugin that will do URL extraction automatically from manifest without you needing to use JMeter extractors, as a consequence even when segment’s URLs will change due to Wowza Cloud scaling, this will be taken into account.
Besides, it will accurately similate how player request the server and give metrics on User Experience.
Still as written by the other answer ensure you:
ask for authorization to avoid your test being marked as DDOS
ensure you disable Java DNS caching for JMeter's JVM
Disclaimer: I work for the company that develops it.
As you are testing a multi-tenant cloud environment the first thing you must do is get permission from Wowza. Almost all Cloud applications have restrictions on the use of automation outside of their published interfaces. Your point of contact inside of Wowza will work with you for your testing window, scale, approve your performance test plan, your pacing and think times to ensure that they are reasonable and will not impact their service to other tenants on the system.
They can also provide technical insight on how to construct your tests given some unique features/capabilities/engineering for the site. They may even be able to provide you with sample code.
As a general rule of thumb, you don't point and fire tactical nuclear software at sites you don't own, manage, control or have direct written permission from those that do have those rights.

What are the technologies for building real-time servers?

I am a backend developer and I would like to know what are the common technologies for building real-time servers. I know I could use a service like Firebase, but I really want to create it. I have some experience using Websockets on Java, but I would like to know more ways to achieve a real-time server. When I say real-time, I mean something like Facebook. I also would like to know how to scale real-time servers.
Thank you all!
I've asked the same in multiple forums. Common answer to this question is strangely enough still:
WebSocket
Socket.io
Server-Sent Events (SSE)
But those are mainly ways of transporting or streaming events to the clients. Something needs to be built on top of it. And there are multiple other things to consider, such as:
Considerations for real-time API's
What events to send to the client
How to send each client only the events they need
How to handle authorization for events
Where to keep state on the event subscriptions (for stateless services)
How to recover from missed events due to lost connections and service crashes
Producing events for search-, or pagination queries
How to scale
Publish/Subscribe solutions
There are multiple pub/sub solutions out there, such as:
Pusher
PubNub
SocketCluster
etc.
But because of the limitation of a topic based pub/sub architecture, some of the above questions are still left unanswered and has to be dealt with by yourself. Examples are lost connections, where Pusher has no fallback, neither does SocketCluster, and PubNub has a limited queue.
Resgate - Realtime API Gateway
An alternative to the traditional topic based pub/sub pattern is using a resource-aware realtime API Gateway, such as Resgate.
Instead of the client subscribing to topics, the gateway keeps track on which resources (objects or arrays) that the client has fetched, keeping the client data up to date until it unsubscribes.
As a developer of Resgate, I can really recommend checking it out as it solves all above question, is language agnostic, simple and light-weight, and blazingly fast.
Read more at NATS blog.
Scaling
Let's say you want to scale both in the number of concurrent clients and the number of events that is produced. You will eventually need to ensure each client only gets the data they are interested in through either traditional topic based publish/subscribe, or through resource subscriptions. All above solutions handles that.
I also assume all the above mentioned solutions scales concurrent clients by allowing you to add more nodes/servers that handles the persistent WebSocket connections.
With Resgate, first level of scaling is done by simply running multiple instances (it is a simple executable), and adding a load balancer that distributes the connection evenly between them:
Handling 100M concurrent clients
Let's say a single Resgate instance handles 10000 persistent WebSocket connections, and you can add 10000 Resgates (distributed to multiple data centers) to a single NATS Server. This would allow a total of 100M connections. Of course, depending on your data, you might have other scaling issues as well, such as network traffic ;) .
A second layer of scaling (and adding redundancy) would be to replicate the whole setup to different data centers, and have the services synchronize their data between the data centers using other tools like Kafka, CockroachDB, etc.
Scaling data retrieval
With the traditional publish/subscribe solution that only deals with events, you will also have to handle scaling for the HTTP (REST) requests.
With Resgate, this is not required, as resource data is also fetched over the WebSocket connection. This allows Resgate not only to ensure that resource data and events are synchronized (another issue with separate pub/sub solutions), but also that the data can be cached. If multiple clients requests the same data, Resgate will only need to fetch it from the service once, effectively improving scalability.
Butterfly Server .NET is a real-time server written in C# allowing you to create real-time apps. You can see the source at https://github.com/firesharkstudios/butterfly-server-dotnet.

Streaming log messages of a Spring boot web application

This question is for asking general advice on what tools should I use for this task, and possibly pointing me to some related tutorials.
I have a Spring Boot web application, which during operation generates log messages into a database. There is a JavaScript management tool in the making for this REST application, and 1 function of it would be to show the log messages real-time. Meaning, when the user is on the log showing page, he should see the new log messages appearing without refresing the page.
My questions:
What should be used to provide this for the javascript client at some endpoint? I'm looking at these spring boot starters right now: websocket, redis, amqp. I have not used any of these before.
How should I "catch" the log messages as they are generated inside the application? So I could send them to the client with the chosen solution.
I'm not really looking for a periodic query type of solution, but rather a server pushing the data as it appears solution.
Any suggestions and code samples are appreciated.
Storing logs in a database is usually not a good option unless you use a database which is capable of handling a lot of write requests, such as Apache Cassandra. Streaming data from a database is not the most intuitive thing to do, however.
A modern alternative is to use a messaging system such as Apache Kafka to stream logs from producing systems to multiple subscribing systems. There are multiple ways how you can achieve that. For example, for streaming logs from your Spring Boot app you could use a special log4j appender (see here and an example here). To be able to present logs in a web browser in real-time, you will need another backend system which will receive the log records from Kafka topics and forward them to JavaScript web clients via websockets, most likely using a publisher/subscriber model.
Also, you could consider using server sent events (SSE) instead of websockets. Because you have only a unidirected message flow (logs are streamed from a backend system to a javascript client in the browser, but not the other way around), SSE can be a good option as a replacement for websockets. Websockets are more difficult to operate than SSE and usually use more resources at the backend. As always, you will need to choose between trade-offs (see here).

Serving static files in a microservices environment?

What is the preferred way of serving static files for an application that is deployed in a microservices architecture (in production)?
Let's say for simplicity that I have 3 application servers and one load-balancer that forwards requests to these servers.
Should the load-balancer store the files and serve them imminently upon request? OR..
Should the load-balancer forward static files requests to the different application instances (each request to a different instance)?
Is there a best practice for this?
As stated in other comments/answers, there are a lot of ways to handle this. This largely depends on what you actually need (version control, access control, http headers, CDN).
Specifically to your question, if it was me, I wouldn't deploy these files on the load balancers, because a newer version of the static files would require a downtime on the load balancers. Instead, I would build very simple Nginx/Caddy containers that their sole purpose is to serve these files, and have the LB route the traffic to those containers.
Best practice would be to store it in a service meant for static content like blob storage (in the cloud this would be Azure Storage, S3, etc.). If necessary, leverage a CDN to improvement latency and throughput to end users.
But as someone else commented, there are many ways to handle this depending on your particular requirements.

What technology to use to avoid too many VMs

I have a small web and mobile application partly running on a webserver written in PHP (Symfony). I have a few clients using the application, and slowly expanding to more clients.
My back-end architecture looks like this at the moment:
Database is Cloud SQL running on GCP (every client has it's own
database instance)
Files are stored on Cloud Storage (GCP) or S3 (AWS), depending on the client. (every client has it's own bucket)
PHP application is running in a Compute Engine VM (GCP), (every client has it's own VM)
Now the thing is, in the PHP code, the only thing client specific is a settings file with the database credentials and the Storage/S3 keys in it. All the other code is exactly the same for every client. And mostly the different VMs sit idle all day, waiting on a few hours usage per client.
I'm trying to find a way to avoid having to create and maintain a VM for every customer. How could I rearchitect my back-end so I can keep separate Databases and Storage Buckets per client, but only scale up my VM's when capacity is needed?
I'm hearing alot about Docker, was thinking about keeping db credentials and keys in a Redis DB or Cloud Datastore, was looking at Heroku, AppEngine, Elastic Beanstalk, ...
This is my ideal scenario as I see it now
An incoming request is done, hits a load balancer
From the request, determine which client the request is for
Find the correct settings file, or credentials from a DB
Inject the settings file in an unused "container"
Handle the request
Make the container idle again
And somewhere in there, determine based on the the amount of incoming requests or traffic, if I need to spin up or spin down containers to handle the extra or reduced (temporary) load.
All this information overload has me stuck, I have no idea what direction to choose, and I fail seeing how implementing any of the above technologies will actually fix my problem.
There are several ways do it with minimum efforts:
Rewrite loading of config file depending from customer
Make several back-end web sites on one VM (best choice i think)

Resources