Skip to content

Commit 37faa5c

Browse files
committed
add hsts and other fix-up
1 parent 677dccb commit 37faa5c

File tree

5 files changed

+61
-52
lines changed

5 files changed

+61
-52
lines changed

articles/azure-functions/functions-best-practices.md

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,16 @@ The following are best practices in how you build and architect your serverless
2525

2626
Large, long-running functions can cause unexpected timeout issues. To learn more about the timeouts for a given hosting plan, see [function app timeout duration](functions-scale.md#timeout).
2727

28-
A function can become large due to many Node.js dependencies. Importing dependencies can also cause increased load times that result in unexpected timeouts. Dependencies are loaded both explicitly and implicitly. A single module loaded by your code may load its own additional modules.
28+
A function can become large because of many Node.js dependencies. Importing dependencies can also cause increased load times that result in unexpected timeouts. Dependencies are loaded both explicitly and implicitly. A single module loaded by your code may load its own additional modules.
2929

30-
Whenever possible, refactor large functions into smaller function sets that work together and return responses fast. For example, a webhook or HTTP trigger function might require an acknowledgment response within a certain time limit; it is common for webhooks to require an immediate response. You can pass the HTTP trigger payload into a queue
31-
to be processed by a queue trigger function. This approach allows you to defer the actual work and return an immediate response.
30+
Whenever possible, refactor large functions into smaller function sets that work together and return responses fast. For example, a webhook or HTTP trigger function might require an acknowledgment response within a certain time limit; it's common for webhooks to require an immediate response. You can pass the HTTP trigger payload into a queue to be processed by a queue trigger function. This approach lets you defer the actual work and return an immediate response.
3231

3332

3433
### Cross function communication
3534

3635
[Durable Functions](durable/durable-functions-overview.md) and [Azure Logic Apps](../logic-apps/logic-apps-overview.md) are built to manage state transitions and communication between multiple functions.
3736

38-
If not using Durable Functions or Logic Apps to integrate with multiple functions, it is generally a best practice to use storage queues for cross function communication. The main reason is storage queues are cheaper and much easier to provision.
37+
If not using Durable Functions or Logic Apps to integrate with multiple functions, it's best to use storage queues for cross-function communication. The main reason is that storage queues are cheaper and much easier to provision than other storage options.
3938

4039
Individual messages in a storage queue are limited in size to 64 KB. If you need to pass larger messages between functions, an Azure Service Bus queue could be used to support message sizes up to 256 KB in the Standard tier, and up to 1 MB in the Premium tier.
4140

@@ -48,45 +47,41 @@ Event hubs are useful to support high volume communications.
4847

4948
Functions should be stateless and idempotent if possible. Associate any required state information with your data. For example, an order being processed would likely have an associated `state` member. A function could process an order based on that state while the function itself remains stateless.
5049

51-
Idempotent functions are especially recommended with timer triggers. For example, if you have something that absolutely must run once a day, write it so it can run any time during the day with the same results. The function can exit when there is no work for a particular day. Also if a previous run failed to complete, the next run should pick up where it left off.
50+
Idempotent functions are especially recommended with timer triggers. For example, if you have something that absolutely must run once a day, write it so it can run anytime during the day with the same results. The function can exit when there's no work for a particular day. Also if a previous run failed to complete, the next run should pick up where it left off.
5251

5352

5453
### Write defensive functions
5554

5655
Assume your function could encounter an exception at any time. Design your functions with the ability to continue from a previous fail point during the next execution. Consider a scenario that requires the following actions:
5756

58-
1. Query for 10,000 rows in a db.
57+
1. Query for 10,000 rows in a database.
5958
2. Create a queue message for each of those rows to process further down the line.
6059

6160
Depending on how complex your system is, you may have: involved downstream services behaving badly, networking outages, or quota limits reached, etc. All of these can affect your function at any time. You need to design your functions to be prepared for it.
6261

63-
How does your code react if a failure occurs after inserting 5,000 of those items into a queue for processing? Track items in a set that you’ve completed. Otherwise, you might insert them again next time. This can have a serious impact on your work flow.
62+
How does your code react if a failure occurs after inserting 5,000 of those items into a queue for processing? Track items in a set that you’ve completed. Otherwise, you might insert them again next time. This double-insertion can have a serious impact on your work flow, so [make your functions idempotent](functions-idempotent.md).
6463

6564
If a queue item was already processed, allow your function to be a no-op.
6665

6766
Take advantage of defensive measures already provided for components you use in the Azure Functions platform. For example, see **Handling poison queue messages** in the documentation for [Azure Storage Queue triggers and bindings](functions-bindings-storage-queue.md#trigger---poison-messages).
6867

6968
## Scalability best practices
7069

71-
There are a number of factors which impact how instances of your function app scale. The details are provided in the documentation for [function scaling](functions-scale.md). The following are some best practices to ensure optimal scalability of a function app.
70+
There are a number of factors that impact how instances of your function app scale. The details are provided in the documentation for [function scaling](functions-scale.md). The following are some best practices to ensure optimal scalability of a function app.
7271

7372
### Share and manage connections
7473

75-
Re-use connections to external resources whenever possible. See [how to manage connections in Azure Functions](./manage-connections.md).
74+
Reuse connections to external resources whenever possible. See [how to manage connections in Azure Functions](./manage-connections.md).
7675

7776
### Don't mix test and production code in the same function app
7877

7978
Functions within a function app share resources. For example, memory is shared. If you're using a function app in production, don't add test-related functions and resources to it. It can cause unexpected overhead during production code execution.
8079

8180
Be careful what you load in your production function apps. Memory is averaged across each function in the app.
8281

83-
If you have a shared assembly referenced in multiple .NET functions, put it in a common shared folder. Reference the assembly with a statement similar to the following example if using C# Scripts (.csx):
82+
If you have a shared assembly referenced in multiple .NET functions, put it in a common shared folder. Otherwise, you could accidentally deploy multiple versions of the same binary that behave differently between functions.
8483

85-
#r "..\Shared\MyAssembly.dll".
86-
87-
Otherwise, it is easy to accidentally deploy multiple test versions of the same binary that behave differently between functions.
88-
89-
Don't use verbose logging in production code. It has a negative performance impact.
84+
Don't use verbose logging in production code, which has a negative performance impact.
9085

9186
### Use async code but avoid blocking calls
9287

@@ -98,19 +93,15 @@ Asynchronous programming is a recommended best practice. However, always avoid r
9893

9994
Some triggers like Event Hub enable receiving a batch of messages on a single invocation. Batching messages has much better performance. You can configure the max batch size in the `host.json` file as detailed in the [host.json reference documentation](functions-host-json.md)
10095

101-
For C# functions you can change the type to a strongly-typed array. For example, instead of `EventData sensorEvent` the method signature could be `EventData[] sensorEvent`. For other languages you'll need to explicitly set the cardinality property in your `function.json` to `many` in order to enable batching [as shown here](https://github.com/Azure/azure-webjobs-sdk-templates/blob/df94e19484fea88fc2c68d9f032c9d18d860d5b5/Functions.Templates/Templates/EventHubTrigger-JavaScript/function.json#L10).
96+
For C# functions, you can change the type to a strongly-typed array. For example, instead of `EventData sensorEvent` the method signature could be `EventData[] sensorEvent`. For other languages, you'll need to explicitly set the cardinality property in your `function.json` to `many` in order to enable batching [as shown here](https://github.com/Azure/azure-webjobs-sdk-templates/blob/df94e19484fea88fc2c68d9f032c9d18d860d5b5/Functions.Templates/Templates/EventHubTrigger-JavaScript/function.json#L10).
10297

10398
### Configure host behaviors to better handle concurrency
10499

105-
The `host.json` file in the function app allows for configuration of host runtime and trigger behaviors. In addition to batching behaviors, you can manage concurrency for a number of triggers. Often adjusting the values in these options can help each instance scale appropriately for the demands of the invoked functions.
106-
107-
Settings in the hosts file apply across all functions within the app, within a *single instance* of the function. For example, if you had a function app with 2 HTTP functions and concurrent requests set to 25, a request to either HTTP trigger would count towards the shared 25 concurrent requests. If that function app scaled to 10 instances, the 2 functions would effectively allow 250 concurrent requests (10 instances * 25 concurrent requests per instance).
108-
109-
**HTTP concurrency host options**
100+
The `host.json` file in the function app allows for configuration of host runtime and trigger behaviors. In addition to batching behaviors, you can manage concurrency for a number of triggers. Often adjusting the values in these options can help each instance scale appropriately for the demands of the invoked functions.
110101

111-
[!INCLUDE [functions-host-json-http](../../includes/functions-host-json-http.md)]
102+
Settings in the host.json file apply across all functions within the app, within a *single instance* of the function. For example, if you had a function app with two HTTP functions and [`maxConcurrentRequests`](functions-bindings-http-webhook.md#trigger---hostjson-settings) requests set to 25, a request to either HTTP trigger would count towards the shared 25 concurrent requests. When that function app is scaled to 10 instances, the two functions effectively allow 250 concurrent requests (10 instances * 25 concurrent requests per instance).
112103

113-
Other host configuration options can be found [in the host configuration document](functions-host-json.md).
104+
Other host configuration options are found in the [host.json configuration article](functions-host-json.md).
114105

115106
## Next steps
116107

articles/azure-functions/functions-bindings-http-webhook.md

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,6 @@ The HTTP request length is limited to 100 MB (104,857,600 bytes), and the URL le
781781

782782
If a function that uses the HTTP trigger doesn't complete within about 2.5 minutes, the gateway will time out and return an HTTP 502 error. The function will continue running but will be unable to return an HTTP response. For long-running functions, we recommend that you follow async patterns and return a location where you can ping the status of the request. For information about how long a function can run, see [Scale and hosting - Consumption plan](functions-scale.md#timeout).
783783

784-
## Trigger - host.json properties
785-
786-
The [host.json](functions-host-json.md) file contains settings that control HTTP trigger behavior.
787-
788-
[!INCLUDE [functions-host-json-http](../../includes/functions-host-json-http.md)]
789-
790784
## Output
791785

792786
Use the HTTP output binding to respond to the HTTP request sender. This binding requires an HTTP trigger and allows you to customize the response associated with the trigger's request. If an HTTP output binding is not provided, an HTTP trigger returns HTTP 200 OK with an empty body in Functions 1.x, or HTTP 204 No Content with an empty body in Functions 2.x.
@@ -799,14 +793,51 @@ The following table explains the binding configuration properties that you set i
799793
|---------|---------|
800794
| **type** |Must be set to `http`. |
801795
| **direction** | Must be set to `out`. |
802-
|**name** | The variable name used in function code for the response, or `$return` to use the return value. |
796+
| **name** | The variable name used in function code for the response, or `$return` to use the return value. |
803797

804798
## Output - usage
805799

806800
To send an HTTP response, use the language-standard response patterns. In C# or C# script, make the function return type `IActionResult` or `Task<IActionResult>`. In C#, a return value attribute isn't required.
807801

808802
For example responses, see the [trigger example](#trigger---example).
809803

804+
## host.json settings
805+
806+
This section describes the global configuration settings available for this binding in version 2.x. The example host.json file below contains only the version 2.x settings for this binding. For more information about global configuration settings in version 2.x, see [host.json reference for Azure Functions version 2.x](functions-host-json.md).
807+
808+
> [!NOTE]
809+
> For a reference of host.json in Functions 1.x, see [host.json reference for Azure Functions 1.x](functions-host-json-v1.md).
810+
811+
```json
812+
{
813+
"extensions": {
814+
"http": {
815+
"routePrefix": "api",
816+
"maxOutstandingRequests": 200,
817+
"maxConcurrentRequests": 100,
818+
"dynamicThrottlesEnabled": true,
819+
"hsts": {
820+
"isEnabled": true,
821+
"maxAge": "10"
822+
},
823+
"customHeaders": {
824+
"X-Content-Type-Options": "nosniff"
825+
}
826+
}
827+
}
828+
}
829+
```
830+
831+
|Property |Default | Description |
832+
|---------|---------|---------|
833+
| customHeaders|none|Allows you to set custom headers in the HTTP response. The previous example adds the `X-Content-Type-Options` header to the response. |
834+
|dynamicThrottlesEnabled|true<sup>\*</sup>|When enabled, this setting causes the request processing pipeline to periodically check system performance counters like connections/threads/processes/memory/cpu/etc. and if any of those counters are over a built-in high threshold (80%), requests will be rejected with a 429 "Too Busy" response until the counter(s) return to normal levels. <sup>\*</sup>The default in a consumption plan is `true`. The default in a dedicated plan is `false`.|
835+
|hsts|not enabled|When `isEnabled` is set to `true`, enables the [HTTP Strict Transport Security (HSTS) behavior of .NET Core](/aspnet/core/security/enforcing-ssl?view=aspnetcore-3.0&tabs=visual-studio#hsts), as defined in the [`HstsOptions` class](/dotnet/api/microsoft.aspnetcore.httpspolicy.hstsoptions?view=aspnetcore-3.0). The above example also sets the [`maxAge`](/dotnet/api/microsoft.aspnetcore.httpspolicy.hstsoptions.maxage?view=aspnetcore-3.0#Microsoft_AspNetCore_HttpsPolicy_HstsOptions_MaxAge) property to 10 days. |
836+
|maxConcurrentRequests|100<sup>\*</sup>|The maximum number of http functions that are executed in parallel. This allows you to control concurrency, which can help manage resource utilization. For example, you might have an http function that uses a lot of system resources (memory/cpu/sockets) such that it causes issues when concurrency is too high. Or you might have a function that makes outbound requests to a third party service, and those calls need to be rate limited. In these cases, applying a throttle here can help. <sup>*</sup>The default for a consumption plan is 100. The default for a dedicated plan is unbounded (`-1`).|
837+
|maxOutstandingRequests|200<sup>\*</sup>|The maximum number of outstanding requests that are held at any given time. This limit includes requests that are queued but have not started executing, as well as any in progress executions. Any incoming requests over this limit are rejected with a 429 "Too Busy" response. That allows callers to employ time-based retry strategies, and also helps you to control maximum request latencies. This only controls queuing that occurs within the script host execution path. Other queues such as the ASP.NET request queue will still be in effect and unaffected by this setting. <sup>\*</sup>\The default for a consumption plan is 200. The default for a dedicated plan is unbounded (`-1`).|
838+
|routePrefix|api|The route prefix that applies to all routes. Use an empty string to remove the default prefix. |
839+
840+
810841
## Next steps
811842

812843
[Learn more about Azure functions triggers and bindings](functions-triggers-bindings.md)

articles/azure-functions/functions-host-json-v1.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,15 @@ Configuration settings for [http triggers and bindings](functions-bindings-http-
210210
}
211211
```
212212

213-
[!INCLUDE [functions-host-json-http](../../includes/functions-host-json-http.md)]
213+
|Property |Default | Description |
214+
|---------|---------|---------|
215+
|dynamicThrottlesEnabled|false|When enabled, this setting causes the request processing pipeline to periodically check system performance counters like connections/threads/processes/memory/cpu/etc. and if any of those counters are over a built-in high threshold (80%), requests will be rejected with a 429 "Too Busy" response until the counter(s) return to normal levels.|
216+
|maxConcurrentRequests|unbounded (`-1`)|The maximum number of http functions that will be executed in parallel. This allows you to control concurrency, which can help manage resource utilization. For example, you might have an http function that uses a lot of system resources (memory/cpu/sockets) such that it causes issues when concurrency is too high. Or you might have a function that makes outbound requests to a third party service, and those calls need to be rate limited. In these cases, applying a throttle here can help.|
217+
|maxOutstandingRequests|unbounded (`-1`)|The maximum number of outstanding requests that are held at any given time. This limit includes requests that are queued but have not started executing, as well as any in progress executions. Any incoming requests over this limit are rejected with a 429 "Too Busy" response. That allows callers to employ time-based retry strategies, and also helps you to control maximum request latencies. This only controls queuing that occurs within the script host execution path. Other queues such as the ASP.NET request queue will still be in effect and unaffected by this setting.|
218+
|routePrefix|api|The route prefix that applies to all routes. Use an empty string to remove the default prefix. |
214219

215220
## id
216221

217-
*Version 1.x only.*
218-
219222
The unique ID for a job host. Can be a lower case GUID with dashes removed. Required when running locally. When running in Azure, we recommend that you not set an ID value. An ID is generated automatically in Azure when `id` is omitted.
220223

221224
If you share a Storage account across multiple function apps, make sure that each function app has a different `id`. You can omit the `id` property or manually set each function app's `id` to a different value. The timer trigger uses a storage lock to ensure that there will be only one timer instance when a function app scales out to multiple instances. If two function apps share the same `id` and each uses a timer trigger, only one timer will run.

0 commit comments

Comments
 (0)