微服务介绍,通讯,注册和发现
带着两个问题 什么是微服务 ,什么是架构
什么是架构:

然后引出什么是微服务的思考:
都围绕一个领域模型,下面就是微服务架构
下面是一个完成的微服务架构图 :
微服务的约束总结:

4.异步消息控制模式
上面的设计模式要根据问题的边界去选择
最通用的方式是聚合设计模式
选择设计模式注意:1业务特点 2公司组织 3公司每个人的利益
为什么要使用微服务架构:
重点微服务如何拆分:
微服务拆分方法:
微服务内部结构
每次拆分因为有生命周期每个生命周期都会出现新的领域每个领域都会有新的主体每个主体都会有边界,每个边界和主体都会生产一个领域模型。
http 是restful rpc 是 rpc 和 grpc
领域模型其实就是model interface是解耦model的 services是为了处理一些业务逻辑的 respositories是和数据库打交道的
webapi 是 Resful的落地方式
例如 团队管理项目 他的边界是公司
销售 技术 售后 售前 人事等等
上面这些团队都是有成员的,成员也是有位置的上班地点 所以更具名词拆分 得到 团队=====成员=====成员位置
出现了 团队 和 成员 两个名词 这里就可以拆分为两个服务 团队服务 成员服务 和 位置服务
粒度问题如何决定
1 组织--如果公司只有一个人==单体
2 业务本身
3 如果公司有2个人 ==拆分为两个服务 (团队服务 成员服务) 位置服务
一个简单的微服务代码构造如图:
什么是注册中心?
如何使用consul?

如何使用Consul
步骤
1、Consul下载地址
官网地址: https://www.consul.io/
下载地址: https://releases.hashicorp.com/consul/1.7.2/ 或 https://www.consul.io/downloads.html
下载后解开压缩包.拷贝Consul到你的PATH路径中,在Unix系统中~/bin
和/usr/local/bin
是通常的安装目录.根据你是想为单个用户安装还是给整个系统安装来选择.
在Windows系统中有可以安装到%PATH%
的路径中.
2、服务端启动
完成安装后,通过打开一个新终端窗口检查consul
安装是否成功.通过执行 consul
你应该看到类似下面的输出
启动服务 consul agent -dev 开发模式
consul agent -server 生产模式
开发模式和生产模式是一样的只是生产模式会数据持久化
1.开发模式启动命令:

