Installation of our .Net desktop application on Azure is a recommended architecture, addressing concurrency issues. This thin-client model communicates to a web service that handles onward interaction with the database and any task results.
Our Azure installation includes:
- App Service – .Net6 Web Service that handles any client communication.
- App Service – .Net6 Task Service that handles any long-running server tasks (thereby freeing compute in the client facing web service)
- Service Bus – messaging system to queue/receive tasks and topic to synchronise any system cache between the two Services.
- Storage Account – allowing for system generated files to be stored and shared between components.
- SQL database – the golden source of all LemonEdge information.
As we deploy to the end-client cloud ecosystem, by default, private network settings and authentication options are open for subsequent configuration based on their controls.
The client application is only concerned with web service data flow (other components do not need external access), via a REST API (predominantly OData). The service subsequently performs CRUD operations against the database. If longer running tasks are involved, the details will be stored in the database and a message posted to the queue. The Task Service then picks up the task and starts processing. Depending on the task, result sets can then be saved to the storage account ready for the web service to feed to the client. Any operations requiring a refresh of pseudo-static data are synchronised across the services using a topic in the service bus.
Recommended Minimum Architecture
Web Service and Task Service Requirements
Core: 2 vCPU
Currently, this equates to Azure's Premium v2 Service Plan: P2v2.
We do our best to provide an accurate baseline and/or recommended system specification for running LemonEdge. What are considered acceptable performance levels are subjective. The performance of the application greatly depends on factors such as data volume, concurrent users, and other environment variables.
SQL Service Requirements
SQL Server 2019
Core: 2 vCPU
Storage: 1TB SSD
See our estimate (via Azure's Pricing Calculator) to run the above here.
There are many ways to deploy and host the application, even on Azure. Currently, we deploy .Net zipped stand-alone auto-scaling AppServices pointing to a SQL serverless instance, allowing everything to pause/sleep when not being used and spin up and increase compute during periods of high demand (each component can be scaled independently). There are many considerations surround architecture, functionality, performance, and cost:
- Serverless SQL enhances cost control by charging for compute usage, pausing when idle for a specified period. Although serverless SQL does not allow SQL CLR, additional reporting metrics (like IRR) are calculated in the LemonEdge service architecture, enabling its adoption. SQL Managed Instance and stand-alone SQL Server can utilise LemonEdge assemblies to calculate these metrics natively in queries. The choice depends on downstream reporting requirements, and by default we opt for the more cost-conscious option.
- Our current zipped installs give limited ability to update the software container. We are migrating to using Docker images as standard (deployed using “AppService for Containers”) to enable us to configure the container independently of the deployment pipeline (in your ecosystem). The components are OS agnostic and, where applicable, have Linux and Windows versions.
- Depending on the existing ecosystem, the system can be configured with different authentication mechanisms and security policies.
LemonEdge deployment is a two-step process: infrastructure, then code. Following the creation of a DevOps code repository, ARM templates offer infrastructure as code that automate the provision and connection of the components described above. After the infrastructure is in place, a build pipeline downloads the latest code as an artifact available for distribution. The associated release pipeline can then deploy the artifact across any environment at any time. In parallel, we host NuGet libraries of our extensions that can auto-update according to the deployed version offering a one-step database upgrade, in most circumstances. Replicating this environment as a DEV/UAT/PROD instance in the client ecosystem allows staged testing of any configuration or code augmentations made to the core platform and attached services. For code deployment, we are introducing a “latest” and “latest-stable” channel: latest being our build from the CICD pipeline including development features, and latest-stable being our last quarterly official release with any hot-fixes included. The choice between the two is a switch in the client DevOps code-build pipeline – these pipelines can be cloned if you want the latest in one environment for testing, but the latest-stable in UAT and PROD, for example.