至此,我们的解决方案中新建了三个项目,网关(Zhengwei.Gateway)、认证中心(Zhengwei.Identity)和用户资源API(Zhengwei.Use.Api)。当要访问用户API的某个资源先要访问网关,网关要对请求进行认证,然后要访问认证中心,认证通过后才能访问对应的资源。今天我们要讲的是在认证的时候我们需要较验用户的信息,这时就要访问用户服务(因该项目采用微服务,所有的模块都叫服务),这就涉及到服务之间的访问与发现了。所以这节重点在于使用consul注册服务与发现服务。多说也不益,直接上项目吧。

1、  下载consul 下载地址:https://www.consul.io/downloads.html

下载下来的文件是一个.exe文件,如下图:

2、  cmd打开我们的命令窗口,切换到对应的下载目录,输入命令consul agent –dev,看到如下的信息说明你的consul服务正常启动。

3、  consul提供了一个UI的访问界面,界面上可以看到注册的服务,地址:http://localhost:8500,界面如下,现在还没有服务注册:

4、 回到我们项目中开始注册服务吧。现在要求zhengwei.user.api这个项目在启动时就向consul中注册服务。引用consul包到zhengwei.user.api项目中。

5、增加配置,配置consul服务器的地址和要注册的服务名,配置的意思是向http://127.0.0.1:8500所在的服务器(也就是consul所在的服务器)上注册名为userapi的服务,如下图:

6、在项目启动时注册服务时自定义RegisterService()方法,在项目停止时取消服务自定义DeRegisterService()方法。下面贴出Startup.cs类完整代码。但是这里有一个小问题:我用的127.0.0.1无法访问,用localhost就可以,我的IP和别名映射没有问题的。但是就是访问报错,可能是跨域的问题吗,这里暂不讨论,有解决了的园友可以给我留言。

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.AddDbContext<UserContext>(options =>
{
options.UseMySQL(Configuration.GetConnectionString("MysqlUser")); }); services.Configure<ServiceDisvoveryOptions>(Configuration.GetSection("ServiceDiscovery"));
services.AddSingleton<IConsulClient>(p => new ConsulClient(cfg =>
{
var s = p.GetRequiredService<IOptions<ServiceDisvoveryOptions>>().Value;
if(!string.IsNullOrEmpty(s.Consul.HttpEndpoint))
{
cfg.Address = new Uri(s.Consul.HttpEndpoint);
}
}));
services.AddMvc(p=>p.Filters.Add(typeof(GlobalExceptionFilter))); //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IApplicationLifetime lifetime,
IOptions<ServiceDisvoveryOptions> serviceOptions,
IConsulClient consul) {
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// app.UseHsts();
} //启动时注册服务 安装consul后,通过localhost:8500可以查看服务
lifetime.ApplicationStarted.Register(()=> {
RegisterService(app, serviceOptions,consul,lifetime);
});
//停止时注销服务
lifetime.ApplicationStopped.Register(() => {
DeRegisterService(app, serviceOptions, consul, lifetime);
});
app.UseMvc();
//UserContextSeed.SeedAsync(app, loggerFactory).Wait(); } private void DeRegisterService(IApplicationBuilder app, IOptions<ServiceDisvoveryOptions> serviceOptions, IConsulClient consul, IApplicationLifetime lifetime)
{
var features = app.Properties["server.Features"] as FeatureCollection;
var addresses = features.Get<IServerAddressesFeature>()
.Addresses
.Select(p => new Uri(p));
foreach (var address in addresses)
{
var serviceId = $"{serviceOptions.Value.ServiceName}_{address.Host}:{address.Port}"; consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult(); } } private void RegisterService(IApplicationBuilder app, IOptions<ServiceDisvoveryOptions> serviceOptions, IConsulClient consul, IApplicationLifetime lifetime)
{ var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(),
Interval = TimeSpan.FromSeconds(),
HTTP = $"http://127.0.0.1:33545/HealthCheck"
}; var anentReg = new AgentServiceRegistration()
{
ID = "userapi:33545",
Check = httpCheck,
Address = "127.0.0.1",
Name = "userapi",
Port =
};
var serviceId = "userapi:127.0.0.1:33545";
consul.Agent.ServiceRegister(anentReg).GetAwaiter().GetResult();
lifetime.ApplicationStopping.Register(()=> {
consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
}); }
}