Version :consul版本
Node ID : consul当前启动节点编号(guid)
Node Name:节点名称(默认为电脑名称)
Datacenter:数据中心
Server:启动是服务端模式,否则就为客户端模式
Client Addr:客户端连接地址,支持http,https,gRPC,DNS。默认我们使用HTTP方式
Cluster Addr:集群地址,就是Server模式下 启动方式
Encrypt:安全
生产模式启动命令:
consul agent -server -bootstrap-expect 1 -data-dir d:/consul/data
会出现错误:提示
主要原因:服务端模式启动的时候,默认绑定的地址是0.0.0.0.希望绑定默认的ip地址
consul agent -server -bind=127.0.0.1 -bootstrap-expect 1 -data-dir d:/consul/data
客户端模式启动
直接使用net程序来进行启动
示例:先下载consul包
// 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri("http://127.0.0.1:8500"); }); // 2、获取服务内部地址 // 3、创建consul服务注册对象 var registration = new AgentServiceRegistration() { ID = Guid.NewGuid().ToString(), Name = "teamservice", Address = "http://localhos", Port = "5001", Tags = new string[], Check = new AgentServiceCheck { // 3.1、consul健康检查超时间 Timeout = TimeSpan.FromSeconds(10), // 3.2、服务停止5秒后注销服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 3.3、consul健康检查地址 HTTP = serviceNode.HealthCheckAddress, // 3.4 consul健康检查间隔时间 Interval = TimeSpan.FromSeconds(10), } }; // 4、注册服务 consulClient.Agent.ServiceRegister(registration).Wait();
项目结构展示:
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) { // 1、注册上下文到IOC容器 services.AddDbContext<TeamContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); }); // 2、注册团队service services.AddScoped<ITeamService, TeamServiceImpl>(); // 3、注册团队仓储 services.AddScoped<ITeamRepository, TeamRepository>(); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); // 注册团队服务 // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri("http://127.0.0.1:8500"); }); // 2、创建consul服务注册对象 var registration = new AgentServiceRegistration() { ID = Guid.NewGuid().ToString(),//指定服务的编号 Name = "teamservice",//服务的名字 Address = "https://localhost",//服务地址 Port = 5004,//服务的端口 Check = new AgentServiceCheck { // 3.1、consul健康检查超时间 Timeout = TimeSpan.FromSeconds(10), // 3.2、服务停止5秒后注销服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 3.3、consul健康检查地址 HTTP = "https://localhost:5004/HealthCheck", // 3.4 consul健康检查间隔时间 Interval = TimeSpan.FromSeconds(3), } }; // 1、不好扩展(集群配置) // 2、不好维护 // 3、完全和业务无关 // 封装 // 3、注册服务 consulClient.Agent.ServiceRegister(registration).Wait(); Console.WriteLine("consul注册成功"); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
微服务聚合服务:
最后微服务发现者进行获取,服务发现代码如下:
// 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri("http://127.0.0.1:8500"); }); // 2、consul查询服务,根据具体的服务名称查询 var queryResult = await consulClient.Catalog.Service("teamservice"); // 3、将服务进行拼接 var list = new List<ServiceUrl>(); foreach (var service in queryResult.Response) { list.Add(new ServiceUrl { Url = service.ServiceAddress + ":" + service.ServicePort }); }
/// <summary> /// 服务调用实现 /// </summary> public class HttpTeamServiceClient : ITeamServiceClient { private readonly IHttpClientFactory httpClientFactory; public HttpTeamServiceClient(IHttpClientFactory httpClientFactory) { this.httpClientFactory = httpClientFactory; } public async Task<IList<Team>> GetTeams() { // 开始消费 // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri("http://127.0.0.1:8500"); }); // 2、consul查询服务,根据具体的服务名称查询 var queryResult = await consulClient.Catalog.Service("teamservice"); // 3、将服务进行拼接 var list = new List<string>(); foreach (var service in queryResult.Response) { list.Add(service.ServiceAddress + ":" + service.ServicePort ); } // 1、建立请求 HttpClient httpClient = httpClientFactory.CreateClient(); HttpResponseMessage response = await httpClient.GetAsync(list[0]+"/Teams"); // 1.1json转换成对象 IList<Team> teams = null; if (response.StatusCode == HttpStatusCode.OK) { string json = await response.Content.ReadAsStringAsync(); teams = JsonConvert.DeserializeObject<List<Team>>(json); } return teams; } }
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) { // 1、注册restfulapi调用 services.AddHttpClient(); // 2、service注入到ioc容器 services.AddScoped<ITeamServiceClient, HttpTeamServiceClient>(); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
注意注册服务心跳发现部分:
Check = new AgentServiceCheck { // 3.1、consul健康检查超时间 Timeout = TimeSpan.FromSeconds(10), // 3.2、服务停止5秒后注销服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 3.3、consul健康检查地址 HTTP = "https://localhost:5004/HealthCheck", // 3.4 consul健康检查间隔时间 Interval = TimeSpan.FromSeconds(3), }
上面的服务注册和服务发现 都是硬编码的
1、不好扩展(集群配置)
2、不好维护
3、完全和业务无关
所以我们应该封装一个工具类库 Core
定义注册和发现接口
/// <summary> /// 服务发现 /// </summary> public interface IServiceDiscovery { /// <summary> /// 服务发现 /// </summary> /// <param name="serviceName">服务名称</param> /// <returns></returns> Task<IList<ServiceUrl>> Discovery(string serviceName); } /// <summary> /// 服务注册 /// </summary> public interface IServiceRegistry { /// <summary> /// 注册服务 /// </summary> void Register(ServiceRegistryConfig serviceNode); /// <summary> /// 撤销服务 /// </summary> void Deregister(ServiceRegistryConfig serviceNode); }
注册和发现的配置类:
/// <summary> /// 服务发现配置 /// </summary> public class ServiceDiscoveryConfig { /// <summary> /// 服务注册地址 /// </summary> public string RegistryAddress { set; get; } } /// <summary> /// 服务注册节点 /// </summary> public class ServiceRegistryConfig { // 服务ID public string Id { get; set; } // 服务名称 public string Name { get; set; } // 服务标签(版本) public string[] Tags { set; get; } // 服务地址(可以选填 === 默认加载启动路径) public string Address { set; get; } // 服务端口号(可以选填 === 默认加载启动路径端口) public int Port { set;get; } // 服务注册地址 public string RegistryAddress { get; set; } // 服务健康检查地址 public string HealthCheckAddress { get; set; } }
服务Url类
/// <summary> /// 服务url /// </summary> public class ServiceUrl { public string Url { set; get; } }
consul服务注册实现
/// <summary> /// consul服务注册实现 /// </summary> public class ConsulServiceRegistry : IServiceRegistry { /// <summary> /// 注册服务 /// </summary> /// <param name="serviceNode"></param> public void Register(ServiceRegistryConfig serviceNode) { // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceNode.RegistryAddress); }); // 2、获取服务内部地址 // 3、创建consul服务注册对象 var registration = new AgentServiceRegistration() { ID = serviceNode.Id, Name = serviceNode.Name, Address = serviceNode.Address, Port = serviceNode.Port, Tags = serviceNode.Tags, Check = new AgentServiceCheck { // 3.1、consul健康检查超时间 Timeout = TimeSpan.FromSeconds(10), // 3.2、服务停止5秒后注销服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 3.3、consul健康检查地址 HTTP = serviceNode.HealthCheckAddress, // 3.4 consul健康检查间隔时间 Interval = TimeSpan.FromSeconds(10), } }; // 4、注册服务 consulClient.Agent.ServiceRegister(registration).Wait(); // 5、关闭连接 consulClient.Dispose(); } /// <summary> /// 注销服务 /// </summary> /// <param name="serviceNode"></param> public void Deregister(ServiceRegistryConfig serviceNode) { // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceNode.RegistryAddress); }); // 2、注销服务 consulClient.Agent.ServiceDeregister(serviceNode.Id); // 3、关闭连接 consulClient.Dispose(); } }
consul服务发现实现:
/// <summary> /// consul服务发现实现 /// </summary> public class ConsulServiceDiscovery : IServiceDiscovery { private readonly IConfiguration configuration; public ConsulServiceDiscovery(IConfiguration configuration) { this.configuration = configuration; } public async Task<IList<ServiceUrl>> Discovery(string serviceName) { ServiceDiscoveryConfig serviceDiscoveryConfig = configuration.GetSection("ConsulDiscovery").Get<ServiceDiscoveryConfig>(); // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceDiscoveryConfig.RegistryAddress); }); // 2、consul查询服务,根据具体的服务名称查询 var queryResult = await consulClient.Catalog.Service(serviceName); // 3、将服务进行拼接 var list = new List<ServiceUrl>(); foreach (var service in queryResult.Response) { list.Add(new ServiceUrl { Url = service.ServiceAddress + ":" + service.ServicePort }); } return list; } }
微服务注册发现使用扩展:
/// <summary> /// 微服务注册发现使用扩展 /// </summary> public static class MicroServiceConsulApplicationBuilderExtensions { public static IApplicationBuilder UseConsulRegistry(this IApplicationBuilder app) { // 1、从IOC容器中获取Consul服务注册配置 var serviceNode = app.ApplicationServices.GetRequiredService<IOptions<ServiceRegistryConfig>>().Value; // 2、获取应用程序生命周期 var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>(); // 2.1 获取服务注册实例 var serviceRegistry = app.ApplicationServices.GetRequiredService<IServiceRegistry>(); // 3、获取服务地址 var features = app.Properties["server.Features"] as FeatureCollection; var address = features.Get<IServerAddressesFeature>().Addresses.First(); var uri = new Uri(address); // 4、注册服务 serviceNode.Id = Guid.NewGuid().ToString(); serviceNode.Address = $"{uri.Scheme}://{uri.Host}"; serviceNode.Port = uri.Port; serviceNode.HealthCheckAddress = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceNode.HealthCheckAddress}"; serviceRegistry.Register(serviceNode); // 5、服务器关闭时注销服务 lifetime.ApplicationStopping.Register(() => { serviceRegistry.Deregister(serviceNode); }); return app; } }
注册中心扩展:
/// <summary> /// Console 注册中心扩展(加载配置) /// </summary> public static class MicroServiceConsulServiceCollectionExtensions { // consul服务注册 public static IServiceCollection AddConsulRegistry(this IServiceCollection services, IConfiguration configuration) { // 1、加载Consul服务注册配置 services.Configure<ServiceRegistryConfig>(configuration.GetSection("ConsulRegistry")); // 2、注册consul注册 services.AddSingleton<IServiceRegistry, ConsulServiceRegistry>(); return services; } // consul服务发现 public static IServiceCollection AddConsulDiscovery(this IServiceCollection services,IConfiguration configuration) { // 1、加载Consul服务发现配置 // services.Configure<ServiceDiscoveryConfig>(configuration.GetSection("ConsulDiscovery")); // 2、注册consul服务发现 services.AddSingleton<IServiceDiscovery, ConsulServiceDiscovery>(); return services; } }
微服务种的StartUp
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) { // 1、注册上下文到IOC容器 services.AddDbContext<TeamContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); }); // 2、注册团队service services.AddScoped<ITeamService, TeamServiceImpl>(); // 3、注册团队仓储 services.AddScoped<ITeamRepository, TeamRepository>(); // 5、添加服务注册条件 services.AddConsulRegistry(Configuration); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); // 1、consul服务注册 app.UseConsulRegistry(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!