.NET Core微服务一:Consul服务中心

.NET Core微服务二:Ocelot API网关

.NET Core微服务三:polly熔断与降级

本文的项目代码,在文章结尾处可以下载。

本文使用的环境:Windows10 64位 + VS 2019 + .NET Core 3.1

Consul有关介绍:https://www.jianshu.com/p/32dc52f28a14

Consul官方网址:https://www.consul.io/

一、安装Consul

1.官网下载对应版本,并解压出来

2.打开cmd,cd到解压的目录,运行如下其中一条命令

本次演示都在同一台计算机上,所以本文选择命令一;这两条命令请在开发环境使用,生产环境不要使用。

命令一:“consul.exe agent -dev”服务中心的ip地址,将会使用127.0.0.1

命令二:“consul.exe agent -dev -client x.x.x.x”指定服务中心的ip地址

3.命令运行成功后,打开“http://127.0.0.1:8500/”,出现如下画面

二、创建服务

1.服务端项目大体结构:

2.新建.NET Core类库项目,命名为“ClassLibrary”,然后NuGet搜索并安装

“Consul”、“Microsoft.Extensions.Configuration”、“Microsoft.Extensions.Configuration.Json”

Common.cs代码:

 using Consul;
using Microsoft.Extensions.Configuration;
using System; namespace ClassLibrary
{
public class Common
{
public static IConfiguration Configuration { get; }
static Common()
{
Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build();
} /// <summary>
/// 需要注册的服务地址
/// </summary>
public static string ConsulServiceIP
{
get
{
return Configuration["Consul:ServiceIP"];
}
} /// <summary>
/// 需要注册的服务端口
/// </summary>
public static int ConsulServicePort
{
get
{
string str = Configuration["Consul:ServicePort"];
return int.Parse(str);
}
} /// <summary>
/// 服务注册
/// </summary>
public static void ConsulRegister()
{
ConsulClient client = new ConsulClient(
(ConsulClientConfiguration c) =>
{
c.Address = new Uri(Configuration["Consul:Address"]); //Consul服务中心地址
c.Datacenter = Configuration["Consul:DataCenter"]; //指定数据中心,如果未提供,则默认为代理的数据中心。
}
);
string checkUrl = Configuration["Consul:CheckUrl"];
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = Guid.NewGuid().ToString(), //服务编号,不可重复
Name = Configuration["Consul:ServiceName"], //服务名称
Port = ConsulServicePort, //本程序的端口号
Address = ConsulServiceIP, //本程序的IP地址
Check = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromMilliseconds(), //服务停止后多久注销
Interval = TimeSpan.FromSeconds(), //服务健康检查间隔
Timeout = TimeSpan.FromSeconds(), //检查超时的时间
HTTP = $"http://{ConsulServiceIP}:{ConsulServicePort}{checkUrl}" //检查的地址
}
});
} }
}

3.新建.NET Core的webapi项目,命名为“ServiceStudent”,把“为HTTPS配置”的勾选去掉

Controller代码:

 using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic; namespace ServiceStudent.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class DefaultController : ControllerBase
{
static List<Student> list = new List<Student>() {
new Student(){ ID = "", StudentName = "学生1", StudentAge = },
new Student(){ ID = "", StudentName = "学生2", StudentAge = },
new Student(){ ID = "", StudentName = "学生3", StudentAge = }
}; /// <summary>
/// 健康检查接口
/// </summary>
[HttpGet]
public string Check()
{
return "";
} [HttpGet]
public List<Student> GetList()
{
Console.WriteLine(DateTime.Now.ToString());
return list;
} [HttpGet]
public Student GetModel(string id)
{
Console.WriteLine(DateTime.Now.ToString());
return list.Find(t => t.ID == id);
}
}
}

其中有一段健康检查的接口,作用是让服务中心知道服务没有挂掉还能访问,不需要什么业务,所以怎么简单怎么来:

Model代码:

    public class Student
{
public string ID { get; set; }
public string StudentName { get; set; }
public int StudentAge { get; set; }
}

appsettings.json的配置,加入"Consul",注意ServiceIP改为自己电脑的IP(这个不要配置为127.0.0.1,后面访问会不正常)

 {
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Consul": {
"Address": "http://127.0.0.1:8500",
"CheckUrl": "/api/Default/Check",
"DataCenter": "dc1",
"ServiceIP": "192.168.2.119",
"ServicePort": ,
"ServiceName": "Student"
}
}

Program.cs的CreateHostBuilder方法改为:

 public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
string ip = Common.ConsulServiceIP;
int port = Common.ConsulServicePort;
webBuilder.UseStartup<Startup>().UseUrls($"http://{ip}:{port}");
});

