Lighttpd FASTCGI varying instances by path - fastcgi

I have a multi-tenanted application where each tenant's data is in a separate database.
I want to implement FASTCGI programs under LIGHTTPD, but I want different instances of the program for each database.
For example, I would like any connection {site}/app/c123/a/b to be routed to instances of the FASTCGI app connected to database C123, and any connection {site}/app/c578/a/b to be routed to instances connected to database C578.
For startup purposes, assume that the FASTCGI app takes a startup parameter (ie, -Dc123 or -Dc578) to select the database which it opens.
The /a/b are placeholders for elements of the path that will be passed through to any of the FASTCGI instances, regardless of the database to which it is connected. For example, {site}/app/c123/Accounts/List might return a list of accounts which are contained in the C123 database.
To support expected concurrency by tenant, I might want two instances of the app connected to database C123, eight instances of the app connected to database C578, and so on for different databases.
So, given these examples, what configuration of LIGHTTPD do I need such that 1..n instances of the FASTCGI app may be started for each database?

You can run separate backend daemons for each user
lighttpd mod_fastcgi
PHP-FPM
Alternatively, you can run a single backend and have it manage connecting to different database, as appropriate.

Related

How to configure ActiveRecord default open connection with database and how to verify it

We would like to get your help with regards to the following- (a) In RoR Active Records, how to specify or control the number of database (DB) connections to be open by default? (b) How to monitor and verify what number of actual connections have been established between Active Records and database? (c) Does it depend on the actual database server- like is it going to be different for Postgres and AWS Aurora?
You can use pool key in your config/database.yml file.
To monitor connections take a look at http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html
It has stat method, that returns some pool usage related data.

How to switch MongoDB database on the fly while using db.collection.insert()?

I have a multi-domain Rails 4 app where the request.domain of the http request determines which functionality I expose a given visitor to.
Each domain in my app should be served by its own MongoDB database. E.g. domain1.com is served by db_for_domain_1, etc.
I can read in the MongoDB docs on runtime persistence that
Mongoid.override_database("db_for_#{request.domain}")
enables me to switch database on the fly.
But how do I keep the persistence when I bypass Mongoid and use the mongo Shell method db.collection.insert()? I will still do it from within my application though.
The answer might be in the MongoDB docs on collection access, but I don't understand it. So how do I switch database before/during this operation?:
MyModel.collection.insert({field_1: "Value 1", field_2: "Value 2"})
If I understand your question correctly: you have an app that connects to different mongodbs on different servers, but want to use mongo shell to connect to the database outside of your application? If true, you would connect to the desired database through the shell with
mongo db_for_domain_1:<port>/<dbName>
and then
db.<collectionName>.insert({doc})
see mongo --help for username and password options.

How do you read data like tables from SQL Developer using Grails?

I have fair amount of knowledge of Grails but I cannot find a way how to read data from a table from sql developers using Grails. How can I do this?
By default when you use run-app, the database is in-memory (the url is something like "jdbc:h2:mem:devDb"), so there's no way to connect to it from outside the JVM. If you change it to a "real" database you can connect to it from both Grails and another client.
To do this with H2, one option is to start a standalone server. This requires that you find the H2 jar - it will be under $HOME/.m2/repository or $HOME/.grails/ivy-cache. For example on my machine the command to start on port 9092 (the default) is
java -cp /home/burt/.m2/repository/com/h2database/h2/1.3.170/h2-1.3.170.jar org.h2.tools.Server -tcp -tcpPort 9092
Then change the url in grails-app/conf/DataSource to
url = 'jdbc:h2:tcp://localhost:9092/dbname'
where "dbname" is arbitrary - H2 supports creating multiple databases per server. You can then start Grails and it will connect to that server, and you can connect from another client too.
A simpler way to do this is to use H2's auto-server mode, e.g. with this url
url = 'jdbc:h2:./dbname;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9092'
it will start up an in-memory database but with a TCP socket on port 9092 that you can connect to externally. This avoids having to find the jar and explicitly start the database server.
See http://h2database.com/html/main.html for more configuration information.
You can also use a different server, e.g. a MySQL/PostgreSQL/Oracle/etc server.
But having said all this, there is a convenient database client already running that you can access. When you start Grails with run-app you can connect to http://localhost:8080/appname/dbconsole in a web browser and access your table information, do SQL queries, etc. This is an H2 feature, but it works with whatever database you use since it works with JDBC, so you can use it with MySQL or whatever. See http://grails.org/doc/latest/guide/conf.html#databaseConsole for more information on this.

Elmah XML Logging on Load Balanced Environment

