至此,我们的解决方案中新建了三个项目,网关(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. C# 基础知识系列- 13 常见类库介绍(一)

    0. 前言 每篇一个前言,介绍一下这一篇的内容.之前的内容都是针对某些知识点进行的介绍,这篇内容介绍一下实际开发中常用的一些类和命名空间.这一篇是个连续剧,大概有个三四集.嗯,就是这样. 1. Sys ...

  2. Linux网络编程(2)

    Preview 基于上一篇博客,本文将继续展开TCP面向连接的,客户端以及服务端各自需要进行的操作,我们按照真实TCP连接的顺序,分别阐述客户端socket(), connect()以及服务端sock ...

  3. fashion_mnist多分类训练,两种模型的保存与加载

    from tensorflow.python.keras.preprocessing.image import load_img,img_to_array from tensorflow.python ...

  4. audio的自动播放报错解决

    使用audio标签时,当前页面没有进行交互时,比如用户刷新了页面后,play()调用就会报错,如下图 查找资料后,发现是2018年4月以后,chrome浏览器对这块进行了优化,为了节约流量,禁止了自动 ...

  5. HDFS一些基本操作方法

    启动hadoop cd /usr/local/hadoop ./sbin/start-dfs.sh 在浏览器中打开localhost:50070 找到 进入  操作 1)新建文件夹      在根目录 ...

  6. GitHub 如何忽略文件或者文件夹

    在我们开发项目的时候,往往会产生一些不必要的文件,我们会选择忽略他们,不提交到版本控制中,那我们该如何做呢? 步骤一:在项目根目录下,右键,git bash,在弹出的命令行输入框中输入命令:touch ...

  7. vagrant + 宝塔 环境搭建遇到的一些问题

    1.js时间戳单位为毫秒,php时间戳为秒. 2.tp里的where()方法如果where("id=".$id)不能用的话就用数组形式的:where(array("id& ...

  8. 利用python画出SJF调度图

    最先发布在csdn.本人原创. https://blog.csdn.net/weixin_43906799/article/details/105510046 SJF算法: 最短作业优先(SJF)调度 ...

  9. hdu3033 I love sneakers! 分组背包变形(详解)

    这个题很怪,一开始没仔细读题,写了个简单的分组背包交上去,果不其然WA. 题目分析: 分组背包问题是这样描述的:有K组物品,每组 i 个,费用分别为Ci ,价值为Vi,每组物品是互斥的,只能取一个或者 ...

  10. 狄慧201771010104《面向对象程序设计(java)》第十六周学习总结

    实验十六  线程技术 实验时间 2017-12-8 一.知识点总结: 1.程序与进程的概念 ‐程序是一段静态的代码,它是应用程序执行的蓝本. ‐进程是程序的一次动态执行,它对应了从代码加载.执行至执行 ...