微服务对应的就是单体式开发,单体开发和微服务的优缺点:
单体式开发:
单体式开发简单理解为所有服务都部署在一起(一台服务器),比如电商系统,把订单、财务、仓储、物流、用户等模块放到一起。
优点:开发简单,集中管理,不会重复开发,没有分布式的管理和损耗。
缺点:不好维护,升级很难,扩展性不足,无法应对现代化的迭代节奏。
微服务架构:
微服务架构把多个模块拆分成独立的模块,部署在一台或多台服务器上。
优点:
- 微服务是松藕合的,无论是在开发阶段或部署阶段都是独立的。
- 能够快速响应, 局部修改容易, 一个服务出现问题不会影响整个应用。
- 易于和第三方应用系统集成, 支持使用不同的语言开发, 允许你利用融合最新技术。
- 每个微服务都很小,足够内聚,足够小,代码容易理解。团队能够更关注自己的工作成果, 聚焦指定的业务功能或业务需求。
- 开发简单、开发效率提高,一个服务可能就是专一的只干一件事, 能够被小团队单独开发,这个小团队可以是 2 到 5 人的开发人员组成。
缺点:
- 微服务架构带来过多的运维操作, 可能需要团队具备一定的 DevOps 技巧.
- 分布式系统可能复杂难以管理。因为分布部署跟踪问题难。当服务数量增加,管理复杂性增加。
下面开始创建微服务的应用实例:
1.添加webapi服务(包括添加log4net、注册到控制器、记录日志) 微服务所有实例均基于.NetCore3.1
API程序创建好了以后添加log4net的相关配置,用于记录日志。
操作步骤可以参考:
在Controllers文件夹中添加一个控制器values
代码如下:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
#region 依赖注入
private readonly ILogger<ValuesController> _logger;
private IConfiguration _IConfiguration;
public ValuesController(ILogger<ValuesController> logger, IConfiguration configuration)
{
_logger = logger;
_IConfiguration = configuration;
}
#endregion
[HttpGet]
public IActionResult Get()
{
this._logger.LogInformation("ValuesController-Get执行");
return new JsonResult(
new
{
Id = 123,
Name = "张三",
Remark = this._IConfiguration["Consul:ServiceRemark"],
currentPort = this._IConfiguration["Port"],
CurrentPath = base.HttpContext.Request.Path
});
}
}
2.启动webapi服务
使用命令行启动两个应用程序实例,端口分别为5726,5727(端口是随意指定的),操作步骤如下:
将项目编译下,然后进入项目的程序目录中(bin\Debug\xxxxxx)
在这个目录里面,按住键盘的Shift键,然后点击鼠标右键,选择“在此处打开命令窗口”
这时候命令窗口就打开,并自动定位到当前目录下,在窗口中输入命令:
dotnet NetCore.DemoProject.dll --urls="http://*:5726" --ip="127.0.0.1" --port=5726
NetCore.DemoProject.dll是程序集的名称,不同的项目程序集不同。
命令输入完成后,回车,就可以看到如下情况:
这就表示程序启动成功,在浏览器输入 http://localhost:5726/api/values 就可以看到api返回的信息:
用同样的操作再启动一个实例,在项目文件夹下按住Shift点击鼠标右键,选择“在此处打开命令窗口”,输入命令:
dotnet NetCore.DemoProject.dll --urls="http://*:5727" --ip="127.0.0.1" --port=5727
注意这次是5727端口,其他的不变。
这样就表示启动成功,在浏览器中访问5727端口:
到这一步为止,已经启动了两个实例(其实是同一个webapi程序)。
3.下载并安装Consul
下载完成后直接运行consul.exe程序
启动consul:
找到consul的安装目录,然后在当前文件夹中打开cmd(和上面的操作一样)
输入命令:
consul agent -dev
看到这个表示consul启动成功了。
在浏览器输入:http://localhost:8500/ui/dc1/services 便可看到相关服务信息:(8500是consul默认端口)
到此为止,consul和刚才创建的webapi还没有产生任何关系,下面就将webapi服务注册到cousul。
3.使用consul对webapi服务进行注册
首先在webapi项目中使用NuGet包管理器安装Consul程序集
安装完成后在项目中创建ConsulRegister.cs的类,类中写一个扩展方法,用于将webapi服务注册到consul中
代码如下:
public static class ConsulRegister
{
/// <summary>
/// 扩展方法 将服务注册到consul
/// </summary>
/// <param name="configuration"></param>
public static void RegisterConsul(this IConfiguration configuration)
{
#region 注册consul
string ip = configuration["ip"] ?? "Localhost"; //configuration["ip"] 为null时取Localhost
//部署到不同服务器的时候不能写成127.0.0.1或者0.0.0.0,因为这是让服务消费者调用的地址
//int port = int.Parse(configuration["Consul:ServicePort"]);//服务端口
int port = string.IsNullOrWhiteSpace(configuration["port"]) ? 44344 : int.Parse(configuration["port"]);
ConsulClient client = new ConsulClient(obj =>
{
obj.Address = new Uri("http://127.0.0.1:8500");
obj.Datacenter = "dcl";
});
//向consul注册服务
Task<WriteResult> result = client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = "ApiServiceTest_" + Guid.NewGuid(),//服务编号,不能重复,用guid最简单
Name = "ApiServiceTest",//服务名称
Address = ip,
Port = port,
Tags = new string[] { },//可以用来设置权重
Check = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务停止多久后取消
Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔,或者成为心跳间隔
HTTP = $"http://{ip}:{port}/api/health",//健康检查地址
Timeout = TimeSpan.FromSeconds(5)//检测时最长等待时间
}
});
#endregion
}
}
4.完成健康检查(心跳检查)
添加健康检查的控制器
代码如下:
[Route("api/[controller]")]
[ApiController]
public class HealthController : ControllerBase
{
#region 依赖注入
private readonly ILogger<HealthController> _logger;
private IConfiguration _IConfiguration;
public HealthController(ILogger<HealthController> logger, IConfiguration configuration)
{
_logger = logger;
_IConfiguration = configuration;
}
#endregion
[HttpGet]
public IActionResult Check()
{
this._logger.LogInformation($"{this._IConfiguration["port"]}- Health Check!");
return Ok();//200
}
}
5.在Startup.cs类中调用第三步创建的扩展方法RegisterConsul,在webapi程序启动时将服务注册到consul:
到此为止,代码编写完成。
重新编译项目代码,重新启动webapi服务(多个应用程序实例),可以看到控制台输出了健康检查(心跳检查)的日志信息。
在浏览器中进入consul默认页面,可以看到比刚开始多了名称为ApiServiceTest的服务:
进入ApiServiceTest的详情页面
到此为止,成功把webapi服务注册到consul中。
接下去就是基于consul完成服务的调用......