7、从注册的代码中可以看到在注册服务前会进行健康检查也就是调用Zhengwei.Use.Api项目中HealthCheckController控制器的Ping()方法。那么我们现在将这个方法加上。代码简单,直接上截图吧。

8、我们在UserController还要加一个方法CheckOrCreate()供认证时调用

9、启动项目,再次进入localhost:8500页面,会看到一个名叫userapi的服务已注册到我们的consul中。

10、服务注册到我们的consul中后,接下来就要在认证时(Zhengwei.Identity项目中)找到这个服务,并调用对应的CheckOrCreate()方法。

11、在这个系统的第四篇文章中(NetCore项目实战篇04---集成IdentityService4)已经写好了调用use.api的接口和实现类,并实现了方法CheckOrCreate()只不过当时我们这个方法是写死的,直接return 1;现在我们就要真正开始调用Zhengwei.Use.Api项目中的这个方法了。见代码:

public class UserService : IUserService
{
//private string _userServiceUrl = "http://localhost:33545";
private string _userServiceUrl;
private HttpClient _httpClient;
public UserService(HttpClient httpClient,IOptions<Dtos.ServiceDisvoveryOptions> serOp,IDnsQuery dnsQuery)
{
_httpClient = httpClient; var address = dnsQuery.ResolveService("service.consul",serOp.Value.ServiceName);
var addressList = address.First().AddressList;
var host = addressList.Any() ? addressList.First().ToString() : address.First().HostName;
var port = address.First().Port;
_userServiceUrl = $"http://{host}:{port}"; }
public async Task<int> CheckOrCreate(string phone)
{
var from = new Dictionary<string, string> { { "phone", phone } };
var content = new FormUrlEncodedContent(from); var response = await _httpClient.PostAsync(_userServiceUrl + "/api/users/check-or-create", content);
if(response.StatusCode == System.Net.HttpStatusCode.OK)
{
var userId =await response.Content.ReadAsStringAsync();
int.TryParse(userId, out int intuserId);
return intuserId;
}
return ; }
}

在这个类中,我们先是发现了use.api服务的ip地址,并给_userServiceUrl字段赋值,在CheckOrCreate方法中就直接调用这个地址对应的方法了。

12、 所有编码完成生成没有问题后,同时启动这三个项目,再次打开postman,通过:http://localhost:4157/connect/token获取token,再用token值去访问:http://localhost:4157/users,如果一切正常,那就会返回对应的用户信息。

到此,我们网关、认证、服务注册与发现这条线就算是走通了。

但是,这里还会有一个问题,就是在UserService.cs类中CheckOrCreate方法是直接调用的另一个服务,对的,这里就是直接调用的,很粗暴,对调用后的错误没有作处理,如服务是否响应,调用时是否报错等,都没有处理。这里是否会有更好的处理方法呢,请看下篇《NetCore项目实战篇07---服务保护之polly》

