<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Oleksandr Zvieriev</title> <link>https://world.optimizely.com/blogs/oleksandr-zvieriev/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>SNAT - Azure App Service socket exhaustion</title>            <link>https://world.optimizely.com/blogs/oleksandr-zvieriev/dates/2024/5/snat---azure-app-service-socket-exhaustion/</link>            <description>&lt;p&gt;&lt;strong&gt;Did you know that using &lt;code&gt;HttpClient&lt;/code&gt; within a &lt;code&gt;using&lt;/code&gt; statement can cause SNAT (Source Network Address Translation) port exhaustion?&lt;/strong&gt; This can lead to serious performance issues in your application.&lt;/p&gt;
&lt;h3&gt;What happens when SNAT ports are exhausted?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Slow or hanging connections&lt;/strong&gt; to remote endpoints&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Socket exceptions&lt;/strong&gt; due to connection timeouts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This issue is hard to replicate in a local environment, but it can severely impact production systems, causing widespread disruptions.&lt;/p&gt;
&lt;h3&gt;Why is this important?&lt;/h3&gt;
&lt;p&gt;If your application interacts with multiple third-party APIs, a misconfigured &lt;code&gt;HttpClient&lt;/code&gt; can slow down or cause timeouts across all your HTTP requests, even those that are unrelated.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;I&#39;ve seen many different ways to use &lt;code&gt;HttpClient&lt;/code&gt; in a wrong way. Few examples:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public async Task&amp;lt;HttpResponseMessage&amp;gt; Get(string? requestUri)
{
    return await new HttpClient().GetAsync(requestUri);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In C#, the &lt;code&gt;using&lt;/code&gt; statement is typically used to ensure that disposable objects, like &lt;code&gt;HttpClient&lt;/code&gt;, are properly disposed of once the block is exited.&lt;/p&gt;
&lt;p&gt;However, in the case of &lt;code&gt;HttpClient&lt;/code&gt;, it&amp;rsquo;s best to &lt;strong&gt;avoid&lt;/strong&gt; this pattern. While &lt;code&gt;HttpClient&lt;/code&gt; does implement the &lt;code&gt;IDisposable&lt;/code&gt; interface, it is designed to be a &lt;strong&gt;shared&lt;/strong&gt; object, meaning that it should not be frequently disposed of and recreated.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public async Task&amp;lt;HttpResponseMessage&amp;gt; Get(string? requestUri)
{
    using (var httpClient = new HttpClient())
        return await httpClient.GetAsync(requestUri);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Scoped)]
public class MyService : IMyService
{
    private readonly HttpClient _httpClient = new HttpClient();

    public async Task&amp;lt;HttpResponseMessage&amp;gt; Get(string? requestUri)
    {
        return await _httpClient.GetAsync(requestUri);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Instead of creating a new instance of HttpClient for each execution you should share a single instance of HttpClient for the entire lifetime of the application.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here i&#39;ll show a better way to do so:&lt;/p&gt;
&lt;p&gt;[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)] will help you to have a singleton for IMyService instance&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
    private readonly HttpClient _httpClient = new HttpClient();

    public async Task&amp;lt;HttpResponseMessage&amp;gt; Get(string? requestUri)
    {
        return await _httpClient.GetAsync(requestUri);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;In .NET Core, it&#39;s recommended to create a reusable client using an injected&lt;/strong&gt; &lt;code&gt;IHttpClientFactory&lt;/code&gt; &lt;strong&gt;object.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now i&#39;ll show the best way to use &lt;code&gt;IHttpClientFactory&lt;/code&gt; with services:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;// register specific client in StartUp.cs
services.AddHttpClient(&quot;MyClient&quot;, (provider, client) =&amp;gt; {
    client.BaseAddress = new Uri(&quot;YOU URL&quot;);
    client.DefaultRequestHeaders.Add(&quot;x-api-key&quot;, &quot;YOUR API KEY&quot;);
 });&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
    private readonly IHttpClientFactory _httpClientFactory;

    public OrderHistorySyncService(IHttpClientFactory httpClientFactory)
    {
       _httpClientFactory = httpClientFactory;
    }

    public async Task&amp;lt;HttpResponseMessage&amp;gt; Get(string? requestUri)
    {
        return await _httpClientFactory.CreateClient(&quot;MyClient&quot;).GetAsync(requestUri);
    }
}&lt;/code&gt;&lt;/pre&gt;</description>            <guid>https://world.optimizely.com/blogs/oleksandr-zvieriev/dates/2024/5/snat---azure-app-service-socket-exhaustion/</guid>            <pubDate>Mon, 09 Sep 2024 17:56:55 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>