微服务无法连接到数据库

时间:2019-07-30 01:37:45

标签: asp.net sql-server docker docker-compose

我正在尝试与docker学习微服务,对此有很多麻烦。
docker-compose:

version: "3.2"

networks:
   frontend:
   backend:

services:
   catalog:
      build:
         context: .\src\Services\ProductCatalogApi
         dockerfile: Dockerfile
      image: microservices-v1.0.0
      environment:
         - DatabaseServer=mssqlserver
         - DatabaseName=CatalogDb
         - DatabaseUser=sa
         - DatabaseUserPassword=ProductApi(!)
      container_name: catalogapi
      ports:
         - "5000:80"
      networks:
         - backend
         - frontend
      depends_on:
         - mssqlserver

   mssqlserver:
      image: "microsoft/mssql-server-linux:latest"
      ports:
         - "2200:1433"
      container_name: mssqlcontainer
      environment:
         - ACCEPT_EULA=Y
         - SA_PASSWORD=ProductApi(!)
      networks:
         - backend

我的API中的Dockerfile:

FROM microsoft/aspnetcore-build:2.0.0 AS build

WORKDIR /code

COPY . .

RUN dotnet restore

RUN dotnet publish --output /out/ --configuration Release 

FROM microsoft/aspnetcore:2.0.0

COPY --from=build /out /app/

WORKDIR  /app

ENTRYPOINT ["dotnet","ProductCatalogApi.dll"]

这里是我的问题:

  1. 我无权访问我的API。与IIServer一起运行时,我无法与localhost:5000 / swagger连接。

这是我的Program.cs和Startup.cs:

    var host = CreateWebHostBuilder(args).Build();

    using(var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<CatalogContext>();
            //context.Database.Migrate();
            CatalogSeed.SeedAsync(context).Wait();
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            //var logger = services.GetRequiredService<ILogger>();
            //logger.LogError(ex, "An error occured while seeding database");
        }
    }
    host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ProductCatalogApi.Data;
using Swashbuckle.AspNetCore.Swagger;

namespace ProductCatalogApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CatalogSettings>(Configuration);

            var server = Configuration["DatabaseServer"];
            //var server = Environment.GetEnvironmentVariable("DatabaseServer");
            var database = Configuration["DatabaseName"];
            //var database = Environment.GetEnvironmentVariable("DatabaseName");
            var user = Configuration["DatabaseUser"];
            //var user = Environment.GetEnvironmentVariable("DatabaseUser");
            var password = Configuration["DatabaseUserPassword"];
            //var password = Environment.GetEnvironmentVariable("DatabaseUserPassword");
            var connectionString = String.Format("Server={0};Database={1};User={2};Password={3};", server, database, user, password);

            services.AddDbContext<CatalogContext>(options => options.UseSqlServer(connectionString));
            services.AddMvc();

            services.AddSwaggerGen(options =>
            {
                options.DescribeAllEnumsAsStrings();
                options.SwaggerDoc("v1", new Info
                {
                    Title = "microservice - product",
                    Version = "v1",
                    Description = "Description",
                    TermsOfService = "Tersm of Service"
                });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseSwagger()
            .UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint($"/swagger/v1/swagger.json", "ProductCatalogAPI V1");
            });

            app.UseMvc();
        }
    }
}

我可以通过SSMS连接到数据库,因此凭据很好。 当未注释掉Migrate时,它将填充我的数据库,因此我的程序可以以某种方式连接到数据库。 2)尝试运行我的服务时,出现此错误:

  

失败:Microsoft.EntityFrameworkCore.Query [10100]
      catalogapi |迭代时数据库中发生异常
   上下文类型'ProductCatalogApi.Data.CatalogContext'的查询结果。
      catalogapi | System.Data.SqlClient.SqlException(0x80131904):无法
   登录所请求的打开数据库“ CatalogDb”。登录失败。
      catalogapi |用户“ sa”的登录失败。

它并不总是抛出该异常,有时它只是种子db(通过mssms检查),但是api仍然不可访问。 但是容器正在运行。

这里是放置整个项目的github(甚至没有一项完整的服务),因此您可以在这里查看:https://github.com/AGranosik/microservices-udemy-v2

1 个答案:

答案 0 :(得分:1)

Program.cs中的行是一种解决方案:

context.Database.Migrate();

如果不存在,这是初始化正确的数据库。