上一篇我们基础服务初步搭建完毕,接下来我们整一下认证和网关。

搭建认证服务

认证服务的话,ABP CLI生成的所有模板都包括了一个AuthServer。我们直接生成模板然后微调一下就可以直接用了。

abp new FunShow -t app --tiered

使用命令创建模板后,我们可以找到一个AuthServer。把项目移动到Apps目录下,然后我们开始改造一下这个项目。
首先修改项目文件的引用配置
修改EFCore项目引用为AdministrationService.EntityFrameworkCore和IdentityService.EntityFrameworkCore,
然后添加Shared.Localization和Shared.Hosting.AspNetCore项目引用,别的基本不用怎么修改,完整项目配置为:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <Import Project="..\..\..\..\common.props" />

  <PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<UserSecretsId>b83bc18b-a6ca-4e2d-a827-26ffaff35dce</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..\..\..</DockerfileContext>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
</ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="7.0.0" />
<PackageReference Include="Volo.Abp.EventBus.RabbitMQ" Version="7.0.0" />
<PackageReference Include="Volo.Abp.BackgroundJobs.RabbitMQ" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Account.Application" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Account.HttpApi" Version="7.0.0" />
</ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\..\services\administration\src\FunShow.AdministrationService.EntityFrameworkCore\FunShow.AdministrationService.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\services\identity\src\FunShow.IdentityService.EntityFrameworkCore\FunShow.IdentityService.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\shared\FunShow.Shared.Hosting.AspNetCore\FunShow.Shared.Hosting.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\..\shared\FunShow.Shared.Localization\FunShow.Shared.Localization.csproj" />
</ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="2.0.0-*" />
</ItemGroup> <ItemGroup>
<Compile Remove="Logs\**" />
<Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup> </Project>

然后修改Program文件,主要是日志配置修改一下,别的不用改动

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using FunShow.Shared.Hosting.AspNetCore;
using Serilog; namespace FunShow.AuthServer; public class Program
{
public async static Task<int> Main(string[] args)
{
var assemblyName = typeof(Program).Assembly.GetName().Name; SerilogConfigurationHelper.Configure(assemblyName); try
{
Log.Information($"Starting {assemblyName}.");
var builder = WebApplication.CreateBuilder(args);
builder.Host
.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<FunShowAuthServerModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, $"{assemblyName} terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
}

修改module.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using FunShow.AdministrationService.EntityFrameworkCore;
using FunShow.IdentityService.EntityFrameworkCore;
using FunShow.Shared.Hosting.AspNetCore;
using Prometheus;
using StackExchange.Redis;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.Auditing;
using Volo.Abp.BackgroundJobs.RabbitMQ;
using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Emailing;
using Volo.Abp.EventBus.RabbitMq;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.OpenIddict;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using Microsoft.AspNetCore.HttpOverrides;
using FunShow.Shared.Localization; namespace FunShow.AuthServer; [DependsOn(
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpEventBusRabbitMqModule),
typeof(AbpBackgroundJobsRabbitMqModule),
typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
typeof(AbpAccountWebOpenIddictModule),
typeof(AbpAccountApplicationModule),
typeof(AbpAccountHttpApiModule),
typeof(AdministrationServiceEntityFrameworkCoreModule),
typeof(IdentityServiceEntityFrameworkCoreModule),
typeof(FunShowSharedHostingAspNetCoreModule),
typeof(FunShowSharedLocalizationModule)
)]
public class FunShowAuthServerModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration(); PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
options.AddAudiences("AccountService");
options.UseLocalServer();
options.UseAspNetCore();
});
});
if (!hostingEnvironment.IsDevelopment())
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
options.AddDevelopmentEncryptionAndSigningCertificate = false;
}); PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment, configuration));
builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment, configuration));
});
}
} public override void ConfigureServices(ServiceConfigurationContext context)
{
//You can disable this setting in production to avoid any potential security risks.
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration(); ConfigureBundles();
ConfigureSwagger(context, configuration);
ConfigureSameSiteCookiePolicy(context);
ConfigureExternalProviders(context); Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = true;
}); Configure<AbpAuditingOptions>(options =>
{
options.ApplicationName = "AuthServer";
}); Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
}); Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "FunShow:";
}); var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("FunShow");
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "FunShow-Protection-Keys"); context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim().RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
}); #if DEBUG
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
#endif if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<FunShowSharedLocalizationModule>(Path.Combine(
hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}shared{Path.DirectorySeparatorChar}FunShow.Shared.Localization"));
});
}
} public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment(); var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseAbpRequestLocalization(); if (!env.IsDevelopment())
{
app.UseErrorPage();
}
var forwardOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
RequireHeaderSymmetry = false
}; forwardOptions.KnownNetworks.Clear();
forwardOptions.KnownProxies.Clear(); // ref: https://github.com/aspnet/Docs/issues/2384
app.UseForwardedHeaders(forwardOptions); app.UseCorrelationId();
app.UseAbpSecurityHeaders();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseCookiePolicy();
app.UseHttpMetrics();
app.UseAuthentication();
app.UseAbpOpenIddictValidation();
app.UseAbpSerilogEnrichers();
app.UseUnitOfWork();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Account Service API");
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
});
app.UseAuditing();
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapMetrics();
});
} private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
LeptonXLiteThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
} private void ConfigureExternalProviders(ServiceConfigurationContext context)
{
context.Services.AddAuthentication();
} private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv, IConfiguration configuration)
{
var fileName = "authserver.pfx";
var passPhrase = "2D7AA457-5D33-48D6-936F-C48E5EF468ED";
var file = Path.Combine(hostingEnv.ContentRootPath, fileName); if (!File.Exists(file))
{
throw new FileNotFoundException($"Signing Certificate couldn't found: {file}");
} return new X509Certificate2(file, passPhrase);
} private void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration)
{
SwaggerConfigurationHelper.ConfigureWithAuth(
context: context,
authority: configuration["AuthServer:Authority"],
scopes: new Dictionary<string, string> {
/* Requested scopes for authorization code request and descriptions for swagger UI only */
{ "AccountService", "Account Service API" }
},
apiTitle: "Account Service API"
);
} private void ConfigureSameSiteCookiePolicy(ServiceConfigurationContext context)
{
context.Services.AddSameSiteCookiePolicy();
}
}

