.net framework 4.5 +steeltoe+ springcloud(二) 实现服务发现与调用功能
首先,写一个简单的可被调用的服务注册到服务中心,我们这命名为java-service,用的是IDEA创建一个spring boot项目,选择spring client类型。
修改application.properties,配置服务中心地址和服务端口号:
spring.application.name=java-service server.port=3222 eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
修改pom.xml,加入架包引用:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
修改主程序入口DemoclientApplication.java:
package com.ty.democlient; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableEurekaClient @RestController public class DemoclientApplication { public static void main(String[] args) { SpringApplication.run(DemoclientApplication.class, args); } @Value("${server.port}") String port; @RequestMapping("/hi") public String home(@RequestParam String name) { return "hi "+name+",i am from port:" +port; } }
把服务跑起来之后,我们看到在服务中心已经能看见这个服务了:
打开浏览器输入http://localhost:3222/hi?name=demo,可以看到服务正常返回:
现在我们的目标是在另外一个.NET MVC项目里通过服务名就能正常调用到这个服务,来看看怎么做:
新建一个基于.Net Framework 4.5 的MVC项目,首先根目录还是要有一个appsettings.json的文件作为服务配置文件:
{ "spring": { "application": { "name": "demo_netfetch" } }, "eureka": { "client": { "serviceUrl": "http://localhost:8761/eureka/", "shouldFetchRegistry": true, "shouldRegisterWithEureka": true, "validate_certificates": false }, "instance": { "port": 3001 // Remove comments to enable SSL requests // More changes in Program.cs are required if using direct C2C communications //,"securePortEnabled": true } }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "Pivotal": "Debug", "Steeltoe": "Debug" } } }
shouldFetchRegistry设置为true代表这是一个服务发现客户端
然后在项目目录下创建Service调用的类,配置具体调用的服务名,内容输出方式等:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using System.Web; using Microsoft.Extensions.Logging; using Steeltoe.Common.Discovery; namespace DemoNetFetchClient.Services { public class FetchServise : IFetchServise { DiscoveryHttpClientHandler _handler; private const string RANDOM_FORTUNE_URL = "http://java-service/hi?name=tian";//服务中心已注册的服务地址 private ILogger<FetchServise> _logger; public FetchServise(IDiscoveryClient client, ILoggerFactory logFactory = null) { _handler = new DiscoveryHttpClientHandler(client); _logger = logFactory?.CreateLogger<FetchServise>(); } public async Task<string> RandomFortuneAsync() { _logger?.LogInformation("RandomFortuneAsync"); var client = GetClient(); return await client.GetStringAsync(RANDOM_FORTUNE_URL); } private HttpClient GetClient() { var client = new HttpClient(_handler, false); return client; } } }
注意这里需要引用扩展包:Steeltoe.Common.Discovery,从NuGet里加载就可以,注意版本,要选择NET专用的,而不是Core用的。
修改HomeController.cs,异步请求调用内部服务:
public class HomeController : Controller { IFetchServise _fortunes; ILogger<HomeController> _logger; public HomeController(IFetchServise fortunes, ILoggerFactory logFactory = null) { _fortunes = fortunes; _logger = logFactory?.CreateLogger<HomeController>(); } public async System.Threading.Tasks.Task<ActionResult> Index() { ViewBag.Message = await _fortunes.RandomFortuneAsync(); return View(); } }
修改Global.asax,注册服务客户端:
这里要注意,如果项目是webapi程序,需要按Autofac集成webAPI的配置,具体请参考我的另一篇笔记:C# Autofac集成之Framework WebAPI
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); ApplicationConfig.RegisterConfig("development"); var builder = new ContainerBuilder(); // Add Microsoft Options to container builder.RegisterOptions(); // Add Microsoft Logging to container builder.RegisterLogging(ApplicationConfig.Configuration); // Add Console logger to container builder.RegisterConsoleLogging(); // Register all the controllers with Autofac builder.RegisterControllers(typeof(MvcApplication).Assembly); // Register IDiscoveryClient, etc. builder.RegisterDiscoveryClient(ApplicationConfig.Configuration); // Register FortuneService builder.RegisterType<FetchServise>().As<IFetchServise>().SingleInstance(); // Create the Autofac container var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // Get a logger from container var logger = container.Resolve<ILogger<MvcApplication>>(); logger.LogInformation("Finished container build, starting background services"); // Start the Discovery client background thread container.StartDiscoveryClient(); logger.LogInformation("Finished starting background services"); }
ok!done!程序跑起来效果,成功调用到服务中心内部服务java-service: