018 微服務之間調用

1 服務說明

    準備兩個maven項目,eureka-sales、eureka-user,經過訪問eureka-sales服務調用eureka-user服務,三種訪問方式下 eureka-user 代碼不變,只是爲了提供被訪問接口。git

    1-1 eureka

        pom依賴:算法

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-parent</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

        application.ymlspring

server:
  port: 8761
  
spring:
  application:
    name: eureka

eureka: 
  client:
    register-with-eureka: false
    fetch-registry: false
    server:
      waitTimeInMsWhenSyncEmpty: 0
    serviceUrl:
      defaultZone: http://localhost:${server.port}/eureka/

        啓動類,加上 @EnableEurekaServer 註解:bash

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaApplication.class, args);
	}
}

    1-2 eureka-sales

        pom依賴:app

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-parent</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

        定義接口:負載均衡

@RequestMapping("/sales")
public interface SalesRest {
    @RequestMapping(value = "/queryGoodsList/{type}", method = RequestMethod.GET)
    Object queryGoodsList(Integer type);
}

        接口實現類,根據傳入的type,決定以何種方式訪問 eureka-user 服務,1 表示 ribbon 方式,2 表示feign 方式,其餘數字表示 http 方式:maven

@RestController
public class SalesRestImpl implements SalesRest {

    @Autowired
    private SalesService salesService;

    @Override
    public String queryGoodsList(@PathVariable Integer type) {
    	System.out.println("start to queryGoodsList --->");
    	if(type.intValue() == 1) {
    		return salesService.queryGoodsListByRibbon();
    	}else if(type.intValue() == 2) {
    		return salesService.queryGoodsListByFeign();
    	}else {
            return salesService.queryGoodsListByHttp();
    	}
    }

}

        方法實現:ide

@Service
public class SalesService {
	
	@Autowired
	RestTemplate restTemplate;
	
	@Autowired
	UserFeignClient userFeignClient;
	
	private static final String RIBBON_URL = "http://user:8082/user/getUserInfo";
	private static final String HTTP_URL = "http://127.0.0.1:8082/user/getUserInfo";
	private static final String IP = IpUtil.getIp();

	public String queryGoodsListByRibbon() {
		String sales_result = "queryGoodsListByRibbon success : [sales_ip:" + IP + "] ";
		String result = restTemplate.getForObject(RIBBON_URL, String.class);
		return sales_result + result;
	}

	public String queryGoodsListByFeign() {
		String sales_result = "queryGoodsListByFeign success : [sales_ip:" + IP + "] ";
		String result = (String) userFeignClient.getUserInfo();
		return sales_result + result;
	}

	public String queryGoodsListByHttp() {
		String sales_result = "queryGoodsListByHttp success : [sales_ip:" + IP + "] ";
		String result = HttpClientUtil.doGet(HTTP_URL);
		return sales_result + result;
	}
}

        client工具

@FeignClient(name = "USER")
public interface UserFeignClient {
	@RequestMapping(value = "/user/getUserInfo", method = RequestMethod.GET)
	String getUserInfo();
}

    1-3 eureka-user

        pom依賴:測試

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-parent</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

        接口:

@RequestMapping("/user")
public interface UserRest {
	@RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
	String getUserInfo();
}

        接口實現類:

@RestController
public class UserRestImpl implements UserRest{
	
	@Autowired
	private UserService userService;

	@Override
	public String getUserInfo() {
		System.out.println("start to getUserInfo --->");
		return userService.getUserInfo(); 
	}

}

        方法實現,爲了驗證 ribbon 的負載均衡,這裏返回服務的端口號:

@Service("userService")
public class UserService {
	
	@Value("${server.port}")
	private Integer port;
	
	public String getUserInfo() {
		// 當前項目所在IP
		String ip = IpUtil.getIp();
		return "getUserInfo success : [user_ip:" + ip + "user_port:" + port + "] ";
	}

}

2 ribbon方式

        Ribbon 是 Netflix 發佈的負載均衡器,與 Eureka 配合使用時,Ribbon 能夠自動從 Eureka Server 獲取服務提供者地址列表,並基於負載均衡算法,請求其中某個服務提供者實例。Ribbon的依賴是:

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

