上一篇说了一下用HttpClientFactory实现了简单的熔断降级。

这篇就来简单说说用HttpClientFactory来实现服务发现。由于标题已经好明显的说了Steeltoe

因此这里会要求有Spring Clound的相关环境,本文也默认各位对这里有些许了解,所以不会涉及搭建过程的。

下面就开始正文了。

这里的Service,其实可以比较简单的理解成对注册到Eureka的服务进行调用,然后进行后续处理。

  1. public interface IMyService
  2. {
  3. Task<string> GetTextAsync();
  4. }
  5. public class MyService : IMyService
  6. {
  7. private readonly ILogger _logger;
  8. private readonly HttpClient _httpClient;
  9. private const string MY_URL = "";
  10. public MyService(HttpClient httpClient, ILoggerFactory logFactory)
  11. {
  12. _logger = logFactory.CreateLogger<MyService>();
  13. _httpClient = httpClient;
  14. }
  15. public async Task<string> GetTextAsync()
  16. {
  17. HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, MY_URL);
  18. var responseMessage = await _httpClient.SendAsync(requestMessage);
  19. var result = await responseMessage.Content.ReadAsStringAsync();
  20. _logger.LogInformation("GetTextAsync: {0}", result);
  21. return result;
  22. }
  23. }

在上面的Service中,都是常规的不能再常规的HttpClient的用法!似乎也没有看到任何和服务发现相关的东西呀。

确实,就上面的代码,完成不了服务发现,因为我们的主角,HttpClientFactory还没有出场!

先定义好这个Service,是因为我们这里要用另一种client方式(Typed Client)。

下面就去Startup进行相关的配置了。

在进行配置之前,我们要先添加Steeltoe.Discovery.ClientCore的引用。

  1. <PackageReference Include="Steeltoe.Discovery.ClientCore" Version="2.1.0-rc1" />

再按照Steeltoe的配置说明,在appsettings.json中添加下面的配置

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft": "Error"
  6. }
  7. },
  8. "AllowedHosts": "*",
  9. "spring": {
  10. "application": {
  11. "name": "clienttest"
  12. }
  13. },
  14. "eureka": {
  15. "client": {
  16. "serviceUrl": "http://192.168.1.133:7070/eureka/",
  17. "shouldFetchRegistry": true,
  18. "ValidateCertificates": false
  19. },
  20. "instance": {
  21. "port": 7788,
  22. "instanceId": "192.168.1.116:7788",
  23. "hostName": "192.168.1.116"
  24. }
  25. }
  26. }

最后就是在ConfigureServices方法里面进行操作了。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. //服务发现客户端
  4. services.AddDiscoveryClient(Configuration);
  5. //服务发现的Handler
  6. services.AddTransient<DiscoveryHttpMessageHandler>();
  7. //HttpClient
  8. services.AddHttpClient("my", c =>
  9. {
  10. c.BaseAddress = new Uri("http://bservicetest/api/values/");
  11. })
  12. .AddHttpMessageHandler<DiscoveryHttpMessageHandler>()
  13. .AddTypedClient<IMyService, MyService>();
  14. //2.1
  15. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  16. }

这里注册HttpClient,涉及到了两个点。一个是Typed Client,另一个是outgoing request middleware

Typed Client 主要是AddTypedClient<IMyService, MyService>(),表明注册的这个HttpClient是给这个类型用的。

DiscoveryHttpMessageHandler表明,使用这个HttpClient的时候,会使用这个Handler.

另外,这里指定的BaseAddress是http://bservicetest/api/values/。

这个是已经注册到Eureka的另外一个测试服务,我们就是要发现它,然后从这个服务里面取到结果。

然后,自然就是控制器了。

Controller就是很简单的了,不需要多说。

  1. [Route("api/[controller]")]
  2. [ApiController]
  3. public class ValuesController : ControllerBase
  4. {
  5. // GET api/values/text
  6. [HttpGet("text")]
  7. public async Task<string> GetTextAsync([FromServices]Services.IMyService service)
  8. {
  9. return await service.GetTextAsync();
  10. }
  11. }

这里还加了一个日志,是为了方便发布后查看日志,所以添加了NLog来输出日志。

添加一个nlog.config,内容大致如下。

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. autoReload="true"
  5. throwConfigExceptions="true">
  6. <!-- the targets to write to -->
  7. <targets>
  8. <target xsi:type="File"
  9. name="archive"
  10. archiveEvery="Day"
  11. archiveFileName = "test-{########}.log"
  12. archiveNumbering = "Date"
  13. archiveDateFormat = "yyyyMMdd"
  14. maxArchiveFiles = "4"
  15. fileName="logs/test.log"
  16. layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
  17. </targets>
  18. <!-- rules to map from logger name to target -->
  19. <rules>
  20. <!--All logs, including from Microsoft-->
  21. <logger name="*" minlevel="Info" writeTo="archive" />
  22. <logger name="Microsoft.*" minlevel="Error" writeTo="archive" final="true" />
  23. </rules>
  24. </nlog>

然后在Program添一行使用NLog的代码。

  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. CreateWebHostBuilder(args).Build().Run();
  6. }
  7. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  8. WebHost.CreateDefaultBuilder(args)
  9. .UseStartup<Startup>()
  10. .UseNLog();
  11. }

发布之后,可以看到Eureka上面已经成功注册了我们的这个ClientTest服务

其中,上图两个箭头的地方就是我们用到的服务,CLIENTTEST就是我们刚才发布的。BSERVICETEST是另一个测试服务。

CLIENTTEST就是会调用BSERVICETEST这个测试服务拿数据。

下面请求看看效果。

从动图来看,是已经达到预期了,由于BSERVICETEST有两个实例,所以也可以看到上面的结果是,两个实例在随机返回结果。

最后看看日志

请求也确实是到了我们的BSERVICETEST,而不是直接通过这个service的直接地址去访问的。

Outgoing request middleware这个功能对HttpClientFactoty来说,用途似乎不少,就看各位怎么发挥了。

Steeltoe团队似乎也在尝试将Hystrix以HttpClientFactoty的形式来调用。对比Polly,就个人而言,还是觉得Polly好用一点。

最后附上本文的示例代码

SteeltoeWithHttpClientFactory

版权声明:本文为catcher1994原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/catcher1994/p/9381735.html