Get startedGet started for free

Best practices for cloud application development (1)

1. Best practices for cloud application development (1)

SPEAKER: Welcome to Developing Applications with Google Cloud-- Foundations. Module 1-- Best Practices for Cloud Application Development. Before we discuss the details of Google Cloud application development, we look at some best practices for application development in the cloud. Applications that run in the cloud must be built to handle global reach. Your application should be responsive and accessible to users across the world. Scalability and high availability-- your application should be able to handle high traffic volumes reliably. The application architecture should use the capabilities of the underlying cloud platform to scale elastically in response to changes in load. Security-- your application and the underlying infrastructure should implement security best practices. Depending on the use case, you might be required to isolate your user data in a specific region for security and compliance reasons. Here are some best practices for managing your application code and environment. First, store your code in a code repository in a version control system such as Git. Using a code repository will enable you to track changes to your source code and set up systems for continuous integration and delivery. Second, do not store external dependencies such as JAR files or external packages in your code repository. Instead, depending on your application platform, explicitly declare your dependencies with their versions, and install them by using a dependency manager. For example, in a Node.js application, you can declare your application dependencies in a package.json file and later install them by using the npm install command. Third, separate your configuration settings from your code. Do not store configuration settings as constants in your source code. Instead, specify configuration settings as environment variables. Passing configuration by using environment variables lets you modify settings between development, test, and production environments, which ensures that the tested code is used in production. Instead of implementing a monolithic application, consider implementing or refactoring your application as a set of microservices. Most applications are changed significantly over time. In a monolithic application, the code base might become bloated. It can be difficult to determine all code that needs to change when implementing a new feature. Packages or components of the application can have tangled dependencies. The entire application must be deployed and tested, even if a change is only made to a small part of the code base. Monolithic applications increase the effort and risk when feature changes and bug fixes are done. Microservices let you restructure your application components in relation to your business boundaries. Refactoring a monolithic application into microservices may require significant time and effort. But the benefits gained can be worth the cost. The code base for each microservice is modular. It's easy to determine where the code needs to be changed. Each service can be updated, tested, and deployed independently without requiring its customers to change simultaneously. Each service can be scaled independently, depending on the load. Ensure that you evaluate the costs and benefits of optimizing and converting a monolithic application into one that uses a microservices architecture. Remote operations can have unpredictable response times and can make your applications seem slow. Keep the operations that happen in the user thread at a minimum. Perform backend operations asynchronously. Use event-driven processing where possible. For example, if your application processes uploaded images, you can use a Cloud Storage bucket to store the uploaded images. You can then implement a function or service in Cloud Run that is triggered whenever a new image is uploaded. The function processes the image and uploads the results to a different cloud storage location. Design application components so that they are loosely coupled at runtime. Tightly coupled components can make an application less resilient to failures, spikes in traffic, and changes to services. An event or message queue can be used to implement loose coupling, perform asynchronous processing, and buffer requests if traffic spikes. You can use an Eventarc trigger as an event queue or a Pub/Sub topic as a message queue. The order and inventory services are loosely cabled, which allows them to operate independently. In the context of HTTP API payloads, customers of HTTP APIs should bind loosely with the publishers of the API. In the example, the email service retrieves information about each customer from the customer service. The customer service returns the name, age, and email address of the customer in its payload. To send an email, the email service should only reference the name and email fields in the payload. It should not attempt to bind with all fields in the payload. This method of loosely binding fields allows the publisher to evolve the API and add fields to the payload in a backward-compatible manner. Implement application components so that they do not store state internally or share state. Accessing a shared state is a common bottleneck for scalability. Design each application component so that it focuses on compute tasks only. This approach allows you to use a worker pattern to add or remove additional instances of the component for scalability. Application components should start up quickly to enable efficient scaling and then shut down gracefully when they receive a termination signal. For example, if traffic to your application can vary significantly, you can use Cloud Run for your application and scale capacity based on traffic. The Cloud Run services process the incoming requests but don't store or share state. So they can be shut down easily when traffic is reduced. Data should be persisted in a separate database, like Firestore. When accessing services and resources in a distributed system, applications need to be resilient to temporary and long-lasting errors. Resources can sometimes become unavailable due to transient network errors. In this case, applications should implement retry logic with exponential backoff and fail gracefully if the errors persist. Exponential backoff helps ensure that applications don't make the problem worse by overloading the backend or network. The cloud client libraries retry failed requests automatically. When services are down with long-lasting errors, the application should not generate traffic or waste CPU cycles attempting to retry the request. In this case, applications should implement a circuit breaker and handle the failure gracefully. For errors that are propagated back to the user, consider degrading the application gracefully instead of explicitly displaying the error message. For example, if the recommendation engine is down, consider hiding the recommendation section instead of displaying error messages every time the page is displayed.

2. Let's practice!

Create Your Free Account

or

By continuing, you accept our Terms of Use, our Privacy Policy and that your data is stored in the USA.