【问题标题】:How to solve this:Web process failed to bind to $PORT within 60 seconds of launch heroku .NET Core 3.1 Console Application?如何解决:Web 进程在启动 heroku .NET Core 3.1 控制台应用程序后 60 秒内无法绑定到 $PORT?
【发布时间】:2021-02-23 15:32:26
【问题描述】:

2020-11-11T15:57:56.534313+00:00 heroku[web.1]:错误 R10(启动 timeout) -> Web 进程未能在 60 秒内绑定到 $PORT 启动 2020-11-11T15:57:56.552989+00:00 heroku[web.1]:停止 使用 SIGKILL 2020-11-11T15:57:56.622618+00:00 处理 heroku[web.1]:进程以状态 137 退出 2020-11-11T15:57:56.669934+00:00 heroku[web.1]:状态从 开始崩溃

在 heroku 我的 .NET Core 控制台应用程序上部署几分钟后,我收到此错误,如何解决?

有我的 Program.cs

internal class Program
    {
        private static async Task Main(string[] args)
        {
            var host = GetHost(args);
            await ConfigureVkAuth(host);
            host.Services.GetRequiredService<VkService>();
            host.Services.GetRequiredService<PostMessage>();
            host.Services.GetRequiredService<MyContext>();
            await host.RunAsync();
        }

        private static IHost GetHost(string[] args) =>
            new HostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureAppConfiguration(b => b.AddCommandLine(args))
                .ConfigureAppConfiguration((c, b) =>
                {
                    b.AddJsonFile("appsettings.json", true, true);
                })
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.AddConsole();
                })
                .ConfigureServices((context, services) =>
                {
                    ConfigureMain(context, services);

                    ConfigureBot(services);

                    ConfigureVK(services);

                    services.InstallServicesInAssembly();
                })
                .Build();

        private static void ConfigureMain(HostBuilderContext context, IServiceCollection services)
        {
            services.Configure<DataOptions>(opts =>
                context.Configuration.GetSection(nameof(DataOptions)).Bind(opts));
            services.Configure<BotOptions>(opts =>
                context.Configuration.GetSection(nameof(BotOptions)).Bind(opts));
            services.Configure<ApiAuthParams>(opts =>
            {
                context.Configuration.GetSection(nameof(VkApiAuthParams)).Bind(opts);
                opts.Settings = Settings.All;
            });
        }

        private static void ConfigureBot(IServiceCollection services)
        {
            services.AddHttpClient<ITelegramBotClient, TelegramBotClient>()
                .AddTransientHttpErrorPolicy(builder =>
                    builder.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(5d)));
            services.AddSingleton<ITelegramBotClient, TelegramBotClient>(provider =>
                new TelegramBotClient(provider.GetRequiredService<IOptions<BotOptions>>().Value.Token,
                    provider.GetRequiredService<IHttpClientFactory>().CreateClient(nameof(ITelegramBotClient))));
            services.TryAddTransient(s =>
                s.GetRequiredService<IHttpClientFactory>().CreateClient(string.Empty));
            services.AddTransient<PostPhoto>();
        }
        private static void ConfigureVK(IServiceCollection services)
        {
            services.AddSingleton<IVkApi, VkApi>(provider =>
                new VkApi(provider.GetRequiredService<ILogger<VkApi>>()));
            services.AddSingleton<VkService>();
            services.AddTransient<PostMessage>();
        }

        private static async Task ConfigureVkAuth(IHost host)
        {
            var vk = host.Services.GetRequiredService<IVkApi>();
            var credentials = host.Services.GetRequiredService<IOptions<ApiAuthParams>>().Value;
            await vk.AuthorizeAsync(credentials);
        }

【问题讨论】:

标签: heroku .net-core deployment console-application


【解决方案1】:

三个步骤帮助我解决了这个问题:

  1. 使用默认最小配置创建您的 startup.cs 文件:

代码示例:

public class Startup
{
    // startup with one main web page allows heroku to override listening port
    // otherwise heroku app goes down immediately

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "Default",
                pattern: "{controller=Home}/{action=Index}");
            endpoints.MapRazorPages();
        });
    }
}
  1. 创建默认控制器。它可以返回 200ok 响应。 (不确定 Heroku 是否需要它,尚未测试)

代码示例:

public class HomeController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            return Ok();
        }
    }
  1. 将您的 Startup 绑定到 webHostDefaults,并且不要忘记使用带有 PORT 环境变量的 UseKestrel:

示例代码:

...
private const string DefaultListenPort = "8080";

Host.CreateDefaultBuilder(args)
    .UseSerilog()
    .ConfigureWebHostDefaults(webBuilder =>
    {
         webBuilder.UseStartup<Startup>();
         webBuilder.UseKestrel(options =>
               options.ListenAnyIP(int.Parse(Environment.GetEnvironmentVariable("PORT") ??
                                                          DefaultListenPort)));
    })
    .ConfigureServices(...)

【讨论】:

  • 问题是如何使用控制台应用程序做到这一点,而不是使用 web api
猜你喜欢
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 2013-03-19
  • 2019-07-12
  • 2014-03-15
  • 2018-05-26
  • 2021-02-19
相关资源
最近更新 更多