最后修改配置文件

{
"App": {
"SelfUrl": "https://localhost:44322",
"CorsOrigins": "http://localhost:4200,http://localhost:9527,https://localhost:44307,https://localhost:44325,https://localhost:44353,https://localhost:44367,https://localhost:44388,https://localhost:44381,https://localhost:44361",
"RedirectAllowedUrls": "http://localhost:4200,https://localhost:44307,https://localhost:44321,http://localhost:9527"
},
"AuthServer": {
"Authority": "https://localhost:44322",
"RequireHttpsMetadata": "true",
"SwaggerClientId": "WebGateway_Swagger"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"AdministrationService": "Host=localhost;Port=5432;User ID=postgres;password=myPassw0rd;Pooling=true;Database=FunShow_Administration;",
"IdentityService": "Host=localhost;Port=5432;User ID=postgres;password=myPassw0rd;Pooling=true;Database=FunShow_Identity;"
},
"StringEncryption": {
"DefaultPassPhrase": "fCrJICTG3WoyissG"
},
"Redis": {
"Configuration": "localhost:6379"
},
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "localhost"
}
},
"EventBus": {
"ClientName": "FunShow_AuthServer",
"ExchangeName": "FunShow"
}
},
"ElasticSearch": {
"Url": "http://localhost:9200"
}
}

这样我们认证服务即修改完成。

搭建网关服务

网关服务我们直接新建一个空asp.net core项目。
然后只需要添加一个我们的Shared.Hosting.Gateways项目引用即可。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <Import Project="..\..\..\..\common.props" />

  <PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup> <ItemGroup>
<ProjectReference Include="..\..\..\..\shared\FunShow.Shared.Hosting.Gateways\FunShow.Shared.Hosting.Gateways.csproj" />
</ItemGroup> <ItemGroup>
<Compile Remove="Logs\**" />
<Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup> </Project>

