We currently have a centralised web app and database (running on glassfish and oracle) which is accessed from multiple stations distributed about the country.
At the stations there is data entered into and read from the system (through the browser).
When the (external) connection goes down between the station and the centralized web app we would like for the stations to continue to function - store and present data, then when the connection returns the data is pushed back into the central server maintaining database integrity.
Given that we would be willing to change our app server or database if it was worth it, how is this best handled, is there any out of the box solution for this?
Install the servers at the individual locations, replicate what you want to share across them "routinely", and leave all of the other centralized, but non-vital tasks (like, say, reporting) on the central system.
There is not "out of the box" solution. You system is centralized for whatever reason it's centralized. You're asking for it to be decentralized. By doing so you need to reconsider why it's centralized in the first place, and what dependencies there are because of that centralization (such as each site having instant access to data at all of the other sites).
Address those issues of what you can do without, for how long, and how to share it, and then you can set up autonomous sites. The magnitude and complexity of this process is dependent upon you application and the services it supplies to the remote users.
If you can tolerate losing the current sessions I would point you to look for a distributed database (replication). Oracle probably supports it. In each office you would have a glassfish server
But it is going to cost a lot:
Licences
Hardware (servers)
Properly securing the server
(Lots of) tuning/rewritting to avoid new bottlenecks
Maybe it would be easier / cheaper if you chose to just use redundant internet access for all of your offices.
If you are willing to go cutting edge, then look into HTML 5 with Local Storage. Note that the local storage specification in HTML 5 is still in transition. The second link I included has a good fallback option for when HTML 5 local storage is unavailable. With the fallback option of Store.js, you won't even need to require your clients to use a modern browser, though it definitely helps.
Another option, if you are open to moving in that direction, is to use Adobe Flex 3 for your UI, talking through LiveCycle to your application hosted on Glassfish. There will be more moving parts and a steeper learning curve though.
Related
Can someone answer on my dilemma which method to use for connecting Android device to mySQL or Postgresql?
I can do it in both ways without any errors and problems, with no noticeable difference but everyone recommend web service instead of using jdbc driver and direct connection,
Can someone explain why with some facts?
EDIT: I did'n mention that is more simple and needs less time to do it over jdbc. So, why web service, or why not?
You think it's simpler and faster to do it with JDBC because you aren't considering the real world operating environment of phones and portable devices. They often have flakey connectivity through buggy traffic rewriting proxies and insane firewalls. They're typically using a network transport layer that has high and variable packet loss rates and latencies that vary over many orders of magnitude in short spans of time. TCP really isn't great in this environment and particularly struggles with long lived connections.
The key benefit of a web service is that it:
Has short-lived connections with minimal state, so it's easy to get back to where you were when the device switches WiFi networks, to/from cellular, loses connectivity briefly, etc; and
Can pass through all but the most awful and draconian web proxies
You will routinely encounter problems with a direct JDBC connection. One challenge is reliably timing out dead connections, re-establishing sessions and releasing locks held by the old session (as the server may not decide it's dead at the same time the client does). Another is packet loss causing very slow operations, long-running database transactions, and consequent problems with lock durations and transactional cleanup tasks. You'll also meet every variety of insane and broken proxy and firewall under the sun - proxies that support CONNECT but then turn out to assume all traffic is HTTPs and mangle it if it isn't; firewalls with buggy stateful connection tracking that cause connections to fail or go to a half-open zombie state; every NAT problem you can imagine; carriers "helpfully" generating TCP ACKs to reduce latency, never mind the problems that causes with packet loss discovery and window sizing; wacky port blocking; etc.
Because everyone uses HTTP, you can expect that to work - at least, vastly more often than anything else does. This is particularly true now that common websites use REST+JSON communication style even in mobile web apps.
You can also write your web service calls to be idempotent using unique request tokens. That lets your app re-send modification requests without fear that it'll perform an action against the database twice. See idempotence and definining idempotence.
Seriously, JDBC from a mobile device might look like a good idea now - but the only way I'd even consider it would be if the mobile devices were all on a single high-reliably WiFi network under my direct control. Even then I'd avoid it for reasons of database performance management if I possibly could. You can use something like PgBouncer to pool connections among many devices at the server side so connection pooling isn't a big problem, but cleanup of lost and abandoned connections is, as is the tcp keepalive traffic required to make it work and the long stalled transactions from abandoned connections.
I can think of a few reasons
JDBC android driver support for your database.
Connection pooling across various Android devices make it difficult to monitor and cap them.
Result sets sent from the DB to android will consume a lot of bandwidth and battery power.
Proxies usuall allow HTTP access to your device.
Exposing your database directly to the client has security implications.
Web services can provide additional features on top of the JDBC connection like authentication / quality of service / authorization / conditional GET requests / error handling etc. JDBC cannot do any of these.
Besides all things Craig Ringer said, which I completely agree, JDBC has another problem: it will force to expose your database to the world. If you want android devices to access it, you will need to provide your app with database credentials, and the database will have to have public access.
Using a WebService or RESTful API is clearly the way to go to make your application secure.
Another option would be to use a database sync tool like SymmetricDS.
This would let you have say a Postgres database on your server, and a SQLite database on your tablet.
SymmetricDS would synchronize the databases over HTTP, when a connection is available. You don't have to sync the whole db of course, just the relevant parts.
(I am not affiliated with SymmetricDS)
TL;DR: It depends!
(Sorry to all the "never ever ever ever do it, direct conns are always evil"-devs)
When creating a public domain / general app for the playstore kind of thing, I am mainly with my fellow responders. Opening your DB to "everyone" (especially when permissions are badly or not at all configured) is typically not a great idea!!
However(!), the story might be totally different, when you e.g. create something for internal use within the network boundaries of your company, like Android handheld devices for logistics, inventory, etc. In these cases I would even most of the time definately recommend going with JDBC or a similar direct connection. Reaons being:
One less point of failure
One less development (sub-)project
One less thing to maintain and keep up to date with your data-structure
One less thing to keep up and running, CI/CD, test, etc. (you get the draft)
Which - im my humble opinion - is worse than the (implement it once) effort of connection pooling, reestablishment, etc. (if it really becomes necesseary, be careful with premature optimization there).
But for public projects ... well, if they only ever require read access, I could possibly imagine it as well, or if there are only certain tables were you allow adding, but not delete or modifications. There are some tricks you could apply to make it still secure (allowing adds but not reads with id-secrets for a certain table, triggers, and general reads for other tables, etc.), but there is a lot to think and a lot to miss about these. So generally, I would say it is bad practice to allow your public domain client to get hold of your SQL connection. But still, don't let that hinder you to ask yourself (and understand) "why" and look at the specific situation. There might even be good cause/use for that. Especially since it is "less", which is also often better. It definately depends.
Just be careful and aware that (even if permissions are set correctly) a lot can be misused (and only little hindered), with a direct connection at your client. (Plus possible connection issues to be taken care of.)
As a sidenote: A lot of these considerations are relevant again with the use of technologies like GraphQL, which shares some similarities (however without connection issues and with a little bit more secure control).
I'm currently building an application that is about VOIP / random chatting, which is similar to skype or chatroullet. My question is extension to this
https://stackoverflow.com/questions/11384155/running-java-server-application-24-7-not-on-local-machine
I've been experimenting and playing around with TCP / UDP sockets and now I have ability to build VOIP / instant chatting applications. But as you might already know, in order for data transmission between client to client or client to server, the server application has to be powered on (in other word, be online) and be accessible by client applications. The problem is that, I'm not living by my self but with my family, which I can't simply use one of my computer to run my server application for 24/7 mainly due to the electricity bills and my lack of knowledge about the networking concerns me about the security, because I had to go through some configuration / port forwarding on my current router in order to make the protocol accessible by other users outside of my local network. So my biggest question is that, how do people or developers normally have been dealing with this kind of situations? Have they been simply using their own computer to run the server application? or have they purchased an external machine to run the server application
===========================================
Additional question:
Is TCP / UDP socket the only way of making applications such as MMO, VOIP and instant chatting programs?
i see that your topic was closed in the previous thread. I think such questions are unrelated to stackoverflow.
However, i would like to give you a glimpse of what is happening to most of us who own / make Java Web Applications. I used to work in a datacenter for a year and a half. Java applications are a little harder to put online as they require resources that not many data centres are willing to invest time and support in. Other than that, they are pretty much as straightforward as normal PHP applications.
You will need the standard options like Colocation, Dedicated Server, VPS, Cloud Virtual Machine, or a shared tomcat / application server hosting.
Colocation is where you put your own purchased and configured server with the data center, you have complete ownership of the server, nobody can touch it unless permitted by yourself. You pay to put your server into the data center, and are in charged of anything that happens within the server, including OS patch.
Usually servers in data centers (due to size constraint) come in rack units. 1U refers to 1 rack space, usually this is equivalent to one PC, although a server is much more powerful. In Singapore, the charges per U is SG$200.
Dedicated server is where you lease a server from the data center. The server is managed by the data center and can be as powerful as you want it to be. OS updates, installations, service guarantees are provided by the data center.
VPS is having a fraction of a server resource, but many challenge that you do not have the "root" access to the server in most cases.
Cloud is the virtualization of the entire operating system. If this was Linux, you would have the root access to it. Many of us now are going for this option because of its scalability. Some data centers may use popular virtualization hypervisors like VMware ESXi, Microsoft Hyper V.
The list above is represented from the most expensive to the least. Of course, that is depending on your location and service provider.
Hardly anybody i know tries to put a running server at home, it is a fire hazard itself, you will not know when your electricity will be cut off, standard dedicated bandwidth would as expensive.
Hosting with a data center would be much cost efficient and safer in my opinion.
EDIT:
Is TCP / UDP socket the only way of making applications such as MMO, VOIP and instant chatting programs?
Have you looked at HTML 5 Web Sockets, or any AJAX based framework for this?
Try searching the web for cloud hosting. For example, Heroku, AWS and many others provide a hosted service. That is what people use to host their service and it is more cost effective than trying to maintain something yourself.
Are you writing an Android application for it as well? Just as an aside you might want to make use of this ARO tool to ensure you are using the network efficiently. http://developer.att.com/developer/legalAgreementPage.jsp?passedItemId=9700312
I am developing a custom server application that will access a database. I need to decide where I will store the credentials (and to address) to that server.
A common solution is to put the credential in a config file. However, I do not want a compromised server to mean that the hacker has access to the DB (which is hosted on a separate server).
I could store the credentials in the environment, but that is just security through obscurity. Mr. Evil can just look in the environment to find it.
Someone suggested encryption. However, if I store the key in the executable, a quick de-compile (we are using Java) and I am still doomed.
I also want to avoid having to enter a paraphrase every time I start the server.
Any suggestions? I feel like I'm missing something simple.
Thanks
I don't think you're missing something simple. Either the server in question can connect to the database without your help, in which case it has to have the credentials; or it cannot connect without your supplying them. You can take various steps like the ones you've listed to make it harder for a compromised server to reveal the credentials to the database, but at the end of the day, if it has to have those credentials and supply them to the DB server to connect, they'll have to be stored on it somewhere — or at least, it will have to have some means of getting them, and so will be hackable in that sense.
Your best bet is to focus on finding out about intrusions (compromised servers) as quickly as possible, keeping good off-site, off-line backups for the worst case, putting up lots of barriers to intrusion in the first place, etc.
I am sharing, the way I had solved this.
Build API, to query the authentication details from a foreign domain.
Use public key, and private key to read through the details.
But, honestly the only thing this did was over complicate simple things. After that, I created several users to the database, with different privileges.
Like
guest can only to SELECT
mod can only CREATE, INSERT, UPDATE, DELETE
etc and switched the user, whenever authenticated users appeared.
With the combination of users and session, I have been able to escape the threats so far. But ofcourse the code vulnerability have to be tested thoroughly.
Lock it down. Prevent Mr. Evil from gaining root. I know, easy right?
Write a secure application and keep your application server locked down. Follow best practices there, and that's most of the work.
When I've setup databases in a secure environment, the only server that was on the same physical network with the database server was the application server. There were two ways to access the database server:
Application server
Console
Therefore, in order to compromise the database server, they'd have to compromise the application server.
So, lock down the application server. Of course the only thing worse than being compromised is being compromised and not knowing about it. If you do discover a compromise, you need to fix the vulnerability if there was one. Forensics are important here (enable logs and monitor them). You also need a recovery plan in place.
Prevention, detection, correction, and recovery are paramount.
We have a typical Flash+J2EE application that makes multiple requests from client to server (over Flex remoting), which is taking quite a long time on some client systems (and hence results in poor application performance on such systems).
Now, suspecting issues with network connectivity (latency) on such client system(s), we need to identify how far does it contribute to the slow response of the application (rather than performance issues in the application itself).
So, what are the best way(s) to diagnose this on a client system (Windows)?
Note that we have tried profiling our application, which does not indicate bottlenecks there, so we just need to clearly identify the possible network issues.
Thanks.
Consider the use of a network impairment solution to model these uncontrolled network characteristics for the user(s) who are complaining. The industry defacto solution set is from Shunra (http://www.shunra.com), but if all you want is single session to look at the behavior of one user, then you might consider an open source solution such as WanEm, (http://wanem.sourceforge.net).
This should allow you to model the network characteristics between a single client and the server over a congested network link to observe how the single user application performance changes with different network conditions. With WanEm you get to model one logical link between the two. With Shunra you could model your whole network if you so desired. Don't accept the default installation of WanEm on a virtual machine, timing is critical to network impairment and the clock will "float" inside of a virtual machine - Go ahead and stand up a single host for this.
Architecture:
A bunch of clients send out messages to a server which is behind a VIP. Obviously this server poses an availability risk.
The client monitors a resource and the server is responsible to take action based on the what status the majority of the clients report to it and hence the need for only 1 server/leader.
I am thinking of adding another server as a backup on the VIP, which gets turned on only when the first server fails. However when the backup comes up it would have no information to process and would lose time waiting for clients to report and waiting for the required thresholds etc.
Problem:
What is the best and easiest way to have two servers share client state information with only one receiving client traffic?
Solution1:
I thought of have having the server forward client state information to backup server and in the event of a failure when the backup server comes up, it can take it from there.
Is there any other way to do this? I thought of having a common/shared place to store state information where both servers can read client state information from. But this doesn't work well as the shared space is a single point of failure too.
One option is to use a write-ahead log. Essentially, any modification you make to your state gets sent over to the backup server, which replays the change on its own copy of the state. As long as it can keep up with the streaming log, the backup is always up-to-date.
This is the approach generally used by most databases; if you use one as your backend, you may be able to get support for this with little work.
Be careful to have a plan to recover from communication failure - either save the log to disk and resend the missing portion, or send a snapshot of the state, plus all log entries since the snapshot on reconnect.
There are various distributed caching products which do the kind of thing you're talking about here. Some are supplied with App Servers, such as WebSphere's dynacache and Object Grid. In fact ObjectGrid can be used in JSE, no need for an App Server.
Those distributed cache products use various push and pull models with pub-sub messaging to achieve consistency across the instances. Working for IBM I'm a fan of ObjectGrid, but more impartant, I'm fan of not reinventing wheels. My take is that this stuff can get quite complex and hence finding something off-the shelf might save a load of work - there are links to various Open Source solutions here.
The is very much dependent on how available your solution needs to be (how many 9's). There is a spectrum of solution.
A lightweight one could be crafted around Memcache: extremely fast distributed state facility. As example, it is used extensively on Google AppEngine.