Modern applications are hard to get right. The tools, constraints, and possibilities are changing too fast. Oracle presents a framework for application development to simplify the architectural decision-making to build and run apps that are highly available, resilient, fully secure, and compliant using a set of design principles and technology recommendations.
Do you already know what you're looking to do? Go directly to our Architecture Library
Common requirements that apply to any modern application
Best practices that govern application architectures
Opinionated patterns with recommended technologies choices
A list of recommended technologies for modern applications validated using feedback gathered from Oracle customers
Common requirements that apply to any modern application.
Align security policies with industry best practices and enforce them across the layers of the app stack. Ensure the confidentiality and integrity of data. Use privilege management to identify and manage who can perform certain tasks. Make it easy to detect and diagnose security events.
Make apps available 24/7/365 with no downtime, planned or otherwise.
Scale gracefully from tens to thousands to millions of users and handle increasing volumes of data—without needing to redesign the app in the future.
Provide the lowest latency and highest throughput required for the best possible user experience.
Rely on modern automation tools and methods for build and deployment processes. Avoid bottlenecks caused by the need for manual tasks.
Record performance metrics and monitor system performance for any degradation. Enable teams to automatically generate alarms when these measurements are outside expected boundaries.
When problems happen, ensure that apps recover gracefully, quickly restore lost functionality, prevent data loss, and don’t negatively impact user experience.
Run at the lowest possible total cost, balancing all the other requirements.
Ensure that application architecture adheres to open standards—which eases migration from on-premises to cloud, or across vendors.
Best practices that govern application architectures.
The programming language, library, and framework choices and patterns that you adopt to build applications play a pivotal role in their successful delivery and maintenance over time. Language and framework choices have a long-term impact on how you scale your business, operate your apps, and deliver high-quality features to your customers. Changes to either language or framework are typically expensive. Supporting parallel ecosystems of different languages and frameworks adds complexity and cost and reduces agility. When choosing a language and framework, consider a range of factors, including delivery speed, stability and strength of the existing ecosystem, operational readiness, and production performance.
When building apps, consider how the languages and frameworks you choose contribute to successful delivery. Consider how the tooling and design features of the languages and frameworks help you to build correct app behaviors, test app code, enable positive change, and prevent unnecessary change. Consider how making consistent choices across your business can help you invest in common patterns and capabilities.
Use Java running on GraalVM for services, and TypeScript and JET for web interfaces. Build microservice applications using Helidon or Micronaut.
Use typed, memory-safe languages that are well-suited to app development. Type-safe languages contribute to app correctness through compile-time checking and, when coupled with static analysis tooling, can eliminate many common security and stability issues. Type-safe languages can be used to bind external contracts (such as API specifications) more accurately into code, can significantly reduce the incidence and impact of bugs upfront, and can reduce the need for exhaustive testing. Type-safe languages are also easier to refactor correctly (through development tools), enabling safer and bolder change as requirements evolve.
Prefer mature languages with mature ecosystems over less mature ones. Newer languages tend to have a higher rate of change in their language design and in the corresponding ecosystem and libraries. This higher rate of change can make evaluating the risk of technology choices harder and subsequent changes expensive.
Use modern, lightweight, opinionated app frameworks that balance improving task focus (business logic over boilerplate and scaffolding) with flexibility (allowing you to support current and future feature needs). Adopt frameworks that provide easy-to-consume sensible and uncontroversial defaults for common features such as logging, telemetry, security, configuration, and common patterns (such as building REST APIs). Adopt one preferred framework for your organization that allows generalization of common patterns to you and portability of skills between teams.
Use frameworks that decouple app code and modules from their environment to simplify app portability between development and production environments and testing of apps during build.
Adopt Java as your programming language. Java provides a stable and broad set of capabilities for most common app use cases and has a healthy ecosystem of trusted and stable libraries and frameworks for developing modern apps. Java's focus on simplicity and readability coupled with its excellent support for developer tooling—including static analysis tools and testing frameworks—reduce software maintenance costs and the risk of bugs in production apps.
Use GraalVM JDK for developing and running apps. GraalVM JDK couples the stability of Java with best-in-class performance through dynamic runtime optimization, frequent and proactive patching of security vulnerabilities, and low-cost performance analysis and diagnostic tooling through Java Flight Recorder.
Build apps with an API-first approach by using either the Helidon or Micronaut framework. Both frameworks provide scaffolding that significantly reduces the time to deliver apps and easy-to-use patterns for common use cases such as REST APIs, based on a set of simple, uncontroversial framework choices for common activities such as logging, telemetry, and storage. Both frameworks support high performance services through support for nonblocking I/O with idiomatic reactive APIs, and low latency through support for high performance network libraries.
Both Helidon and Micronaut have built-in support for GraalVM native image compilation, which enables you to build memory-efficient and compact apps where needed.
A service-oriented approach delivers functionality for specific business outcomes. API contracts provide a clear and understandable interface for communicating with and between services.
Building an application with independently scalable services that encapsulate specific functionality provides a high degree of agility for a development team. Defining API contracts for services provides the necessary mechanisms for teams to collaborate and consume functionality without depending on the internal details of the implementation. For example, a service can be wholly owned by a development team that can freely improve on the implementation without having to coordinate code dependencies with other teams.
An API contract-first approach results in services with a clear and easy to consume interface. We recommend that you implement your services using lightweight frameworks such as Micronaut or Helidon. Deploy the services on serverless platforms such as Oracle Cloud Infrastructure (OCI) Container Engine for Kubernetes or Oracle Functions for ease of deployment, scalability, and cost-efficiency. Use Oracle API Gateway to create protected and governed private or public endpoints from the API description.
Begin with a contract-first approach, based on the business requirement. Describe the behavior of the service by using an implementation-agnostic format such as OpenAPI. Then prototype the API to let your stakeholders, such as the team implementing the API and other teams who will use it, try it out. After everyone agrees that it behaves as expected, teams can work in parallel to implement the service and the other services that will consume it.
Define your policy enforcements for security and service level agreements (SLAs) early in the lifecycle to ensure that everyone is clear on all aspects of the service contract. Use an infrastructure-as-code approach to manage deployments in an automated and repeatable way that eliminates one-off changes in production. Use a version control system to maintain your code, API descriptions, and policy configurations.
Use OpenAPI to describe your API. Use Terraform to create templates for API deployments so that your continuous integration and deployment (CI/CD) system can manage the API deployments. To ensure that changes are properly tracked, use a version control system such as GitHub.
API deployments that are defined by using Terraform files follow an infrastructure-as-code approach by including the API policy configuration alongside code. With the Resource Manager configuration and template features, a project with the API configuration can be automatically applied by CI/CD pipelines using the environment configurations at deployment time.
Use Oracle API Gateway to provide a common endpoint infrastructure that is consistently protected and governed.
A container packages application code and dependencies as one unit that can be quickly and reliably run across different environments. Compared to traditional virtual machines, containers are smaller, require fewer resources, and have faster start times. They are also platform independent and to run apps anywhere.
To take advantage of these benefits, decompose your apps into services that perform discrete business functions and package them as containers. With legacy apps, gradually replace existing functions in the app with containerized components until the whole app can be refactored.
Containers are instances of container images. Use Oracle Cloud Infrastructure Registry (Container Registry) to store your container images and Oracle Cloud Infrastructure Container Engine for Kubernetes (Container Engine) to run and manage containers at scale. These fully managed services are tightly integrated with various OCI platform capabilities, are available in all Oracle Cloud regions, and meet regulatory standards such as PCI, ISO, SOC, HIPAA, and FedRAMP.
Packaging application code and dependencies into a single executable unit makes containers extremely portable. By combining this portability with infrastructure abstraction, containers bring operational consistency to apps. Whether the app is running on-premises on a physical server or in the cloud on a virtual machine, it produces the same results every time.
Through this consistent reproducibility and predictability, containers simplify DevOps processes and let development teams ship apps faster. By providing process-level isolation, and because they’re frequently ripped and replaced, containers simplify and expedite the processes associated with remediating software vulnerabilities. Breaking down apps into modular containerized services also makes them very robust. An error or failure in an individual service doesn’t bring down the entire app, and you can update or patch each service independently from the rest of the app.
Containers don’t come with an operating system of their own. Instead, they share the operating system of the host they run on. As a result, containers are smaller in size and faster to start than virtual machines. Most container images are tens of megabytes in size compared to virtual machines that can be several gigabytes, and their start times are in seconds instead of the minutes it takes to start virtual machines.
The best way to run and scale apps with modularized services in containers is to deploy only one service per container. This approach isolates services from each other, which eliminates downtime and enables independent scaling for each service.
Container Engine is a certified Kubernetes-conformant service. Through its support for virtual machine, bare metal, Arm, GPU, and HPC shapes, Container Engine helps developers fully optimize their containerized applications for different use cases. You can use OCI and Container Engine mechanisms for the following tasks:
In addition to storing container images in Container Registry, you can store manifest lists (sometimes called multi-architecture images) to support multiple architectures, such as Arm and AMD64. To identify and mitigate potential security vulnerabilities, you can enable image scanning on all images uploaded to Container Registry. You should also sign your container images to ensure that only authorized and trusted images are deployed to Container Engine.
Continuous integration (CI) and continuous deployment (CD) are a set of tools, procedures, and practices that development teams use to frequently and reliably deliver code changes. CI/CD best practices include processes such as code reviews, and guidance for unit testing, integration testing, code check-ins, filing tickets, and deploying applications to development and test environments.
When using CI/CD to build applications, consider the tools that each team member uses and what roles and responsibilities they perform to deliver the apps safely and agilely.
Use the Oracle Cloud Infrastructure DevOps service to automate your DevOps processes, make development more efficient, and increase how quickly you release features. Use the DevOps code repositories to store code securely and trigger builds; use build pipelines to automate build steps; and use deployment pipelines to automate deployment steps. Use the Resource Manager service to automate infrastructure creation, and use maximum security zones to enforce deployment security.
CI/CD provides best practices for storing, integrating, deploying, and maintaining code to automate how you build your apps.
Use a Git-based code repository to store all code assets and use an immutable artifact service to store any created assets.
To implement continuous integration, merge all code into a “release candidate” branch at least once a day. When you merge code into that branch, ensure that builds are automatically triggered. As part of the build pipeline, run all unit tests, and immediately fix any pipeline failures before doing more development in the release candidate branch. Use security scans on the code to detect vulnerabilities, and don’t store any artifact that has a vulnerability issue. Fix all vulnerabilities in the release candidate branch before doing more development.
To implement continuous deployment, automatically deploy release candidates to a test environment or use canary deployments. When test deployments pass, automatically promote them to full production. If test deployments fail, immediately resolve the issues before doing more development in the release candidate branch. Use security features as part of deployments to prevent unauthorized and vulnerable artifacts from being deployed on the infrastructure.
In the production environment, use monitoring tools to assess the health of the deployed apps and detect any post-deployment vulnerabilities. If any issues are detected, implement automatic rollback to the previous version. Perform security checks in the post-deployment environment, and immediately resolve any issues that are detected.
Use the DevOps service to automate deployment of your cloud native apps. First, store the code in a DevOps code repository and create a release branch. Work in small increments to make changes to the release branch, and reconcile issues in the branch daily to keep it stable. Then, use the triggers functionality in the code repository to automatically start a DevOps build pipeline.
Use a single DevOps build pipeline to build all artifacts associated with the triggering code repository. If the build fails, configure the build pipeline to wait for approval before it completes. The approval request should go to the committer who triggered the build, and they should resolve the issue with a new code commit and then approve the completion of the build. For successful builds, configure the build pipeline to automatically deliver the artifacts to the Oracle Cloud Infrastructure Artifacts Registry service and to automatically trigger a DevOps deployment pipeline.
Use Resource Manager to create all your infrastructure environments in a maximum security zone to automatically get deployment security. By using Resource Manager, you can use infrastructure as code to automate infrastructure creation across all your regions in a consistent manner. Then, you can configure the DevOps deployment pipeline to always deploy to the resources that you have created in the security zone.
Create a single DevOps deployment pipeline that deploys all the artifacts created from a single build pipeline. Organize deployment environments OCI region, availability domain, and fault domain. Configure the pipeline with a canary, rolling, or blue-green deployment strategy, and configure it to trigger tests automatically. Enable OCI Monitoring and Application Performance Monitoring on your application and infrastructure to detect issues.
If no issues are detected and tests complete successfully, configure the deployment pipeline to automatically deploy the artifacts to the next environment in the deployment strategy until the artifacts are fully deployed in all production environments. When deploying to the production environment, configure the pipeline to deploy to all fault domains in an availability domain one at a time. Deploy to each availability domain in a region one at a time, and then finally to each region one at a time. Continue to use OCI Monitoring and Application Performance Monitoring on the application and infrastructure to quickly detect issues. Set up alerts, and if any key metrics suddenly drop during deployment, automatically fail the deployment and trigger a rollback to the previous version.
Managed services let you focus on creating value for your customers by making it easy to develop and by handling security, operations, and maintenance of your data and applications. They also abstract the underlying infrastructure and resource management. You benefit from highly available, up-to-date secure services that can be scaled to meet the needs of your applications. And you get best-in-class solutions without needing expertise in each domain to build and operate your apps.
Reduce complexity in data management by storing your data in Oracle Autonomous Database for transactions and data warehouse workloads, and in Oracle Cloud Infrastructure storage services for object, file, block, and archive storage. These services are highly available and cost-optimized with high performance. Autonomous Database offers in-memory, NoSQL, and SQL databases with an autonomous advantage to reduce management overhead.
Use Oracle Application Express (APEX) to quickly build low-code apps, and use Oracle Functions to create, run, and scale apps that run for short durations. These services significantly enhance productivity for developers, incorporate security in the framework, and provide code instrumentation and tracing to easily debug apps.
Use managed services to develop and run apps and store data. Managed services offer the expertise of seasoned professionals managing your data and apps without the need for human intervention to maintain or operate.
Managed services abstract the complexity of the underlying components, making it easy to store and retrieve data, or to create and run apps. They integrate with tool sets that enable automated building, testing, and deployment of apps. Managed services improve productivity and help you quickly get your apps ready for customer consumption.
Managed services centralize and automate various infrastructure management tasks, removing human error and the need for specialized skills. The underlying platforms are kept up-to-date and secure, and they let you monitor and track modifications or access, which ensures the confidentiality and integrity of your apps and data.
Managed services are highly available and scalable, which makes it easy to meet the needs of your app, and you pay only for what you use. You can start small and scale without experiencing any degradation in performance or service reliability as the needs of your business grow.
Use managed services to create highly available, scalable, agile, resilient, and performant applications with security, compliance, and resiliency.
Use purpose-built managed services to ensure high availability, reliability, and security. We offer various managed services to meet the needs of your app development. We recommend the following services:
These services are elastic, and the underlying infrastructure is managed and patched to ensure that your sensitive apps remain protected.
Keep the application tier stateless, and preserve the state of the application in an external persistence store. Use as few persistence stores as possible—ideally one to ensure data consistency.
Examples of the state include the user session (such as the page a user was on or the size and items in a shopping cart), data caches, user preferences, personalization, messages exchanged between services, position in a multiple-step workflow, and app deployment and runtime configuration.
Application state is typically stored in various artifacts and formats such as serialized objects, JSON or XML documents, text files, and security stores. This state is often spread out across multiple persistent stores or even local node disks, which can result in the state getting lost or out of sync after failures. Restoring a service from a backup or in a different region after a disaster is difficult when the state is spread out. Not only must all the states be identified and restored, they often must be brought to a consistent point in time.
As a result, the application state should be stored in a few (ideally one) external persistence stores. Keeping the state external to the app itself lets you make the app easily recoverable after failures. Keeping the app itself stateless simplifies its lifecycle management—patching becomes only a matter of replacing the executable . The state should be automatically restored so that users can continue where they left off if, for example, the user closes the app, the app goes through a lifecycle event (such as getting restarted or patched), or the apps fails over to a different instance, availability domain, or region.
For apps that use a database, use the database to also store the application state. A database provides better availability, integrity, and security than other alternatives. Ideally, use a converged database—which can store different formats—to store all application state artifacts. Using a converged database instead of multiple single-purpose data stores also lets you easily achieve and maintain consistency among all the application states.
Oracle Database is an ideal fit for this purpose. It stores different formats, offers active-active high availability within and across regions, and provides the highest level of security and data integrity.
Note: Although it’s permissible to store cached state in the app, the app must be designed to use the database as the source of truth and be able to recreate its state from the database.
For apps that don’t use a database, consider other durable persistence stores such as Oracle Cloud Infrastructure Object Storage to store the state. If the application state can’t be kept in a single data store, design the app to store the state in multiple data stores that can be kept in sync and recovered as a consistent unit after failure.
Losing the application state can result in loss of data, app malfunction, a suboptimal user experience—and sometimes, complete app failure.
If the application state is stored solely on local file systems or in the memory of a single host, then it might get lost if the app experiences planned or unplanned outages, such as restarts or localized disk failures.
If the application state is stored across multiple persistence stores such as external file systems, message stores, object stores, multiple databases, or elastic block storage, then it’s possible for the different data stores to get out of sync and result in state inconsistencies. Apps must also implement transactions, joins, and idempotency to ensure data consistency when the state needs to be updated as a unit.
State data scattered across multiple stores also creates more opportunities for security vulnerabilities. Lifecycle operations—such as adding and removing nodes, patching, backup and recovery, and replication for disaster and recovery—become extremely complex and require special consideration to keep state consistency across different stores. Applications need to rely on additional capabilities of application containers—such as clustering, session state replication, transaction management, separate storage for transaction and messaging logs, special network configuration, and reliance on external storage solutions.
As a result, a better approach is to store all the state and app data in a single database if possible. Data stays consistent in a single store and is easier to manage.
With this approach, application instances can be replaced. This especially helps with modern app architectures such as elastic microservices or ephemeral instances where an instance exists only for serving a single or a few requests. Adding a node is simplified because a new node can get the latest copy of the state—and removing a node doesn’t result in losing the state entirely. Patches can be applied in a rolling fashion just by replacing the executables. A node can be restored from backups and acquire the state from database. State can be consistently replicated as a unit to different regions for disaster recovery. Having a consistent state in different regions can ensure there won’’t be any app functional issues after a failover or switchover.
Oracle Database provides predictable performance, so storing application state in it doesn’t result in-app performance degradation.
Following are some suggestions for storing state in Oracle Database.
For your application’s data tier, use databases that natively support different types of data, such as JSON, relational, graph, and spatial. Take advantage of database functionality to simplify app logic. For example, use SQL for queries, joins, and analysis; use transactions to guarantee consistency and isolation; and use built-in machine-learning algorithms and analytics capabilities to avoid unnecessary data transfers. To protect sensitive data, use the database’s security features and access control, and use replication to improve the availability, scalability, and resiliency of your apps.
Oracle Autonomous Database provides full consistency and ACID transaction guarantees across all data types. It also provides built-in machine-learning algorithms and fast queries over large volumes of data.
Use Oracle Autonomous Database as your app’s data tier. Apply the "data-first" principle, and store data in the format that provides the most benefit for your app. Use SQL to analyze and aggregate across different types of data, and apply cohesive data access and governance rules across all the data.
Use multimodel, converged databases to store different types of data such as JSON documents, property graphs, and relational data. Advanced multimodel databases offer full-featured support for any kind of data stored in the database. You can store a new JSON document, insert relational rows, and update a property graph all within the same ACID transaction. You can use SQL statements to join, filter, and aggregate across these different types of data, which provides strong consistency and concurrency guarantees that you’re accustomed to from relational databases. Along with offering this rich set of features, multimodel databases can also be used as single-purpose data stores that can be accessed by using natural APIs other than SQL , such as REST APIs, document store APIs, and graph APIs.
A key advantage of using a multimodel database is reusability. Although data might be of different types and shapes, the underlying technology to manage that data doesn’t have to change. This means that you don't have to learn a separate database technology and understand how to use and tune it for each type of data. And because the technology is the same, app code doesn't have to be rewritten. You can reuse existing app code and frameworks, rather than having to start from scratch, which provides faster time to market. Also, multimodel databases improve app resiliency by reducing data fragmentation, thus making backups and recovery easier.
Use the database's data processing capabilities to avoid copying data out of the database. Doing so improves performance by minimizing network roundtrips, and improves data security and freshness.
Use Oracle Autonomous Database, a multimodel converged database, to store, manage, and analyze all your data. Ease the maintenance of your app by using views to expose the data in tables, so that the underlying schema can be changed without affecting existing apps. Use edition-based redefinition to enable upgrading your app with no downtime. Use Oracle Data Safe to implement and evaluate security controls, mask sensitive data, and audit data accesses. Use Oracle Data Guard as a highly scalable read cache for your data, and to maintain a consistent backup for disaster recovery.
Leverage Autonomous Database's rich set of built-in data processing capabilities to improve performance and enhance security by avoiding unnecessary data copies. Use Oracle Machine Learning for your application's ML and AI needs, including data preparation, model building and management, and inference. Use Oracle Text to search through textual data, leveraging built-in capabilities such as fuzzy search and indexing. Use Oracle Database advanced queuing (AQ) for asynchronous messaging to achieve low-overhead transactional semantics across messaging and other database operations.
Oracle Autonomous Database performs operational tasks with no impact or interruption to the workload. Complex compensational logic for the data tier doesn’t have to be put into the app itself to handle scaling or failover scenarios. The database manages resources such as CPU and storage independently and provides elastic bi-directional scalability for all of them. Resources can be scaled fully online without having to restart the database in a different “shape”.
Developers, administrators, and security officers must maintain an authoritative and timely understanding of an application’s health, performance, operational state, and possible security incidents. This understanding ensures that an app’s function and performance meet expectations during the test and production lifecycle, and can also streamline incident diagnosis and application recovery. Comprehensive monitoring also allows intelligent and automated integration with tools to dynamically adjust resource capacity and coordinate responses to unexpected events. Comprehensive end-to-end monitoring and tracing should be straightforward to implement and manage without adding complexity to an app environment.
Oracle has created cloud platforms and services to enable end-to-end monitoring and tracing while minimizing the development and administrative overhead of traditional solutions. The following OCI services help you consolidate your logging, monitoring, and tracing across the environments that host your apps: Logging, Monitoring, Logging Analytics; Application Performance Monitoring; OS Management; Database Management; and Java Management. These fully managed services are integrated with common OCI infrastructure resources and also provide supported mechanisms to integrate your custom app resources.
The way we build software has changed. When we built monolithic applications, all the ways that they could fail were known. With the move to microservices, apps can fail in more numerous and unpredictable ways because of the many interactions between the app’s different components. Even the infrastructure that an app runs on is elastic and might exist for only hours, minutes, or seconds. So having a clear, accurate, and timely understanding of an app’s operational state and history is not just about measuring an end user's experience—it’s also about being able to quickly identify and respond to increasingly complex issues. You might also need to maintain compliance with regional or national jurisdictions, which might require the ability to generate, on demand, detailed activity reports or attestations about the handling of specific sensitive data elements.
Starting with development, you need to build comprehensive monitoring capabilities into your apps that remain consistent throughout the app lifecycle. These capabilities should be straightforward to implement and manage without adding complexity to the development, test, and deployment processes. Where possible, adopt solutions that extend to accommodate the diversity of platforms that you currently use and might deploy in the future.
Monitoring solutions should be compatible with third-party tools in general and align with your environment’s administrative tools in particular. It’s important to maintain design flexibility and avoid vendor lock-in.
Beginning with the development process, integrate monitoring and tracing frameworks with your app stack. OCI services are designed to provide out of the box support for monitoring, such as the Monitoring Service. Also, many OCI services can be extended to your app components by using a consistent deployment and management experience through supported APIs and SDKs. For example, you can add automated monitoring metric collection or log capture with centralized storage for all your virtual machines and apps.
During development and testing, configure services to collect only basic debugging or performance testing information. As the app approaches production deployment, increase the scope, frequency, and traceability of information collected by making simple updates to existing configuration parameters.
Adopt fully managed, scalable services that deliver the features you need without undue integration or administrative overhead. Managed services let you offload the engineering, management, and typically higher costs of running solutions that don’t align with your core business. The OS Management and Java Management services can increase app availability while reducing administrative costs.
Use robust, centralized data collection for your entire cloud tenancy environment, to provide a single location for analysis, coordinated investigation, and alert generation. Service Connector Hub enables flexible, consistent, and customizable responses to events. Logging Analytics enables efficient analysis and investigation of all your cloud (and external) event logging systems. You can also use Service Connector Hub, Oracle Functions, and Oracle Notifications to transform ingested metrics and logs into actionable alerts. And you can take advantage of our integrations with third-party products and services, such as Splunk and Grafana.
Despite the reliability of modern cloud hardware, disks, machines, and networks fail. Even entire data centers can become unavailable because of disasters such as fires, earthquakes, floods, and hurricanes. For your application to achieve high availability, you must ensure that the data on which the app depends remains available when failures occur. The key to the high availability of data is replication. Data replication across machines and the use of redundant networking protects you against routine machine and network failures. Using active-active replication provides better resource use and higher availability. And replicating your data across geographical regions protects against disasters.
Oracle Cloud Infrastructure offers an array of storage services—from Block Volumes, Object Storage, and File Storage to Autonomous Database and Vault—that replicate data within and across regions to ensure the durability and availability of data when routine failures and disasters occur. Using these managed services gives you highly available data while freeing you from building and maintaining your own expensive storage infrastructure. Oracle Autonomous Database, Data Guard, and GoldenGate provide active-active hardware and software replication for high availability as well as zero-downtime patching and upgrades.
Data replication faces two key challenges: consistency of data across replicas and independence of failures.
To achieve high availability and durability, typically data is replicated across a minimum of three copies. Keeping all the copies in sync is a problem, and algorithms such as Paxos are the key to doing it. Over time, however, disks fail and some copies might disappear, and you have to create new copies to meet availability requirements.
Replicated systems can function in two different modes: active-passive and active-active. In active-passive mode, there is a single primary replica and one or more secondary replicas. Only the primary replica participates in-app data processing. In the active-active mode, all replicas participate in data processing. This mode leads to better resource use and higher availability because no primary-secondary failover is needed.
Replication relies on the independent failure of replicas. Machine or disk failures are typically independent, but network or power failures might take out a whole group of machines. To ensure high availability, multiple replicas of data must not become unavailable when a power outage occurs. To protect against such incidents, network and power infrastructure should be redundant, and data replicas must be carefully placed across different units that can’t fail together.
To ensure the integrity and security of your data, data must be checksummed, encrypted, and access-controlled. Checksums protect data against silent software and hardware corruption; encryption protects against data theft and leakage; and access control protects against unauthorized access.
Use Oracle Autonomous Database, Data Guard, and GoldenGate for high availability database use cases. All these systems provide high availability and efficient resource use through active-active data storage and processing.
OCI data centers are carefully engineered to eliminate single points of catastrophic failure. A typical data center or availability domain contains multiple independent failure units known as fault domains. Two independent fault domains can’t fail together. Similarly, a single region might have multiple availability domains, which are geographically separated to ensure that two of them can’t fail at the same time.
Use OCI storage services such as Block Volumes, Object Storage, and File Storage to replicate data across fault and availability domains at all times so that no single failure impacts the availability of your app data. Use Container Engine for Kubernetes to ensure that your app instances are deployed across fault and availability domains to automatically take advantage of the resilient fault isolation patterns built into OCI.
To protect against disaster scenarios that can take out entire regions, use the cross-region replication capabilities provided by GoldenGate, Object Storage, and Block Volumes, which satisfy your availability and compliance requirements. Use the Vault service to store and replicate your keys so that your apps can continue to access your encrypted data. In disaster scenarios, use the OCI DNS service to failover your app from one region to another.
Securing customer data in applications is critical. Developers need access to simple and prescriptive security controls to secure their apps, rather than having to manually configure a complicated set of security controls which could be error-prone. Automated security controls eliminate human error which is a root cause of many security incidents, and help developers secure their apps and data without requiring them to become security experts. Easy-to-use automated security controls must be implemented in all stages of the application lifecycle, including development, build, test, deployment, and runtime. Security must verify users, permissions, and access policies at each step in the process and ensure that access is granted only when appropriate. Security restrictions must detect security issues that are introduced early in the software development lifecycle. Early detection ensures that the app is deployed in production with security architecture best practices and that operational security issues caused by misconfigurations or disclosed vulnerabilities are detected and mitigated.
Oracle Cloud Infrastructure offers multiple automated security services to secure apps and customer data. Use Web Application Firewall (WAF) to limit traffic from unknown locations or Tor nodes. Enforce the principle of minimum reachability to endpoint isolation by using the network security groups feature in OCI virtual cloud networks (VCNs). Launch apps in a secure-by-default configuration by using Security Zones. Use Identity and Access Management (IAM) for an identity-first approach to security that enables easy onboarding and management of users, strong and contextual authentication mechanisms, and restrictive access permissions. Monitor for security misconfigurations and anomalous actions by using Cloud Guard. Use Vulnerability Scanning to periodically scan instances and containers for known security issues. Use Vault to securely store encryption keys used to encrypt app data, and credentials used by the app.
Apps must be accessed securely. Here are some specific ways that you can secure an app through its lifecycle:
Use maximum security zones for compartments with private subnets. Ensure that operator access to any compute instances in private subnets goes through the OCI Bastion service.
Use OCI IAM on the front end to authenticate users with strong authentication methods while maintaining an optimal user experience through context-aware adaptive security, optional social or federated logon, or passwordless authentication (depending on requirements). Support regulatory requirements by enabling users to manage their consent for terms-of-use and by supporting data residency requirements.
Use OCI IAM on the backend to restrict access to app components as needed. Enforce authentication for administrators through strong MFA options. Enforce strong security policies that allow access only through explicitly granted permissions. Separate responsibilities so that access is limited to those who need it.
Use built-in security principals to authorize compute instances to perform actions on other OCI services. If you must use app passwords, store the passwords in secrets and rotate them every three months through automation.
Enable Cloud Guard and resolve or accept and disable all problems. Enable notification on drift and treat new problems with urgency.
Enable Data Safe to secure Oracle databases by monitoring users and access. Data Safe also scans the databases for security best practices and alerts on divergences.
Periodically scan instances and containers for known security issues by using the Vulnerability Scanning service. Encrypt data-at-rest with keys stored in the Vault service, backed by hardware security modules (HSMs). Prefer to use separate encryption keys for each service, but align Vault entities with compartments. Rotate master encryption keys at least annually and data keys every three months. Use a private vault in production, and replicate keys in secondary regions. Create backups and store them in Object Storage in a separate region.
For TLS, use certificates for load balancers and use autorotation. Enable WAF on every load balancer that serves HTTPS content. Enable Oracle-managed rules and tune for false positives. Limit traffic from countries that you don't do business with through geo-IP access rules. Use threat intelligence in WAF to block Tor nodes.
Enable Netflow logging on every VCN. Monitor DNS logging for cryptomining activity or command and control (C&C) server activity.
Opinionated patterns with recommended technologies choices.
Web applications typically contain a front end which is what users see, and a back end which has the business logic. In response to a user or API request, a web application interacts with the API or with data stored in a file system, object storage, block storage, or database. The application must support different clients, such as browsers and mobile devices, and interact with other systems and apps by using APIs.
Messaging solutions connect application components—including existing on-premises systems—to cloud solutions. This can enable data transfer as part of a well-defined distributed processing pipeline, or for publication of messages to multiple independent downstream systems that evolve independently.
In the cloud, an event is any significant occurrence or change in a system. The core tenets of an event-driven architecture are capture, communicate, process, and persist events. When building an event-driven application on Oracle Cloud Infrastructure (OCI), you can subscribe to changes in your cloud resources and to events generated by your application. This enables you to respond to them in near real-time. Most modern apps built with microservices rely on an event-driven architecture.
Big data is a set of capabilities and patterns that enables you to manage, collect, store, catalog, prepare, process, and analyze all data types (unstructured, semi-structured, and structured)—whether they come from sources such as databases, videos, forms, documents, log files, web pages, or images. Oracle's big data capabilities span various services and tools so that you can begin your big data journey based on your skills and preferences.
Data scientists and ML engineers don’t want to spend time provisioning, upgrading, patching, and securing infrastructure. They want to build, train, deploy, and monitor models that impact the business. A machine-learning platform should be fully managed and allow them to perform all these steps in the model development lifecycle.
Oracle Fusion Cloud, the enterprise software as a service (SaaS) offering from Oracle, spans solutions for areas such as HCM, ERP, SCM, and CX. It provides extensive functionality, but sometimes organizations want to create customized UI and business processes that extend that functionality. These extension apps integrate with information from Oracle Fusion Cloud, use the same security layer, and often “mash up” data from other systems, delivering a user experience that seamlessly integrates with Oracle Cloud Apps.
Low-code platforms are well suited for building opportunistic applications in collaboration with business stakeholders; building data reporting and analysis apps; extending SaaS apps; and modernizing legacy applications. Every line of code has a cost associated with it—to author it, maintain it, debug it, upgrade it, and secure it. Oracle Application Express (APEX) helps developers avoid these costs by providing high-level components and common design patterns through an intuitive and graphical development experience.
Data-centric applications are core to modern enterprises, which routinely collect vast amounts and varieties of operational data from business systems and devices, running billions of transactions per day. Data integrity and data consistency across all data is key to the business, and databases have traditionally simplified these data-centric operations.
A list of recommended technologies for modern applications validated using feedback gathered from Oracle customers.
Oracle recommends using Java as your development language. Use Helidon or Micronaut framework to benefit from low-cost access to common cross-cutting requirements like tracing integration, logging, application scaffolding, and GraalVM to run applications faster and scale better with reduced CPU and memory requirements. GraalVM Enterprise Edition’s optimizing compiler accelerates application performance by up to 55% without any code changes.
Oracle Cloud Infrastructure (OCI) DevOps service enables continuous development (CD) automation, deployment history, conditional deployment, and rollbacks. The fully-managed terraform-based Oracle Cloud Infrastructure (OCI) Resource Manager helps you automate infrastructure creation at scale. For version control of artifacts, use the OCI Artifact Registry.
OCI API Gateway helps validate, rate-limit, and cache incoming API requests. It serves as a common point of policy enforcement and shields consumers from backend implementations. Use the OCI Load Balancing service to provide automated traffic distribution from one entry point to multiple servers reachable from your virtual cloud network (VCN). For container orchestration, the Oracle Container Engine for Kubernetes (OKE) provides industry-leading cluster provisioning times, and predictable and consistent performance of Gen-2 infrastructure. It supports rich compute shapes—HPC, GPU, ARM, Flex, bare metal, and VM—to support a variety of applications. Use OCI Container Registry (OCIR) to store and share container images and enable the OCI Vulnerability Scanning Service for container image security. For code that runs for short durations, Oracle Cloud Functions provides a serverless platform that lets developers create, run, and scale applications without managing any infrastructure.
Oracle Autonomous Database is highly recommended for storing application state and data. It provides full consistency and atomicity, consistency, isolation, and durability (ACID) transaction guarantees across all data types. Use Oracle Data Guard for high availability (HA) and disaster recovery (DR). Use OCI Cloud Storage services for block, file, or object storage across availability and fault domains.
Oracle recommends using Oracle Web Application Firewall (WAF) to limit traffic from unknown locations, nodes, and virtual cloud network (VCN) security groups to enforce the minimum reachability principle and to provide endpoint isolation. The Oracle Security Zone service enables compartments creation for infrastructure resources that are secure by default, as part of a preventative mechanism to secure applications. Choose OCI Identity and Access Management (IAM) for strong authentication and security policies for access control. Use Oracle Cloud Guard to monitor for misconfigurations and anomalous activity.
OCI Monitoring service provides metrics and alarms to monitor resources both actively and passively. Log Analytics gives you deep analytics capabilities into logs that span application and infrastructure data. Choose APM for deep visibility into the performance of your application. For Java applications, use Java Management Service, which enables you to monitor and manage your Java runtimes using telemetry data from the Java Virtual Machine (JVM).