修改Program.cs

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using FunShow.Shared.Hosting.AspNetCore;
using Serilog; namespace FunShow.WebGateway; public class Program
{
public async static Task<int> Main(string[] args)
{
var assemblyName = typeof(Program).Assembly.GetName().Name; SerilogConfigurationHelper.Configure(assemblyName); try
{
Log.Information($"Starting {assemblyName}.");
var builder = WebApplication.CreateBuilder(args);
builder.Host
.AddAppSettingsSecretsJson()
.AddYarpJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<FunShowWebGatewayModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, $"{assemblyName} terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
}

这里和认证服务基本一致,就是多了一个AddYarpJson()来添加我们的yarp的配置文件。
在目录下新建yarp.json文件,添加我们的yarp配置内容。配置集群和路由如下:

{
"ReverseProxy": {
"Routes": {
"Account Service": {
"ClusterId": "accountCluster",
"Match": {
"Path": "/api/account/{**everything}"
}
},
"Identity Service": {
"ClusterId": "identityCluster",
"Match": {
"Path": "/api/identity/{**everything}"
}
},
"Administration Service": {
"ClusterId": "administrationCluster",
"Match": {
"Path": "/api/abp/{**everything}"
}
},
"Logging Service": {
"ClusterId": "loggingCluster",
"Match": {
"Path": "/api/LoggingService/{**everything}"
}
},
"feature-management-route": {
"ClusterId": "feature-management-cluster",
"Match": {
"Path": "/api/feature-management/{**everything}"
}
},
"permission-management-route": {
"ClusterId": "permission-management-cluster",
"Match": {
"Path": "/api/permission-management/{**everything}"
}
},
"setting-management-route": {
"ClusterId": "setting-management-cluster",
"Match": {
"Path": "/api/setting-management/{**everything}"
}
}
},
"Clusters": {
"accountCluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44322"
}
}
},
"identityCluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44388"
}
}
},
"administrationCluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44367"
}
}
},
"loggingCluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:45124"
}
}
},
"feature-management-cluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44367"
}
}
},
"permission-management-cluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44367"
}
}
},
"setting-management-cluster": {
"Destinations": {
"destination1": {
"Address": "https://localhost:44367"
}
}
}
}
}
}

在appsettings.json文件添加我们认证服务的地址

{
"App": {
"SelfUrl": "https://localhost:44325",
"CorsOrigins": "http://localhost:4200,https://localhost:44307,http://localhost:9527"
},
"AuthServer": {
"Authority": "https://localhost:44322",
"RequireHttpsMetadata": "true",
"SwaggerClientId": "WebGateway_Swagger"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Redis": {
"Configuration": "localhost:6379"
},
"ElasticSearch": {
"Url": "http://localhost:9200"
}
}

最后我们添加FunShowWebGatewayModule文件。配置我们yarp的服务。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using FunShow.Shared.Hosting.AspNetCore;
using FunShow.Shared.Hosting.Gateways;
using Volo.Abp;
using Volo.Abp.Modularity; namespace FunShow.WebGateway; [DependsOn(
typeof(FunShowSharedHostingGatewaysModule)
)]
public class FunShowWebGatewayModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// Enable if you need hosting environment
// var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment(); SwaggerConfigurationHelper.ConfigureWithAuth(
context: context,
authority: configuration["AuthServer:Authority"],
scopes: new
Dictionary<string, string> /* Requested scopes for authorization code request and descriptions for swagger UI only */ {
{ "AccountService", "Account Service API" },
{ "IdentityService", "Identity Service API" },
{ "AdministrationService", "Administration Service API" },
{ "LoggingService", "Logging Service API" }
},
apiTitle: "Web Gateway API"
); context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim().RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
} public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCorrelationId();
app.UseAbpSerilogEnrichers();
app.UseCors();
app.UseSwaggerUIWithYarp(context); app.UseRewriter(new RewriteOptions()
// Regex for "", "/" and "" (whitespace)
.AddRedirect("^(|\\|\\s+)$", "/swagger")); app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapReverseProxy();
});
}
}

UseSwaggerUIWithYarp是从我们Yarp配置文件中读取服务信息去构造swagger路由配置。
好了,到这我们认证服务和网关服务也搭建完毕,下一篇我们开始迁移数据库。

