I. Introduction
This article was originally continue to share IdentityServer4
the relevant article, because before Bo Friends ask me about 微服务
related issues, I would skip IdentityServer4
the sharing, 微服务
the relevant technical learning and sharing. 微服务
I shared directory is placed in the beginning of April to share a series of articles, here on the first pass through the lower, pre-arranged 微服务
opening article applications 电商系统升级之微服务架构的应用
.
This blog and the number of public adhere to the thinking of architecture to share technology, share more than just a simple Demo how to use .
Two, Scene
Under the first to review my articles on the application Asp.Net Core IdentityServer4 authorized centers in actual combat , the electricity supplier by the architecture 单体式架构
upgrade to Split多网关架构
Before you upgrade
After the upgrade:
However, after the upgrade problem again, due to the increase before the agency and the business 授权中心
and 支付网关
split out separately, which makes the company's business orders turned a few times, this time the entire electricity supplier system reached a bottleneck, if we do not find a solution You have to program the system is down.
2.1 Problems and Solutions
Through research and analysis of technical problems, the bottleneck causing the problem mainly in the following reasons, just need to solve the following problem you can get a great performance boost
- Surge orders per day, resulting in much the order data, however, the entire electrical system data stored in a supplier database, and is
单表
,单数据库
(not separated read and write), in order that the data continuously surge. - Related businesses need to rely order inquiries, orders that caused the collapse of a database query slow
- The whole business system to achieve electrical connections bottleneck (already distributed deployment, the server will consume more pay more funding and reach the best value for money)
In order to solve the above problems once and for all, through research and technology, decided to make the following order business upgrade:
- Split orders independent micro-services (This section focuses on sharing)
- Using
ES
data migration (divided by year, and to read and write separation, there is not focus on how, next time to learn and share with you) - Increase
分布式缓存
(this is not the focus of follow-up come to learn and share with you)
After Chart upgraded as follows:
Chart description:
- On behalf of the right of same color or previous electricity supplier system
单体式架构
, for a split single business architecture, business process in which a mixed layer of distributed cache processing - The left is the micro-architecture services, this upgrade is the split architecture, which has a database and migrate data from the original database split into ES cluster, and a separate read and write.
- Order service free to expansion into distributed services, dynamic expansion of support services and server through a number of tools.
- The right of the follow-up business can also be split, split into different business services.
- Subsequent upgrades may also be considered a related aspect the message queue, etc., not contemplated architecture diagram (used in the subsequent return to share the upgrade of the related art, there is a return to the core of the article
微服务
)
Third, micro-Services Overview
微服务
The concepts I will not say more, or less on the first micro-service advantages and disadvantages brought about by simple overview.
3.1 Advantages of micro-services
- The large, complex applications can deliver sustained and continuous deployment: Continuous Delivery and Continuous Deployment is part of DevOps, DevOps is a fast, frequent and reliable software delivery practices. Efficient DevOps organizations often deploy software faced with fewer problems and failure to production. DevOps tools
Docker
,Kubernets
,Jenkins
,Git
and so on. - Each service is relatively small and easy to maintain: micro Services Architecture Application monomer is small compared to the more developers understand the logic code service easier. Small code base, packing, start the service fast.
- Services can be deployed independently: Each service can be deployed independently of the other services
- It can be independently extended services: services can be extended independently, whether the X-axis extended Cloning of example, the Z-axis or flow partitioning. In addition, each service can be deployed on top of the hardware to fit their needs
- Micro-service architecture can achieve autonomy team: the team can be split according to the service. Each team has its own micro-responsible services, without concern that they are not responsible for service.
- Easier to test and adopt new technologies: Finally, micro-services can eliminate long-term reliance on a technology stack. Because the service is smaller, the use of programming languages and techniques to rewrite the replacement of a service becomes possible, this also means that, after a failed attempt on a new technology, you can directly discard this part of the work will not apply to the whole band to the risk of failure.
- Better fault tolerance: micro-services architecture can also achieve fault isolation replacement. For example, a service triggered a fatal error will not affect other services. Other services are still operating normally.
- Service can be independently expansion: For the whole structure, it can choose to expand and load-related business, conducted through random expansion of the relevant technical tools Dynamic
3.2 micro inferior services
- Split and service definition is a challenge: the use of micro-service architecture bear the brunt of the problem is that there is no one specific, well-defined algorithm can complete the split work services. As with software development, split, and the definition of service is more like an art. Worse, if the service system appeared split deviation is likely to build a distributed application monomer; contains a lot of tight coupling between each service, but must be deployed together the so-called distributed systems. This will put the drawbacks of both monomers architecture and micro-architecture services rolled into one.
- Distributed systems due to the complex nature, the development, testing and deployment becomes more difficult: Another problem with micro-services architecture is to create additional developer must deal with the complexity of distributed systems. Services must be inter-process communication. This is much more complex than a simple method call.
- More needs to be carefully coordinated development teams when deploying services across multiple functions: the use of micro-services architecture Another challenge is the need to more carefully coordinate the development team when deploying services across multiple functions. Must develop a release plan, sorted according to the service dependencies. This is now under way to deploy multiple components of different monomers architecture.
- Developers need to think in the end you should use the micro-service architecture at what stage of the application: Another problem with micro-service architecture is decided to start using this architecture in which stage of the application life cycle.
- Problem of cross-service data: in monomer applications, all data in one database, while the micro-services architecture, each service has its own database, you want to acquire, operate other data services, only through the service provides an API call, thus bringing the issue is a problem, the process of communication, if it comes to business, you also need to manage the affairs Saga, increasing the difficulty of development.
3.3 microService split principle
When it comes to 单体架构
splitting, it is not free to split, is to have certain principles, is the advantage of a good split, the split is not chaos. The following is my access to information as well as my experience summed up the principle of split
- 1, single responsibility, high cohesion and low coupling
- 2, the micro-size service moderate
- 3, consider the team structure
- 4, in order to cut into the business model
- 5, an evolved split
- 6, the annular avoid dependence and dependence bidirectional
- 7, DDD (consider using
领域驱动设计
to carry out the design of the underlying service, follow-up analyzes articles about the design of the individual)
Fourth, the micro-service combat
Well, here we have some understanding of the micro-services, do not continue a detailed overview of the concept of something related, directly below the line and the code, so that everyone familiar with the application of micro-services. Here I use 莫堇蕈
the open source on github micro-services framework , Frame Source Address: https://github.com/overtly/core-grpc ( I strongly recommend that this framework is now more mature company for production environments )
In order to better maintain open source projects and technical exchanges, deliberately created an exchange group, group number: 1083147206 Those interested to join the open source exchange
4.1 core-grpc
Micro Services Framework advantages:
- Consul achieve integration and service discovery mechanisms such as registration and health checks
- Real-time monitoring service status
- Multi-node polling mechanism
- Failover, pull into the blacklist
- Support Framework and .Net Core two frameworks
- Based Grpc micro service
- Deployment Support Environment Variables
4.2 combat
Creating Jlion.NetCore.OrderService
orders microService
We vs2019
create a console application to select the frame .Net Core 3.1 named Jlion.NetCore.OrderService
later referred to 订单服务
, after we have created through nuget
the introduction of package core-grpc
micro-services framework, as follows:
the current core-grpc
micro-services framework, the latest official release version is 1.0.3
Cites core-grpc
We also need to install a tool VS RPC Menu
, this tool is also a big God provided free of charge, the picture is as follows:
Because Microsoft's official download more slowly, I am here to share network disk Baidu, Baidu network disk download address is as follows:
Links: https://pan.baidu.com/s/1twpmA4_aErrsg-m0ICmOPw extraction code: cshs
If not installed by downloading vs integrated installation, the download is complete and needs to close vs 2019 related to normal installation.
VS RPC Menu tool as follows:
- The client code generation support for Grpc and Thrift
us again in订单服务
creating a project inOrderRequest.proto
a file, this isGrpc
the grammar, syntax do not understand the students can click gRPC official Chinese version of the document _V1.0 learning, address: HTTP: // DOC .oschina.net / grpc? t = 56831
OrderRequest.proto
code show as below:
syntax = "proto3";
package Jlion.NetCore.OrderService.Service.Grpc;
//定义订单查找参数实体
message OrderSearchRequest{
string OrderId = 1; //定义订单ID
string Name = 2;
}
//定义订单实体
message OrderRepsonse{
string OrderId = 1;
string Name = 2;
double Amount = 3;
int32 Count = 4;
string Time = 5;
}
//定义订单查找列表
message OrderSearchResponse{
bool Success = 1;
string ErrorMsg = 2;
repeated OrderRepsonse Data = 3;
}
The above is the definition of several news entity,
we then create the JlionOrderService.proto
following code:
syntax = "proto3";
package Jlion.NetCore.OrderService.Service.Grpc;
import "OrderRequest.proto";
service JlionOrderService{
rpc Order_Search(OrderSearchRequest) returns (OrderSearchResponse){}
}
The above code can see the top of package Jlion.NetCore.OrderService.Service.Grpc
the code, which is a statement after the package name is generated after the code name space, this is very important .
At the same time defines the JlionOrderService
service entrance, and defines a method of searching an order Order_Search
, here we have completed a small part of.
Generate client code
Then the JlionOrderService.proto
file inside right "choice Grpc Code Generation" Grpc code automatically survival of micro-service client code.
Survival tool has the following features:
- Survival Grpc client code
- Grpc compiler (not used)
- Grpc package (commonly used to publish client dll to nuget server)
- You can also generate the code and packetizes Thrift
Create a Jlion.NetCore.OrderService.Grpc
class library
Just by the tool to generate Grpc
client code direct copy of Jlion.NetCore.OrderService.Grpc
this library (package must be consistent with the code of the above statement Grpc) hereinafter referred to 订单服务客户端
, and need to Nuget
add packages Overt.Core.Grpc
dependency, the code structure is as follows:
Jlion.NetCore.OrderService.Grpc
library has been constructed, and now let Jlion.NetCore.OrderService
service reference Jlion.NetCore.OrderService.Grpc
library
订单服务
Achieve theirIHostedService
Create a HostService
class that inherits IHostedService
code is as follows:
public class HostedService : IHostedService
{
readonly ILogger _logger;
readonly JlionOrderServiceBase _grpcServImpl;
public HostedService(
ILogger<HostedService> logger,
JlionOrderServiceBase grpcService)
{
_logger = logger;
_grpcServImpl = grpcService;
}
//服务的启动机相关配置
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.Factory.StartNew(() =>
{
var channelOptions = new List<ChannelOption>()
{
new ChannelOption(ChannelOptions.MaxReceiveMessageLength, int.MaxValue),
new ChannelOption(ChannelOptions.MaxSendMessageLength, int.MaxValue),
};
GrpcServiceManager.Start(BindService(_grpcServImpl), channelOptions: channelOptions, whenException: (ex) =>
{
_logger.LogError(ex, $"{typeof(HostedService).Namespace.Replace(".", "")}开启失败");
throw ex;
});
System.Console.WriteLine("服务已经启动");
_logger.LogInformation($"{nameof(Jlion.NetCore.OrderService.Service).Replace(".", "")}开启成功");
}, cancellationToken);
}
//服务的停止
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.Factory.StartNew(() =>
{
GrpcServiceManager.Stop();
_logger.LogInformation($"{typeof(HostedService).Namespace.Replace(".", "")}停止成功");
}, cancellationToken);
}
}
The above code is mainly created a host computer and realized the StartAsync
service and start StopAsync
service stop method.
We've created HostedServicce
the code again created previously defined Grpc
method of service implementation class JlionOrderServiceImpl
, as follows:
public partial class JlionOrderServiceImpl : JlionOrderServiceBase
{
private readonly ILogger _logger;
private readonly IServiceProvider _serviceProvider;
public JlionOrderServiceImpl(ILogger<JlionOrderServiceImpl> logger, IServiceProvider provider)
{
_logger = logger;
_serviceProvider = provider;
}
public override async Task<OrderSearchResponse> Order_Search(OrderSearchRequest request, ServerCallContext context)
{
//TODO 从底层ES中查找订单数据,
//可以设计成DDD 方式来进行ES的操作,这里我就为了演示直接硬编码了
var response = new OrderSearchResponse();
try
{
response.Data.Add(new OrderRepsonse()
{
Amount = 100.00,
Count = 10,
Name = "订单名称测试",
OrderId = DateTime.Now.ToString("yyyyMMddHHmmss"),
Time = DateTime.Now.ToString()
});
response.Data.Add(new OrderRepsonse()
{
Amount = 200.00,
Count = 10,
Name = "订单名称测试2",
OrderId = DateTime.Now.ToString("yyyyMMddHHmmss"),
Time = DateTime.Now.ToString()
});
response.Data.Add(new OrderRepsonse()
{
Amount = 300.00,
Count = 10,
Name = "订单名称测试2",
OrderId = DateTime.Now.ToString("yyyyMMddHHmmss"),
Time = DateTime.Now.ToString()
});
response.Success = true;
}
catch (Exception ex)
{
response.ErrorMsg = ex.Message;
_logger.LogWarning("异常");
}
return response;
}
}
Modify Program
the code, and to HostedService
and JlionOrderServiceImpl
poured into the container, as follows:
class Program
{
static void Main(string[] args)
{
var host = new HostBuilder()
.UseConsoleLifetime() //使用控制台生命周期
.ConfigureAppConfiguration((context, configuration) =>
{
configuration
.AddJsonFile("appsettings.json", optional: true)
.AddEnvironmentVariables();
})
.ConfigureLogging(logger =>
{
logger.AddFilter("Microsoft", LogLevel.Critical)
.AddFilter("System", LogLevel.Critical);
})
.ConfigureServices(ConfigureServices)
.Build();
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
var logFactory = host.Services.GetService<ILoggerFactory>();
var logger = logFactory.CreateLogger<Program>();
logger.LogError(e.ExceptionObject as Exception, $"UnhandledException");
};
host.Run();
}
/// <summary>
/// 通用DI注入
/// </summary>
/// <param name="context"></param>
/// <param name="services"></param>
private static void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
//HostedService 单例注入到DI 中
services.AddSingleton<IHostedService, HostedService>();
services.AddTransient<JlionOrderServiceBase, JlionOrderServiceImpl>();
}
}
To here simply 微服务
already been encoded, but also the lack of two configuration files, we created appsettings.json
profiles, and consulsettings.json
service registration found in the configuration file
consulsettings.json
configuration file as follows:
{
"ConsulServer": {
"Service": {
"Address": "127.0.0.1:8500"// 你的Consul 服务注册及发现配置地址
}
}
}
The above address configuration is just a simple example, here I assume my Consul
service address is 127.0.0.1:8500 services start at will be registered with this address.
appsettings.json
Configuration files are as follows:
{
"GrpcServer": {
"Service": {
"Name": "JlionOrderService",
"Port": 10001,
"HostEnv": "serviceaddress",
"Consul": {
"Path": "dllconfigs/consulsettings.json"
}
}
}
}
I am here to serve the listening port 10001, registration back to Consul
the port will also see the
official full configuration file as follows:
{
"GrpcServer": {
"Service": {
"Name": "OvertGrpcServiceApp", // 服务名称使用服务名称去除点:OvertGrpcServiceApp
"Host": "service.g.lan", // 专用注册的域名 (可选)格式:ip[:port=default]
"HostEnv": "serviceaddress", // 获取注册地址的环境变量名字(可选,优先)环境变量值格式:ip[:port=default]
"Port": 10001, // 端口自定义
"Consul": {
"Path": "dllconfigs/consulsettings.json" // Consul路径
}
}
}
}
Well, 订单服务
have all been completed, 订单服务
the overall structure of the service is as follows:
Well, we here at the command line to start JlionOrderService
the service, you can build in a production environment Docker
inside the container
Before we can build a good look at my Consul
service, open the management interface, as shown:
images can be found just started the service has registered to go in, but there are a health check failed, mainly due to the server can not access my local of 订单服务
all health checks can not pass. You can set up your locally Consul
for testing services.
I come back to open a local service configurations by the port number 10001 into 10002, and then view the Consul
management interface, as shown below:
found to have registered two services, port numbers are 10001 and 10002, which can be customized tools and services to automatically add the shelf services, distributed services are complete.
Here 订单服务
start has been completely successful, we need next is a client that is above architecture diagram 电商业务网关
or 支付网关
so on to keep 订单服务
communication up.
Create an order gateway (with order service for communication)
Before you create an order I put the above Gateway 订单服务客户端
publish library to my nuget package, there is not demonstrated. I tested the package name published JlionOrderServiceDemo
nuget official search can find. You can also search directly added to your Demo for testing.
I created Asp.Net Core 3.1 framework by VS 2019 WebApi
named Jlion.NetCore.OrderApiService
below referred to 订单网关服务
now I posted earlier 微服务
client dependencies JlionOrderServiceDemo
added to 订单网关服务
the following chart:
Now 订单网关服务
add the OrderController
api controller, as follows:
namespace Jlion.NetCore.OrderApiService.Controllers
{
[Route("[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
private readonly IGrpcClient<OrderService.Service.Grpc.JlionOrderService.JlionOrderServiceClient> _orderService;
public OrderController (IGrpcClient<OrderService.Service.Grpc.JlionOrderService.JlionOrderServiceClient> orderService)
{
_orderService = orderService;
}
[HttpGet("getlist")]
public async Task<List<OrderRepsonse>> GetList()
{
var respData =await _orderService.Client.Order_SearchAsync(new OrderService.Service.Grpc.OrderSearchRequest()
{
Name = "test",
OrderId = "",
});
if ((respData?.Data?.Count ?? 0) <= 0)
{
return new List<OrderRepsonse>();
}
return respData.Data.ToList();
}
}
}
Injected via the constructor code OrderService
and provides an GetList
interface methods. Next, we also need to OrderService.Service.Grpc.JlionOrderService
inject into the container, as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//注册Grpc 客户端,具体可以查看源代码
services.AddGrpcClient();
}
Now the entire 订单网关服务
project structure below:
There are two most important project configuration dllconfig//Jlion.NetCore.OrderService.Grpc.dll.json
and consulsettings.json
they are doing it? We were content to see me both local configuration
Jlion.NetCore.OrderService.Grpc.dll.json
configuration is as follows:
{
"GrpcClient": {
"Service": {
"Name": "JlionOrderService", // 服务名称与服务端保持一致
"MaxRetry": 0, // 最大可重试次数,默认不重试
"Discovery": {
"Consul": { // Consul集群,集群优先原则
"Path": "dllconfigs/consulsettings.json"
},
"EndPoints": [ // 单点模式
{
"Host": "127.0.0.1",
"Port": 10001
}]
}
}
}
}
Jlion.NetCore.OrderService.Grpc.dll.json
Configuration is to tell 订单网关服务
and 订单服务
what to communicate, and communication among some of the parameters. To test my local use single mode, without the use of Consul mode
consulsettings.json
configuration is as follows:
{
"ConsulServer": {
"Service": {
"Address": "127.0.0.1:8500"
}
}
}
Have not found the same configuration and the configuration of the server before, it is to tell 订单网关服务
(clients caller) and 订单服务
server-side service discovery cluster address, if the above configuration is a single-point mode if this configuration will not work.
Here 订单网关服务
(client-side call) coding is completed, we started it:
I'm here fixed 5003 port, now a perfect start, we visited orders interface look successful. Access results as shown below:
Micro service perfect run successfully.
The above construction of micro-services is still relatively trouble, the official provides a more rapid way to build micro-services you need, do not need to write that code above, all of those codes to build your micro-services through the template, there is a need to learn to be click on
micro-services project to build templates tutorial
tutorial address: https://www.cnblogs.com/jlion/p/12494525.html
Article Demo code has been filed on github, code address: https://github.com/a312586670/IdentityServerDemo
Micro Services Framework open source project Address: https://github.com/overtly/core-grpc