Advantages of Distributed Architectures
- Isolation – Robustness, scalability and improved testing strategies all stem from the concept of isolation. Isolation gives an application architecture many of the advantages that encapsulation provides in object-oriented design.
- Robustness – Services are robust because their underlying implementation can change with shifting load requirements, libraries, and languages without detriment to the rest of the application.
- Scalability – When using services, you need to think up front about how to separate data and manage interaction. This partitioning of logic and data provides the ability to scale the size of the code base and team in addition to the number of requests to process.
- Agility – Upgrades to the underlying system components are easier with services. Further, new versions of existing services and completely new services can be implemented outside the full architecture. This can provide much-needed agility for mature code bases where changes are typically expensive to verify with the rest of the application.
- Interoperability – Using HTTP-based services is a great way to expose the functionality of legacy applications or external vendors.
- Reuse – Service-oriented design enables reuse of components across multiple applications or clients.
All Ocean services are fully exposed to the Internet. Hence:
- they are individually deployed (allows individual and dynamic scaling),
- they are individually load-balanced,
- they are individually protected from flooding,
- they perform and require individual authentication and authorisation.
New Ocean Services
Ruby on Rails
Services are perhaps most practically written in Rails, but other languages and frameworks are definitely possible as long as they implement Ocean's aggressive caching and protection from flooding, authentication and authorisation according to the same principes as the rest of the services. Rails apps acquire these properties via the
In future, we may provide application containers, as the term goes, for other languages such as Python, Erlang or Java. Ocean is an open source project: contributions in this area are most welcome.
It's however easy to implement services in other languages by using Ocean as a thin layer interfacing to workers written in, e.g., Java or Erlang. The CRUD operations implemented by Ocean simply generate calls to workers, returning whatever data is returned, perhaps after massaging it in various ways. This is essentially the same process employed when converting a legacy application.
Each service has its own service-specific database. It is important that a service never accesses tables of databases used by other services, neither by direct access, nor by database joins. The data world of a service must be completely private to that service alone. Isolation is crucial. In some cases, this requires the overall database design to take into consideration such things as denormalisation of certain tables, or automatic synchronisation via a messaging system.
It would be beneficial to use noSQL databases for new services, in particular AWS DynamoDB.
DynamoDB is a cost-effective and extremely fast database storage service provided by AWS. DynamoDB provides constant low-latency access times as fast as 2 or 3 ms, scales limitlessly and seamlessly and requires no provisioning of server instances, requires no maintenance and has no downtime. Ocean uses DynamoDB in several of its core services to achieve massive scalability. As a result, authentication is fast even when large spikes occur, such as when users log in. Another important use of DynamoDB is in the asynchronous Job service, which also uses AWS Simple Qeueue Service to provide massive scalability for asynchronous jobs. This is essential to implement a scalable application architecture able to support millions of clients. DynamoDB will gradually replace all SQL database tables in the Ocean core services.
Interfacing to legacy code is easiest done by letting a Rails Ocean application act as a thin layer of abstraction communicating with the legacy application using a messaging system such as ZeroMQ, through simple pipes, or using HTTP calls. The Rails layer provides the data abstractions (hyperlinked resources, aggressive caching, etc), while the legacy layer does the heavy lifting.