準備兩個maven項目,eureka-sales、eureka-user,經過訪問eureka-sales服務調用eureka-user服務,三種訪問方式下 eureka-user 代碼不變,只是爲了提供被訪問接口。git
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); } }
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(); }
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 + "] "; } }
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 便可。
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; } }
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次,結果說明有進行負載均衡
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; } }
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次,結果說明有進行負載均衡
就是本身封裝一個 httpclient 的 get 方法,而後訪問:
http://127.0.0.1:8081/sales/queryGoodsList/3,而後觀察結果,發現並無自動進行負載均衡:
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 中