ABP微服务系列学习-搭建自己的微服务结构(三)的更多相关文章

  1. springcloud微服务架构搭建

    SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...

  2. SprngCloud微服务框架搭建(一)

    参照来源 :https://blog.csdn.net/forezp/article/details/70148833 1.简介 目前来说,SpringCloud是比较完整的微服务解决方案框架.不像其 ...

  3. Spring Cloud 微服务中搭建 OAuth2.0 认证授权服务

    在使用 Spring Cloud 体系来构建微服务的过程中,用户请求是通过网关(ZUUL 或 Spring APIGateway)以 HTTP 协议来传输信息,API 网关将自己注册为 Eureka ...

  4. 【spring colud】spring cloud微服务项目搭建【spring boot2.0】

    spring cloud微服务项目搭建 =================================== 示例版本: 1.spring boot 2.0版本 2.开发工具 IntellJ IDE ...

  5. 简单Spring Cloud 微服务框架搭建

    微服务是现在比较流行的技术,对于程序猿而言,了解并搭建一个基本的微服务框架是很有必要滴. 微服务包含的内容非常多,一般小伙伴们可以根据自己的需求不断添加各种组件.框架. 一般情况下,基本的微服务框架包 ...

  6. java架构之路-(微服务专题)初步认识微服务与nacos初步搭建

    历史演变: 以前我们都是一个war包,包含了很多很多的代码,反正我开始工作的时候做的就是这样的项目,一个金融系统,代码具体多少行记不清楚了,内部功能超多,但是实际能用到的不多,代码冗余超大,每次部署大 ...

  7. 十一、Docker搭建部署SpringCloud微服务项目Demo

    环境介绍 技术选型:SpringCloud&SpringCloud Alibaba&Docker 微服务模块划分: 员工模块:ems-employees 部门模块:ems-depart ...

  8. SpringCloudAlibaba 微服务讲解(二)微服务环境搭建

    微服务环境搭建 我们这次是使用的电商项目的商品.订单.用户为案例进行讲解 2.1 案例准备 2.1.1 技术选型 maven :3.3.9 数据库:mysql 持久层:SpringData JPA S ...

  9. (3)go-micro微服务项目搭建

    目录 一 微服务项目介绍 二 go-micro安装 1.拉取micro镜像 2.生成项目目录 三 项目搭建 使用DDD模式开发项目: 四 最后 一 微服务项目介绍 账户功能是每一个系统都绕不开的一部分 ...

  10. springCloud 微服务框架搭建入门(很简单的一个案例不喜勿扰)

    Spring cloud 实现服务注册及发现 服务注册与发现对于微服务系统来说非常重要.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只需要使用服务的标识符,就可以访问到服务. clou ...

随机推荐

  1. jupyter 数据显示设置

    #设置显示行数pd.set_option('display.max_row',None)#设置显示列数pd.set_option('display.max_column',None)#设置显示宽度pd ...

  2. JavaScript入门⑩-ES6归纳总结

    JavaScript入门系列目录 JavaScript入门①-基础知识筑基 JavaScript入门②-函数(1)基础{浅出} JavaScript入门③-函数(2)原理{深入}执行上下文 JavaS ...

  3. TCPView工具

    TCPView:一个查看端口和线程的小工具.(不需安装) 主界面: 启动程序之后,你就发现TCPView将你目前在使用的所有进程都列举出来了,并时不时的会用红.黄.绿三种颜色标注某些进程: 红色代表该 ...

  4. DNS欺骗

    原理: dns欺骗又可以叫作中间人人攻击,主要是通过拦截受害人在访问某个网站时设备向外发送的dns请求,然后给出伪造的dns应答,实现欺骗过程. 实验脚本如下: from scapy.layers.d ...

  5. github的初体验

    首先你得注册一个自己的GitHub账号,注册网址:https://github.com/join有了自己的账号以后,就可以进行登录,开始创建一个新的项目创建一个新的项目,填写项目名称,描述创建完成之后 ...

  6. [seaborn] seaborn学习笔记11-绘图实例(3) Drawing example(3)

    11 绘图实例(3) Drawing example(3)(代码下载) 本文主要讲述seaborn官网相关函数绘图实例.具体内容有: Plotting a diagonal correlation m ...

  7. 使用IDEA搭建SSM项目

    使用IDEA搭建SSM项目   摘要:前几天学习了SSM项目的搭建,但是因为配置过程中出现了问题因此没有搭起来,我最讨厌不确定的事情,因此自己花费了点时间钻研搭建SSM项目的方法,终于习得了SSM项目 ...

  8. Python导入Excel表格数据并以字典dict格式保存

      本文介绍基于Python语言,将一个Excel表格文件中的数据导入到Python中,并将其通过字典格式来存储的方法.   我们以如下所示的一个表格(.xlsx格式)作为简单的示例.其中,表格共有两 ...

  9. java入门与进阶 P-2.5+P-2.6

    嵌套和级联的判断 嵌套的判断 当if的条件满足或者不满足的时候要执行的语句也可以是一条if或if-else语句,这就是嵌套的if语句 else的匹配 else总是和最近的那个if匹配 tips 在if ...

  10. 使用 flexible.js + rem 制作苏宁移动端首页

    一.技术选型 二.搭建相关文件夹 三.设置视口标签以及引入初始化样式文件和js文件 四.body 样式 五.rem 适配方案二 body样式修改 index.css body { min-width: ...