We're implementing Elmah for an internal application. For development and testing we use a single server instance but on the production environment the app is delivered using a load balanced environment.
Everything works as charm using Elmah, except for the fact that the logs are done independant in each server. What I mean with this is that if an error happens in Server1 the xml file is stored physically on that server and the same for Server2, since I'm storing that files on the App_Data
When I access the axd location to see the error list, I just see the ones of the server that happened to attend my request.
Is there any way to consolidate the xml files other than putting them on a shared folder? Having a shared folder will make us to allow the user that executes the application on the server to have access to that separate folder and to be on only one of the servers instead of both.
I cannot use In-Memory or Database logging since FileLog is the only one allowed.
You might consider using ElmahR for this case, since you are not able to implement In-Memory or Database logging. ElmahR will provide you with a central location for the two load balanced servers to send errors to (in addition to logging them locally) via an Http post. Then you can access the ElmahR site for to view an aggregated list. Also, ElmahR is storing the error messages in a SqlServerCE database, so it can persist the error messages it receives.
Keep in mind that if the ElamhR Dashboard app design does not meet your initial needs/desires, it could be modified as needed given that it is an open source project.
Hope this might be a viable option.

How can I update a DataSnap server while clients are still connected?

We use stateful DataSnap servers for some business logic tasks and also to provide clientdataset data.
If we have to update the server to modify a business rule, we copy the new version into a new empty folder and register it (depending on the Delphi version, just by launching or by running the TRegSvr utility).
We can do this even while the old server instance is running. However, after registering the new version, all new client connections will still use the currently running (old) server instance. All clients have to disconnect first, then the new server will be used for the next clients.
Is there a way to direct all new client connections to the new server, immediately after registering?
(I know that new or changed method signatures will also require a change and restart of the clients but this question is about internal modifications which do not affect the interface)
We are using Socket connections, and all clients share the same server application (only one application window is open). In the early days we have used a different configuration of the remote datamodule which resulted in one app window per client. Maybe this could be a solution? (because every new client will launch the currently registered executable)
Update: does Delphi XE offer some support for 'hot deployment' (of updated servers)? We use Delphi 2009 at the moment but would upgrade to XE if it offers easier implementation of 'hot deployment'.
you could separate your appserver into 2 new servers, one being a simple proxy object redirecting all methods (and optionally containing state info if any) to the second one actually implementing your business logic. you also need to implement "silent reconnect" feature within your proxy server in order not to disturb connected clients if you decide to replace business appserver any time you want. never did such design myself before but hope the idea is clear
Have you tried renaming the current server and placing the new in the same location with the correct name (versus changing the registry location). I have done this for COM libraries before with success. I am not sure if it would apply to remote launch rules through as it may look for an existing instance to attach to instead of a completely fresh server.
It may be a bit hackish but you would have the client call a method on the server indicating that a newer version is available. This would allow it to perform any necessary cleanup so it doesn't end up talking to both the existing server instance and new server instance at the same time.
There is probably not a simple answer to this question, and I suspect that you will have to modify the client. The simplest solution I can think of is to have a flag (a property or an out parameter on some commonly called method) on the server that the client checks periodically that tells the client to disconnect and reconnect (called something like ImBeingRetired).
It's also possible to write callbacks under certain circumstances for datasnap (although I've never done this). This would allow the server to inform the client that it should restart or reconnect.
The last option I can think of (that hasn't already been mentioned) would be to make the client/server stateless, so that every time the client wants something it connects, gets what it wants then disconnects.
Unfortunately none of these options are the answer you want to your question, but might give you some ideas.
(optional) set up vmware vSphere, ESX, or find a hosting service that already has one.
Store the session variables in db.
Prepare 2 web boxes with 2 distinct IP address and deploy your stuff.
Set up DNS, firewall, load balancer, or BSD vm so name "example.com" resolves to web box 1.
Deploy new version to web box 2.
Switch over to web box 2 using whatever routing method you chose.
Deploy new version to web box 1 if things look ok.
Using DNS is probably easiest, but it takes time for the mapping to propagate to the client (if the client is outside your LAN) and also two clients may see different results. Some firewalls have IP address mapping feature that you can map public IP address and internal IP address. The ideal way is to use load balancer and configure it to 50:50 and change it to 100:0 when you want to do upgrade, but it costs money. A cheaper alternative is to run software load balancer on BSD vm, but it probably requires some work.
Edit: What I meant to say is session variables, not session. You said the server is stateful. If it contains some business logic that uses session variable, it needs to get stored externally to be preserved across reconnection during switch over. Actual DataSnap session will be lost, so when you shutdown web box 1 during upgrade, the client will get "Session {some-uuid} is not found" error by web box 1, and it will reconnect to web box 2.
Also you could use 3 IP addresses (1 public and 2 private) so the client always sees 1 address , which is better method.
I have done something similar by having a specific table which held my "data version". Each time I would update the server or change a system wide global setting, I would increment this field. When a client starts it always checks this value, and will check again before any transactions/queries. If the value was ever different from when I first started, then I needed to go through my re-initialization logic, which could easily include a re-login to an updated server.
I was using IIS to publish my app servers, so the data that would change would be the path to the app server. I kept the old ones available, to respond to any existing transactions that were in play. Eventually these would be removed once I knew there were no more client connections to that version.
You could easily handle knowing what versions to keep around if you log what server the client last connected too (and therefore would know about).
For newer versions (Delphi 2010 and up), there is an interesting solution
for systems using the HTTP transport:
Implementing Failover and Load Balancing in DataSnap 2010 by Andreano Lanusse
and a related question for the TCP/IP transport:
How to direct DataSnap client connections to various DS Servers?

Resources