一个微服务架构的系统中,不同服务之间是会相互调用的,如一个订单服务需要取用户数据,则需要调用用户服务,有多个用户服务实例时,Eureka会负载均衡到其中一个服务实例,和上一章一样,我们先通过Java版的服务发现及调用服务来做例子并移植到.net core版本。
1.Java版服务调用
1.1创建订单服务
和前面一样创建一个空的Maven项目,并改造成为一个Eureka客户端,修改下配置文件,服务名为userservice,端口设置为6661
1.2使用Ribbon做客户端负载均衡
添加ribbon的依赖,ribbon是一个客户端的负载均衡组件,服务间相互调用通过它来负载均衡
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
创建一个OrderController,同样创建一个User实体(实际项目中如果有多处调用同一个实体可以独立出来一个实体模块),在启动类中创建一个方法restTemplate()来注入restTemplate,并加上@Bean配置注解, @LoadBalanced负载均衡注解
@Bean
@LoadBalanced
RestTemplate restTemplate() {return newRestTemplate();
}
搜索:Spring RestTemplate as a Load Balancer Client

1.3订单服务调用用户服务
创建一个Service类用来封装调用其他服务,这里创建一个UserService类,封装userservice服务的方法,创建一个restTemplate变量加上@Autowired注解来实现自动扫描注入
packagecom.tz.orderservice;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.core.ParameterizedTypeReference;importorg.springframework.http.HttpMethod;importorg.springframework.http.ResponseEntity;importorg.springframework.web.client.RestTemplate;importjava.util.ArrayList;importjava.util.List;
@Servicepublic classUserService {
@AutowiredprivateRestTemplate restTemplate;public ListgetAll() {
ParameterizedTypeReference> responseType = new ParameterizedTypeReference>(){};
ResponseEntity> resp = restTemplate.exchange("http://userservice/user/getall",
HttpMethod.GET,null, responseType);
List list =resp.getBody();returnlist;
}
}
订单Controller中创建获取用户信息的方法
@RestController
@RequestMapping("/order")public classOrderController {
@AutowiredprivateUserService userService;
@RequestMapping("/getalluser")public ListgetAllUser(){returnuserService.getAll();
}
}
启动Eureka Server,启动两个userservice实例,启动orderservice,刷新服务注册中心,发现订单服务orderservice已经注册成功

浏览器访问订单服务的获取用户信息方法,可以看到成功调用了用户服务的方法

2. .net core版服务调用
2.1创建订单服务
按照上一章的方法创建一个.net Core的微服务,端口设置为6660,创建一个IUserService的接口,这里使用异步方法
public interfaceIUserService
{
Task>getAll() ;
TaskgetPort();
}
2.2订单服务调用用户服务
创建一个UserService类,实现IUserService接口来调用服务
Json序列化组件:Newtonsoft.Json
public classUserService : IUserService
{
DiscoveryHttpClientHandler _handler;private const string serviceUrl = "http://userservice/user";publicUserService(IDiscoveryClient client)
{
_handler= newDiscoveryHttpClientHandler(client);
}public async Task>getAll()
{var client =GetClient();var json= await client.GetStringAsync(serviceUrl+"/getall");
List list= JsonConvert.DeserializeObject>(json);returnlist;
}public async TaskgetPort()
{var client =GetClient();return await client.GetStringAsync(serviceUrl + "/getport");
}privateHttpClient GetClient()
{var client = new HttpClient(_handler, false);returnclient;
}
}
在Startup类的ConfigureServices中配置UserService的依赖注入
public voidConfigureServices(IServiceCollection services)
{//添加注入配置
services.AddScoped();//判断是否能获取Eureka配置
if (Configuration.GetSection("eureka").GetChildren().Any())
{//添加Steeltoe服务发现客户端服务配置
services.AddDiscoveryClient(Configuration);
}
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
创建一个OrderController,使用IUserService接口来调用,在构造方法中注入实例
[Route("[controller]")]
[ApiController]public classOrderController : ControllerBase
{private readonlyIUserService userService;//构造方法来注入实例
publicOrderController(IUserService userService)
{this.userService =userService;
}
[Route("getalluser")]
[HttpGet]public async Task>getAll()
{
List list = awaituserService.getAll();returnlist;
}
[Route("getuserserviceport")]
[HttpGet]public async TaskgetUserServicePort()
{var port = awaituserService.getPort();returnport;
}
}
启动项目,在刷新下Eureka Server,端口为6660的orderservice实例就注册到了服务中心

在浏览器中输入:http://localhost:6660/order/getuserserviceport,来调用userservice的获取端口的方法,多刷新几次就可以看到端口会不断的切换,说明已经实现了负载均衡。


.net core版的服务调用完成。
本文介绍了一个微服务架构中服务之间的调用过程,包括Java版和.NET Core版的实现方式,通过负载均衡实现服务间的高效调用。

4878

被折叠的 条评论
为什么被折叠?