在Startup.cs的Configure方法中加入“ClassLibrary.Common.ConsulRegister();”

这样一个“Student”服务就创建好了,“Teacher”服务也是如法炮制,但是需要改appsettings.json的服务名和端口号,代码就不贴了,请到文章结尾处下载。

三、启动服务

通过命令行来启动,打开cmd,cd到Debug目录,各自运行“dotnet ServiceStudent.dll”和“dotnet ServiceTeacher.dll”。

请检查端口有没有被占用或超出范围,如果失败了,在配置文件中换成其它端口试试。

服务运行成功后,打开“http://127.0.0.1:8500/”,如下画面注册成功

如果出现一项打X,那就是失败,这个服务会在1分钟之后被踢出列表

一个服务可能会部署到多个服务器上,用“Teacher”来模拟下多台机器运行。

前面运行好的服务不要关闭,打开Teacher的Debug目录下的配置文件,

修改它的端口号,服务名不用改,再新开一个cmd,运行“dotnet ServiceTeacher.dll”

那么服务中心就会有变化

四、使用服务

1.客户端项目大体结构:

2.新建.net core类库项目,命名为“ClassLibrary”,然后NuGet搜索并安装

“Consul”、“Microsoft.Extensions.Configuration”

Common.cs代码:

using Consul;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks; namespace ClassLibrary
{
public class Common
{
public static IConfiguration Configuration { get; }
static Common()
{
Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build();
} public static string ConsulAddress
{
get { return Configuration["ConsulAddress"]; }
} /// <summary>
/// 获取服务
/// </summary>
public static string GetService(string serviceName)
{
ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); var response = client.Agent.Services().Result.Response; //服务名称区分大小写,若要不区分:Equals(serviceName, StringComparison.OrdinalIgnoreCase)
var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); //进行取模,随机取得一个服务器,或者使用其它负载均衡策略
var service = services.ElementAt(Environment.TickCount % services.Count()); return service.Address + ":" + service.Port;
} /// <summary>
/// 获取服务(异步方法)
/// </summary>
public async Task<string> GetService2(string serviceName)
{
ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); var response = (await client.Agent.Services()).Response; //服务名称区分大小写,若要不区分:Equals(serviceName, StringComparison.OrdinalIgnoreCase)
var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); //进行取模,随机取得一个服务器,或者使用其它负载均衡策略
var service = services.ElementAt(Environment.TickCount % services.Count()); return service.Address + ":" + service.Port;
} public static string HttpGetString(string url)
{
HttpClient httpClient = new HttpClient();
string result = httpClient.GetAsync(url)
.Result.Content.ReadAsStringAsync().Result;
httpClient.Dispose();
return result;
} public static T HttpGetObject<T>(string url)
{
string result = HttpGetString(url);
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result);
} }
}

3.新建.NET Core的webapi项目,命名为“ClientSite”,把“为HTTPS配置”的勾选去掉

StudentController代码:

 using ClassLibrary;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; namespace ClientSite.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class StudentController : ControllerBase
{
[HttpGet]
public object GetList()
{
string ip = Common.GetService("Student");
List<Student> list = Common.HttpGetObject<List<Student>>($"http://{ip}/api/Default/GetList");
return new
{
address = ip,
data = list
};
} [HttpGet]
public object GetModel(string id)
{
string ip = Common.GetService("Student");
Student model = Common.HttpGetObject<Student>($"http://{ip}/api/Default/GetModel?id={id}");
return new
{
address = ip,
data = model
};
}
}
}

TeacherController代码:

 using ClassLibrary;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; namespace ClientSite.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class TeacherController : ControllerBase
{
[HttpGet]
public object GetList()
{
string ip = Common.GetService("Teacher");
List<Teacher> list = Common.HttpGetObject<List<Teacher>>($"http://{ip}/api/Default/GetList");
return new
{
address = ip,
data = list
};
} [HttpGet]
public object GetModel(string id)
{
string ip = Common.GetService("Teacher");
Teacher model = Common.HttpGetObject<Teacher>($"http://{ip}/api/Default/GetModel?id={id}");
return new
{
address = ip,
data = model
};
}
}
}

appsettings.json加入:

"ConsulAddress": "http://127.0.0.1:8500"

4.用VS启动站点,然后用postman访问

“http://ip:port/api/Student/GetList”

“http://ip:port/api/Student/GetModel?id=002”

 

多次访问“http://ip:port/api/Teacher/GetList”,则address会随机切换,注意看返回的端口号

 

代码:https://files.cnblogs.com/files/shousiji/netcore_wfw.rar

