ServiceCollectionExtensions.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using Grpc.Core;
  2. using Grpc.Extension.Abstract;
  3. using Grpc.Extension.Abstract.Discovery;
  4. using Grpc.Extension.Client.Interceptors;
  5. using Grpc.Extension.Client.Internal;
  6. using Grpc.Extension.Client.LoadBalancer;
  7. using Grpc.Extension.Client.Model;
  8. using Grpc.Extension.Common;
  9. using Grpc.Extension.Discovery;
  10. using Microsoft.Extensions.Configuration;
  11. using Microsoft.Extensions.DependencyInjection;
  12. using Microsoft.Extensions.Logging;
  13. using Microsoft.Extensions.Options;
  14. using OpenTracing;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Reflection;
  19. using System.Text;
  20. namespace Grpc.Extension.Client
  21. {
  22. /// <summary>
  23. /// ServiceCollectionExtensions
  24. /// </summary>
  25. public static class ServiceCollectionExtensions
  26. {
  27. /// <summary>
  28. /// 添加GrpcClient扩展
  29. /// </summary>
  30. /// <param name="services"></param>
  31. /// <param name="conf"></param>
  32. /// <returns></returns>
  33. public static IServiceCollection AddGrpcClientExtensions(this IServiceCollection services, IConfiguration conf)
  34. {
  35. //注入配制
  36. services.Configure<GrpcClientOptions>(conf.GetSection("GrpcClient"));
  37. //GrpcClientApp
  38. services.AddSingleton<GrpcClientApp>();
  39. //添加客户端中间件的CallInvoker
  40. services.AddSingleton<AutoChannelCallInvoker>();
  41. services.AddSingleton<CallInvoker, InterceptorCallInvoker>();
  42. //添加Channel的Manager
  43. services.AddSingleton<ChannelPool>();
  44. services.AddSingleton<GrpcClientManager>();
  45. //默认使用轮询负载策略,在外面可以注入其它策略
  46. if (!services.Any(p => p.ServiceType == typeof(ILoadBalancer)))
  47. {
  48. services.AddSingleton<ILoadBalancer, RoundLoadBalancer>();
  49. }
  50. //默认使用consul服务注册,服务发现,在外面可以注入其它策略
  51. if (!services.Any(p => p.ServiceType == typeof(IServiceRegister)))
  52. {
  53. services.AddConsulDiscovery();
  54. }
  55. //添加缓存
  56. services.AddMemoryCache();
  57. //添加客户端中间件
  58. services.AddClientCallTimeout();
  59. services.AddClientMonitor();
  60. //Jaeger
  61. services.AddClientJaeger(conf);
  62. return services;
  63. }
  64. /// <summary>
  65. /// 添加GrpcClient到Discovery,生成元数据
  66. /// </summary>
  67. /// <typeparam name="T"></typeparam>
  68. /// <param name="services"></param>
  69. /// <param name="discoveryServiceName">Discovery上客户端服务名字</param>
  70. /// <param name="discoveryUrl">Discovery的服务器地址</param>
  71. /// <param name="channelOptions">ChannelOption</param>
  72. /// <returns></returns>
  73. public static IServiceCollection AddGrpcClient<T>(this IServiceCollection services, string discoveryServiceName, string discoveryUrl = "", IEnumerable<ChannelOption> channelOptions = null) where T : ClientBase<T>
  74. {
  75. services.AddSingleton<T>();
  76. var channelConfig = new ChannelConfig
  77. {
  78. DiscoveryUrl = discoveryUrl,
  79. DiscoveryServiceName = discoveryServiceName,
  80. ChannelOptions = channelOptions
  81. };
  82. var bindFlags = BindingFlags.Static | BindingFlags.NonPublic;
  83. channelConfig.GrpcServiceName = typeof(T).DeclaringType.GetFieldValue<string>("__ServiceName", bindFlags);
  84. ChannelPool.Configs.Add(channelConfig);
  85. return services;
  86. }
  87. /// <summary>
  88. /// 添加GrpcClient到Discovery,生成元数据
  89. /// </summary>
  90. /// <typeparam name="T"></typeparam>
  91. /// <param name="services"></param>
  92. /// <param name="discoveryServiceName">Discovery上客户端服务名字</param>
  93. /// <param name="discoveryUrl">Discovery的服务器地址</param>
  94. /// <param name="channelOptions">ChannelOption</param>
  95. /// <returns></returns>
  96. public static IServiceCollection AddGrpcClientByDiscovery<T>(this IServiceCollection services, string discoveryServiceName, string discoveryUrl = "", IEnumerable<ChannelOption> channelOptions = null) where T : ClientBase<T>
  97. {
  98. services.AddGrpcClient<T>(discoveryServiceName, discoveryUrl, channelOptions);
  99. return services;
  100. }
  101. /// <summary>
  102. /// 添加客户端日志监控Interceptor
  103. /// </summary>
  104. /// <param name="services"></param>
  105. /// <returns></returns>
  106. private static IServiceCollection AddClientMonitor(this IServiceCollection services)
  107. {
  108. services.AddClientInterceptor<ClientMonitorInterceptor>();
  109. return services;
  110. }
  111. /// <summary>
  112. /// 添加客户端超时Interceptor
  113. /// </summary>
  114. /// <param name="services"></param>
  115. /// <returns></returns>
  116. private static IServiceCollection AddClientCallTimeout(this IServiceCollection services)
  117. {
  118. services.AddSingleton<ClientInterceptor>(sp =>
  119. {
  120. var options = sp.GetService<IOptions<GrpcClientOptions>>().Value;
  121. return new ClientCallTimeout(options.GrpcCallTimeOut);
  122. });
  123. return services;
  124. }
  125. /// <summary>
  126. /// 添加Jaeger
  127. /// </summary>
  128. /// <param name="services"></param>
  129. /// <param name="conf"></param>
  130. /// <returns></returns>
  131. public static IServiceCollection AddClientJaeger(this IServiceCollection services, IConfiguration conf)
  132. {
  133. //读取Jaeger配制
  134. var key = conf["GrpcServer:ServiceAddress"] != null ? "GrpcServer" : "GrpcClient";
  135. var jaegerOptions = conf.GetSection($"{key}:Jaeger").Get<JaegerOptions>();
  136. if (jaegerOptions == null || jaegerOptions.Enable == false)
  137. return services;
  138. //jaeger
  139. if (!services.Any(p => p.ServiceType == typeof(ITracer)))
  140. {
  141. services.AddSingleton<ITracer>(sp =>
  142. {
  143. var options = sp.GetService<IOptions<GrpcClientOptions>>().Value;
  144. var tracer = new Jaeger.Tracer.Builder(options.Jaeger.ServiceName)
  145. .WithLoggerFactory(sp.GetService<ILoggerFactory>())
  146. .WithSampler(new Jaeger.Samplers.ConstSampler(true))
  147. .WithReporter(new Jaeger.Reporters.RemoteReporter.Builder()
  148. .WithFlushInterval(TimeSpan.FromSeconds(5))
  149. .WithMaxQueueSize(5)
  150. .WithSender(new Jaeger.Senders.UdpSender(jaegerOptions.AgentIp, jaegerOptions.AgentPort, 1024 * 5)).Build())
  151. .Build();
  152. return tracer;
  153. });
  154. }
  155. //添加jaeger中间件
  156. services.AddClientInterceptor<ClientJaegerTracingInterceptor>();
  157. return services;
  158. }
  159. /// <summary>
  160. /// 添加客户端Interceptor
  161. /// </summary>
  162. /// <typeparam name="T"></typeparam>
  163. /// <param name="services"></param>
  164. /// <returns></returns>
  165. public static IServiceCollection AddClientInterceptor<T>(this IServiceCollection services) where T : ClientInterceptor
  166. {
  167. services.AddSingleton<ClientInterceptor, T>();
  168. return services;
  169. }
  170. }
  171. }