NetCore项目实战篇06---服务注册与发现之consul的更多相关文章

  1. NetCore项目实战篇08---Docker挂载mysql并连接.netCoreWeb

    我们的项目之前在直接连接的mysql,今天我们将通过docker挂载mysql 并与我们开发的webapi项目连接. 1. 安装docker 下载地址: https://download.docker ...

  2. Spring Cloud Alibaba 实战 之 Nacos 服务注册和发现

    服务注册与发现,服务发现主要用于实现各个微服务实例的自动化注册与发现,是微服务治理的核心,学习 Spring Cloud Alibaba,首先要了解框架中的服务注册和发现组件——Nacos. 一.Sp ...

  3. Spring Boot + Spring Cloud 构建微服务系统(一):服务注册和发现(Consul)

    使用Consul提供注册和发现服务 什么是 Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul ...

  4. 服务注册和发现(Consul)

    使用Consul提供注册和发现服务 什么是 Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul ...

  5. NetCore项目实战篇04---集成IdentityService4

    大家都知道我们的项目中已有web api,现在可以正式访问,不论任何人只要通过输入对应的api网址就可以访问到我们的api 资源,这样是很不安全的,我们需求对当前用户进行身份验证,因此我们在项目中使用 ...

  6. NetCore项目实战篇05---添加Ocelot网关并集成identity server4认证

    今天来给我们的项目增加API网关,使用Ocelot. 它是系统暴露在外部的一个访问入口,这个有点像代理访问的家伙,就像一个公司的门卫承担着寻址.限制进入.安全检查.位置引导.等等功能.同时我们还要在网 ...

  7. NetCore项目实战篇07---服务保护之polly

    1.  为什么要用polly 前面的项目中,一个服务调用另一个(Zhengwei.Identity调用Zhengwei.Use.Api)服务时是直接调用的,在这个调用的过程中可能会发生各种瞬态故障,这 ...

  8. SpringCloud核心教程 | 第三篇:服务注册与发现 Eureka篇

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...

  9. .NET微服务从0到1:服务注册与发现(Consul)

    目录 Consul搭建 基于Docker搭建Consul 基于Windows搭建Consul ServiceA集成Consul做服务注册 Ocelot集成Consul做服务发现 更多参考 Consul ...

随机推荐

  1. js的localStorage基础认识

    新建a.html文件: <!DOCTYPE html> <html> <body> <div id="result"></di ...

  2. s3cmd s3命令行工具

    Amazon S3 Tools: Command Line S3 Client Software and S3 Backup 官方网站

  3. 杂园日记-H5-IOS-Android混合开发

    1.js 调用 原生API iOS: window.webkit.messageHandlers.yourFunName.postMessage({"1":"3" ...

  4. Ansible playbook Vault 加密

    Ansible playbook Vault 加密详解与使用案例 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务 ...

  5. windows 删除非法目录

    用PHP写错了路径,创建了非法目录,提示不存在该项目 复制下面 添加为批处理文件 DEL /F /A /Q \\?\%1RD /S /Q \\?\%1 将文件移入这个文件

  6. Django Channel实时推送与聊天

    先来看一下最终的效果吧 开始聊天,输入消息并点击发送消息就可以开始聊天了 点击 “获取后端数据”开启实时推送 先来简单了解一下 Django Channel Channels是一个采用Django并将 ...

  7. Next.js 7发布,构建速度提升40%

    Next.js团队发布了其开源React框架的7版本.该版本的Next.js主要是改善整体的开发体验,包括启动速度提升57%.开发时的构建速度提升40%.改进错误报告和WebAssembly支持. \ ...

  8. Soldiers Sortie

    这部2006年上映的作品豆瓣评分9.3,时至今日仍然有人乐此不疲地讨论剧情和启发,我想称之为经典应该不算过分. 这部剧我至少完整看过3遍,随着阅历增加,对某些角色的体会也变得更深刻. 许三多 许三多是 ...

  9. 使用C++STL的map容器实现一种命令映射

    因为最近在练习写一个ftp的服务器,其中的命令有很多种,每个命令对应一个执行函数,能够想到的最简单的实现方式便是使用if--else匹配命令和执行对应的函数,如下所示: if(strcmp(" ...

  10. python-unittest环境下单独运行一个用例的方法

    在unittest单元测试的框架下,想要调出如图所示的绿三角 需要有两个步骤: 1.确定在工具栏中时在unittest模式下运行的,如果为普通模式的话可以通过下三角下拉修改运行环境: 2.在代码中im ...