.NET Core微服务一:Consul服务中心的更多相关文章

  1. .NET CORE微服务中CONSUL的相关使用

    .NET CORE微服务中CONSUL的相关使用 1.consul在微服务中的作用 consul主要做三件事:1.提供服务到ip的注册 2.提供ip到服务地址的列表查询 3.对提供服务方做健康检查(定 ...

  2. 基于.net core微服务(Consul、Ocelot、Docker、App.Metrics+InfluxDB+Grafana、Exceptionless、数据一致性、Jenkins)

    1.微服务简介 一种架构模式,提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(RESTfu ...

  3. (3).NET CORE微服务 Micro-Service ---- Consul服务治理

    Consul是注册中心,服务提供者.服务提供者.服务消费者等都要注册到Consul中,这样就可以实现服务提供者.服务消费者的隔离. 除了Consul之外,还有Eureka.Zookeeper等类似软件 ...

  4. (3)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Consul服务治理

    Consul是注册中心,服务提供者.服务提供者.服务消费者等都要注册到Consul中,这样就可以实现服务提供者.服务消费者的隔离. 除了Consul之外,还有Eureka.Zookeeper等类似软件 ...

  5. (4).NET CORE微服务 Micro-Service ---- Consul服务发现和消费

    上一章说了  Consul服务注册  现在我要连接上Consul里面的服务 请求它们的API接口 应该怎么做呢? 1.找Consul要一台你需要的服务器 1.1 获取Consul下的所有注册的服务 u ...

  6. (4)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Consul服务发现和消费

    上一章说了  Consul服务注册  现在我要连接上Consul里面的服务 请求它们的API接口 应该怎么做呢? 1.找Consul要一台你需要的服务器 1.1 获取Consul下的所有注册的服务 u ...

  7. .NET Core微服务之基于Consul实现服务治理

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.Consul基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发 ...

  8. .NET Core微服务之基于Consul实现服务治理(续)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧. 一.Consul ...

  9. ASP.NET Core 微服务初探[1]:服务发现之Consul

    ASP.NET Core 微服务初探[1]:服务发现之Consul   在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件 ...

随机推荐

  1. C#反射与特性(一):反射基础

    目录 C#反射与特性(一):反射基础 1. 说明 1.1 关于反射.特性 2. 程序集操作 2.1 获取 程序集对象(Assembly) 2.2 Assembly 使用 2.3 获取程序集的方式 C# ...

  2. Mysql(超级详细)

    Mysql(超级详细) (黑小子-余) 一.Mysql介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理 ...

  3. 宣布一件事,通过写博客,挣到了人生的第一个 10w

    今天是 2019 年的最后一天,对于我来说,2019 年可以说是我高考进入大学以来,最重要的一年了.这一年,也是我收获最多的一年,其中最重要的收获应该就是『找工作』和『运营公众号』以及『挣到了人生的第 ...

  4. 洛谷$P5444\ [APIO2019]$奇怪装置 数论

    正解:数论 解题报告: 传送门$QwQ$ 我好像当初考的时候这题爆零了,,,部分分都没想到,,,我真的好菜$kk$ 考虑如果在$t_1,t_2$两个时刻有$x_1=x_2,y_1=y_2$是什么情况$ ...

  5. $HDOJ5542\ The\ Battle\ of\ Chibi$ 数据结构优化$DP$

    $AcWing$ $Description$ $Sol$ 首先显然是是以严格递增子序列的长度为阶段,由于要单调递增,所以还要记录最后一位的数值 $F[i][j]$表示前$i$个数中以$A_i$结尾的长 ...

  6. 从零开始学asyncio(中)

    本篇文章主要是讲解asyncio模块的实现原理. 这个系列还有另外两篇文章: 从零开始学asyncio(上) 从零开始学asyncio(下) 一. asyncio模块简介 asyncio是python ...

  7. POJ 1458 Common Subsequence (动态规划)

    题目传送门 POJ 1458 Description A subsequence of a given sequence is the given sequence with some element ...

  8. 【Java基础总结】总结

    总想着把学习的过程全都记录下来 以便某一时刻回头的时候,还能看见走过的路 对于基础来说,即使不回头看,也知道这条路是什么样子的 记录不记录,都无所谓 况且我不是专业的记录者,不记录比记录好 实在想不起 ...

  9. 【Java基础总结】IO流

    字节流 1. InputStream 字节输入流 代码演示 InputStream in = System.in; System.out.println("int read(byte b) ...

  10. JSP九大内置对象之session以及eclispe如何关联源码

    一.session的特点及其实例 session:同一次会话共享 a.浏览网站:开始->关闭 b.购物:浏览.付款.退出 c.电子邮件:浏览.写邮件.退出  从一次开始到一次结束,是一次会话.  ...