升級微服務架構3:服務發現及服務相互調用


  一個微服務架構的系統中,不同服務之間是會相互調用的,如一個訂單服務需要取用戶數據,則需要調用用戶服務,有多個用戶服務實例時,Eureka會負載均衡到其中一個服務實例,和上一章一樣,我們先通過Java版的服務發現及調用服務來做例子並移植到.net core版本。

  1.Java版服務調用

  1.1創建訂單服務

  和前面一樣創建一個空的Maven項目,並改造成為一個Eureka客戶端,修改下配置文件,服務名為userservice,端口設置為6661

  1.2使用Ribbon做客戶端負載均衡

  添加ribbon的依賴,ribbon是一個客戶端的負載均衡組件,服務間相互調用通過它來負載均衡  

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

  創建一個OrderController,同樣創建一個User實體(實際項目中如果有多處調用同一個實體可以獨立出來一個實體模塊),在啟動類中創建一個方法restTemplate()來注入restTemplate,並加上@Bean配置注解, @LoadBalanced負載均衡注解  

@Bean
@LoadBalanced
RestTemplate restTemplate() {
    return new RestTemplate();
}

  參考官網文檔:http://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_spring_resttemplate_as_a_load_balancer_client

  搜索:Spring RestTemplate as a Load Balancer Client

  

  

  1.3訂單服務調用用戶服務

  創建一個Service類用來封裝調用其他服務,這里創建一個UserService類,封裝userservice服務的方法,創建一個restTemplate變量加上@Autowired注解來實現自動掃描注入  

package com.tz.orderservice;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    public List<User> getAll() {
        ParameterizedTypeReference<List<User>> responseType = new ParameterizedTypeReference<List<User>>(){};
        ResponseEntity<List<User>> resp = restTemplate.exchange("http://userservice/user/getall",
                HttpMethod.GET, null, responseType);
        List<User> list = resp.getBody();
        return list;
    }    
}

   訂單Controller中創建獲取用戶信息的方法

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private UserService userService;

    @RequestMapping("/getalluser")
    public List<User> getAllUser(){
        return userService.getAll();
    }
}

 

  啟動Eureka Server,啟動兩個userservice實例,啟動orderservice,刷新服務注冊中心,發現訂單服務orderservice已經注冊成功

  

  瀏覽器訪問訂單服務的獲取用戶信息方法,可以看到成功調用了用戶服務的方法

  

  2. .net core版服務調用

   2.1創建訂單服務

   按照上一章的方法創建一個.net Core的微服務,端口設置為6660,創建一個IUserService的接口,這里使用異步方法   

public interface IUserService
{
    Task<List<User>> getAll() ;

    Task<string> getPort();
}

 

   2.2訂單服務調用用戶服務

  創建一個UserService類,實現IUserService接口來調用服務

  參考:http://steeltoe.io/docs/steeltoe-discovery/#1-2-6-discovering-services

  Json序列化組件:Newtonsoft.Json  

public class UserService : IUserService
{
    DiscoveryHttpClientHandler _handler;
    private const string serviceUrl = "http://userservice/user";
    public UserService(IDiscoveryClient client)
    {
        _handler = new DiscoveryHttpClientHandler(client);
    }
    public async Task<List<User>> getAll()
    {
        var client = GetClient();
        var json= await client.GetStringAsync(serviceUrl+"/getall");
        List<User> list= JsonConvert.DeserializeObject<List<User>>(json);
        return list;
    }

    public async Task<string> getPort()
    {
        var client = GetClient();
        return await client.GetStringAsync(serviceUrl + "/getport");
    }
private HttpClient GetClient()
    {
        var client = new HttpClient(_handler, false);
        return client;
    }
}

 

  

  在Startup類的ConfigureServices中配置UserService的依賴注入

public void ConfigureServices(IServiceCollection services)
{
    //添加注入配置
    services.AddScoped<Controllers.IUserService, Controllers.UserService>();
    //判斷是否能獲取Eureka配置
    if (Configuration.GetSection("eureka").GetChildren().Any())
    {
        //添加Steeltoe服務發現客戶端服務配置
        services.AddDiscoveryClient(Configuration);
    }
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

  

  創建一個OrderController,使用IUserService接口來調用,在構造方法中注入實例  

[Route("[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
    private readonly IUserService userService;
    //構造方法來注入實例
    public OrderController(IUserService userService)
    {
        this.userService = userService;
    }

    [Route("getalluser")]
    [HttpGet]
    public async Task<List<User>> getAll()
    {
        List<User> list = await userService.getAll();
        return list;
    }

    [Route("getuserserviceport")]
    [HttpGet]
    public async Task<string> getUserServicePort()
    {
        var port = await userService.getPort();
        return port;
    }

}

 

 

  啟動項目,在刷新下Eureka Server,端口為6660的orderservice實例就注冊到了服務中心

  

  在瀏覽器中輸入:http://localhost:6660/order/getuserserviceport,來調用userservice的獲取端口的方法,多刷新幾次就可以看到端口會不斷的切換,說明已經實現了負載均衡。

  

  

  .net core版的服務調用完成。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM