Azure Service Bus & Azure Function Trigger & Nuget Downgrade

Azure Service Bus์™€ console app์œผ๋กœ ๋ฉ”์„ธ์ง€ ํ”„๋กœ์„ธ์‹ฑ์„ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์ด๋ฒˆ์— Azure Function Trigger๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณ€๊ฒฝํ•˜๋ฉด์„œ ๋А๋‚€ ๊ฒƒ์€ Azure Function์ด .NET 5๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ์š”.
๋•๋ถ„์— ์ œ๊ฐ€ ์‚ฌ์šฉํ•˜๋˜ ์†Œ์Šค์ฝ”๋“œ๋“ค๋„ C# 9.0 โ†’ C# 8.0์œผ๋กœ ๋‹ค ๊ณ ์น˜๊ณ โ€ฆ์‚ฌ์šฉํ•˜๋˜ Nuget Package๋„ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Microsoft.Extensions.Http, Microsoft.Extensions.DependencyInjection ๋“ฑ๋“ฑ์ด ์žˆ๋Š”๋ฐ์š”.

๊ถ๊ธˆํ•œ ๊ฒƒ์€ .NET 5๋ฅผ ์ข…์†์„ฑ์œผ๋กœ ๊ฐ€์ง€์ง€ ์•Š์€ Nuget Package ๋“ค๋„ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋˜๋Š” ํŒจํ‚ค์ง€๊ฐ€ System.ComponentModel.Annotations 5.0.0 ์ธ๋ฐ์š”โ€ฆ ์ €์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋งŒ๋‚˜์‹  ๋ถ„๋“ค์„ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ๋งŒ๋‚  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. System.ComponentModel.Annotatoins Version=5.0.0.0 (doesn't exist) ยท Issue #7221 ยท Azure/azure-functions-host ยท GitHub

์•„๋ฌด๋ž˜๋„ ์•„์ง ํ•ด๊ฒฐ์ด ๋˜์ง€ ์•Š์€ ๋“ฏ ํ•ฉ๋‹ˆ๋‹ค.
System.ComponentModel.Annotations 5.0.0 ์˜ ๋ฒ„์ „์„ 4.7๋กœ ๋‚ฎ์ถ”๋ ค๊ณ  ํ•˜๋ฉด Visual Studio 2019์—์„œ ์•„๋ž˜ ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ์š”.
image

์—ฌ๊ธฐ์„œ ์ง์ ‘ ์ฐธ์กฐํ•˜๋ผ๋Š” ๋ง์€ DLL ํ˜•ํƒœ๋กœ ํŒจํ‚ค์ง€๋ฅผ ๋ฐ›์•„์„œ ์ˆ˜๋™์œผ๋กœ ํ”„๋กœ์ ํŠธ์— ์—ฐ๊ฒฐํ•ด์ฃผ๋ผ๋Š” ๋ง์ผ๊นŒ์š”?

Azure Function ์‚ฌ์šฉ ๊ฒฝํ—˜ ์žˆ์œผ์‹  ๋ถ„๋“ค์˜ ์กฐ์–ธ์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

์ž๋‹ตํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ํžŒํŠธ๋ฅผ ์ฃผ์‹  ๋ถ„์ด .NET 5๋กœ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค ํ•˜์…”์„œ ๋ฌธ์„œ๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค.
์ด๊ฒŒ MSDN์„ ํ•œ๊ธ€๋กœ ๋ณด๋˜ ์Šต๊ด€์ด ์žˆ๋‹ค๋ณด๋‹ˆ ์ด๋Ÿฐ ๊ฑธ ์บ์น˜๋ฅผ ๋ชปํ•˜๋„ค์š”.

์ด ๋ฌธ์„œ์— ๋ณด๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด VS2019์—์„œ๋Š” .NET 5 Azure Function์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋‚˜์˜ต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์˜์–ด ๋ฌธ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

image

๊ทธ๋ฆฌ๊ณ  VS2019 16.10 ๋ฒ„์ „์€ ์ถœ์‹œ๋œ์ง€ 1๋‹ฌ์ด ์ง€๋‚˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹คโ€ฆ
์ €๋„ 4์›” ๋ง์— 16.9๋ฒ„์ „๊นŒ์ง€ ์“ฐ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์—…๋ฐ์ดํŠธ๋ฅผ ์ž์ฃผ ์•ˆํ–ˆ๋”๋‹ˆ ์ง€์› ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ์ด ์ ์—ˆ๋„ค์š”.

์•„๋ฌดํŠผ ์ด ๋ฌธ์„œ๋Œ€๋กœโ€ฆVS2019๋ฅผ 16.10.3 ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋‹ˆ ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ .NET 5๊ฐ€ Azure Function ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๊ฒฉ๋ฆฌ๋Š” ๋ฌด์Šจ ๋œป์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”.

image

.NET 5๋กœ Azure Function์„ ์ƒ์„ฑํ•˜๋ฉด ์ตœ์ดˆ ์งˆ๋ฌธ์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ Nuget ํŒจํ‚ค์ง€๋“ค์ด ๋ชจ๋‘ .NET 5๋กœ ๋œ ๊ฒƒ๋“ค์ด ์ž๋™์œผ๋กœ ์ฐธ์กฐ๊ฐ€ ๋˜์–ด ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

.NET Core 3.1๋กœ Azure Function ๊ฐœ๋ฐœํ•  ๋•Œ IoC ์ปจํ…Œ์ด๋„ˆ๋Š” Startup ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด์„œ ํ–ˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ, .NET 5๋กœ Azure Function ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” Program ํด๋ž˜์Šค๊ฐ€ ์žˆ์–ด์„œ ๊ทธ๋ƒฅ ์—ฌ๊ธฐ์— ์ž‘์„ฑํ•˜๋ฉด ๋  ๋“ฏ ํ•ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

.NET 5๋กœ Azure Service Bus Trigger๋ฅผ Azure Function์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

        static async Task Main()
        {
            IHost host = new HostBuilder()
                .ConfigureFunctionsWorkerDefaults()
                .ConfigureAppConfiguration((hostingContext, configuration) =>
                {
                    //configuration.Sources.Clear();

                    IHostEnvironment env = hostingContext.HostingEnvironment;
                    configuration.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
                    configuration.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true);

                    IConfigurationRoot configurationRoot = configuration.Build();
                    ShopeeSecretKeySettings shopeeSecretKeySettings = new();
                    configurationRoot.GetSection(nameof(ShopeeSecretKeySettings)).Bind(shopeeSecretKeySettings);
                })
                .ConfigureServices((context, services) =>
                {
                    services.Configure<ShopeeSecretKeySettings>(context.Configuration.GetSection(nameof(ShopeeSecretKeySettings)));

                    services.AddHttpClient();
                    services.AddHttpClient("RequestLimitHttpClient").ConfigurePrimaryHttpMessageHandler(() =>
                    {
                        return new HttpClientHandler
                        {
                            MaxConnectionsPerServer = MaxConnection,
                        };
                    });
                })
                .Build();

            await host.RunAsync();
        }

์œ„ ์†Œ์Šค์—์„œ ์ฃผ์„์ฒ˜๋ฆฌํ•œ configuration.Sources.Clear() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด local.settings.json์— ์ž‘์„ฑํ•œ ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.