标签:hat 订阅 ext 支持 jpg process stream erro start
微信:tangy8080
电子邮箱:914661180@qq.com
更新时间:2019-06-28 14:25:40 星期五
欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程中的编写的文章
如您在阅读过程中发现文章错误,可添加我的微信 tangy8080 进行反馈.感谢您的支持。
介绍多个服务之间进行通讯
[无]
服务之间应该尽量较少调用.以减少耦合度,如果彼此调用链过于频繁.可能会引起整个调用链的异常.
https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/architect-microservice-container-applications/communication-in-microservice-architecture
The microservice community promotes the philosophy of "smart endpoints and dumb pipes" This slogan encourages a design that‘s as decoupled as possible between microservices, and as cohesive as possible within a single microservice. As explained earlier, each microservice owns its own data and its own domain logic. But the microservices composing an end-to-end application are usually simply choreographed by using REST communications rather than complex protocols such as WS-* and flexible event-driven communications instead of centralized business-process-orchestrators.
但服务之间的调用有时候会变得"随其自然",以上一章利用consul实现k8s服务自动发现
结尾的两个服务为例说明
terminal需要数据库的配置信息(ip,port等)以存储各个终端的数据,这些配置存放在configcenter中.那么terminal服务如何从configcenter中取出配置呢? 这时候就涉及到了服务间的通讯了
凡是涉及到通讯的,一般都会涉及到两个概念
在微服务之间通讯目前比较流行的有两种 TCP和HTTP
HTTP
这里,我选择自己手撸一个简单的微服务之间的调用的库,它的工作模式如下
在ConsulCaller中,我们使用了Consul库进行服务发现.当发现了服务实例时,程序会根据随机算法选取实例.然后返回给调用方.
git://gitblit.honeysuckle.site/public/Honeysuckle.git
public static void AddConsulCaller(this IServiceCollection services, Action<ConsulCallerOptions> optionsAction)
{
var consulConfiguration=new ConsulConfiguration();
services.AddSingleton<IConsulConfiguration>(consulConfiguration);
services.AddSingleton<IServiceDiscover, ServiceDiscover>();
services.AddSingleton<IConsulClientFactory, ConsulClientFactory.ConsulClientFactory>();
services.AddTransient<IConsulCaller, ConsulCaller>();
var consulCallerOptions = new ConsulCallerOptions(consulConfiguration);
optionsAction.Invoke(consulCallerOptions);
}
public IConsulClient Get(IConsulConfiguration config)
{
return new ConsulClient(c =>
{
c.Address = new Uri($"http://{config.Host}:{config.Port}");
if (!string.IsNullOrEmpty(config?.Token))
{
c.Token = config.Token;
}
});
}
3.另外一个重要的接口是IServiceDiscover,它包含一个GetServices的函数,该函数根据服务名称返回服务实例列表
private readonly IConsulClient _consul;
private const string VersionPrefix = "version-";
public ServiceDiscover(IConsulClientFactory consulClientFactory, IConsulConfiguration consulConfiguration)
{
_consul = consulClientFactory.Get(consulConfiguration);
}
public List<Service> GetServices(string key)
{
var queryResult = _consul.Health.Service(key, string.Empty, true).Result;
var services = new List<Service>();
foreach (var serviceEntry in queryResult.Response)
{
if (IsValid(serviceEntry))
{
var nodes = _consul.Catalog.Nodes().Result;
if (nodes.Response == null)
{
services.Add(BuildService(serviceEntry, null));
}
else
{
var serviceNode = nodes.Response.FirstOrDefault(n => n.Address == serviceEntry.Service.Address);
services.Add(BuildService(serviceEntry, serviceNode));
}
}
else
{
Console.WriteLine($"Unable to use service Address: {serviceEntry.Service.Address} and Port: {serviceEntry.Service.Port} as it is invalid. Address must contain host only e.g. localhost and port must be greater than 0");
}
}
return services;
}
private static Service BuildService(ServiceEntry serviceEntry, Node serviceNode)
{
return new Service(
serviceEntry.Service.Service,
new ServiceHostAndPort(serviceNode == null ? serviceEntry.Service.Address : serviceNode.Name, serviceEntry.Service.Port),
serviceEntry.Service.ID,
GetVersionFromStrings(serviceEntry.Service.Tags),
serviceEntry.Service.Tags ?? Enumerable.Empty<string>());
}
private static bool IsValid(ServiceEntry serviceEntry)
{
if (string.IsNullOrEmpty(serviceEntry.Service.Address) || serviceEntry.Service.Address.Contains("http://") || serviceEntry.Service.Address.Contains("https://") || serviceEntry.Service.Port <= 0)
{
return false;
}
return true;
}
private static string GetVersionFromStrings(IEnumerable<string> strings)
{
return strings
?.FirstOrDefault(x => x.StartsWith(VersionPrefix, StringComparison.Ordinal))
.TrimStart(VersionPrefix);
}
4.最后我们提供了一个IConsulCaller接口,它提供一个Call接口,输入服务名称和一个回调函数.
1.在asp.net core引用中添加了ConsulCaller服务
//使用ConsulCaller服务
services.AddConsulCaller(options =>
{
options.ConsulConfiguration.Host = Configuration["Consul:Host"];
options.ConsulConfiguration.Port = Convert.ToInt32(Configuration["Consul:Port"]);
});
2.调用集群中的其他服务
const string serviceName = "configcenter";
_consulCaller.Call(serviceName, (endpoint, httpclient) =>
{
try
{
var uri = $"http://{endpoint.DownstreamHost}:{endpoint.DownstreamPort}/Consul/Get";
//根据返回的服务实例,实现自己的调用逻辑
}
catch (Exception ex)
{
var errorMsg = $"{nameof(TerminalServerDbContext)}.{nameof(OnConfiguring)} _consulCaller.Call Error ";
Console.WriteLine(errorMsg + ex.Message);
Logger.Error(errorMsg, ex);
}
finally
{
httpclient.Dispose();
}
});
[无]
标签:hat 订阅 ext 支持 jpg process stream erro start
原文地址:https://www.cnblogs.com/gytangyao/p/11407232.html