可是 spring-cloud-starter-eureka 中已經包含了 ribbon 依賴,因此直接添加 eureka 便可。

    2-1 eureka-sales

        pom依賴,這裏直接有 eureka 就行,eureka 已經包含了 ribbon 依賴:

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
	</dependencies>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-parent</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

        application.yml

server:
  port: 8081

spring:
  application:
    name: sales
    
eureka:
  client:
    serviceUrl: 
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

        啓動類,這裏把 RestTemplate 註冊一下,而且加上 @LoadBalanced 開啓負載均衡:

@SpringBootApplication
@EnableDiscoveryClient
public class SalesApplication {
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
    	return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(SalesApplication.class,args);
    }

}

       調用 eureka-user 服務,其中 RIBBON_URL 中的 user 是eureka-user註冊到eureka中心的名稱,也就是 application.name :

@Service
public class SalesService {
	
	@Autowired
	RestTemplate restTemplate;
	
	private static final String RIBBON_URL = "http://user:8082/user/getUserInfo";
	private static final String IP = IpUtil.getIp();

	public String queryGoodsListByRibbon() {
		String sales_result = "queryGoodsListByRibbon success : [sales_ip:" + IP + "] ";
		String result = restTemplate.getForObject(RIBBON_URL, String.class);
		return sales_result + result;
	}
}

    2-2 測試

        1. 啓動 eureka 2. 啓動 eureka-sales 3.啓動 eureka-user 4.修改 eureka-user 的 application.yml 文件,將端口改成8083,啓動第二個 eureka-user 服務。

        訪問接口:http://127.0.0.1:8081/sales/queryGoodsList/1 

        此時以 ribbon 的方式訪問10次,結果說明有進行負載均衡

3 feign方式

    3-1 eureka-sales

        pom依賴,添加 feign 依賴:

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
	</dependencies>
	</build>
	
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-parent</artifactId>
				<version>Camden.SR3</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

        application.yml

server:
  port: 8081

spring:
  application:
    name: sales
    
eureka:
  client:
    serviceUrl: 
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

        啓動類,添加 @EnableFeignClients 註解: 

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class SalesApplication {
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
    	return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(SalesApplication.class,args);
    }

}

        建立 feign client 接口,這裏的 USER 是 eureka-user 在 eureka 中心的註冊名稱,裏面的接口定義成跟 eureka-user(被調用服務)中的接口同樣:

@FeignClient(name = "USER")
public interface UserFeignClient {
	@RequestMapping(value = "/user/getUserInfo", method = RequestMethod.GET)
	String getUserInfo();
}

         調用 eureka-user 服務:

@Service
public class SalesService {
	
	@Autowired
	UserFeignClient userFeignClient;
    private static final String IP = IpUtil.getIp();

	public String queryGoodsListByFeign() {
		String sales_result = "queryGoodsListByFeign success : [sales_ip:" + IP + "] ";
		String result = (String) userFeignClient.getUserInfo();
		return sales_result + result;
	}
}

    3-2 測試

        1. 啓動 eureka 2. 啓動 eureka-sales 3.啓動 eureka-user 4.修改 eureka-user 的 application.yml 文件,將端口改成8083,啓動第二個 eureka-user 服務。

        訪問接口:http://127.0.0.1:8081/sales/queryGoodsList/2

        此時以 ribbon 的方式訪問10次,結果說明有進行負載均衡

4 http方式

        就是本身封裝一個 httpclient 的 get 方法,而後訪問:

http://127.0.0.1:8081/sales/queryGoodsList/3,而後觀察結果,發現並無自動進行負載均衡:

5 附錄

    eureka 項目:https://code.aliyun.com/995586041/eureka.git

    eureka-sales 項目:https://code.aliyun.com/995586041/ribbon_feign_http_sales.git

    eureka-user 項目:https://code.aliyun.com/995586041/ribbon_feign_http_user.git

    core-simple 項目:https://code.aliyun.com/995586041/core-simple.git

    上文中相關工具方法在 core-simple 中 

相關文章
相關標籤/搜索